Problem for FlexCAN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 
14,239件の閲覧回数
AaronsCook
Contributor III

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

ラベル(1)
0 件の賞賛
返信
1 解決策
9,082件の閲覧回数
Hui_Ma
NXP TechSupport
NXP TechSupport

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.

元の投稿で解決策を見る

0 件の賞賛
返信
27 返答(返信)
9,083件の閲覧回数
Hui_Ma
NXP TechSupport
NXP TechSupport

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.

0 件の賞賛
返信
1,650件の閲覧回数
AaronsCook
Contributor III

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

pastedImage_1.png

pastedImage_0.png

0 件の賞賛
返信
1,650件の閲覧回数
Hui_Ma
NXP TechSupport
NXP TechSupport

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.

0 件の賞賛
返信
1,650件の閲覧回数
AaronsCook
Contributor III

Hi,

Oh I see.

Thank you very much.

Best Regards

Aaron

0 件の賞賛
返信
1,650件の閲覧回数
AaronsCook
Contributor III

OK

I will study this code carefully and test the function.

Thanks

B.R.

laplenden

0 件の賞賛
返信
1,650件の閲覧回数
Hui_Ma
NXP TechSupport
NXP TechSupport

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

0 件の賞賛
返信
1,650件の閲覧回数
AaronsCook
Contributor III

Thanks

B.R.

Laplenden

0 件の賞賛
返信