This commit is contained in:
2026-02-28 11:59:16 +01:00
parent 1b850d8de8
commit c914333236
9 changed files with 208 additions and 78 deletions

View File

@@ -13,6 +13,12 @@
#define AUDIO_THREAD_STACK_SIZE 2048
#define AUDIO_THREAD_PRIORITY 5
#define AUDIO_PATH "/lfs/a"
#define AUDIO_BLOCK_SIZE 8192 /* 512 Samples Stereo (16-bit) = 8192 Bytes */
#define AUDIO_BLOCK_COUNT 4
#define AUDIO_WORD_WIDTH 16
#define AUDIO_SAMPLE_RATE 16000
LOG_MODULE_REGISTER(audio, LOG_LEVEL_DBG);
/* Dauer eines Blocks in ms (4096 Bytes / (16kHz * 2 Kanäle * 2 Bytes)) = 64 ms */
@@ -48,25 +54,39 @@ static char next_random_filename[64] = {0};
static uint32_t audio_file_count = 0;
static char cached_404_path[] = "/lfs/sys/404";
static struct k_mutex i2s_lock;
static struct k_work audio_stop_work;
static void audio_stop_work_handler(struct k_work *work)
{
ARG_UNUSED(work);
k_mutex_lock(&i2s_lock, K_FOREVER);
enum pm_device_state state;
pm_device_state_get(i2s_dev, &state);
if (state == PM_DEVICE_STATE_ACTIVE)
{
LOG_DBG("Triggering I2S DROP to stop ongoing transmission");
i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_DROP);
}
k_mutex_unlock(&i2s_lock);
}
void i2s_suspend(void)
{
LOG_DBG("Suspending I2S interface for power saving");
i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_DROP);
/* Nutzt jetzt die korrekte Spezifikation */
gpio_pin_set_dt(&amp_en_dev, 0);
k_mutex_lock(&i2s_lock, K_FOREVER); // Sperren
pm_device_action_run(i2s_dev, PM_DEVICE_ACTION_SUSPEND);
k_mutex_unlock(&i2s_lock); // Freigeben
}
void i2s_resume(void)
{
LOG_DBG("Resuming I2S interface");
/* Zuerst Pin auf High, dann Hardware wecken */
gpio_pin_set_dt(&amp_en_dev, 1);
k_mutex_lock(&i2s_lock, K_FOREVER);
pm_device_action_run(i2s_dev, PM_DEVICE_ACTION_RESUME);
k_mutex_unlock(&i2s_lock);
}
void audio_refresh_file_count(void)
@@ -154,7 +174,13 @@ void audio_stop(void)
LOG_DBG("Playback abort requested");
abort_playback = true;
k_msgq_purge(&audio_play_msgq);
i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_DROP);
if (k_is_in_isr())
{
LOG_DBG("audio_stop called from ISR, deferring I2S DROP");
}
k_work_submit(&audio_stop_work);
}
void audio_play(const char *filename)
@@ -372,6 +398,8 @@ int audio_init(void)
}
gpio_pin_configure_dt(&amp_en_dev, 0);
k_mutex_init(&i2s_lock);
k_work_init(&audio_stop_work, audio_stop_work_handler);
audio_refresh_file_count();
LOG_INF("Audio initialized: %u bits, %u.%03u kHz", config.word_size, config.frame_clk_freq / 1000, config.frame_clk_freq % 1000);

View File

@@ -1,18 +1,6 @@
#ifndef AUDIO_H
#define AUDIO_H
#define AUDIO_PATH "/lfs/a"
#define AUDIO_EVENT_PLAY BIT(0)
#define AUDIO_EVENT_STOP BIT(1)
#define AUDIO_EVENT_SYNC BIT(8)
#define AUDIO_EVENTS_MASK (AUDIO_EVENT_PLAY | AUDIO_EVENT_STOP | AUDIO_EVENT_SYNC)
#define AUDIO_BLOCK_SIZE 8192 /* 512 Samples Stereo (16-bit) = 8192 Bytes */
#define AUDIO_BLOCK_COUNT 4
#define AUDIO_WORD_WIDTH 16
#define AUDIO_SAMPLE_RATE 16000
/**
* @brief Initializes the audio subsystem
*

View File

@@ -14,14 +14,25 @@ static const struct gpio_dt_spec usb_led_spec = GPIO_DT_SPEC_GET(USB_LED_NODE, g
static const struct gpio_dt_spec button_spec = GPIO_DT_SPEC_GET(BUZZER_BUTTON_NODE, gpios);
static struct gpio_callback button_cb_data;
static struct k_work button_audio_work;
static struct k_work_delayable debounce_work;
void button_isr(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
gpio_pin_interrupt_configure_dt(&button_spec, GPIO_INT_DISABLE);
static void button_audio_work_handler(struct k_work *work)
{
ARG_UNUSED(work);
LOG_DBG("Button pressed, triggering audio play");
audio_stop();
audio_play(NULL);
}
void button_isr(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
ARG_UNUSED(dev);
ARG_UNUSED(cb);
ARG_UNUSED(pins);
gpio_pin_interrupt_configure_dt(&button_spec, GPIO_INT_DISABLE);
k_work_submit(&button_audio_work);
k_work_reschedule(&debounce_work, K_MSEC(50));
}
@@ -71,6 +82,7 @@ int io_init(void)
return ret;
}
k_work_init(&button_audio_work, button_audio_work_handler);
k_work_init_delayable(&debounce_work, debounce_work_handler);
gpio_pin_interrupt_configure_dt(&button_spec, GPIO_INT_EDGE_TO_ACTIVE);
gpio_init_callback(&button_cb_data, button_isr, BIT(button_spec.pin));