|
@@ -0,0 +1,50 @@
|
|
|
|
+/*
|
|
|
|
+ * SPDX-FileCopyrightText: 2023 Helmut Pozimski <helmut@pozimski.eu>
|
|
|
|
+ *
|
|
|
|
+ * SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include <driver/ledc.h>
|
|
|
|
+#include <esp_err.h>
|
|
|
|
+#include <freertos/FreeRTOS.h>
|
|
|
|
+#include <freertos/event_groups.h>
|
|
|
|
+
|
|
|
|
+#define MODE LEDC_LOW_SPEED_MODE
|
|
|
|
+#define CHANNEL LEDC_CHANNEL_0
|
|
|
|
+#define DUTY 4095
|
|
|
|
+
|
|
|
|
+/* TODO: This code works reasonably well for low frequencies
|
|
|
|
+ * but has nasty high-pitched interference for high frequencies.
|
|
|
|
+ * It needs to be checked if this is caused by the code or the
|
|
|
|
+ * circutry.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+void alarm_init(uint32_t frequency) {
|
|
|
|
+ ledc_timer_config_t ledc_timer = {
|
|
|
|
+ .speed_mode = MODE,
|
|
|
|
+ .timer_num = LEDC_TIMER_0,
|
|
|
|
+ .duty_resolution = LEDC_TIMER_13_BIT,
|
|
|
|
+ .freq_hz = frequency, // Set output frequency at 5 kHz
|
|
|
|
+ .clk_cfg = LEDC_AUTO_CLK
|
|
|
|
+ };
|
|
|
|
+ ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
|
|
|
+
|
|
|
|
+ ledc_channel_config_t ledc_channel = {
|
|
|
|
+ .speed_mode = MODE,
|
|
|
|
+ .channel = CHANNEL,
|
|
|
|
+ .timer_sel = LEDC_TIMER_0,
|
|
|
|
+ .intr_type = LEDC_INTR_DISABLE,
|
|
|
|
+ .gpio_num = 5,
|
|
|
|
+ .duty = 0,
|
|
|
|
+ .hpoint = 0
|
|
|
|
+ };
|
|
|
|
+ ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void beep(uint32_t length_ms) {
|
|
|
|
+ ESP_ERROR_CHECK(ledc_set_duty(MODE, CHANNEL, DUTY));
|
|
|
|
+ ESP_ERROR_CHECK(ledc_update_duty(MODE, CHANNEL));
|
|
|
|
+ vTaskDelay(length_ms / portTICK_PERIOD_MS);
|
|
|
|
+ ESP_ERROR_CHECK(ledc_set_duty(MODE, CHANNEL, 0));
|
|
|
|
+ ESP_ERROR_CHECK(ledc_update_duty(MODE, CHANNEL));
|
|
|
|
+}
|