Hello.
I am using PicoCore™MX8ULP and I have a problem using edma for sai1.
In the attached code I initialize SAI1(#define USE_SAI1) or SAI0 (#define USE_SAI0) to send data using edma (function config_sai_tx_edma();) or without edma (function config_sai_tx();). When using SAI0 both functions work and data comes out from corresponding pins initialized for SAI0. But when I use SAI1 I can send data without edma and it comes out from pins, but when I use edma (function config_sai_tx_edma();) there is no data output. In edma registers (DMA0->MP_ES) I see destination bus error. Is this related to some incorrect initialization of edma for sai1 on my part or some other error in the settings?
my code:
C
- #include <stdio.h>
- #include <string.h>
- #include "clock_config.h"
- #include "board.h"
- #include "fsl_debug_console.h"
- #include "fsl_reset.h"
- #include "fsl_sai.h"
- #include "fsl_edma.h"
- #include "fsl_sai_edma.h"
- #include "fsl_common.h"
- #include "fsl_fusion.h"
- #include "fsl_rgpio.h"
- #include "fsl_iomuxc.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #define USE_SAI0
- #ifdef USE_SAI1
- #define CURRENT_SAI SAI1
- #define SAI_CLK CLOCK_GetIpFreq(kCLOCK_Sai1)
- #define SAI_DMA_MUX kDmaRequestMux0SAI1Tx
- #else
- #define CURRENT_SAI SAI0
- #define SAI_CLK CLOCK_GetIpFreq(kCLOCK_Sai0)
- #define SAI_DMA_MUX kDmaRequestMux0SAI0Tx
- #endif
- #define SAI_CHANNEL kSAI_Channel1Mask
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- void InitPins_sai(void);
- void config_sai_tx();
- void setClock_sai();
- void config_sai_tx_edma();
- /*******************************************************************************
- * Code
- ******************************************************************************/
- static void saiCallback(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData);
- static void dmaCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);
- /*!
- * @brief Main function
- */
- int main(void)
- {
- BOARD_BootClockRUN();
- InitPins_sai();
- setClock_sai();
- if (BOARD_IsLowPowerBootType() != true) /* not low power boot type */
- {
- BOARD_HandshakeWithUboot(); /* Must handshake with uboot, unless will get issues(such as: SoC reset all the
- time) */
- }
- else /* low power boot type */
- {
- BOARD_SetTrdcGlobalConfig();
- }
- #ifdef USE_SAI1
- config_sai_tx_edma();
- // config_sai_tx();
- #else
- config_sai_tx_edma();
- // config_sai_tx();
- #endif
- int i = 0;
- while (1)
- {
- }
- }
- edma_handle_t s_saiDmaHandle;
- void setClock_sai()
- {
- #ifdef USE_SAI1
- UPOWER_PowerOnMemPart(0U, (uint32_t)kUPOWER_MP1_DMA0);
- CLOCK_SetIpSrc(kCLOCK_Sai1, kCLOCK_Cm33SaiClkSrcPll1Pfd2Div);
- CLOCK_EnableClock(kCLOCK_Dma0Ch0);
- RESET_PeripheralReset(kRESET_Sai1);
- #else
- UPOWER_PowerOnMemPart(0U, (uint32_t)kUPOWER_MP1_DMA0);
- CLOCK_SetIpSrc(kCLOCK_Sai0, kCLOCK_Cm33SaiClkSrcPll1Pfd2Div);
- CLOCK_EnableClock(kCLOCK_Dma0Ch0);
- RESET_PeripheralReset(kRESET_Sai0);
- #endif
- }
- static void saiCallback(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData)
- {
- if (kStatus_SAI_TxError == status)
- {
- /* Handle the error. */
- bool fail = true;
- }
- else
- {
- }
- }
- static void dmaCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
- {
- if (kStatus_SAI_TxError == status)
- {
- bool fail = true;
- // #warning "no receive error handling"
- }
- else
- {
- }
- }
- static sai_handle_t s_saiTxHandle = {0};
- uint8_t dataForTransfer3[520] = {0};
- uint8_t dataForTransfer4[520] = {0};
- void config_sai_tx()
- {
- sai_transfer_t saiXfer;
- sai_transceiver_t config;
- dataForTransfer3[0] = 0xff;
- saiXfer.data = dataForTransfer3;
- saiXfer.dataSize = 26;
- SAI_Init(CURRENT_SAI);
- SAI_TransferTxCreateHandle(CURRENT_SAI, &s_saiTxHandle, saiCallback, NULL);
- SAI_GetClassicI2SConfig(&config, kSAI_WordWidth16bits, kSAI_Stereo, SAI_CHANNEL);
- config.bitClock.bclkSource = kSAI_BclkSourceBusclk;
- config.masterSlave = kSAI_Master;
- SAI_TransferTxSetConfig(CURRENT_SAI, &s_saiTxHandle, &config);
- SAI_TxSetBitClockRate(CURRENT_SAI, SAI_CLK, kSAI_SampleRate48KHz, kSAI_WordWidth16bits, 2);
- int sendCount = 0;
- while (true)
- {
- if (kStatus_Success == SAI_TransferSendNonBlocking(CURRENT_SAI, &s_saiTxHandle, &saiXfer))
- {
- if (sendCount++ > 1000)
- sendCount = 0;
- }
- }
- }
- sai_edma_handle_t s_saiTxHandleEdma;
- uint8_t dataForTransfer0[500];
- uint8_t dataForTransfer1[500];
- void config_sai_tx_edma()
- {
- edma_config_t dmaConfig = {0};
- sai_transfer_t saiXfer;
- sai_transceiver_t config;
- EDMA_GetDefaultConfig(&dmaConfig);
- EDMA_Init(DMA0, &dmaConfig);
- EDMA_CreateHandle(&s_saiDmaHandle, DMA0, 0);
- EDMA_SetChannelMux(DMA0, 0, SAI_DMA_MUX);
- SAI_Init(CURRENT_SAI);
- SAI_TransferTxCreateHandleEDMA(CURRENT_SAI, &s_saiTxHandleEdma, dmaCallback, NULL, &s_saiDmaHandle);
- SAI_GetClassicI2SConfig(&config, kSAI_WordWidth16bits, kSAI_Stereo, SAI_CHANNEL);
- config.masterSlave = kSAI_Master;
- config.syncMode = kSAI_ModeAsync; // kSAI_ModeSync;
- SAI_TransferTxSetConfigEDMA(CURRENT_SAI, &s_saiTxHandleEdma, &config);
- SAI_TxSetBitClockRate(CURRENT_SAI, SAI_CLK, kSAI_SampleRate48KHz, kSAI_WordWidth16bits, 1);
- sai_transfer_t saiXfer2[2];
- saiXfer2[0].data = dataForTransfer3;
- saiXfer2[1].data = dataForTransfer4;
- saiXfer2[0].dataSize = 480;
- saiXfer2[1].dataSize = 480;
- for (int i = 1; i < saiXfer2[0].dataSize; i++)
- {
- dataForTransfer0[i] = 0xAA;
- dataForTransfer1[i] = 0xCC;
- }
- if (SAI_TransferSendLoopEDMA(CURRENT_SAI, &s_saiTxHandleEdma, &saiXfer2, 2) != kStatus_Success)
- {
- bool fail;
- fail = true;
- };
- int counter = 0;
- }
- void InitPins_sai(void)
- {
- #ifdef USE_SAI1
- // IOMUXC_SetPinMux(IOMUXC_PTA17_I2S1_TXD1, 0U);
- IOMUXC_SetPinMux(IOMUXC_PTC19_I2S1_TXD1, 0U);
- IOMUXC_SetPinMux(IOMUXC_PTA13_I2S1_MCLK, 0U);
- IOMUXC_SetPinMux(IOMUXC_PTA14_I2S1_TX_BCLK, 0U);
- IOMUXC_SetPinMux(IOMUXC_PTA15_I2S1_TX_FS, 0U);
- #else
- IOMUXC_SetPinMux(IOMUXC_PTA5_I2S0_TX_BCLK, 0U);
- //IOMUXC_SetPinMux(IOMUXC_PTA8_I2S0_TXD1, 0U);
- IOMUXC_SetPinMux(IOMUXC_PTC6_I2S0_TXD1, 0U);
- IOMUXC_SetPinMux(IOMUXC_PTA6_I2S0_TX_FS, 0U);
- #endif
- }