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