/* * MTG RFID Companion - Piezo buzzer driver (LEDC PWM) */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "driver/ledc.h" #include "hw_pins.h" #include "buzzer.h" static const char *TAG = "buzzer"; #define BUZZER_SPEED_MODE LEDC_LOW_SPEED_MODE #define BUZZER_TIMER_NUM LEDC_TIMER_0 #define BUZZER_CHANNEL LEDC_CHANNEL_0 esp_err_t buzzer_init(void) { ledc_timer_config_t timer_cfg = { .speed_mode = BUZZER_SPEED_MODE, .timer_num = BUZZER_TIMER_NUM, .duty_resolution = LEDC_TIMER_13_BIT, .freq_hz = 2000, .clk_cfg = LEDC_AUTO_CLK, }; esp_err_t ret = ledc_timer_config(&timer_cfg); if (ret != ESP_OK) { return ret; } ledc_channel_config_t chan_cfg = { .gpio_num = HW_BUZZER_GPIO, .speed_mode = BUZZER_SPEED_MODE, .channel = BUZZER_CHANNEL, .timer_sel = BUZZER_TIMER_NUM, .duty = 0, .hpoint = 0, }; ret = ledc_channel_config(&chan_cfg); if (ret != ESP_OK) { return ret; } ESP_LOGI(TAG, "buzzer ready on GPIO %d", HW_BUZZER_GPIO); return ESP_OK; } esp_err_t buzzer_start(uint32_t freq_hz, uint32_t duty_percent) { if (freq_hz == 0) { return buzzer_stop(); } uint32_t duty = ((uint32_t)1 << 13) * duty_percent / 100u; if (duty_percent >= 100) { duty = ((uint32_t)1 << 13); } esp_err_t ret = ledc_set_freq(BUZZER_SPEED_MODE, BUZZER_TIMER_NUM, freq_hz); if (ret != ESP_OK) { return ret; } ret = ledc_set_duty(BUZZER_SPEED_MODE, BUZZER_CHANNEL, duty); if (ret != ESP_OK) { return ret; } return ledc_update_duty(BUZZER_SPEED_MODE, BUZZER_CHANNEL); } esp_err_t buzzer_stop(void) { ledc_set_duty(BUZZER_SPEED_MODE, BUZZER_CHANNEL, 0); return ledc_update_duty(BUZZER_SPEED_MODE, BUZZER_CHANNEL); } esp_err_t buzzer_chirp(uint32_t freq_hz, uint32_t duration_ms) { esp_err_t ret = buzzer_start(freq_hz, 30); if (ret != ESP_OK) { return ret; } vTaskDelay(pdMS_TO_TICKS(duration_ms)); return buzzer_stop(); }