Hello community!
I've noticed strange behavior in FLEXCAN_Initialize. No matter what you pass as the last argument (clock source), this option is never applied. I performed a small investigation and found the reason for this. Prior to actually setting the clock source, softreset is issued to flexcan (kflexcan.c:325):
if((can_reg_ptr->MCR & CAN_MCR_MDIS_MASK) == 0x00000000)
{
/* clock disable (module) */
can_reg_ptr->MCR = CAN_MCR_MDIS_MASK;
/* wait until disable mode acknowledged */
while (!can_reg_ptr->MCR & CAN_MCR_LPMACK_MASK) {}
}
/* Reset FLEXCAN, Halt, freeze mode */
if(FLEXCAN_Softreset(dev_num))
return (FLEXCAN_INIT_FAILED);
/* Wait for entering the freeze mode */
while((can_reg_ptr->MCR & CAN_MCR_FRZACK_MASK) == 0) {}
/*
** Select the clock source
** Default: internal bus clock (fsys/2).
*/
FLEXCAN_Select_clk (dev_num, clk);
In the FLEXCAN_Softreset, flexcan leaves "module disable" state. But according to K20 Sub-Family Reference Manual, clock source bit (CLKSRC of CANx_CTRL1) can be modified only in "module disable" state (p. 1112).
Best regards,
Mikhail Burakov
Hi, Mikhail
I think the FlexCAN initialize steps just as follow code refer as the manual reference.
canx->MCR |= CAN_MCR_MDIS_MASK; //disable CAN
canx->CTRL1 |= CAN_CTRL1_CLKSRC_MASK; // select the peripheral clock as clock source
//and the enable CAN and software reset
canx->MCR |= CAN_MCR_HALT_MASK;
canx->MCR |= CAN_MCR_FRZ_MASK;
canx->MCR &= ~CAN_MCR_MDIS_MASK;
while(!(canx->MCR & CAN_MCR_LPMACK_MASK));
canx->MCR ^= CAN_MCR_SOFTRST_MASK;
while(canx->MCR & CAN_MCR_SOFTRST_MASK);
while(!(canx->MCR & CAN_MCR_FRZACK_MASK));
Best Regards
Laplenden
Hello!
Actually I don't have any problems with FlexCAN initialization. Just pointing out a quirk in MQX code, because someone can lose some time investigating this issue. The described behavior can be worked around with ease.
Best regards,
Mikhail Burakov