From 84fa5389796f366dd6f098bef45a5f4bc6b17d8d Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Fri, 27 Feb 2026 20:33:06 +0000 Subject: [PATCH] echoplayer: add PCM debug menu Display DMA error counters and the SAI underrun counter in the debug menu. Change-Id: I235bfcb0fa965d87c30deeb300535141eda5f974 --- firmware/target/arm/stm32/debug-stm32h7.c | 57 +++++++++++++++++++ .../arm/stm32/echoplayer/pcm-echoplayer.c | 27 +++++++++ 2 files changed, 84 insertions(+) diff --git a/firmware/target/arm/stm32/debug-stm32h7.c b/firmware/target/arm/stm32/debug-stm32h7.c index 99a3849b41..f8cd7200c3 100644 --- a/firmware/target/arm/stm32/debug-stm32h7.c +++ b/firmware/target/arm/stm32/debug-stm32h7.c @@ -86,11 +86,68 @@ static bool swd_menu(void) return simplelist_show_list(&info); } +#if defined(ECHO_R1) +extern volatile int pcm_sai_xrun_count; +extern volatile int pcm_dma_teif_count; +extern volatile int pcm_dma_dmeif_count; +extern volatile int pcm_dma_feif_count; + +struct pcmdebug_counter +{ + const char *name; + volatile int *value; +}; + +static const struct pcmdebug_counter pcmdebug_counters[] = +{ + {"SAI xrun count", &pcm_sai_xrun_count}, + {"DMA TEIF count", &pcm_dma_teif_count}, + {"DMA DMEIF count", &pcm_dma_dmeif_count}, + {"DMA FEIF count", &pcm_dma_feif_count}, +}; + +static int pcmdebug_menu_action_cb(int action, struct gui_synclist *lists) +{ + if (action == ACTION_STD_OK) + { + int item = gui_synclist_get_sel_pos(lists); + const struct pcmdebug_counter *counter = &pcmdebug_counters[item]; + + *counter->value = 0; + action = ACTION_REDRAW; + } + + if (action == ACTION_NONE) + action = ACTION_REDRAW; + + return action; +} + +static const char *pcmdebug_menu_get_name(int item, void *data, char *buf, size_t bufsz) +{ + const struct pcmdebug_counter *counter = &pcmdebug_counters[item]; + (void)data; + + snprintf(buf, bufsz, "%s: %d", counter->name, *counter->value); + return buf; +} + +static bool pcm_debug_menu(void) +{ + struct simplelist_info info; + simplelist_info_init(&info, "PCM debug", ARRAYLEN(pcmdebug_counters), NULL); + info.action_callback = pcmdebug_menu_action_cb; + info.get_name = pcmdebug_menu_get_name; + return simplelist_show_list(&info); +} +#endif + /* Menu definition */ static const struct { const char *name; bool (*function) (void); } menuitems[] = { + {"PCM debug", pcm_debug_menu}, {"SWD/JTAG", swd_menu}, }; diff --git a/firmware/target/arm/stm32/echoplayer/pcm-echoplayer.c b/firmware/target/arm/stm32/echoplayer/pcm-echoplayer.c index d85acad377..c1d457ef8d 100644 --- a/firmware/target/arm/stm32/echoplayer/pcm-echoplayer.c +++ b/firmware/target/arm/stm32/echoplayer/pcm-echoplayer.c @@ -65,6 +65,11 @@ static volatile int play_active; static int pcm_last_freq = -1; +volatile int pcm_sai_xrun_count; +volatile int pcm_dma_teif_count; +volatile int pcm_dma_dmeif_count; +volatile int pcm_dma_feif_count; + static void play_dma_start(const void *addr, size_t size) { commit_dcache_range(addr, size); @@ -151,8 +156,12 @@ static void sai_init(void) SLOTSZ_V(DATASZ), /* slot size = data size */ FBOFF(0)); /* no bit offset in slot */ + /* Enable xrun error interrupt */ + reg_writelf(sai1a, SAI_SUBBLOCK_IM, OVRUDR(1)); + /* Enable interrupts in NVIC */ nvic_enable_irq(NVIC_IRQN_DMA1_STR0); + nvic_enable_irq(NVIC_IRQN_SAI1); } struct div_settings @@ -326,6 +335,15 @@ void dma1_ch0_irq_handler(void) const void *addr; size_t size; + if (reg_vreadf(lisr, DMA_LISR, TEIF0)) + pcm_dma_teif_count++; + + if (reg_vreadf(lisr, DMA_LISR, DMEIF0)) + pcm_dma_dmeif_count++; + + if (reg_vreadf(lisr, DMA_LISR, FEIF0)) + pcm_dma_feif_count++; + if (reg_vreadf(lisr, DMA_LISR, TEIF0) || reg_vreadf(lisr, DMA_LISR, DMEIF0) || reg_vreadf(lisr, DMA_LISR, FEIF0)) @@ -352,3 +370,12 @@ void dma1_ch0_irq_handler(void) panicf("%s: %08lx", __func__, lisr); } } + +void sai1_irq_handler(void) +{ + if (reg_readlf(sai1a, SAI_SUBBLOCK_SR, OVRUDR)) + { + reg_assignlf(sai1a, SAI_SUBBLOCK_CLRFR, OVRUDR(1)); + pcm_sai_xrun_count++; + } +}