130 lines
2.6 KiB
C

/*
* SPDX-License-Identifier: AGPL-3.0-only
* Copyright (c) Camden Dixie O'Brien
*/
#include "sound.h"
#include "console.h"
#include "driver/dac.h"
#include "esp_log.h"
#include "esp_timer.h"
#include <string.h>
#define TAG "Sound"
#define CHANNEL DAC_CHANNEL_1
#define SIGNAL_FREQ CONFIG_ALERT_FREQ
#define SIGNAL_AMPLITUDE CONFIG_ALERT_AMPLITUDE
#define TOGGLE_PERIOD_US (1000 * CONFIG_ALERT_TOGGLE_PERIOD_MS)
static esp_timer_handle_t timer;
static bool signal_active;
static void toggle_signal(void *arg)
{
(void)arg;
if (signal_active) {
const esp_err_t error = dac_cw_generator_enable();
if (error != ESP_OK)
ESP_LOGE(TAG, "Error enabling signal: %04x", error);
else
signal_active = false;
} else {
const esp_err_t error = dac_cw_generator_disable();
if (error != ESP_OK)
ESP_LOGE(TAG, "Error disabling signal: %04x", error);
else
signal_active = true;
}
}
static int alert_command_func(int argc, char **argv)
{
if (argc != 2) {
printf("Invalid number of arguments\n");
return 1;
} else if (strcmp(argv[1], "on") == 0) {
sound_alert_on();
return 0;
} else if (strcmp(argv[1], "off") == 0) {
sound_alert_off();
return 0;
} else {
printf("Invalid state %s\n", argv[1]);
return 1;
}
}
void sound_init()
{
esp_err_t error;
dac_cw_config_t wave_gen_config = {
.en_ch = CHANNEL,
.scale = SIGNAL_AMPLITUDE,
.freq = SIGNAL_FREQ,
};
error = dac_cw_generator_config(&wave_gen_config);
if (error != ESP_OK) {
ESP_LOGE(TAG, "Error configuring wave generator: %04x", error);
return;
}
const esp_timer_create_args_t timer_config = {
.callback = &toggle_signal,
.arg = NULL,
.name = "signal toggle task",
};
error = esp_timer_create(&timer_config, &timer);
if (error != ESP_OK) {
ESP_LOGE(TAG, "Error creating toggle timer: %04x", error);
return;
}
console_register(
"alert", "Set alert sound on and off", "alert <on|off>",
alert_command_func);
}
void sound_alert_on()
{
esp_err_t error;
error = dac_output_enable(CHANNEL);
if (error != ESP_OK) {
ESP_LOGE(TAG, "Error enabling DAC output: %04x", error);
return;
}
signal_active = false;
toggle_signal(NULL);
error = esp_timer_start_periodic(timer, TOGGLE_PERIOD_US);
if (error != ESP_OK) {
ESP_LOGE(TAG, "Error starting toggle timer: %04x", error);
return;
}
}
void sound_alert_off()
{
esp_err_t error;
error = esp_timer_stop(timer);
if (error != ESP_OK) {
ESP_LOGE(TAG, "Error stopping toggle timer: %04x", error);
return;
}
if (signal_active)
toggle_signal(NULL);
error = dac_output_disable(CHANNEL);
if (error != ESP_OK) {
ESP_LOGE(TAG, "Error disabling DAC output: %04x", error);
return;
}
}