Hi,
We've a requirement to set SPI Master Frequency exactly to 10MHz (i.e. 10Mbps baud rate). But as per the analysis and the study over SPI Master frequency to be set, we had understand that we can't set the exact 10MHz SPI Master Frequency on MiMX RT-600 controller, either we can set 9.6MHz or 12 MHz.
Please have a look on the analysis explained below:
Referring the register SPI Divider register (ffset = 0x424) from the RT6xx User manual. We got to know that
DIVVAL: Rate divider value. Specifies how the Flexcomm Interface clock (FCLK) is divided to produce the SPI clock rate in master mode.
DIVVAL is -1 encoded such that the value 0 results in FCLK/1, the value 1 results in FCLK/2, up to the maximum possible divide value of 0xFFFF, which results in FCLK/65536.
Referring the section 23.7.4.1 Data rate calculations from the RT6xx User manual. We understood, In master mode, the SPI rate clock produced by the SPI clock divider is used directly as the outgoing SCK.
The SPI clock divider is an integer divider. The SPI in master mode can be set to run at
the same speed as the selected FCLK, or at lower integer divide rates.
The SPI rate will be = FCLK of Flexcomm Interface n / DIVVAL
to calculate the DIVVAL for above formula for SPI rate, used the API form the SDK EVK-MIMXRT685 v2.11.1 as following from fsl_spi.c source file stored at location ../boards/devices/drivers:
/*!
* brief Sets the baud rate for SPI transfer. This is only used in master.
*
* param base SPI base pointer
* param baudrate_Bps baud rate needed in Hz.
* param srcClock_Hz SPI source clock frequency in Hz.
*/
status_t SPI_MasterSetBaud(SPI_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz)
{
uint32_t tmpDiv;
/* assert params */
assert(!((NULL == base) || (0U == baudrate_Bps) || (0U == srcClock_Hz)));
if ((NULL == base) || (0U == baudrate_Bps) || (0U == srcClock_Hz))
{
return kStatus_InvalidArgument;
}
/* calculate baudrate, round up the result */
tmpDiv = ((srcClock_Hz * 10U) / baudrate_Bps + 5U) / 10U - 1U;
if (tmpDiv > 0xFFFFU)
{
return kStatus_SPI_BaudrateNotSupport;
}
base->DIV &= ~SPI_DIV_DIVVAL_MASK;
base->DIV |= SPI_DIV_DIVVAL(tmpDiv);
return kStatus_Success;
}
Taking Example of 10MHz SPI Master frequency we need to find DIVVAL:
1. DIVVAL will calculate by above API and will be stored to DIV registered.
2. DIVVAL = ((srcClock_Hz * 10U) / baudrate_Bps + 5U) / 10U - 1U
Here, srcClock_Hz = 48000000 (48MHz)
baudrate_Bps = 10000000 (10MHz, our requirement)
DIVVAL = (48000000*10U)/(10000000+5U)/(10U-1U)
DIVVAL = (480000000/10000005)/9U
DIVVAL = 47.999/9U
DIVVAL = 5.33
but as per the section 23.7.4.1 Data rate calculations from the RT6xx User manual. The SPI clock divider is an integer divider.
DIVVAL = 5;
The SPI rate will be = FCLK of Flexcomm Interface n / DIVVAL
SPI Rate = 48000000/5
= 9.6 MHz
Also same SPI rate we have verified with the CRO and it matching approx with theoretical calculated value.
Kindly respond whether or not our understanding is correct? and Can we set exact 10MHz frequency with the same controller?
Based on this analysis we understood that either we can set SPI Clock freq as 9.6MHz or 12MHz. Please correct if our understanding is correct or not.
Looking forward your inputs
Thanks & Regards,
Gopichand Sonawane
Hi,
Your understanding is correct, only in your calculations you add some parentheses that change the hierarchy of operations.
What can be done is to change the clock source of the FXCOM5 as shown in the following figure.
With which we will obtain the following baudrate:
baudrate = PCLK_SPIn / DIVVAL = 39.936MHz / 4 = 9.984MHz
It is not exactly 10MHz, but it is closer to 9.6MHz or 12MHz.
Wish it helps you.
Dear,
Thanks for the reply and solution.
Will check and let you know on this.