diff --git a/README.md b/README.md index c14ecde..476c069 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ -# ESP32IDFDimmer +# ESP32 Triac Dimmer Driver -This library provides an API to control dimmer devices using the ESP32IDF. It supports both toggle and normal modes, and allows you to set the power levels of the dimmer. +This library provides an API to control dimmer devices using ESP-IDF 5.x. +**For ESP-IDF 4.x projects, please use the v1.0.0 release of this library.** +It supports both toggle and normal modes, and allows you to set the power levels of the dimmer. ### Prerequisites -- ESP32 board with ESP-IDF v4.1 or higher -- A dimmable AC load +- ESP32 board with ESP-IDF v5.0 or higher +- A dimmable AC load ### Installation -Clone the project from the repository and add the library to your project. +Clone the component into your project components directory. ### Usage 1. Include the library header in your program @@ -61,6 +63,14 @@ The library provides the following API methods: ![image](https://user-images.githubusercontent.com/49943249/194775053-0badd3f8-0c23-4a86-8843-abe2f994f5b3.png) +## Migrated to ESP-IDF 5.x and Component +This library has been migrated to ESP-IDF 5.x and is no longer compatible with previous versions. +It has also been transformed into an ESP-IDF component for easier integration. + +To use the basic example, add the component to your project's components directory and replace the main file with the code from examples/base/main.c. + +If you are using the library in a project that is not using ESP-IDF 5.x, you can still use the old version of the library (v1.0.0) which is compatible with ESP-IDF 4.x. + ## Contributing We welcome contributions to this library. Please open a pull request or an issue to get started. diff --git a/src/components/esp32-triac-dimmer-driver/CMakeLists.txt b/src/components/esp32-triac-dimmer-driver/CMakeLists.txt new file mode 100644 index 0000000..cfd15c8 --- /dev/null +++ b/src/components/esp32-triac-dimmer-driver/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "esp32-triac-dimmer-driver.c" + INCLUDE_DIRS "include" + REQUIRES driver +) \ No newline at end of file diff --git a/src/components/esp32-triac-dimmer-driver/component.mk b/src/components/esp32-triac-dimmer-driver/component.mk new file mode 100644 index 0000000..f92ebea --- /dev/null +++ b/src/components/esp32-triac-dimmer-driver/component.mk @@ -0,0 +1,2 @@ +COMPONENT_ADD_INCLUDEDIRS = . +COMPONENT_DEPENDS = driver \ No newline at end of file diff --git a/src/lib/esp32idfDimmer.c b/src/components/esp32-triac-dimmer-driver/esp32-triac-dimmer-driver.c similarity index 78% rename from src/lib/esp32idfDimmer.c rename to src/components/esp32-triac-dimmer-driver/esp32-triac-dimmer-driver.c index e66ff9a..c5a0f14 100644 --- a/src/lib/esp32idfDimmer.c +++ b/src/components/esp32-triac-dimmer-driver/esp32-triac-dimmer-driver.c @@ -1,5 +1,5 @@ -#include "esp32idfDimmer.h" +#include "esp32-triac-dimmer-driver.h" static const char *TAG = "Esp32idfDimmer"; @@ -31,7 +31,12 @@ volatile uint16_t togMin[ALL_DIMMERS]; volatile bool togDir[ALL_DIMMERS]; /* timer configurations */ -timer_config_t m_timer_config; +gptimer_config_t m_timer_config; +gptimer_handle_t gptimer = NULL; +typedef struct { + uint64_t event_count; +} example_queue_element_t; + dimmertyp *createDimmer(gpio_num_t user_dimmer_pin, gpio_num_t zc_dimmer_pin) { @@ -56,8 +61,35 @@ dimmertyp *createDimmer(gpio_num_t user_dimmer_pin, gpio_num_t zc_dimmer_pin) return dimmer[current_dim - 1]; } -#define TIMER_DIVIDER 80 // Hardware timer clock divider -#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds +#define TIMER_BASE_CLK 1 * 1000 * 1000, // 1MHz, 1 tick = 1us + +/** + * @brief Configure the timer alarm + */ +void config_alarm(gptimer_handle_t *timer, int ACfreq) +{ + /*self regulation 50/60 Hz*/ + double m_calculated_interval = (1 / (double)(ACfreq * 2)) / 100; + ESP_LOGI(TAG, "Interval between wave calculated for frequency : %3dHz = %5f", ACfreq, m_calculated_interval); + + ESP_LOGI(TAG, "Timer configuration - configure interrupt and timer"); + ESP_LOGI(TAG, "Timer configuration - configure alarm"); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, // counter will reload with 0 on alarm event + .alarm_count = (1000000 * m_calculated_interval), + .flags.auto_reload_on_alarm = true, // enable auto-reload + }; + ESP_LOGI(TAG, "Timer configuration - set alarm action"); + ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config)); + + gptimer_event_callbacks_t cbs = { + .on_alarm = onTimerISR, // register user callback + }; + ESP_LOGI(TAG, "Timer configuration - register event callbacks"); + ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, NULL)); + + ESP_LOGI(TAG, "Timer configuration - configuration completed"); +} void config_timer(int ACfreq) { @@ -72,28 +104,22 @@ void config_timer(int ACfreq) memset(&m_timer_config, 0, sizeof(m_timer_config)); /* Prepare configuration */ - timer_config_t m_timer_config = - { - .alarm_en = TIMER_ALARM_DIS, - .counter_en = TIMER_PAUSE, - .counter_dir = TIMER_COUNT_UP, - .auto_reload = TIMER_AUTORELOAD_EN, - .divider = TIMER_DIVIDER, - }; + gptimer_config_t m_timer_config = { + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = TIMER_BASE_CLK + }; - /*self regulation 50/60 Hz*/ - double m_calculated_interval = (1 / (double)(ACfreq * 2)) / 100; - ESP_LOGI(TAG, "Interval between wave calculated for frequency : %3dHz = %5f", ACfreq, m_calculated_interval); ESP_LOGI(TAG, "Timer configuration - configure interrupt and timer"); /* Configure the alarm value and the interrupt on alarm. */ - timer_init(TIMER_GROUP_0, TIMER_0, &m_timer_config); - timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_SCALE * m_calculated_interval); - timer_enable_intr(TIMER_GROUP_0, TIMER_0); - timer_isr_register(TIMER_GROUP_0, TIMER_0, onTimerISR, (void *)TIMER_0, ESP_INTR_FLAG_IRAM, NULL); + ESP_ERROR_CHECK(gptimer_new_timer(&m_timer_config, &gptimer)); + + /* Configure the alarm value and the interrupt on alarm. */ + config_alarm(gptimer, ACfreq); /* start timer */ ESP_LOGI(TAG, "Timer configuration - start timer"); - timer_start(TIMER_GROUP_0, TIMER_0); - timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN); + ESP_ERROR_CHECK(gptimer_enable(gptimer)); + ESP_ERROR_CHECK(gptimer_start(gptimer)); ESP_LOGI(TAG, "Timer configuration - completed"); } @@ -132,9 +158,9 @@ void ext_int_init(dimmertyp *ptr) } /*ISR debug region*/ -#if DEBUG_ISR_DIMMER == ISR_DEBUG_ON +#if DEBUG_ZERO_CROSS_SIGNAL == ISR_DEBUG_ON -static xQueueHandle gpio_zero_cross_evt_queue = NULL; +static QueueHandle_t gpio_zero_cross_evt_queue = NULL; static void gpio_isr_zerocross_debug(void *arg) { @@ -153,7 +179,7 @@ static void gpio_isr_zerocross_debug(void *arg) /*ISR timer debug region*/ #if DEBUG_ISR_TIMER == ISR_DEBUG_ON -static xQueueHandle timer_event_queue = NULL; +static QueueHandle_t timer_event_queue = NULL; static void timer_isr_debug(void *arg) { @@ -162,7 +188,7 @@ static void timer_isr_debug(void *arg) { if (xQueueReceive(timer_event_queue, &io_num, portMAX_DELAY)) { - printf("Timer interrupt event , counter = %5d \n", io_num); + printf("Timer interrupt event , counter = %5lu \n", io_num); } } } @@ -175,7 +201,7 @@ void begin(dimmertyp *ptr, DIMMER_MODE_typedef DIMMER_MODE, ON_OFF_typedef ON_OF dimMode[ptr->current_num] = DIMMER_MODE; dimState[ptr->current_num] = ON_OFF; -#if DEBUG_ISR_DIMMER == ISR_DEBUG_ON +#if DEBUG_ZERO_CROSS_SIGNAL == ISR_DEBUG_ON if (!_initDone) { // create a queue to handle gpio event from isr @@ -276,7 +302,7 @@ void toggleSettings(dimmertyp *ptr, int minValue, int maxValue) static void IRAM_ATTR isr_ext(void *arg) { -#if DEBUG_ISR_DIMMER == ISR_DEBUG_ON +#if DEBUG_ZERO_CROSS_SIGNAL == ISR_DEBUG_ON uint32_t gpio_num = (uint32_t)arg; xQueueSendFromISR(gpio_zero_cross_evt_queue, &gpio_num, NULL); #endif @@ -295,10 +321,6 @@ static int counter = 0; /* Execution on timer event */ static void IRAM_ATTR onTimerISR(void *para) { - /*Block needed to handle timer ISR*/ - timer_spinlock_take(TIMER_GROUP_0); - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); -/*Give back spinlock at the end of the method*/ /**********************************/ #if DEBUG_ISR_TIMER == ISR_DEBUG_ON counter++; @@ -355,9 +377,4 @@ static void IRAM_ATTR onTimerISR(void *para) } if (toggleCounter >= toggleReload) toggleCounter = 1; - - /* After the alarm has been triggered - we need enable it again, so it is triggered the next time */ - timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0); - timer_spinlock_give(TIMER_GROUP_0); } diff --git a/src/lib/esp32idfDimmer.h b/src/components/esp32-triac-dimmer-driver/include/esp32-triac-dimmer-driver.h similarity index 98% rename from src/lib/esp32idfDimmer.h rename to src/components/esp32-triac-dimmer-driver/include/esp32-triac-dimmer-driver.h index a9a0091..4b3c986 100644 --- a/src/lib/esp32idfDimmer.h +++ b/src/components/esp32-triac-dimmer-driver/include/esp32-triac-dimmer-driver.h @@ -9,7 +9,7 @@ #include "freertos/queue.h" #include "driver/gpio.h" #include "driver/periph_ctrl.h" -#include "driver/timer.h" +#include "driver/gptimer.h" #include "freertos/task.h" #include "math.h" #include "esp_log.h" diff --git a/src/examples/base/example.c b/src/examples/base/main.c similarity index 85% rename from src/examples/base/example.c rename to src/examples/base/main.c index ce1cbfe..445d316 100644 --- a/src/examples/base/example.c +++ b/src/examples/base/main.c @@ -1,4 +1,4 @@ -#include "esp32idfDimmer.h" +#include "esp32-triac-dimmer-driver.h" #include "esp_log.h" #include "esp_err.h" @@ -34,10 +34,10 @@ void app_main() while (1) { // change the output power - getPower(ptr_dimmer) < 60 ? setPower(ptr_dimmer, (getPower(ptr_dimmer) + 5)) : setPower(ptr_dimmer, 1); + getPower(ptr_dimmer) < 50 ? setPower(ptr_dimmer, (getPower(ptr_dimmer) + 1)) : setPower(ptr_dimmer, 20); setPower(ptr_dimmer_2, getPower(ptr_dimmer)); // wait - vTaskDelay(100 / portTICK_PERIOD_MS); + vTaskDelay(1000 / portTICK_PERIOD_MS); } }