Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

echoplayer: pcm: increase SAI FIFO buffer depth

Change the SAI FIFO threshold so that it is always
kept topped up at maximum; DMA needs to do single
transfers to the peripheral now. Ignore FEIF errors
since they seem to occur constantly with this setup
(though it's not exactly clear why this happens).

FEIF only indicates that the SAI made a DMA request
while the DMA FIFO is empty, which isn't a fatal error.
The DMA channel will simply service the request when
it is ready.

Keeping the SAI FIFO constantly full increases the
overall timing margin before underrun so losing the
FEIF info isn't a big deal in practice.

Change-Id: I16eb1cbb17039db76938bd86c4921b8060c83556

authored by

Aidan MacDonald and committed by
Solomon Peachy
da53cc0f 2578411f

+7 -28
-4
firmware/target/arm/stm32/debug-stm32h7.c
··· 89 89 #if defined(ECHO_R1) 90 90 extern volatile int pcm_sai_xrun_count; 91 91 extern volatile int pcm_dma_teif_count; 92 - extern volatile int pcm_dma_dmeif_count; 93 - extern volatile int pcm_dma_feif_count; 94 92 95 93 struct pcmdebug_counter 96 94 { ··· 102 100 { 103 101 {"SAI xrun count", &pcm_sai_xrun_count}, 104 102 {"DMA TEIF count", &pcm_dma_teif_count}, 105 - {"DMA DMEIF count", &pcm_dma_dmeif_count}, 106 - {"DMA FEIF count", &pcm_dma_feif_count}, 107 103 }; 108 104 109 105 static int pcmdebug_menu_action_cb(int action, struct gui_synclist *lists)
+7 -24
firmware/target/arm/stm32/echoplayer/pcm-echoplayer.c
··· 36 36 # define PCM_NATIVE_SAMPLE_SIZE 4 37 37 # define DMA_PSIZE_VAL BV_DMA_CHN_CR_PSIZE_32BIT 38 38 # define SAI_DSIZE_VAL BV_SAI_SUBBLOCK_CR1_DS_32BIT 39 - # define SAI_FIFO_THRESH BV_SAI_SUBBLOCK_CR2_FTH_QUARTER 40 39 # define SAI_FRL_VAL 64 41 40 #elif PCM_NATIVE_BITDEPTH == 24 42 41 # define PCM_NATIVE_SAMPLE_SIZE 4 43 42 # define DMA_PSIZE_VAL BV_DMA_CHN_CR_PSIZE_32BIT 44 43 # define SAI_DSIZE_VAL BV_SAI_SUBBLOCK_CR1_DS_24BIT 45 - # define SAI_FIFO_THRESH BV_SAI_SUBBLOCK_CR2_FTH_QUARTER 46 44 # define SAI_FRL_VAL 64 47 45 #elif PCM_NATIVE_BITDEPTH == 16 48 46 # define PCM_NATIVE_SAMPLE_SIZE 2 49 47 # define DMA_PSIZE_VAL BV_DMA_CHN_CR_PSIZE_16BIT 50 48 # define SAI_DSIZE_VAL BV_SAI_SUBBLOCK_CR1_DS_16BIT 51 - # define SAI_FIFO_THRESH BV_SAI_SUBBLOCK_CR2_FTH_HALF 52 49 # define SAI_FRL_VAL 32 53 50 #else 54 51 # error "Unsupported PCM bit depth" ··· 67 64 68 65 volatile int pcm_sai_xrun_count; 69 66 volatile int pcm_dma_teif_count; 70 - volatile int pcm_dma_dmeif_count; 71 - volatile int pcm_dma_feif_count; 72 67 73 68 static void play_dma_start(const void *addr, size_t size) 74 69 { ··· 105 100 /* Configure DMA1 channel 0 */ 106 101 reg_writelf(dma1_ch0, DMA_CHN_CR, 107 102 MBURST_V(INCR4), /* 32-bit x 4 burst = 16 bytes */ 108 - PBURST_V(INCR4), /* (16|32)-bit x 4 burst = 8-16 bytes */ 103 + PBURST_V(SINGLE), /* (16|32)-bit x 4 burst = 8-16 bytes */ 109 104 TRBUFF(0), /* bufferable mode not used for SAI */ 110 105 DBM(0), /* double buffer mode off */ 111 106 PL_V(VERYHIGH), /* highest priority */ ··· 117 112 DIR_V(MEM_TO_PERIPH), /* read from memory, write to SAI */ 118 113 PFCTRL_V(DMA), /* DMA is flow controller */ 119 114 TCIE(1), /* transfer complete interrupt */ 120 - TEIE(1), /* transfer error interrupt */ 121 - DMEIE(1)); /* direct mode error interrupt */ 115 + TEIE(1)); /* transfer error interrupt */ 122 116 reg_writelf(dma1_ch0, DMA_CHN_FCR, 123 - FEIE(1), /* fifo error interrupt */ 124 117 DMDIS(1), /* enable fifo mode */ 125 118 FTH_V(FULL)); /* fifo threshold = 4 words */ 126 119 ··· 146 139 MUTEVAL_V(ZERO_SAMPLE), /* send zero sample on mute */ 147 140 MUTE(1), /* mute output initially */ 148 141 TRIS(0), /* don't tri-state outputs */ 149 - FTH(SAI_FIFO_THRESH)); /* fifo threshold (2 or 4 samples) */ 142 + FTH_V(FULL)); /* fifo threshold (2 or 4 samples) */ 150 143 reg_writelf(sai1a, SAI_SUBBLOCK_FRCR, 151 144 FSOFF(1), FSPOL(0), FSDEF(1), /* I2S format */ 152 145 FSALL(SAI_FRL_VAL/2 - 1), /* FS active for half the frame */ ··· 336 329 size_t size; 337 330 338 331 if (reg_vreadf(lisr, DMA_LISR, TEIF0)) 339 - pcm_dma_teif_count++; 340 - 341 - if (reg_vreadf(lisr, DMA_LISR, DMEIF0)) 342 - pcm_dma_dmeif_count++; 343 - 344 - if (reg_vreadf(lisr, DMA_LISR, FEIF0)) 345 - pcm_dma_feif_count++; 346 - 347 - if (reg_vreadf(lisr, DMA_LISR, TEIF0) || 348 - reg_vreadf(lisr, DMA_LISR, DMEIF0) || 349 - reg_vreadf(lisr, DMA_LISR, FEIF0)) 350 332 { 351 - reg_assignlf(dma1, DMA_LIFCR, TEIF0(1), DMEIF0(1), FEIF0(1)); 352 - reg_writelf(dma1_ch0, DMA_CHN_CR, EN(0)); 333 + pcm_dma_teif_count++; 334 + reg_assignlf(dma1, DMA_LIFCR, TEIF0(1)); 353 335 354 - pcm_play_dma_status_callback(PCM_DMAST_ERR_DMA); 336 + /* TODO: this case may need additional handling */ 337 + pcm_play_dma_complete_callback(PCM_DMAST_ERR_DMA, NULL, NULL); 355 338 } 356 339 else if (reg_vreadf(lisr, DMA_LISR, TCIF0)) 357 340 {