AnsweredAssumed Answered

Problem for FlexCAN

Question asked by Aaron wang on Nov 19, 2013
Latest reply on Mar 22, 2016 by EARL GOODRICH

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

Outcomes