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.
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?