Hello!
I'm using an i.MX8MM processor and trying to get SAI working via SDMA. My code is very close to the example, but I don't understand why SDMA doesn't run and my saiCallback doesn't run.
Can anyone help me with this?
#define DEMO_SAI_DMA SDMAARM3
#define DEMO_SAI_DMA_CHANNEL (1)
#define DEMO_SAI_DMA_CHANNEL_PRIORITY (2U)
#define DEMO_SAI (I2S5)
#define DEMO_SAI_CLK_FREQ (24576000U)
#define DEMO_SAI_TX_DMA_REQUEST_SOURCE (9) // SAI5 transmit event (pg. 1009 datasheet)
#define DEMO_AUDIO_BIT_WIDTH kSAI_WordWidth16bits
#define DEMO_SAI_CLOCK_SOURCE (kSAI_BclkSourceMclkDiv)
#define DEMO_AUDIO_DATA_CHANNEL (2U)
#define DEMO_AUDIO_MASTER_CLOCK DEMO_SAI_CLK_FREQ
#define DEMO_AUDIO_SAMPLE_RATE (kSAI_SampleRate48KHz)
#define BUFFER_SIZE (1024)
...
int main(void)
{
/* Init board hardware. */
/* Board specific RDC settings */
BOARD_RdcInit();
BOARD_InitBootPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
BOARD_InitMemory();
CLOCK_SetRootDivider(kCLOCK_RootI2c3, 1U, 10U); /* Set root clock to 160MHZ / 10 = 16MHZ */
CLOCK_SetRootMux(kCLOCK_RootSai5, kCLOCK_SaiRootmuxAudioPll1); /* Set SAI source to 393216000Hz*/
CLOCK_SetRootDivider(kCLOCK_RootSai5, 1U, 16U); /* Set root clock to 393216000HZ / 16 = 24.576000MHz */
// SDMA Init
sdma_config_t dmaConfig = {0};
SDMA_GetDefaultConfig(&dmaConfig);
dmaConfig.ratio = kSDMA_ARMClockFreq;
SDMA_Init(DEMO_SAI_DMA, &dmaConfig);
SDMA_CreateHandle(&s_saiDmaHandle, DEMO_SAI_DMA, DEMO_SAI_DMA_CHANNEL, &s_saiSdmaContext);
SDMA_SetChannelPriority(DEMO_SAI_DMA, DEMO_SAI_DMA_CHANNEL, DEMO_SAI_DMA_CHANNEL_PRIORITY);
SDMA_LoadScript(DEMO_SAI_DMA, FSL_SDMA_SCRIPT_CODE_START_ADDR, (void *)g_sdma_multi_fifo_script, FSL_SDMA_SCRIPT_CODE_SIZE);
/* SAI init */
sai_transceiver_t config;
sai_transfer_t saiXfer;
SAI_Init(DEMO_SAI);
SAI_TransferTxCreateHandleSDMA(DEMO_SAI, &s_saiTxHandle, saiCallback, NULL, &s_saiDmaHandle, DEMO_SAI_TX_DMA_REQUEST_SOURCE);
/* I2S mode configurations */
SAI_GetClassicI2SConfig(&config, DEMO_AUDIO_BIT_WIDTH, kSAI_Stereo, kSAI_Channel0Mask);
config.bitClock.bclkSource = DEMO_SAI_CLOCK_SOURCE;
SAI_TransferTxSetConfigSDMA(DEMO_SAI, &s_saiTxHandle, &config);
/* set bit clock divider */
SAI_TxSetBitClockRate(DEMO_SAI, DEMO_AUDIO_MASTER_CLOCK, DEMO_AUDIO_SAMPLE_RATE, DEMO_AUDIO_BIT_WIDTH, DEMO_AUDIO_DATA_CHANNEL);
/* master clock configurations */
mclkConfig.mclkOutputEnable = true, mclkConfig.mclkHz = DEMO_AUDIO_MASTER_CLOCK;
mclkConfig.mclkSourceClkHz = DEMO_SAI_CLK_FREQ;
SAI_SetMasterClockConfig(DEMO_SAI, &mclkConfig);
saiXfer.data = s_buffer;
saiXfer.dataSize = BUFFER_SIZE;
volatile status_t st = SAI_TransferSendSDMA(DEMO_SAI, &s_saiTxHandle, &saiXfer);
while (1)
{
}
}
static void saiCallback(I2S_Type *base, sai_sdma_handle_t *handle, status_t status, void *userData)
{
}
I send a single SDMA request and expect saiCallback to be called when it finishes sending data. But it doesn't happen, where did I go wrong?
Hello,
Did you try to debug it (for example using breakpoint or prints) and compare it with our example sai_sdma_transfer.c?
Best regards.