84 lines
2.1 KiB
C
84 lines
2.1 KiB
C
/*
|
|
* 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();
|
|
} |