RT1021 TDM Configuration clock

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

RT1021 TDM Configuration clock

Jump to solution
918 Views
jarman_zhou
Contributor I

RT1021 The TDM mode fs clock of the SAI is incorrect. Attached are the code of the configuration and the oscilloscope screenshot.

/* Select Audio/Video PLL (786.48 MHz) as sai1 clock source */
#define DEMO_SAI1_CLOCK_SOURCE_SELECT (2U)
/* Clock pre divider for sai1 clock source */
#define DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER (1U)
/* Clock divider for sai1 clock source */
#define DEMO_SAI1_CLOCK_SOURCE_DIVIDER (15U)
/* Get frequency of sai1 clock */
#define DEMO_SAI_CLK_FREQ \
(CLOCK_GetFreq(kCLOCK_AudioPllClk) / (DEMO_SAI1_CLOCK_SOURCE_DIVIDER + 1U) / \
(DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER + 1U))

/* demo audio sample rate */
#define DEMO_AUDIO_SAMPLE_RATE (kSAI_SampleRate16KHz)
/* demo audio data channel */
#define DEMO_AUDIO_DATA_CHANNEL (2U)
/* demo audio bit width */
#define DEMO_AUDIO_BIT_WIDTH (kSAI_WordWidth16bits)

 

int SaiTask(void)
{

edma_config_t dmaConfig = {0};
char input = '1';
uint8_t userItem = 1U;

CLOCK_InitAudioPll(&audioPllConfig);

/* I2C */
/*Clock setting for LPI2C*/
CLOCK_SetMux(kCLOCK_Lpi2cMux, LPI2C_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER);

/*Clock setting for SAI1*/
CLOCK_SetMux(kCLOCK_Sai1Mux, DEMO_SAI1_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Sai1PreDiv, DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER);
CLOCK_SetDiv(kCLOCK_Sai1Div, DEMO_SAI1_CLOCK_SOURCE_DIVIDER);

/*Enable MCLK clock*/
BOARD_EnableSaiMclkOutput(true);

/* Init DMAMUX */
DMAMUX_Init(DEMO_DMAMUX);
DMAMUX_SetSource(DEMO_DMAMUX, DEMO_TX_EDMA_CHANNEL, (uint8_t)DEMO_SAI_TX_SOURCE);
DMAMUX_EnableChannel(DEMO_DMAMUX, DEMO_TX_EDMA_CHANNEL);
DMAMUX_SetSource(DEMO_DMAMUX, DEMO_RX_EDMA_CHANNEL, (uint8_t)DEMO_SAI_RX_SOURCE);
DMAMUX_EnableChannel(DEMO_DMAMUX, DEMO_RX_EDMA_CHANNEL);

PRINTF("SAI Demo started!\n\r");

/* Create EDMA handle */
/*
* dmaConfig.enableRoundRobinArbitration = false;
* dmaConfig.enableHaltOnError = true;
* dmaConfig.enableContinuousLinkMode = false;
* dmaConfig.enableDebugMode = false;
*/
EDMA_GetDefaultConfig(&dmaConfig);
EDMA_Init(DEMO_DMA, &dmaConfig);
EDMA_CreateHandle(&dmaTxHandle, DEMO_DMA, DEMO_TX_EDMA_CHANNEL);
EDMA_CreateHandle(&dmaRxHandle, DEMO_DMA, DEMO_RX_EDMA_CHANNEL);
#if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX
EDMA_SetChannelMux(DEMO_DMA, DEMO_TX_EDMA_CHANNEL, DEMO_SAI_TX_EDMA_CHANNEL);
EDMA_SetChannelMux(DEMO_DMA, DEMO_RX_EDMA_CHANNEL, DEMO_SAI_RX_EDMA_CHANNEL);
#endif

/* SAI init */
SAI_Init(DEMO_SAI);

SAI_TransferTxCreateHandleEDMA(DEMO_SAI, &txHandle, txCallback, NULL, &dmaTxHandle);
SAI_TransferRxCreateHandleEDMA(DEMO_SAI, &rxHandle, rxCallback, NULL, &dmaRxHandle);

/* I2S mode configurations */
//SAI_GetClassicI2SConfig(&saiConfig, DEMO_AUDIO_BIT_WIDTH, kSAI_Stereo, 1U << DEMO_SAI_CHANNEL);
SAI_GetTDMConfig(&saiConfig, kSAI_FrameSyncLenOneBitClk, DEMO_AUDIO_BIT_WIDTH, DEMO_AUDIO_DATA_CHANNEL, 1U << DEMO_SAI_CHANNEL);
saiConfig.frameSync.frameSyncEarly = true;
//saiConfig.syncMode = DEMO_SAI_TX_SYNC_MODE;
//saiConfig.masterSlave = DEMO_SAI_MASTER_SLAVE;
SAI_TransferTxSetConfigEDMA(DEMO_SAI, &txHandle, &saiConfig);
//saiConfig.syncMode = DEMO_SAI_RX_SYNC_MODE;
SAI_TransferRxSetConfigEDMA(DEMO_SAI, &rxHandle, &saiConfig);

/* set bit clock divider */
SAI_TxSetBitClockRate(DEMO_SAI, DEMO_AUDIO_MASTER_CLOCK, DEMO_AUDIO_SAMPLE_RATE, DEMO_AUDIO_BIT_WIDTH,
DEMO_AUDIO_DATA_CHANNEL);
SAI_RxSetBitClockRate(DEMO_SAI, DEMO_AUDIO_MASTER_CLOCK, DEMO_AUDIO_SAMPLE_RATE, DEMO_AUDIO_BIT_WIDTH,
DEMO_AUDIO_DATA_CHANNEL);

/* master clock configurations */
BOARD_MASTER_CLOCK_CONFIG();


//tlv320
tlv6410_i2c_init();
tlv6410_config();
tlv6410_Status();

#if 0
/* Use default setting to init codec */
if (CODEC_Init(&codecHandle, &boardCodecConfig) != kStatus_Success)
{
assert(false);
}
if (CODEC_SetVolume(&codecHandle, kCODEC_PlayChannelHeadphoneLeft | kCODEC_PlayChannelHeadphoneRight,
DEMO_CODEC_VOLUME) != kStatus_Success)
{
assert(false);
}
#endif
/* Enable interrupt to handle FIFO error */
SAI_TxEnableInterrupts(DEMO_SAI, kSAI_FIFOErrorInterruptEnable);
SAI_RxEnableInterrupts(DEMO_SAI, kSAI_FIFOErrorInterruptEnable);
EnableIRQ(DEMO_SAI_TX_IRQ);
EnableIRQ(DEMO_SAI_RX_IRQ);

}

MCLK.jpgBCLK.jpgFS.jpg

0 Kudos
1 Solution
776 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

  Now, both the DMA and the interrupt works.

1. DMA clock issues:

Check attached code:evkmimxrt1020_sai_edma_transfer_TDM_clock.zip

Just use the following clock configuration to the audio PLL.

const clock_audio_pll_config_t audioPllConfig = {
    .loopDivider = 32,  /* PLL loop divider. Valid range for DIV_SELECT divider value: 27~54. */
    .postDivider = 1,   /* Divider after the PLL, should only be 1, 2, 4, 8, 16. */
    .numerator   = 77,  /* 30 bit numerator of fractional loop divider. */
    .denominator = 100, /* 30 bit denominator of fractional loop divider */
};

 

Then you will find the MCLK is :12288750hz

BCLK is 512Khz

SYNC is 16Khz.

 

2. the interrupt issues, check your another post link:

https://community.nxp.com/t5/i-MX-Processors/RT1021-SAI-TDM-mode-transmitter-abnormality/td-p/163416...

I already share it with you.

If your issue is solved, please help to mark the correct answer, thanks.

Best Regards,

Kerry

 

View solution in original post

0 Kudos
8 Replies
801 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

  Interrupt solutions, check this post reply:

https://community.nxp.com/t5/i-MX-Processors/RT1021-SAI-TDM-mode-transmitter-abnormality/td-p/163416...

 

Wish it helps you!
If you still have questions about it, please kindly let me know.
If your question is solved, please help to mark the correct answer, thanks.

Best Regards,

Kerry

0 Kudos
903 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

  What's the detail wave in your attached picture, SYNC, BCLK?

  It's better to put it together.

  Now, which frequency you want to get in SYNC? 16KHZ? then what's the result?

Please give me more description about your question, thanks.

Best Regards,

kerry

0 Kudos
896 Views
jarman_zhou
Contributor I

Look at the above code, after I changed the audio to TMD (SAI_GetTDMConfig), SAI data line IOMUXC_GPIO_AD_B1_03_SAI1_TX_DATA00 could not receive data, But when configured as I2S (SAI_GetClassicI2SConfig) there is data, the clock is always 16kHz, 16Bit, 2 channels.

If I want to configure it as TDM, is there anything missing in the above code? What should I configure?

0 Kudos
871 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

  Which SDK version you have test?

  Please also attach your project which can reproduce the issues, then I will find time to test it on the MIMXRT1020-EVK board, thanks.

Best Regards,

kerry

0 Kudos
866 Views
jarman_zhou
Contributor I

SDK_2_11_0_EVK-MIMXRT1020.

On this project, I changed to TDM mode, the code is blocked at SAI_TransferSendNonBlocking

0 Kudos
807 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

  So sorry for my later reply.

   I find the issue is in the interrupt code, you can use the DMA method, that totally works.

   Please check my attached code for the TDM, this is the test result when I sendout the following data:

__ALIGN_BEGIN const uint8_t music[] __ALIGN_END =
    {
        0x55, 0xaa, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00,
...
}

TDM.jpgRT1020_TDM_16BIT_16KHZ.png

 

You can see the DMA method can output the data correctly.

Your configuration code is correct, just interrupt method have issues.

 

So, I suggest you use the DMA method at first.

Best Regards,

Kerry

 

 

0 Kudos
800 Views
jarman_zhou
Contributor I

Hi, @kerryzhou

 I use the DMA method, The data is there, but I don't think the clock is right. I got the MCLK is 12000kHz and BCLK is 500kHz, FSync is 15.625kHz.

But i use the interrupt TDM, MCLK is 12288kHz and BCLK is 512kHz, FSync is 16kHz.

If the clock is wrong, I don't think the data is right.

 Best Regards,

Jarman

0 Kudos
777 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

  Now, both the DMA and the interrupt works.

1. DMA clock issues:

Check attached code:evkmimxrt1020_sai_edma_transfer_TDM_clock.zip

Just use the following clock configuration to the audio PLL.

const clock_audio_pll_config_t audioPllConfig = {
    .loopDivider = 32,  /* PLL loop divider. Valid range for DIV_SELECT divider value: 27~54. */
    .postDivider = 1,   /* Divider after the PLL, should only be 1, 2, 4, 8, 16. */
    .numerator   = 77,  /* 30 bit numerator of fractional loop divider. */
    .denominator = 100, /* 30 bit denominator of fractional loop divider */
};

 

Then you will find the MCLK is :12288750hz

BCLK is 512Khz

SYNC is 16Khz.

 

2. the interrupt issues, check your another post link:

https://community.nxp.com/t5/i-MX-Processors/RT1021-SAI-TDM-mode-transmitter-abnormality/td-p/163416...

I already share it with you.

If your issue is solved, please help to mark the correct answer, thanks.

Best Regards,

Kerry

 

0 Kudos