@@ -403,9 +403,13 @@ static void i2s_esp32_tx_callback(void *arg, int status)
403403
404404 err = k_msgq_get (& stream -> data -> queue , & item , K_NO_WAIT );
405405 if (err < 0 ) {
406- stream -> data -> state = I2S_STATE_ERROR ;
407- LOG_ERR ("TX queue empty: %d" , err );
408- goto tx_disable ;
406+ /*
407+ * Stop DMA and transition to READY, so the next write()
408+ * can auto-kick TX without requiring a new START trigger.
409+ */
410+ stream -> data -> state = I2S_STATE_READY ;
411+ stream -> conf -> stop_transfer (dev );
412+ return ;
409413 }
410414
411415 mem_block_tmp = stream -> data -> mem_block ;
@@ -459,7 +463,13 @@ static int i2s_esp32_tx_start_transfer(const struct device *dev)
459463
460464 err = k_msgq_get (& stream -> data -> queue , & item , K_NO_WAIT );
461465 if (err < 0 ) {
462- return - ENOMEM ;
466+ /*
467+ * No data queued yet. Leave mem_block NULL and return success.
468+ * START will keep TX in READY; next write() will auto-kick TX.
469+ */
470+ stream -> data -> mem_block = NULL ;
471+ stream -> data -> mem_block_len = 0 ;
472+ return 0 ;
463473 }
464474
465475 stream -> data -> mem_block = item .buffer ;
@@ -1193,6 +1203,11 @@ static int i2s_esp32_trigger_stream(const struct device *dev, const struct i2s_e
11931203
11941204 switch (cmd ) {
11951205 case I2S_TRIGGER_START :
1206+ /* if already streaming, treat as success */
1207+ if (stream -> data -> state == I2S_STATE_RUNNING ) {
1208+ LOG_DBG ("START ignored: already RUNNING" );
1209+ return 0 ;
1210+ }
11961211 if (stream -> data -> state != I2S_STATE_READY ) {
11971212 LOG_ERR ("START - Invalid state: %d" , (int )stream -> data -> state );
11981213 return - EIO ;
@@ -1223,12 +1238,27 @@ static int i2s_esp32_trigger_stream(const struct device *dev, const struct i2s_e
12231238 return - EIO ;
12241239 }
12251240 stream -> data -> last_block = false;
1241+ /*
1242+ * If no mem_block was available (queue empty), stay READY.
1243+ * The next write() will auto-kick TX into RUNNING.
1244+ */
1245+ if (dir == I2S_DIR_TX && stream -> data -> mem_block == NULL &&
1246+ !stream -> data -> dma_pending ) {
1247+ stream -> data -> state = I2S_STATE_READY ;
1248+ irq_unlock (key );
1249+ return 0 ;
1250+ }
12261251 stream -> data -> state = I2S_STATE_RUNNING ;
12271252 irq_unlock (key );
12281253 break ;
12291254
12301255 case I2S_TRIGGER_STOP :
12311256 key = irq_lock ();
1257+ if (stream -> data -> state == I2S_STATE_READY ) {
1258+ /* Already idle; treat STOP as success */
1259+ irq_unlock (key );
1260+ return 0 ;
1261+ }
12321262 if (stream -> data -> state != I2S_STATE_RUNNING ) {
12331263 irq_unlock (key );
12341264 LOG_ERR ("STOP - Invalid state: %d" , (int )stream -> data -> state );
@@ -1249,9 +1279,48 @@ static int i2s_esp32_trigger_stream(const struct device *dev, const struct i2s_e
12491279
12501280 case I2S_TRIGGER_DRAIN :
12511281 key = irq_lock ();
1252- if (stream -> data -> state != I2S_STATE_RUNNING ) {
1282+ int32_t st = stream -> data -> state ;
1283+
1284+ if (st == I2S_STATE_READY ) {
1285+ #if I2S_ESP32_IS_DIR_EN (tx )
1286+ if (dir == I2S_DIR_TX ) {
1287+ bool have_data = (k_msgq_num_used_get (& stream -> data -> queue ) > 0 );
1288+
1289+ /* If there's data queued and TX is idle, kick once and drain */
1290+ if (have_data && !stream -> data -> dma_pending ) {
1291+ int kick = stream -> conf -> start_transfer (dev );
1292+ if (kick < 0 ) {
1293+ irq_unlock (key );
1294+ LOG_ERR ("DRAIN - autostart failed: %d" , kick );
1295+ return - EIO ;
1296+ }
1297+ stream -> data -> last_block = false;
1298+ stream -> data -> stop_without_draining = false;
1299+ stream -> data -> state = I2S_STATE_STOPPING ;
1300+ irq_unlock (key );
1301+ break ;
1302+ }
1303+
1304+ /* Nothing to drain (idle and no queued blocks) */
1305+ if (!have_data && !stream -> data -> dma_pending ) {
1306+ irq_unlock (key );
1307+ return 0 ;
1308+ }
1309+ }
1310+ #endif /* I2S_ESP32_IS_DIR_EN(tx) */
1311+
1312+ #if I2S_ESP32_IS_DIR_EN (rx )
1313+ if (dir == I2S_DIR_RX ) {
1314+ /* If RX is idle and no DMA pending, nothing to drain */
1315+ if (!stream -> data -> dma_pending ) {
1316+ irq_unlock (key );
1317+ return 0 ;
1318+ }
1319+ }
1320+ #endif /* I2S_ESP32_IS_DIR_EN(rx) */
1321+ } else if (st != I2S_STATE_RUNNING ) {
12531322 irq_unlock (key );
1254- LOG_ERR ("DRAIN - Invalid state: %d" , (int )stream -> data -> state );
1323+ LOG_ERR ("DRAIN - Invalid state: %d" , (int )st );
12551324 return - EIO ;
12561325 }
12571326
@@ -1460,6 +1529,34 @@ static int i2s_esp32_write(const struct device *dev, void *mem_block, size_t siz
14601529 return err ;
14611530 }
14621531
1532+ /*
1533+ * Auto-restart TX after an underrun or a START with no data:
1534+ * If TX is in READY and no DMA is pending and there's no current block,
1535+ * kick DMA immediately so we don't require a new START trigger.
1536+ */
1537+ if (stream -> data -> state == I2S_STATE_READY && !stream -> data -> dma_pending &&
1538+ stream -> data -> mem_block == NULL ) {
1539+ unsigned int key = irq_lock ();
1540+ if (stream -> data -> state == I2S_STATE_READY && !stream -> data -> dma_pending &&
1541+ stream -> data -> mem_block == NULL ) {
1542+ int kick = stream -> conf -> start_transfer (dev );
1543+ if (kick < 0 ) {
1544+ irq_unlock (key );
1545+ LOG_ERR ("TX auto-restart failed: %d" , kick );
1546+ return kick ;
1547+ }
1548+ stream -> data -> last_block = false;
1549+ /*
1550+ * If start_transfer pulled from the queue, we are RUNNING;
1551+ * if not (shouldn't happen here), stay READY.
1552+ */
1553+ if (stream -> data -> mem_block != NULL || stream -> data -> dma_pending ) {
1554+ stream -> data -> state = I2S_STATE_RUNNING ;
1555+ }
1556+ }
1557+ irq_unlock (key );
1558+ }
1559+
14631560 return 0 ;
14641561#else
14651562 LOG_ERR ("I2S_DIR_TX not enabled" );
0 commit comments