3static const char *TAG =
"zh_ac_dimmer";
5#define ZH_LOGI(msg, ...) ESP_LOGI(TAG, msg, ##__VA_ARGS__)
6#define ZH_LOGE(msg, err, ...) ESP_LOGE(TAG, "[%s:%d:%s] " msg, __FILE__, __LINE__, esp_err_to_name(err), ##__VA_ARGS__)
8#define ZH_ERROR_CHECK(cond, err, cleanup, msg, ...) \
11 ZH_LOGE(msg, err, ##__VA_ARGS__); \
16static gptimer_handle_t _dimmer_timer = NULL;
17static gptimer_alarm_config_t _alarm_config = {0};
20static volatile uint64_t _prev_us = 0;
21static volatile uint8_t _dimmer_value = 0;
22static volatile bool _is_dimmer_work =
false;
23static bool _is_initialized =
false;
24static bool _is_prev_gpio_isr_handler =
false;
28static esp_err_t _zh_ac_dimmer_timer_init(
void);
29static void _zh_ac_dimmer_isr_handler(
void *arg);
30static bool _zh_ac_dimmer_timer_on_alarm_cb(gptimer_handle_t timer,
const gptimer_alarm_event_data_t *edata,
void *user_ctx);
34 ZH_LOGI(
"AC dimmer initialization started.");
35 ZH_ERROR_CHECK(_is_initialized ==
false, ESP_ERR_INVALID_STATE, NULL,
"AC dimmer initialization failed. AC dimmer is already initialized.");
36 esp_err_t err = _zh_ac_dimmer_validate_config(config);
37 ZH_ERROR_CHECK(err == ESP_OK, err, NULL,
"AC dimmer initialization failed. Initial configuration check failed.");
38 err = _zh_ac_dimmer_gpio_init(config);
39 ZH_ERROR_CHECK(err == ESP_OK, err, NULL,
"AC dimmer initialization failed. GPIO initialization failed.");
40 err = _zh_ac_dimmer_timer_init();
41 if (_is_prev_gpio_isr_handler ==
true)
43 ZH_ERROR_CHECK(err == ESP_OK, err, gpio_isr_handler_remove((gpio_num_t)config->
zero_cross_gpio); gpio_reset_pin((gpio_num_t)config->
triac_gpio);
44 gpio_reset_pin((gpio_num_t)config->
zero_cross_gpio),
"AC dimmer initialization failed. Timer initialization failed.");
48 ZH_ERROR_CHECK(err == ESP_OK, err, gpio_isr_handler_remove((gpio_num_t)config->
zero_cross_gpio); gpio_uninstall_isr_service(); gpio_reset_pin((gpio_num_t)config->
triac_gpio);
49 gpio_reset_pin((gpio_num_t)config->
zero_cross_gpio),
"AC dimmer initialization failed. Timer initialization failed.");
51 _init_config = *config;
52 _is_initialized =
true;
53 ZH_LOGI(
"AC dimmer initialization completed successfully.");
59 ZH_LOGI(
"AC dimmer deinitialization started.");
60 ZH_ERROR_CHECK(_is_initialized ==
true, ESP_ERR_INVALID_STATE, NULL,
"AC dimmer deinitialization failed. AC dimmer is not initialized.");
61 gptimer_stop(_dimmer_timer);
62 gptimer_disable(_dimmer_timer);
63 gptimer_del_timer(_dimmer_timer);
65 if (_is_prev_gpio_isr_handler ==
false)
67 gpio_uninstall_isr_service();
69 gpio_reset_pin((gpio_num_t)_init_config.
triac_gpio);
71 _is_dimmer_work =
false;
72 _is_initialized =
false;
76 ZH_LOGI(
"AC dimmer deinitialization completed successfully.");
82 ZH_LOGI(
"AC dimmer start begin.");
83 ZH_ERROR_CHECK(_is_initialized ==
true, ESP_ERR_INVALID_STATE, NULL,
"AC dimmer start failed. AC dimmer is not initialized.");
84 _is_dimmer_work =
true;
85 ZH_LOGI(
"AC dimmer start completed successfully.");
91 ZH_LOGI(
"AC dimmer stop begin.");
92 ZH_ERROR_CHECK(_is_initialized ==
true, ESP_ERR_INVALID_STATE, NULL,
"AC dimmer stop failed. AC dimmer is not initialized.");
93 _is_dimmer_work =
false;
94 ZH_LOGI(
"AC dimmer stop completed successfully.");
100 ZH_LOGI(
"AC dimmer setup begin.");
101 ZH_ERROR_CHECK(_is_initialized ==
true, ESP_ERR_INVALID_STATE, NULL,
"AC dimmer setup failed. AC dimmer is not initialized.");
102 ZH_ERROR_CHECK(value <= 100, ESP_ERR_INVALID_ARG, NULL,
"AC dimmer setup failed. Dimming value invalid.");
103 _dimmer_value = value;
104 ZH_LOGI(
"AC dimmer setup completed successfully.");
110 ZH_LOGI(
"AC dimmer getting status begin.");
111 ZH_ERROR_CHECK(value != NULL, ESP_ERR_INVALID_ARG, NULL,
"AC dimmer getting status failed. Value is NULL.");
112 ZH_ERROR_CHECK(_is_initialized ==
true, ESP_ERR_INVALID_STATE, NULL,
"AC dimmer getting status failed. AC dimmer is not initialized.");
113 *value = _dimmer_value;
114 ZH_LOGI(
"AC dimmer getting status completed successfully.");
120 ZH_ERROR_CHECK(config != NULL, ESP_ERR_INVALID_ARG, NULL,
"Initial config is NULL.");
121 ZH_ERROR_CHECK(config->
zero_cross_gpio < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG, NULL,
"Zero cross GPIO invalid.");
122 ZH_ERROR_CHECK(config->
triac_gpio < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG, NULL,
"Triac GPIO invalid.");
129 gpio_config_t triac_gpio_config = {
130 .intr_type = GPIO_INTR_DISABLE,
131 .mode = GPIO_MODE_OUTPUT,
133 .pull_down_en = GPIO_PULLDOWN_DISABLE,
134 .pull_up_en = GPIO_PULLUP_DISABLE,
136 esp_err_t err = gpio_config(&triac_gpio_config);
137 ZH_ERROR_CHECK(err == ESP_OK, err, NULL,
"Triac GPIO configuration failed.");
138 gpio_set_level((gpio_num_t)config->
triac_gpio, 0);
139 gpio_config_t zero_cross_gpio_config = {
140 .intr_type = GPIO_INTR_POSEDGE,
141 .mode = GPIO_MODE_INPUT,
143 .pull_down_en = GPIO_PULLDOWN_ENABLE,
144 .pull_up_en = GPIO_PULLUP_DISABLE,
146 err = gpio_config(&zero_cross_gpio_config);
147 ZH_ERROR_CHECK(err == ESP_OK, err, gpio_reset_pin((gpio_num_t)config->
triac_gpio),
"Zero cross GPIO configuration failed.");
148 err = gpio_install_isr_service(ESP_INTR_FLAG_LOWMED);
149 ZH_ERROR_CHECK(err == ESP_OK || err == ESP_ERR_INVALID_STATE, err, gpio_reset_pin((gpio_num_t)config->
triac_gpio); gpio_reset_pin((gpio_num_t)config->
zero_cross_gpio),
150 "Failed install isr service.")
151 if (err == ESP_ERR_INVALID_STATE)
153 _is_prev_gpio_isr_handler =
true;
155 err = gpio_isr_handler_add((gpio_num_t)config->
zero_cross_gpio, _zh_ac_dimmer_isr_handler, NULL);
156 if (_is_prev_gpio_isr_handler ==
true)
158 ZH_ERROR_CHECK(err == ESP_OK, err, gpio_reset_pin((gpio_num_t)config->
triac_gpio); gpio_reset_pin((gpio_num_t)config->
zero_cross_gpio),
"Failed add isr handler.");
162 ZH_ERROR_CHECK(err == ESP_OK, err, gpio_uninstall_isr_service(); gpio_reset_pin((gpio_num_t)config->
triac_gpio); gpio_reset_pin((gpio_num_t)config->
zero_cross_gpio),
163 "Failed add isr handler.");
168static esp_err_t _zh_ac_dimmer_timer_init(
void)
170 gptimer_config_t timer_config = {
171 .clk_src = GPTIMER_CLK_SRC_DEFAULT,
172 .direction = GPTIMER_COUNT_UP,
173 .resolution_hz = 1 * 1000 * 1000,
175 esp_err_t err = gptimer_new_timer(&timer_config, &_dimmer_timer);
176 ZH_ERROR_CHECK(err == ESP_OK, err, NULL,
"Failed create dimmer timer.");
177 gptimer_event_callbacks_t cbs = {
178 .on_alarm = _zh_ac_dimmer_timer_on_alarm_cb,
180 err = gptimer_register_event_callbacks(_dimmer_timer, &cbs, NULL);
181 ZH_ERROR_CHECK(err == ESP_OK, err, gptimer_del_timer(_dimmer_timer),
"Failed register dimmer timer event callbacks.");
182 err = gptimer_enable(_dimmer_timer);
183 ZH_ERROR_CHECK(err == ESP_OK, err, gptimer_register_event_callbacks(_dimmer_timer, NULL, NULL); gptimer_del_timer(_dimmer_timer),
"Failed enable dimmer timer.");
187static void IRAM_ATTR _zh_ac_dimmer_isr_handler(
void *arg)
189 uint64_t _current_us = esp_timer_get_time();
190 if (_current_us - _prev_us <= (1250 * 0.9))
194 gpio_set_level((gpio_num_t)_init_config.
triac_gpio, 0);
195 _prev_us = _current_us;
196 if (_is_dimmer_work ==
false)
200 if (_dimmer_value != 0)
202 if (_dimmer_value == 100)
204 gpio_set_level((gpio_num_t)_init_config.
triac_gpio, 1);
207 _alarm_config.alarm_count = (uint64_t)((((1250 - 330) / 100) * (100 - _dimmer_value)) + 330);
208 _alarm_config.flags.auto_reload_on_alarm =
false;
209 gptimer_set_alarm_action(_dimmer_timer, &_alarm_config);
210 gptimer_start(_dimmer_timer);
214static bool IRAM_ATTR _zh_ac_dimmer_timer_on_alarm_cb(gptimer_handle_t timer,
const gptimer_alarm_event_data_t *edata,
void *user_ctx)
216 gpio_set_level((gpio_num_t)_init_config.
triac_gpio, 1);
217 gptimer_stop(_dimmer_timer);
218 gptimer_set_raw_count(_dimmer_timer, 0);
Structure for initial initialization of AC dimmer.
esp_err_t zh_ac_dimmer_init(const zh_ac_dimmer_init_config_t *config)
Initialize AC dimmer.
esp_err_t zh_ac_dimmer_get(uint8_t *value)
Get AC dimmer dimming value.
esp_err_t zh_ac_dimmer_stop(void)
Stop AC dimmer.
esp_err_t zh_ac_dimmer_start(void)
Start AC dimmer.
esp_err_t zh_ac_dimmer_deinit(void)
Deinitialize AC dimmer.
esp_err_t zh_ac_dimmer_set(uint8_t value)
Set AC dimmer dimming value.