#include "outputs.h" #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "esp_log.h" static const char *TAG = "smart-oil-heater-control-system-outputs"; const uint8_t uCirculationPumpGpioPin = CONFIG_GPIO_CIRCULATION_PUMP; const uint8_t uBurnerGpioPin = CONFIG_GPIO_BURNER; const uint8_t uSafetyContactGpioPin = CONFIG_GPIO_SAFETY_CONTACT; static SemaphoreHandle_t xMutexAccessOutputs = NULL; static eOutput sCirculationPumpState; static eOutput sBurnerState; static eOutput sSafetyContactState; void initOutputs(void) { gpio_config_t ioConfCirculationPump = { .pin_bit_mask = (1ULL << uCirculationPumpGpioPin), // Pin mask .mode = GPIO_MODE_OUTPUT, // Set as output .pull_up_en = GPIO_PULLUP_DISABLE, // Disable pull-up .pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down .intr_type = GPIO_INTR_DISABLE // Disable interrupts }; gpio_config_t ioConfBurner = { .pin_bit_mask = (1ULL << uBurnerGpioPin), // Pin mask .mode = GPIO_MODE_OUTPUT, // Set as output .pull_up_en = GPIO_PULLUP_DISABLE, // Disable pull-up .pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down .intr_type = GPIO_INTR_DISABLE // Disable interrupts }; gpio_config_t ioConfSafetyContact = { .pin_bit_mask = (1ULL << uSafetyContactGpioPin), // Pin mask .mode = GPIO_MODE_OUTPUT, // Set as output .pull_up_en = GPIO_PULLUP_DISABLE, // Disable pull-up .pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down .intr_type = GPIO_INTR_DISABLE // Disable interrupts }; esp_err_t ret = gpio_config(&ioConfCirculationPump); if (ret != ESP_OK) { ESP_LOGE(TAG, "GPIO config failed: %s", esp_err_to_name(ret)); return; } ret = gpio_config(&ioConfBurner); if (ret != ESP_OK) { ESP_LOGE(TAG, "GPIO config failed: %s", esp_err_to_name(ret)); return; } ret = gpio_config(&ioConfSafetyContact); if (ret != ESP_OK) { ESP_LOGE(TAG, "GPIO config failed: %s", esp_err_to_name(ret)); return; } xMutexAccessOutputs = xSemaphoreCreateRecursiveMutex(); if (xMutexAccessOutputs == NULL) { ESP_LOGE(TAG, "Unable to create mutex"); } xSemaphoreGiveRecursive(xMutexAccessOutputs); } eOutput getCirculationPumpState(void) { eOutput ret = ENABLED; if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE) { ret = sCirculationPumpState; xSemaphoreGiveRecursive(xMutexAccessOutputs); } else { ESP_LOGE(TAG, "Unable to take mutex: getCirculationPumpState()"); } return ret; } void setCirculationPumpState(eOutput in) { if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE) { sCirculationPumpState = in; switch (sCirculationPumpState) { case ENABLED: gpio_set_level(uCirculationPumpGpioPin, 0U); // Switch on Circulation Pump break; case DISABLED: gpio_set_level(uCirculationPumpGpioPin, 1U); // Switch off Circulation Pump break; default: break; } xSemaphoreGiveRecursive(xMutexAccessOutputs); } else { ESP_LOGE(TAG, "Unable to take mutex: setCirculationPumpState()"); } } eOutput getBurnerState(void) { eOutput ret = ENABLED; if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE) { ret = sBurnerState; xSemaphoreGiveRecursive(xMutexAccessOutputs); } else { ESP_LOGE(TAG, "Unable to take mutex: getBurnerState()"); } return ret; } void setBurnerState(eOutput in) { if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE) { sBurnerState = in; switch (sBurnerState) { case ENABLED: gpio_set_level(uBurnerGpioPin, 0U); // Switch on Burner break; case DISABLED: gpio_set_level(uBurnerGpioPin, 1U); // Switch off Burner break; default: break; } xSemaphoreGiveRecursive(xMutexAccessOutputs); } else { ESP_LOGE(TAG, "Unable to take mutex: setBurnerState()"); } } eOutput getSafetyControlState(void) { eOutput ret = ENABLED; if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE) { ret = sSafetyContactState; xSemaphoreGiveRecursive(xMutexAccessOutputs); } else { ESP_LOGE(TAG, "Unable to take mutex: getSafetyControlState()"); } return ret; } void setSafetyControlState(eOutput in) { if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE) { sSafetyContactState = in; switch (sSafetyContactState) { case ENABLED: gpio_set_level(uSafetyContactGpioPin, 0U); // Switch on power for Burner break; case DISABLED: gpio_set_level(uSafetyContactGpioPin, 1U); // Switch off power for Burner break; default: break; } xSemaphoreGiveRecursive(xMutexAccessOutputs); } else { ESP_LOGE(TAG, "Unable to take mutex: setSafetyControlState()"); } }