@@ -255,9 +255,9 @@ static void i2s_dma_tx_callback(const struct device *dma_dev, void *arg, uint32_
255255 const struct device * dev = (struct device * )arg ;
256256 struct i2s_dev_data * dev_data = dev -> data ;
257257 struct stream * strm = & dev_data -> tx ;
258+ uint8_t blocks_queued ;
258259 void * buffer = NULL ;
259260 int ret ;
260- uint8_t blocks_queued ;
261261
262262 LOG_DBG ("tx cb" );
263263
@@ -289,35 +289,30 @@ static void i2s_dma_tx_callback(const struct device *dma_dev, void *arg, uint32_
289289 goto disabled_exit_no_drop ;
290290 }
291291
292- switch (strm -> state ) {
293- case I2S_STATE_RUNNING :
294- case I2S_STATE_STOPPING :
295- ret = i2s_tx_reload_multiple_dma_blocks (dev , & blocks_queued );
292+ if (strm -> state != I2S_STATE_RUNNING && strm -> state != I2S_STATE_STOPPING ) {
293+ goto disabled_exit_drop ;
294+ }
296295
297- if (ret ) {
298- strm -> state = I2S_STATE_ERROR ;
299- goto disabled_exit_no_drop ;
300- }
296+ ret = i2s_tx_reload_multiple_dma_blocks (dev , & blocks_queued );
297+ if (ret ) {
298+ strm -> state = I2S_STATE_ERROR ;
299+ goto disabled_exit_no_drop ;
300+ }
301301
302- if (blocks_queued || (strm -> free_tx_dma_blocks < MAX_TX_DMA_BLOCKS )) {
303- goto enabled_exit ;
304- } else {
305- /* all DMA blocks are free but no blocks were queued */
306- if (strm -> state == I2S_STATE_STOPPING ) {
307- /* TX queue has drained */
308- strm -> state = I2S_STATE_READY ;
309- LOG_DBG ("TX stream has stopped" );
310- } else {
311- strm -> state = I2S_STATE_ERROR ;
312- LOG_ERR ("TX Failed to reload DMA" );
313- }
314- goto disabled_exit_no_drop ;
315- }
302+ if (blocks_queued || (strm -> free_tx_dma_blocks < MAX_TX_DMA_BLOCKS )) {
303+ goto enabled_exit ;
304+ }
316305
317- case I2S_STATE_ERROR :
318- default :
319- goto disabled_exit_drop ;
306+ /* all DMA blocks are free but no blocks were queued */
307+ if (strm -> state == I2S_STATE_STOPPING ) {
308+ /* TX queue has drained */
309+ strm -> state = I2S_STATE_READY ;
310+ LOG_DBG ("TX stream has stopped" );
311+ } else {
312+ strm -> state = I2S_STATE_ERROR ;
313+ LOG_ERR ("TX Failed to reload DMA" );
320314 }
315+ goto disabled_exit_no_drop ;
321316
322317disabled_exit_no_drop :
323318 i2s_tx_stream_disable (dev , false);
@@ -344,61 +339,62 @@ static void i2s_dma_rx_callback(const struct device *dma_dev, void *arg, uint32_
344339
345340 LOG_DBG ("RX cb" );
346341
347- switch (strm -> state ) {
348- case I2S_STATE_STOPPING :
349- case I2S_STATE_RUNNING :
350- /* retrieve buffer from input queue */
351- ret = k_msgq_get (& strm -> in_queue , & buffer , K_NO_WAIT );
352- __ASSERT_NO_MSG (ret == 0 );
353-
354- /* put buffer to output queue */
355- ret = k_msgq_put (& strm -> out_queue , & buffer , K_NO_WAIT );
356- if (ret != 0 ) {
357- LOG_ERR ("buffer %p -> out_queue %p err %d" , buffer , & strm -> out_queue , ret );
358- i2s_rx_stream_disable (dev , false, false);
359- strm -> state = I2S_STATE_ERROR ;
360- return ;
361- }
362- if (strm -> state == I2S_STATE_RUNNING ) {
363- /* allocate new buffer for next audio frame */
364- ret = k_mem_slab_alloc (strm -> cfg .mem_slab , & buffer , K_NO_WAIT );
365- if (ret != 0 ) {
366- LOG_ERR ("buffer alloc from slab %p err %d" , strm -> cfg .mem_slab ,
367- ret );
368- i2s_rx_stream_disable (dev , false, false);
369- strm -> state = I2S_STATE_ERROR ;
370- } else {
371- uint32_t data_path = strm -> start_channel ;
372-
373- ret = dma_reload (dev_data -> dev_dma , strm -> dma_channel ,
374- (uint32_t )& base -> RDR [data_path ], (uint32_t )buffer ,
375- strm -> cfg .block_size );
376- if (ret != 0 ) {
377- LOG_ERR ("dma_reload() failed with error 0x%x" , ret );
378- i2s_rx_stream_disable (dev , false, false);
379- strm -> state = I2S_STATE_ERROR ;
380- return ;
381- }
382-
383- /* put buffer in input queue */
384- ret = k_msgq_put (& strm -> in_queue , & buffer , K_NO_WAIT );
385- if (ret != 0 ) {
386- LOG_ERR ("%p -> in_queue %p err %d" , buffer , & strm -> in_queue ,
387- ret );
388- }
389- }
390- } else {
391- i2s_rx_stream_disable (dev , true, false);
392- /* Received a STOP/DRAIN trigger */
393- strm -> state = I2S_STATE_READY ;
394- }
395- break ;
396- case I2S_STATE_ERROR :
342+ if (strm -> state == I2S_STATE_ERROR ) {
397343 i2s_rx_stream_disable (dev , true, true);
398- break ;
399- default :
400- break ;
401344 }
345+
346+ if (strm -> state != I2S_STATE_STOPPING && strm -> state != I2S_STATE_RUNNING ) {
347+ return ;
348+ }
349+
350+ /* retrieve buffer from input queue */
351+ ret = k_msgq_get (& strm -> in_queue , & buffer , K_NO_WAIT );
352+ __ASSERT_NO_MSG (ret == 0 );
353+
354+ /* put buffer to output queue */
355+ ret = k_msgq_put (& strm -> out_queue , & buffer , K_NO_WAIT );
356+ if (ret != 0 ) {
357+ LOG_ERR ("buffer %p -> out_queue %p err %d" , buffer , & strm -> out_queue , ret );
358+ goto error ;
359+ }
360+
361+ if (strm -> state == I2S_STATE_STOPPING ) {
362+ i2s_rx_stream_disable (dev , true, false);
363+ /* Received a STOP/DRAIN trigger */
364+ strm -> state = I2S_STATE_READY ;
365+ return ;
366+ }
367+
368+ /* Now the only possible case is the running state */
369+
370+ /* allocate new buffer for next audio frame */
371+ ret = k_mem_slab_alloc (strm -> cfg .mem_slab , & buffer , K_NO_WAIT );
372+ if (ret != 0 ) {
373+ LOG_ERR ("buffer alloc from slab %p err %d" , strm -> cfg .mem_slab , ret );
374+ goto error ;
375+ }
376+
377+ uint32_t data_path = strm -> start_channel ;
378+
379+ ret = dma_reload (dev_data -> dev_dma , strm -> dma_channel ,
380+ (uint32_t )& base -> RDR [data_path ], (uint32_t )buffer ,
381+ strm -> cfg .block_size );
382+ if (ret != 0 ) {
383+ LOG_ERR ("dma_reload() failed with error 0x%x" , ret );
384+ goto error ;
385+ }
386+
387+ /* put buffer in input queue */
388+ ret = k_msgq_put (& strm -> in_queue , & buffer , K_NO_WAIT );
389+ if (ret != 0 ) {
390+ LOG_ERR ("%p -> in_queue %p err %d" , buffer , & strm -> in_queue , ret );
391+ }
392+
393+ return ;
394+
395+ error :
396+ i2s_rx_stream_disable (dev , false, false);
397+ strm -> state = I2S_STATE_ERROR ;
402398}
403399
404400static void enable_mclk_direction (const struct device * dev , bool dir )
0 commit comments