We'd plan to use the SAI interface of imx8mp_evk, for high speed data receive, not for the normal audio usage. But found that the read speed of SAI RDR(n) Register is too low.
Now we are doing a test of make the SAI1_RX_BCLK = 40 Mhz, 4 data channels(0~3channels)
SAI_RX_SYNX = 40/(32*2), framesize = 64. FIFO mechanism.
But we encountered the FIFO full interrupt.
That means the Read speed is far behind the message receive speed.
And then we take a teat of reading SAI1 RDR register.
void test_read_register(void)
{
SAI_RxEnable(DEMO_SAI, true);
uint32_t *p_testdata = (uint32_t *)g_data_test;
int index =0;
// print_sai_registers(DEMO_SAI);
PRINTF("SAI example begin!\n\r");
int j=0;
while(index < 100000000)
{
p_testdata[j++] = DEMO_SAI->RDR[0];
index++;
p_testdata[j++] = DEMO_SAI->RDR[1];
index++;
p_testdata[j++] = DEMO_SAI->RDR[2];
index++;
p_testdata[j++] = DEMO_SAI->RDR[3];
index++;
p_testdata[j++] = DEMO_SAI->RDR[0];
index++;
p_testdata[j++] = DEMO_SAI->RDR[1];
index++;
p_testdata[j++] = DEMO_SAI->RDR[2];
index++;
p_testdata[j++] = DEMO_SAI->RDR[3];
index++;
j = 0;
}
print_sai_registers(DEMO_SAI);
// print_sai_registers(DEMO_SAI);
PRINTF("\n\r SAI example finished! index =%d\n\r",index);
}
The Clock configuration could be checked in the attachment.
CLOCK_SetRootMux(kCLOCK_RootSai1, kCLOCK_SaiRootmuxAudioPll1); /* Set SAI source to AUDIO PLL1 393216000HZ*/
//chengting
CLOCK_SetRootDivider(kCLOCK_RootSai1, 1U, 1U); /* Set root clock to 393216000HZ / 16 = 24.576MHz */
void BOARD_BootClockRUN(void)
{
/* * The following steps just show how to configure the PLL clock sources using the clock driver on M7 core side .
* Please note that the ROM has already configured the SYSTEM PLL1 to 800Mhz when power up the SOC, meanwhile A core
* would enable SYSTEM PLL1, SYSTEM PLL2 and SYSTEM PLL3 by U-Boot.
* Therefore, there is no need to configure the system PLL again on M7 side, otherwise it would have a risk to make
* the SOC hang.
*/
/* switch AHB NOC root to 24M first in order to configure the SYSTEM PLL1. */
CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxOsc24M);
/* switch AXI M7 root to 24M first in order to configure the SYSTEM PLL2. */
CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxOsc24M);
// CLOCK_InitSysPll2(&g_sysPll2Config); /* init SYSTEM PLL2 run at 1000MHZ */
// CLOCK_InitSysPll3(&g_sysPll3Config); /* init SYSTEM PLL3 run at 600MHZ */
CLOCK_InitAudioPll1(&g_audioPll1Config); /* init AUDIO PLL1 run at 393216000HZ */
CLOCK_InitAudioPll2(&g_audioPll2Config); /* init AUDIO PLL2 run at 361267200HZ */
CLOCK_SetRootDivider(kCLOCK_RootM7, 1U, 1U); /* Set root clock to 800M */
CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxSysPll1); /* switch cortex-m7 to SYSTEM PLL1 */
// CLOCK_SetRootDivider(kCLOCK_RootQspi, 1U, 2U); /* Set root clock to 800M */
// CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxSysPll1); /* switch QSPI to SYSTEM PLL1 */
CLOCK_SetRootDivider(kCLOCK_RootAhb, 1U, 1U); /* Set root clock freq to 133M / 1= 133MHZ */
CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxSysPll1Div6); /* switch AHB to SYSTEM PLL1 DIV6 */
CLOCK_SetRootDivider(kCLOCK_RootAudioAhb, 1U, 2U); /* Set root clock freq to 800MHZ/ 2= 400MHZ*/
CLOCK_SetRootMux(kCLOCK_RootAudioAhb, kCLOCK_AudioAhbRootmuxSysPll1); /* switch AUDIO AHB to SYSTEM PLL1 */
CLOCK_SetRootMux(kCLOCK_RootUart4, kCLOCK_UartRootmuxSysPll1Div10); /* Set UART source to SysPLL1 Div10 80MHZ */
CLOCK_SetRootDivider(kCLOCK_RootUart4, 1U, 1U); /* Set root clock to 80MHZ/ 1= 80MHZ */
CLOCK_EnableClock(kCLOCK_Rdc); /* Enable RDC clock */
CLOCK_EnableClock(kCLOCK_Ocram); /* Enable Ocram clock */
CLOCK_EnableClock(kCLOCK_Audio); /* Enable Audio clock to power on the audiomix domain*/
/* The purpose to enable the following modules clock is to make sure the M7 core could work normally when A53 core
* enters the low power status.*/
CLOCK_EnableClock(kCLOCK_Sim_m);
CLOCK_EnableClock(kCLOCK_Sim_main);
CLOCK_EnableClock(kCLOCK_Sim_s);
CLOCK_EnableClock(kCLOCK_Sim_wakeup);
CLOCK_EnableClock(kCLOCK_Debug);
CLOCK_EnableClock(kCLOCK_Dram);
CLOCK_EnableClock(kCLOCK_Sec_Debug);
/* Power up the audiomix domain by M7 core.*/
GPC->PGC_CPU_M7_MAPPING |= 1U << GPC_PGC_CPU_M7_MAPPING_AUDIOMIX_DOMAIN_SHIFT; /* Map the audiomix domain to M7 */
GPC->PU_PGC_SW_PUP_REQ |= 1U << GPC_PU_PGC_SW_PUP_REQ_AUDIOMIX_SW_PUP_REQ_SHIFT; /* Software request to trigger power up the domain */
while(GPC->PU_PGC_SW_PUP_REQ & (1U << GPC_PU_PGC_SW_PUP_REQ_AUDIOMIX_SW_PUP_REQ_SHIFT)); /* Waiting the GPC_PU_PGC_SW_PUP_REQ_AUDIOMIX_SW_PUP_REQ bit self-cleared after power up */
/* Do the handshake to make sure the NOC bus ready after power up the AUDIOMIX domain. */
GPC->PU_PWRHSK |= 1U << GPC_PU_PWRHSK_GPC_AUDIOMIX_NOC_PWRDNREQN_SHIFT;
while(!(GPC->PU_PWRHSK & (1U << GPC_PU_PWRHSK_GPC_AUDIOMIX_PWRDNACKN_SHIFT))) ;
AUDIOMIX_InitAudioPll(AUDIOMIX, &g_saiPLLConfig); /* init SAI PLL run at 361267200HZ */
/* Update core clock */
SystemCoreClockUpdate();
}
The read speed is too low, 33s/100M, that means only 3 Mhz/s to read the SAI RDR(n) Register
Is that normal or need to other configuration need to do?
Thank you in advance.
SAI is designed for audio, not just for sending and receiving data, so it is normal with slow speeds.
In iMX8MPRM.pdf,chapter 14
• SAI1 supports to up to 8 I2S/TDM Tx lanes and 8 I2S/TDM Rx lanes at 768kHz/32-
bit
How to configure this, by our experiment, it could also result in fifo error.
Does that mean, only SAI SDMA could support that condition?