i.MX8MM SAI SDMA Cortex M4 Baremetal

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX8MM SAI SDMA Cortex M4 Baremetal

171 Views
c0da
Contributor I

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?

0 Kudos
Reply
1 Reply

144 Views
JorgeCas
NXP TechSupport
NXP TechSupport

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.

0 Kudos
Reply