diff --git a/boards/nxp/mimxrt1170_evk/doc/index.rst b/boards/nxp/mimxrt1170_evk/doc/index.rst index dad875250da0..e0c7a13494a8 100644 --- a/boards/nxp/mimxrt1170_evk/doc/index.rst +++ b/boards/nxp/mimxrt1170_evk/doc/index.rst @@ -142,7 +142,7 @@ RT1170 EVKB (``mimxrt1170_evk@B//cm7/cm4``) +-----------+------------+------------------------------------------------+-----------------+-----------------+ | ENET1G | on-chip | ethernet - 10/100/1000M | Supported (M7) | Supported (M7) | +-----------+------------+------------------------------------------------+-----------------+-----------------+ -| SAI | on-chip | i2s | Supported | No support | +| SAI | on-chip | i2s | Supported (M7) | Supported (M7) | +-----------+------------+------------------------------------------------+-----------------+-----------------+ | USB | on-chip | USB Device | Supported (M7) | Supported (M7) | +-----------+------------+------------------------------------------------+-----------------+-----------------+ diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index acb5415a9434..a6982a055cac 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -308,11 +308,23 @@ static void i2s_dma_tx_callback(const struct device *dma_dev, void *arg, uint32_ /* TX queue has drained */ strm->state = I2S_STATE_READY; LOG_DBG("TX stream has stopped"); - } else { - strm->state = I2S_STATE_ERROR; - LOG_ERR("TX Failed to reload DMA"); + goto disabled_exit_no_drop; + } + + LOG_WRN("TX input queue empty!"); + if (strm->free_tx_dma_blocks >= MAX_TX_DMA_BLOCKS) { + /* In running state, no TX blocks for transferring, so stop + * TX (This will disable bit clock to avoid dummy bits + * received in RX side. + */ + const struct i2s_mcux_config *dev_cfg = dev->config; + I2S_Type *base = (I2S_Type *)dev_cfg->base; + + SAI_TxEnable(base, false); + LOG_WRN("TX is paused."); } - goto disabled_exit_no_drop; + goto enabled_exit; + disabled_exit_no_drop: i2s_tx_stream_disable(dev, false); @@ -597,6 +609,7 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, LOG_DBG("tx slab block_size = %d", (uint32_t)i2s_cfg->mem_slab->info.block_size); LOG_DBG("tx slab buffer = 0x%x", (uint32_t)i2s_cfg->mem_slab->buffer); + config.fifo.fifoWatermark = (uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - 1; /* set bit clock divider */ SAI_TxSetConfig(base, &config); dev_data->tx.start_channel = config.startChannel; @@ -976,6 +989,23 @@ static int i2s_mcux_write(const struct device *dev, void *mem_block, size_t size return ret; } + if (strm->state == I2S_STATE_RUNNING && strm->free_tx_dma_blocks >= MAX_TX_DMA_BLOCKS) { + uint8_t blocks_queued = 0; + const struct i2s_mcux_config *dev_cfg = dev->config; + I2S_Type *base = (I2S_Type *)dev_cfg->base; + /* As DMA has been stopped because reloading failure in TX callback, + * here is a good place to reload it and resume TX. + */ + ret = i2s_tx_reload_multiple_dma_blocks(dev, &blocks_queued); + if (ret == 0 && blocks_queued > 0) { + SAI_TxEnable(base, true); + LOG_WRN("TX is resumed"); + } else { + LOG_ERR("TX block reload err, TX is not resumed"); + return ret; + } + } + return ret; } diff --git a/tests/drivers/i2s/i2s_speed/Readme.txt b/tests/drivers/i2s/i2s_speed/Readme.txt index a578ed9a39aa..23646638d0bb 100644 --- a/tests/drivers/i2s/i2s_speed/Readme.txt +++ b/tests/drivers/i2s/i2s_speed/Readme.txt @@ -4,12 +4,20 @@ i2s_speed Test Board-specific details: MIMXRT1170_EVK: -This board uses CONFIG_I2S_TEST_SEPARATE_DEVICES=y and connects two SAI peripherals by shorting -signals externally on the EVK. These are the HW changes required to run this test: - - Remove jumper J8 and resistor R78 - - Short BCLK J9-pin1 (SAI1_RX_BCLK) to J66-pin1 (SAI4_TX_BCLK) - - Short SYNC J9-pin5 (SAI1_RX_SYNC) to J64-pin1 (SAI4_TX_SYNC) - - Short Data J61-pin1 (SAI1_RX_DATA) to J63-pin1 (SAI4_TX_DATA) +This board uses CONFIG_I2S_TEST_SEPARATE_DEVICES=n and connects TX and RX blocks in one +SAI peripheral by shorting signals externally on the EVK. +These are the HW changes required to run this test: + - Short BCLK J9-pin1 (SAI1_RX_BCLK) to J9-pin11 (SAI1_TX_BCLK) + - Short SYNC J9-pin5 (SAI1_RX_SYNC) to J9-pin13 (SAI1_TX_SYNC) + - Short Data J9-pin7 (SAI1_RX_DATA) to J9-pin9 (SAI1_TX_DATA) + +MIMXRT1170_EVKB (SCH-55139 Rev C/C1/C2): +This board uses CONFIG_I2S_TEST_SEPARATE_DEVICES=n and connects TX and RX blocks in one +SAI peripheral by shorting signals externally on the EVK. +These are the HW changes required to run this test: + - Populate R2124, R2125 + - Remove J99, J100 + - Short Data J99-pin1 (SAI1_RX_DATA0) to J100-pin1 (SAI1_TX_DATA0) FRDM-MCXN947: This board uses CONFIG_I2S_TEST_SEPARATE_DEVICES=y and connects two SAI peripherals by shorting diff --git a/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.conf b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.conf index 1f5ccfe104d4..8a1e1c2c47a8 100644 --- a/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.conf +++ b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.conf @@ -4,9 +4,9 @@ # SPDX-License-Identifier: Apache-2.0 # -# SAI peripheral does not have loopback mode. Use 2 SAI peripherals connected -# together externally. -CONFIG_I2S_TEST_SEPARATE_DEVICES=y +# SAI peripheral does not have loopback mode but we can connect CLK, SYNC, +# RXD and TXD of one SAI for test purpose. +CONFIG_I2S_TEST_SEPARATE_DEVICES=n # CONFIG_DMA_TCD_QUEUE_SIZE sets size of queue used to chain DMA blocks (TCDs) # together, and should be sized as needed by the application. If not large @@ -18,7 +18,7 @@ CONFIG_DMA_TCD_QUEUE_SIZE=4 CONFIG_ZTEST_RETEST_IF_PASSED=y # I2S and DMA logging can occur in interrupt context, and interfere with I2S -# stream timing. If using either logging, set logging to deffered +# stream timing. If using either logging, set logging to deferred # CONFIG_LOG_MODE_DEFERRED=y CONFIG_DMA_LOG_LEVEL_OFF=y diff --git a/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay index 24a1defbb3ac..59583a680ce3 100644 --- a/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay +++ b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay @@ -1,26 +1,15 @@ -/* i2s_speed with CONFIG_I2S_TEST_SEPARATE_DEVICES=y uses two I2S peripherals: - * i2s-node0 is the receiver - uses SAI1 peripheral on RT1170 - * i2s-node1 is the transmitter - uses SAI4 peripheral +/* i2s_speed with CONFIG_I2S_TEST_SEPARATE_DEVICES=n uses only one I2S peripheral: + * i2s-node0 is both the transitter and receiver. + * uses SAI1 peripheral on RT1170 */ - / { aliases { i2s-node0 = &sai1; - i2s-node1 = &sai4; }; }; -/* Enable SAI4, and set clocks to match SAI1 */ -&sai4 { - status = "okay"; - podf = < 0x4 >; - pinctrl-0 = <&pinmux_sai4>; - pinctrl-names = "default"; -}; - -/* On MIMXRT1170-EVK, there is a conflict with signal SAI4_TX_BCLK shared with - * ENET_RST. For i2s_speed test, disable ENET peripheral. - */ -&enet { - status = "disabled"; +/* Default DMA channel 0 and 1 maybe used by other peripherals like UART. */ +&sai1 { + nxp,tx-dma-channel = <8>; + nxp,rx-dma-channel = <9>; }; diff --git a/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf new file mode 100644 index 000000000000..8a1e1c2c47a8 --- /dev/null +++ b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2021, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +# SAI peripheral does not have loopback mode but we can connect CLK, SYNC, +# RXD and TXD of one SAI for test purpose. +CONFIG_I2S_TEST_SEPARATE_DEVICES=n + +# CONFIG_DMA_TCD_QUEUE_SIZE sets size of queue used to chain DMA blocks (TCDs) +# together, and should be sized as needed by the application. If not large +# enough, the DMA may starve. Symptoms of this issue include transmit blocks +# repeated, or RX blocks skipped. For I2S driver, queue size must be at least 3. +CONFIG_DMA_TCD_QUEUE_SIZE=4 + +# Repeat test continually to help find intermittent issues +CONFIG_ZTEST_RETEST_IF_PASSED=y + +# I2S and DMA logging can occur in interrupt context, and interfere with I2S +# stream timing. If using either logging, set logging to deferred +# CONFIG_LOG_MODE_DEFERRED=y + +CONFIG_DMA_LOG_LEVEL_OFF=y +CONFIG_I2S_LOG_LEVEL_OFF=y diff --git a/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay new file mode 100644 index 000000000000..59583a680ce3 --- /dev/null +++ b/tests/drivers/i2s/i2s_speed/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -0,0 +1,15 @@ +/* i2s_speed with CONFIG_I2S_TEST_SEPARATE_DEVICES=n uses only one I2S peripheral: + * i2s-node0 is both the transitter and receiver. + * uses SAI1 peripheral on RT1170 + */ +/ { + aliases { + i2s-node0 = &sai1; + }; +}; + +/* Default DMA channel 0 and 1 maybe used by other peripherals like UART. */ +&sai1 { + nxp,tx-dma-channel = <8>; + nxp,rx-dma-channel = <9>; +}; diff --git a/west.yml b/west.yml index d577ce69ce8e..0236e846ae72 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: groups: - hal - name: hal_nxp - revision: b7bd6f67785aee302c1573dababc278e9da00569 + revision: 49ff7e33f848e4b59da59369a77da63e346fb1a3 path: modules/hal/nxp groups: - hal