One thing to note, when create a project and using the FRDMK64 the board reference with SDK v2.5, the default clock configuration uses the PLL with dividers of 15 and 36 to generate 120MHz (assuming 50MHz OSCCLK) out of the PLL. On the surface this seems fine as all of the derived clock frequencies appear correct. However, we found in the CAN drivers, when the CAN bus timing is calculated based on the selected baud (250k in our case) and default PLL configuration, that the bus timing was wrong. We were getting 3.8us vs 4us.
Stepping thru the initialization process with the default values revealed rounding errors resulted in an incorrect value be assigned to the preDivider parameter of the CAN timingConfig. The calculation process was as follows...
OSCCLK = 50MHz
PRDIV = 15
VDIV = 36
fsl_clock.c CLOCK_GetFreq()
MCGPLLCLK = (OSCCLK / PRDIV) = 50MHz / 15 = 3333333Hz
MCGPLLCLK = MCGPLLCLK * VDIV = 3333333Hz * 36 = 119999988Hz
BUS_CLK = MCGPLLCLK / SIM_CLKDIV1[OUTDIV2] = 119999988Hz / 2 = 59999994Hz
fsl_flexcan.c FLEXCAN_SetBaudRate()
priDiv = baudRate_Bps * quantum = 250000Hz * 10 = 2500000Hz
priDiv = (sourceClock_Hz / priDiv) - 1 = (59999994Hz / 2500000Hz) - 1 = 22.9999976, truncated to 22
This yields a CAN Serial Clock (Sclock) of...
Sclock = BUS_CLK / (priDiv + 1) = 59999994Hz / (22 + 1) = 2608695Hz
Which equates to a calculated baud rate of...
Baud = Sclock / quantum = 2608695Hz / 10 = 260869Hz --> 1/260869Hz = 3.834us.
If the value of PRDIV is changed to a value that is a factor of OSCCLK the result will be an integer, unlike the defaults shown. So if PRDIV is changed to 20, for example, the first calculation of MCGPLLCLK will be...
MCGPLLCLK = (OSCCLK / PRDIV) = 50MHz / 20 = 2500000Hz
To obtain the desired PLL clock rate, a new value for VDIV is also required.
VDIV = 120MHz / MCGPLLCLK = 120MHz / 2.5MHz = 48
MCGPLLCLK = MCGPLLCLK * VDIV = 2.5MHz * 48 = 120MHz
These values then provide the correct BUS_CLK rate.
BUS_CLK = MCGPLLCLK / SIM_CLKDIV1[OUTDIV2] = 120MHz / 2 = 60MHz
Using these values in FLEXCAN_SetBaudRate() yields...
priDiv = baudRate_Bps * quantum = 250kHz * 10 = 2.5MHz
priDiv = (sourceClock_Hz / priDiv) - 1 = (60MHz / 2.5MHz) - 1 = 23
This yields a CAN Serial Clock (Sclock) of...
Sclock = BUS_CLK / (priDiv + 1) = 60MHz / (23 + 1) = 2.5MHz
Which equates to a calculated baud rate of...
Baud = Sclock / quantum = 2.5MHz / 10 = 2.5MHz --> 1/2.5MHz = 4us.
In summary, when choosing the divider values for PLL clock calculation, it is important that the PRDIV divisor chosen divides evenly into the PLL clock source providing a integer result. The Clock Utility in IDE v10.3 will not catch this. In addition, the PRDIV value chosen shall also produce a calculated value within the range of 2 - 4MHz as specified in the K64 reference manual. The value for VDIV should then be chosen to obtain the desired PLL clock frequency.
It should also be noted, as described in the reference manual, for applications calling for a tight tolerance (up to 0.1%) in CAN bus timing, the Oscillator clock (OSCERCLK) should be used rather than the internal bus clock (derived from PLL in this case) by configuring CANx_CTRL1[CLKSRC] = 0.