The flexcan can send/receive data successfully between two MX53 baords (On one board running "cansend" and on the other running "candump"). I set the bitrate through flexcan attributes interface (for eg., "echo 125000 > /sys/devices/platform/FlexCAN.0/bitrate").
However MX53 board can not communicate with other CAN devices (for eg., MX6 flexcan). I checked the waveform of MX53 flexcan by an oscilloscope and found the actual bitrate is incorrect. It is about 2.5 time of the expected values.
I reviewed the clock settings of CAN and debugged the driver. By "cat /proc/cpu/clocks" I can see the can_clk-0 is 24MHz, and its parent lp_apm-0 is 24MHz too. They should be all correct.
When I set the bitrate (by "echo ..."), for eg, set to 500KHz, the driver calculated the timing values and got the following results:
brp = 2, phase_seg1 = 4, phase_seg2 = 4, prop_seg = 4
So the bitrate is (24MHz / ((brp + 1) * (phase_seg1 + phase_seg2 + prop_seg + 4))) = 24MHz / (3 * 16) = 500KHz
So everything looks right, but why the bitrate waveform on the oscilloscope is incorrect?
The BSP I used is MX53 Android R10.3.
If anybody has similar issue, please advise. Thanks.
Solved! Go to Solution.
Hi Frank.
in the linux kernel flexcan parent clock is set incorrectly. try to correct arch/arm/mach-mx5/clock.c
int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
{
......
/*set the SPDIF dividers to 1 */
reg = __raw_readl(MXC_CCM_CDCDR);
reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK;
reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK;
__raw_writel(reg, MXC_CCM_CDCDR);
++ clk_set_parent(&can1_clk[0], &lp_apm_clk);
++ clk_set_parent(&can2_clk[0], &lp_apm_clk);
/* Move SSI clocks to SSI_LP_APM clock */
clk_set_parent(&ssi_lp_apm_clk, &lp_apm_clk);
.....
Hi Frank.
in the linux kernel flexcan parent clock is set incorrectly. try to correct arch/arm/mach-mx5/clock.c
int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
{
......
/*set the SPDIF dividers to 1 */
reg = __raw_readl(MXC_CCM_CDCDR);
reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK;
reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK;
__raw_writel(reg, MXC_CCM_CDCDR);
++ clk_set_parent(&can1_clk[0], &lp_apm_clk);
++ clk_set_parent(&can2_clk[0], &lp_apm_clk);
/* Move SSI clocks to SSI_LP_APM clock */
clk_set_parent(&ssi_lp_apm_clk, &lp_apm_clk);
.....
Hi Alexander,
Your patch fixes the bitrate issue. Thanks a lot!