Hi,
I am trying to update the initialization code for my MKL27Z256xxx4's SAI-over-DMA interface to use SDK v2.8.0. I am having a bit of trouble because the new SDK calls seem to use different data structures and I am struggling to translate them over. I am mainly using MCUXpresso's Config Tools to generate the new initialization calls.
According to the MCUXpresso project the old code was based off SDK 2.4.1 and looks like the following:
/* Init DMAMUX */
/* Channel 1 is I2S Transmit
* Channel 0 is I2S Receive
*/
DMAMUX_Init(DMAMUX0);
DMAMUX_SetSource(DMAMUX0, 0, 14); //Map I2S RX to channel 0
DMAMUX_SetSource(DMAMUX0, 1, 15); //MAP I2S TX to channel 1
DMAMUX_EnableChannel(DMAMUX0, 0);
DMAMUX_EnableChannel(DMAMUX0, 1);
/* Init DMA and create handle for DMA */
DMA_Init(DMA0);
DMA_CreateHandle(&dmaRxHandle, DMA0, 0);
DMA_CreateHandle(&dmaTxHandle, DMA0, 1);
// Setup the I2S interface
SAI_TxGetDefaultConfig(&user_config);
user_config.protocol = kSAI_BusI2S;
user_config.syncMode = kSAI_ModeSync;
user_config.mclkOutputEnable = false;
user_config.masterSlave = kSAI_Slave;
SAI_TxInit(I2S0, &user_config);
SAI_RxInit(I2S0, &user_config);
g_SAI_format.bitWidth = kSAI_WordWidth16bits;
g_SAI_format.channel = 0;
g_SAI_format.protocol = kSAI_BusI2S;
g_SAI_format.sampleRate_Hz = kSAI_SampleRate48KHz;
g_SAI_format.stereo = kSAI_Stereo;
SAI_TransferTxCreateHandleDMA(I2S0, &g_m_tx_dma_handle, AudioBufferHandler_DMATxCallback, NULL, &dmaTxHandle);
SAI_TransferTxSetFormatDMA(I2S0,
&g_m_tx_dma_handle,
&g_SAI_format,
CLOCK_GetFreq(kCLOCK_CoreSysClk),
12288000U);
// We are running a Mono Mic
g_SAI_format.stereo = kSAI_MonoLeft;
SAI_TransferRxCreateHandleDMA(I2S0, &g_m_rx_dma_handle, AudioBufferHandler_DMARxCallback, NULL, &dmaRxHandle);
SAI_TransferRxSetFormatDMA(I2S0,
&g_m_rx_dma_handle,
&g_SAI_format,
CLOCK_GetFreq(kCLOCK_CoreSysClk),
12288000U);
Here is what the IDE generated:
/***********************************************************************************************************************
* I2S0 initialization code
**********************************************************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
instance:
- name: 'I2S0'
- type: 'sai'
- mode: 'dma'
- custom_name_enabled: 'false'
- type_id: 'sai_37a0d4b4ecc2db8ea149dbe2026c6550'
- functional_group: 'BOARD_InitPeripherals'
- peripheral: 'I2S0'
- config_sets:
- fsl_sai:
- mclk_config:
- masterClockSource: 'ExternalClock'
- masterClockFrequency: '12.288 MHz'
- init_mclk_config: 'true'
- sai_master_clock: []
- usage: 'record_playback'
- signal_config:
- 0:
- sourceTx: 'Tx'
- sourceRx: 'Rx'
- 1:
- sourceTx: 'Tx'
- sourceRx: 'Rx'
- syncSwapI: []
- bclkTxSetting: []
- bclkRxSetting: []
- syncTxSetting: []
- syncRxSetting: []
- whole:
- tx_group:
- sai_transceiver:
- bitClock:
- modeM: 'slave'
- slaveBitClockFrequency: '12.288MHz'
- bitClockSource: 'kSAI_BclkSourceMclkDiv'
- bclkPolarityM: 'kSAI_PolarityActiveLow'
- bclkInputDelayM: 'false'
- frameSync:
- modeM: 'slave'
- frameSyncWidthM: '16'
- frameSyncPolarityM: 'kSAI_PolarityActiveLow'
- frameSyncEarlyM: 'true'
- sampleRate_Hz: 'kSAI_SampleRate48KHz'
- channelMask: 'kSAI_Channel0Mask'
- serialData:
- differentFirstWord: 'false'
- sameDataWordLengthM: 'kSAI_WordWidth16bits'
- dataOrder: 'kSAI_DataMSB'
- dataFirstBitShiftedM: '16'
- dataWordNumM: '2'
- dataMasked_config:
- dataMasked_L:
- 0: 'false'
- 1: 'false'
- 2: 'false'
- 3: 'false'
- 4: 'false'
- 5: 'false'
- 6: 'false'
- 7: 'false'
- 8: 'false'
- 9: 'false'
- 10: 'false'
- 11: 'false'
- 12: 'false'
- 13: 'false'
- 14: 'false'
- 15: 'false'
- dataMasked_H:
- 0: 'false'
- 1: 'false'
- 2: 'false'
- 3: 'false'
- 4: 'false'
- 5: 'false'
- 6: 'false'
- 7: 'false'
- 8: 'false'
- 9: 'false'
- 10: 'false'
- 11: 'false'
- 12: 'false'
- 13: 'false'
- 14: 'false'
- 15: 'false'
- fifo:
- fifoPacking: 'kSAI_FifoPackingDisabled'
- fifoContinueOneError: 'false'
- dma_group:
- enable_dma_channel: 'true'
- dma_channel:
- DMAn: '1'
- DMA_source: 'kDmaRequestMux0I2S0Tx'
- enableTriggerPIT: 'false'
- enable_custom_name: 'true'
- handle_custom_name: 'dmaTxHandle'
- sai_dma_handle:
- enable_custom_name: 'true'
- handle_custom_name: 'g_m_tx_dma_handle'
- init_callback: 'true'
- callback_fcn: 'AudioBufferHandler_DMATxCallback'
- user_data: ''
- rx_group:
- sai_transceiver:
- bitClock:
- modeM: 'slave'
- slaveBitClockFrequency: '12.288MHz'
- bitClockSource: 'kSAI_BclkSourceMclkDiv'
- bclkPolarityM: 'kSAI_PolarityActiveLow'
- bclkInputDelayM: 'false'
- frameSync:
- modeM: 'slave'
- frameSyncWidthM: '16'
- frameSyncPolarityM: 'kSAI_PolarityActiveLow'
- frameSyncEarlyM: 'true'
- sampleRate_Hz: 'kSAI_SampleRate48KHz'
- channelMask: 'kSAI_Channel0Mask'
- serialData:
- differentFirstWord: 'false'
- sameDataWordLengthM: 'kSAI_WordWidth16bits'
- dataOrder: 'kSAI_DataMSB'
- dataFirstBitShiftedM: '16'
- dataWordNumM: '2'
- dataMasked_config:
- dataMasked_L:
- 0: 'false'
- 1: 'false'
- 2: 'false'
- 3: 'false'
- 4: 'false'
- 5: 'false'
- 6: 'false'
- 7: 'false'
- 8: 'false'
- 9: 'false'
- 10: 'false'
- 11: 'false'
- 12: 'false'
- 13: 'false'
- 14: 'false'
- 15: 'false'
- dataMasked_H:
- 0: 'false'
- 1: 'false'
- 2: 'false'
- 3: 'false'
- 4: 'false'
- 5: 'false'
- 6: 'false'
- 7: 'false'
- 8: 'false'
- 9: 'false'
- 10: 'false'
- 11: 'false'
- 12: 'false'
- 13: 'false'
- 14: 'false'
- 15: 'false'
- fifo:
- fifoPacking: 'kSAI_FifoPackingDisabled'
- fifoContinueOneError: 'false'
- dma_group:
- enable_dma_channel: 'true'
- dma_channel:
- DMAn: '0'
- DMA_source: 'kDmaRequestMux0I2S0Rx'
- enableTriggerPIT: 'false'
- enable_custom_name: 'true'
- handle_custom_name: 'dmaRxHandle'
- sai_dma_handle:
- enable_custom_name: 'true'
- handle_custom_name: 'g_m_rx_dma_handle'
- init_callback: 'true'
- callback_fcn: 'AudioBufferHandler_DMARxCallback'
- user_data: ''
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
/* I2S0 Tx configuration */
sai_transceiver_t I2S0_Tx_config = {
.masterSlave = kSAI_Slave,
.bitClock = {
.bclkSrcSwap = false,
.bclkSource = kSAI_BclkSourceMclkDiv,
.bclkPolarity = kSAI_PolarityActiveLow,
.bclkInputDelay = false
},
.frameSync = {
.frameSyncWidth = 16U,
.frameSyncPolarity = kSAI_PolarityActiveLow,
.frameSyncEarly = true,
},
.syncMode = kSAI_ModeAsync,
.channelMask = kSAI_Channel0Mask,
.startChannel = 0U,
.endChannel = 0U,
.channelNums = 1U,
.serialData = {
.dataWord0Length = (uint8_t)kSAI_WordWidth16bits,
.dataWordNLength = (uint8_t)kSAI_WordWidth16bits,
.dataWordLength = (uint8_t)kSAI_WordWidth16bits,
.dataOrder = kSAI_DataMSB,
.dataFirstBitShifted = 16U,
.dataWordNum = 2U,
.dataMaskedWord = 0x0U
},
.fifo = {
.fifoPacking = kSAI_FifoPackingDisabled,
.fifoContinueOneError = false
}
};
/* I2S0 Rx configuration */
sai_transceiver_t I2S0_Rx_config = {
.masterSlave = kSAI_Slave,
.bitClock = {
.bclkSrcSwap = false,
.bclkSource = kSAI_BclkSourceMclkDiv,
.bclkPolarity = kSAI_PolarityActiveLow,
.bclkInputDelay = false
},
.frameSync = {
.frameSyncWidth = 16U,
.frameSyncPolarity = kSAI_PolarityActiveLow,
.frameSyncEarly = true,
},
.syncMode = kSAI_ModeAsync,
.channelMask = kSAI_Channel0Mask,
.startChannel = 0U,
.endChannel = 0U,
.channelNums = 1U,
.serialData = {
.dataWord0Length = (uint8_t)kSAI_WordWidth16bits,
.dataWordNLength = (uint8_t)kSAI_WordWidth16bits,
.dataWordLength = (uint8_t)kSAI_WordWidth16bits,
.dataOrder = kSAI_DataMSB,
.dataFirstBitShifted = 16U,
.dataWordNum = 2U,
.dataMaskedWord = 0x0U
},
.fifo = {
.fifoPacking = kSAI_FifoPackingDisabled,
.fifoContinueOneError = false
}
};
sai_master_clock_t I2S0_MCLK_config = {
.mclkOutputEnable = false,
.mclkSource = kSAI_MclkSourceSysclk,
.mclkSourceClkHz = I2S0_MCLK_SOURCE_CLOCK_HZ,
.mclkHz = I2S0_USER_MCLK_HZ
};
dma_handle_t dmaTxHandle;
dma_handle_t dmaRxHandle;
sai_dma_handle_t g_m_tx_dma_handle;
sai_dma_handle_t g_m_rx_dma_handle;
static void I2S0_init(void) {
/* Set the source kDmaRequestMux0I2S0Tx request in the DMAMUX */
DMAMUX_SetSource(I2S0_TX_DMAMUX_BASEADDR, I2S0_TX_DMA_CHANNEL, I2S0_TX_DMA_REQUEST);
/* Enable the channel 1 in the DMAMUX */
DMAMUX_EnableChannel(I2S0_TX_DMAMUX_BASEADDR, I2S0_TX_DMA_CHANNEL);
/* Set the source kDmaRequestMux0I2S0Rx request in the DMAMUX */
DMAMUX_SetSource(I2S0_RX_DMAMUX_BASEADDR, I2S0_RX_DMA_CHANNEL, I2S0_RX_DMA_REQUEST);
/* Enable the channel 0 in the DMAMUX */
DMAMUX_EnableChannel(I2S0_RX_DMAMUX_BASEADDR, I2S0_RX_DMA_CHANNEL);
/* Create the DMA dmaTxHandle handle */
DMA_CreateHandle(&dmaTxHandle, I2S0_TX_DMA_BASEADDR, I2S0_TX_DMA_CHANNEL);
/* Create the DMA dmaRxHandle handle */
DMA_CreateHandle(&dmaRxHandle, I2S0_RX_DMA_BASEADDR, I2S0_RX_DMA_CHANNEL);
/* Initialize SAI clock gate */
SAI_Init(I2S0_PERIPHERAL);
/* Create the SAI Tx DMA handle */
SAI_TransferTxCreateHandleDMA(I2S0_PERIPHERAL, &g_m_tx_dma_handle, AudioBufferHandler_DMATxCallback, NULL, &dmaTxHandle);
/* Create the SAI Rx DMA handle */
SAI_TransferRxCreateHandleDMA(I2S0_PERIPHERAL, &g_m_rx_dma_handle, AudioBufferHandler_DMARxCallback, NULL, &dmaRxHandle);
/* Configures SAI Tx sub-module functionality */
SAI_TransferTxSetConfigDMA(I2S0_PERIPHERAL, &g_m_tx_dma_handle, &I2S0_Tx_config);
/* Configures SAI Rx sub-module functionality */
SAI_TransferRxSetConfigDMA(I2S0_PERIPHERAL, &g_m_rx_dma_handle, &I2S0_Rx_config);
/* Initialize SAI master clock */
SAI_SetMasterClockConfig(I2S0_PERIPHERAL, &I2S0_MCLK_config);
}
/***********************************************************************************************************************
* Initialization functions
**********************************************************************************************************************/
void BOARD_InitPeripherals(void)
{
/* Global initialization */
DMAMUX_Init(DMA_DMAMUX_BASEADDR);
DMA_Init(DMA_DMA_BASEADDR);
/* Initialize components */
I2S0_init();
}
I was able to get audio playback and recording with the old code but with the IDE-generated SAI configuration I don't seem to be getting any playback and the record line seems to just be recording white noise.
Any advice would be greatly appreciated
Hello,
In order to help you, Could you tell me if you are based on an example? if yes what kind the example or documentation are you based on?
Best regards,
Pavel