@@ -96,6 +96,10 @@ struct i2s_esp32_cfg {
9696
9797struct i2s_esp32_data {
9898 i2s_hal_clock_info_t clk_info ;
99+ #if I2S_ESP32_IS_DIR_EN (tx )
100+ struct k_timer tx_deferred_transfer_timer ;
101+ const struct device * dev ;
102+ #endif
99103};
100104
101105uint32_t i2s_esp32_get_source_clk_freq (i2s_clock_src_t clk_src )
@@ -348,6 +352,47 @@ static void i2s_esp32_rx_stop_transfer(const struct device *dev)
348352
349353#if I2S_ESP32_IS_DIR_EN (tx )
350354
355+ void i2s_esp32_tx_compl_transfer (struct k_timer * timer )
356+ {
357+ struct i2s_esp32_data * dev_data =
358+ CONTAINER_OF (timer , struct i2s_esp32_data , tx_deferred_transfer_timer );
359+ const struct device * dev = dev_data -> dev ;
360+ const struct i2s_esp32_cfg * const dev_cfg = dev -> config ;
361+ const struct i2s_esp32_stream * stream = & dev_cfg -> tx ;
362+ struct queue_item item ;
363+ int err ;
364+
365+ if (stream -> data -> state == I2S_STATE_STOPPING ) {
366+ if (k_msgq_num_used_get (& stream -> data -> queue ) == 0 ||
367+ stream -> data -> stop_without_draining == true) {
368+ stream -> data -> state = I2S_STATE_READY ;
369+ goto tx_disable ;
370+ }
371+ }
372+
373+ err = k_msgq_get (& stream -> data -> queue , & item , K_NO_WAIT );
374+ if (err < 0 ) {
375+ stream -> data -> state = I2S_STATE_ERROR ;
376+ LOG_ERR ("TX queue empty: %d" , err );
377+ goto tx_disable ;
378+ }
379+
380+ stream -> data -> mem_block = item .buffer ;
381+ stream -> data -> mem_block_len = item .size ;
382+
383+ err = i2s_esp32_restart_dma (dev , I2S_DIR_TX );
384+ if (err < 0 ) {
385+ stream -> data -> state = I2S_STATE_ERROR ;
386+ LOG_ERR ("Failed to restart TX transfer: %d" , err );
387+ goto tx_disable ;
388+ }
389+
390+ return ;
391+
392+ tx_disable :
393+ stream -> conf -> stop_transfer (dev );
394+ }
395+
351396#if SOC_GDMA_SUPPORTED
352397static void i2s_esp32_tx_callback (const struct device * dma_dev , void * arg , uint32_t channel ,
353398 int status )
@@ -356,10 +401,9 @@ static void i2s_esp32_tx_callback(void *arg, int status)
356401#endif /* SOC_GDMA_SUPPORTED */
357402{
358403 const struct device * dev = (const struct device * )arg ;
404+ struct i2s_esp32_data * dev_data = dev -> data ;
359405 const struct i2s_esp32_cfg * const dev_cfg = dev -> config ;
360406 const struct i2s_esp32_stream * stream = & dev_cfg -> tx ;
361- struct queue_item item ;
362- int err ;
363407
364408 if (!stream -> data -> dma_pending ) {
365409 return ;
@@ -385,29 +429,16 @@ static void i2s_esp32_tx_callback(void *arg, int status)
385429 goto tx_disable ;
386430 }
387431
388- if (stream -> data -> state == I2S_STATE_STOPPING ) {
389- if (k_msgq_num_used_get (& stream -> data -> queue ) == 0 ||
390- stream -> data -> stop_without_draining == true) {
391- stream -> data -> state = I2S_STATE_READY ;
392- goto tx_disable ;
393- }
394- }
395-
396- err = k_msgq_get (& stream -> data -> queue , & item , K_NO_WAIT );
397- if (err < 0 ) {
398- stream -> data -> state = I2S_STATE_ERROR ;
399- LOG_ERR ("TX queue empty: %d" , err );
400- goto tx_disable ;
401- }
402-
403- stream -> data -> mem_block = item .buffer ;
404- stream -> data -> mem_block_len = item .size ;
405-
406- err = i2s_esp32_restart_dma (dev , I2S_DIR_TX );
407- if (err < 0 ) {
408- stream -> data -> state = I2S_STATE_ERROR ;
409- LOG_ERR ("Failed to restart TX transfer: %d" , err );
410- goto tx_disable ;
432+ #if CONFIG_I2S_ESP32_ALLOWED_EMPTY_TX_QUEUE_DEFERRAL_TIME_MS
433+ if (k_msgq_num_used_get (& stream -> data -> queue ) == 0 ) {
434+ k_timer_start (& dev_data -> tx_deferred_transfer_timer ,
435+ K_MSEC (CONFIG_I2S_ESP32_ALLOWED_EMPTY_TX_QUEUE_DEFERRAL_TIME_MS ),
436+ K_NO_WAIT );
437+ } else {
438+ #else
439+ {
440+ #endif
441+ i2s_esp32_tx_compl_transfer (& dev_data -> tx_deferred_transfer_timer );
411442 }
412443
413444 return ;
@@ -769,6 +800,14 @@ static int i2s_esp32_initialize(const struct device *dev)
769800#if !SOC_GDMA_SUPPORTED
770801 const i2s_hal_context_t * hal = & (dev_cfg -> hal );
771802#endif /* !SOC_GDMA_SUPPORTED */
803+
804+ #if I2S_ESP32_IS_DIR_EN (tx )
805+ struct i2s_esp32_data * dev_data = dev -> data ;
806+
807+ dev_data -> dev = dev ;
808+ k_timer_init (& dev_data -> tx_deferred_transfer_timer , i2s_esp32_tx_compl_transfer , NULL );
809+ #endif /* I2S_ESP32_IS_DIR_EN(tx) */
810+
772811 if (!device_is_ready (clk_dev )) {
773812 LOG_ERR ("clock control device not ready" );
774813 return - ENODEV ;
0 commit comments