#include #include #include "driver/ledc.h" #include "esp_clk_tree.h" #include "esp_err.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" // IWYU pragma: keep #include "freertos/task.h" #include "hal/ledc_types.h" #include "soc/clk_tree_defs.h" #include "buzzer.h" static const char* TAG = "BUZZER_C"; const uint32_t init_buzzer_freq = 2731; void buzzer_init(const uint32_t frequency) { uint32_t clk_freq = 0; ESP_ERROR_CHECK(esp_clk_tree_src_get_freq_hz( SOC_MOD_CLK_RC_FAST, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &clk_freq)); uint32_t duty_resolution = ledc_find_suitable_duty_resolution(clk_freq, frequency); if (duty_resolution == 0) { ESP_LOGE(TAG, "Could not determine optimal duty resolution.\n"); return; } ledc_timer_config_t ledc_config = {.speed_mode = LEDC_LOW_SPEED_MODE, .timer_num = LEDC_TIMER_0, .freq_hz = frequency, .duty_resolution = duty_resolution, .clk_cfg = LEDC_USE_RC_FAST_CLK}; ESP_ERROR_CHECK(ledc_timer_config(&ledc_config)); ledc_channel_config_t ledc_ch_config = { .gpio_num = 9, .speed_mode = LEDC_LOW_SPEED_MODE, .channel = LEDC_CHANNEL_0, .timer_sel = LEDC_TIMER_0, .duty = (uint32_t)(pow(2, duty_resolution) / 2), // .hpoint = ((uint32_t) pow(2, duty_resolution)) - 1, .hpoint = 0, .sleep_mode = LEDC_SLEEP_MODE_KEEP_ALIVE, .flags.output_invert = false}; ESP_ERROR_CHECK(ledc_channel_config(&ledc_ch_config)); } uint32_t modify_frequency(int amount) { uint32_t freq = ledc_get_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0) + amount; if (freq < 10) { freq = 10; } buzzer_pause(); ESP_ERROR_CHECK(ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, freq)); buzzer_resume(); return freq; } uint32_t reset_frequency() { ESP_ERROR_CHECK( ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, init_buzzer_freq)); return init_buzzer_freq; } void set_frequency(const uint32_t freq) { ESP_ERROR_CHECK(ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, freq)); } void buzzer_pause() { ESP_ERROR_CHECK(ledc_timer_pause(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0)); } void buzzer_reset() { ESP_ERROR_CHECK(ledc_timer_rst(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0)); } void buzzer_resume() { ESP_ERROR_CHECK(ledc_timer_resume(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0)); }