Hi, all
When I use the flexCAN of K60Dx512, I encounter a problem that make me crazy.
Firstly, I set the flexCAN as global masking
canx->MCR &= ~CAN_MCR_IRMQ_MASK; //global
And then I use two MCU as TX & RX.
The ID is 29bits extension.
In the TX MCU I use one MSG object as TX mode and set the 29bits, 8 bytes;
In another RX MCU I use one MSG object as RX mode and set the same 29bits ID;
When I begin to send message, I can use oscilloscope to get signal from the can bus. But the RX terminal can't receive message which I use interrupt to get message.
I set break point in the Interrupt code in order to use debug to trace it. But it doesn't stop on the break point.
So I change the flexCAN as individual masking.
canx->MCR |= CAN_MCR_IRMQ_MASK; //individual
I also use two MCU testing just like above.
This time the RX terminal can receive message but it can't receive continuously when the TX send continuously.
It seem to lost message and I set the baud as 500kps.
this is Initiate function for flexCAN
void initcan()
{
OSC->CR |= OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK;
SIM->SCGC6 |= SIM_SCGC6_FLEXCAN0_MASK;
canx->MCR |= CAN_MCR_MDIS_MASK;
canx->CTRL1 |= CAN_CTRL1_CLKSRC_MASK;
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));
if(mask_mode == CAN_MSGOBJ_GLOBAL_MASKING)
{
canx->MCR &= ~CAN_MCR_IRMQ_MASK;
}
else
{
canx->MCR |= CAN_MCR_IRMQ_MASK;
}
canx->MCR |= CAN_MCR_SUPV_MASK ;
canx->MCR |= CAN_MCR_SRXDIS_MASK ;
canx->MCR &= ~CAN_MCR_WRNEN_MASK;
canx->MCR &= ~CAN_MCR_RFEN_MASK ;
canx->MCR &= ~CAN_MCR_AEN_MASK;
canx->MCR &= ~CAN_MCR_LPRIOEN_MASK;
canx->CTRL2 |= CAN_CTRL2_EACEN_MASK;
canx->CTRL2 &= ~CAN_CTRL2_RRS_MASK;
canx->CTRL2 |= CAN_CTRL2_MRP_MASK;
//canx->CTRL1 |= CAN_CTRL1_LBUF_MASK;
canx->CTRL1 &= ~CAN_CTRL1_LBUF_MASK;
//canx->CTRL1 |= CAN_CTRL1_LPB_MASK; //loop
canx->CTRL1 &= ~CAN_CTRL1_LPB_MASK;
//set baud
prescale = CAN_GET_PRESCALE(g_bus_clock,baud,20); | |
// | |
canx->CTRL1 |= CAN_CTRL1_RJW(2) | |
| CAN_CTRL1_PROPSEG(6) | |
| CAN_CTRL1_PSEG1(6) | |
| CAN_CTRL1_PSEG2(4) | |
| CAN_CTRL1_PRESDIV(prescale); |
canx->TIMER = 0x0000;
for(i = 0;i < MSG_MAX_NO; i++)
{
canx->MB[i].CS = 0x00000000;
canx->MB[i].ID = 0x00000000;
canx->MB[i].WORD0 = 0x00000000;
canx->MB[i].WORD1 = 0x00000000;
}
canx->IFLAG1 = 0xFFFFFFFF;
canx->IFLAG2 = 0xFFFFFFFF;
canx->IMASK1 = 0x00000000;
canx->IMASK2 = 0x00000000;
for(i = 0;i < MSG_MAX_NO; i++)
{
canx->RXIMR[i] = 0x1FFFFFFF;
}
canx->RXMGMASK = 0x1FFFFFFF;
canx->RX14MASK = 0x1FFFFFFF;
canx->RX15MASK = 0x1FFFFFFF;
canx->MCR &= ~CAN_MCR_FRZ_MASK;
while( canx->MCR & CAN_MCR_FRZACK_MASK);
canx->MCR &= ~(CAN_MCR_HALT_MASK);
while( canx->MCR & CAN_MCR_NOTRDY_MASK);
canx->MCR &= ~CAN_MCR_MDIS_MASK;
}
this my send function
void send(.......)
{
if( CAN_GetMsgCode(canx_ptr,msg_num_temp) != CAN_MSGOBJ_TX_UNCONDITIONAL)
{
//CODE INACTIVE
canx_ptr->MB[msg_num_temp].CS |= CAN_MB_CS_CODE(CAN_MSGOBJ_TX_INACTIVE);
//ID
CAN_SetMsgID(canx_ptr,msg_num_temp,message_id);
//Msg data
CAN_WriteData(canx_ptr,msg_num_temp,in_data_length,in_data_buffer);
//Msg length
CAN_SetMsgLength(canx_ptr,msg_num_temp,in_data_length);
//Msg CODE TX_UNCONDITIONAL wait to send
canx_ptr->MB[msg_num_temp].CS |= CAN_MB_CS_CODE(CAN_MSGOBJ_TX_UNCONDITIONAL);
}}
this my receive funtion
void receive(....)
{
message_code = CAN_GetMsgCode(canx,msg_num);
if ((message_code != CAN_MSGOBJ_RX_BUSY) &&
(message_code != CAN_MSGOBJ_RX_OVERRUN))
{
//ID
msg_id = LPLD_CAN_GetMsgID(canx, msg_num);
//read Msg len
data_length = (uint8_t)LPLD_CAN_GetMsgLength(canx, msg_num);
//read data
CAN_GetData(canx, msg_num,data_length,rx_data);
//get time stamp
time_stamp = LPLD_CAN_GetMsgTimeStamp(canx, msg_num);
for(i = data_length; i < 8; i++)
{
rx_data[i] = 0;
}
//save data to can_rx_msg
can_rx_msg->CAN_MsgID = msg_id;
can_rx_msg->CAN_MsgDataLength = data_length;
can_rx_msg->CAN_MsgTimeStamp = time_stamp;
memcpy(can_rx_msg->CAN_MsgDataBuffer,rx_data,data_length);
//unlock msg
timer = CAN_UnlockMsg(canx);
//
CAN_Interrupt_ClearPending(canx,msg_num);
//write code to empty msg
CAN_SetMsgCode(canx,msg_num,CAN_MSGOBJ_RX_EMPTY);
}
}
thank you
Best Regards
Laplenden
解決済! 解決策の投稿を見る。
The CANx_CTRL1 register [CLKSRC] bit can only be written in Disable mode as it is blocked by hardware in other modes.
And you will find in <can.c> file line 128 with below code to exit the Disable mode (Exit from this mode is done by negating the MDIS bit in the MCR Register.):
// Enable CAN module
pFlexCANReg->MCR |= FLEXCAN_MCR_FRZ; // enable HALT feature
pFlexCANReg->MCR &= ~FLEXCAN_MCR_MDIS;
So the code in configure bit rate does not modify CANx_CTRL1 register [CLKSRC] bit.
Wish it helps.
The CANx_CTRL1 register [CLKSRC] bit can only be written in Disable mode as it is blocked by hardware in other modes.
And you will find in <can.c> file line 128 with below code to exit the Disable mode (Exit from this mode is done by negating the MDIS bit in the MCR Register.):
// Enable CAN module
pFlexCANReg->MCR |= FLEXCAN_MCR_FRZ; // enable HALT feature
pFlexCANReg->MCR &= ~FLEXCAN_MCR_MDIS;
So the code in configure bit rate does not modify CANx_CTRL1 register [CLKSRC] bit.
Wish it helps.
Hi, Hui_Ma
When I test the CAN in the debug mode, it away report the CAN error which include Bit1 error,Bit0 error,Form error,and Stuffing error.
I open the CAN error, CAN bus off, Tx & Rx Waring interrupt in the CTL1 and Set break-point in the code.
Then I find that when I finish initialize the CAN, it will generate CAN error interrupt.
In addition, I clear the bit in ESR1 in the coed but it always generate CAN error interrupt because it always has Bit1 error,Bit0 error,Form error,and Stuffing error. I feel it can't clear the error, it always be set.
I don't know if these errors has bad effect on the data transfer on the CAN bus?
But now I feel I always lost message when use the MB interrupt-receive mode in these condition.
May be the poll-receive mode is better than interrupt-receive mode?
This the test picture.
Please kindly help me analysis the bug. Thank you very much.
Best Regards
Aaron
I think that could caused by the CAN node with different baud rate and bit rate. Customer need to check the baud rate setting and bit timing setting.
Wish it helps.
Hi,
Oh I see.
Thank you very much.
Best Regards
Aaron
OK
I will study this code carefully and test the function.
Thanks
B.R.
laplenden
Hi Laplenden,
I am checking this issue. I will let you know when I could get any updated info.
Thank you for the patience.
B.R.
Ma Hui
Thanks
B.R.
Laplenden