AnsweredAssumed Answered

FlexCAN2 Implementation on MPC5554

Question asked by Benoit Courtade on Apr 17, 2008
Latest reply on Mar 22, 2010 by RAMAN MALYA
Hi All,

I’m implementing a FlexCAN2 driver on a MPC5554 development board and I’m encountering transmission problems.

I’ve followed initialization instructions and instead of only negating the HALT bit as mentioned in the reference manual, I have to negate both HALT and FREEZE bits in the MCR in order to leave the freeze mode after initialization..

I’m able to correctly send and receive CAN frames when using loop back mode, but I don’t think that frames are actually being sent on the bus.

Then, when I try sending frames in normal mode (CODE=0x8, ID word set, DATA is written and CODE=0xC) to a CAN analyzer, there is not even a single frame appearing on the oscilloscope triggered on the CANH line. However, a BIT0ERR bit is set in the ESR indicating an inconsistency in the transmission of a dominant bit. Moreover, a read of this bit does not clear it as it should be according to the reference manual.
The same error occurs when transmitting from the CAN B module to the CAN A module on the board using the same initialization parameters.

When frames are being sent to the MPC5554 from a CAN analyzer, the IDLE bit in the ESR is set.

Is there any other setting required to enable the CAN transmission on the MPC5554?



Below is the code I have made to initialize and then send and receive CAN test frames. In loop back mode, interrupts are occuring when messages are received and it seems to work correctly, but in normal mode it seems that the transmission is not enabled or blocked. Buffer 0 is used to transmit data and buffer 15 is used to receive data. Other buffers are disabled and inactive.

#include "typedefs.h"#include "mpc5554.h"void ReceiveCANB (void);void init_CANB(void){ /*************************************/ /*    FlexCAN2 Module for PowerPC    */ /*************************************/ /* initialization Sequence */  int i;      /***************************/  /*      Select Clock       */  /***************************/  CAN_B.MCR.B.MDIS=1; //Disable CAN module  while(!CAN_B.MCR.B.MDISACK){}    CAN_B.CR.B.CLKsrc=1 ; //0 = The CAN engine clock source is the oscillator clock                        //1 = The CAN engine clock source is the system clock                        //Oscillator Clk at 8MHz - System Clock at 12MHz                        // Not affected by reset  CAN_B.MCR.B.MDIS=0; //negate the bit enables CAN module      /***************************/  /*  Perform a soft reset   */  /***************************/  CAN_B.MCR.B.SOFTRST=1;   while(CAN_B.MCR.B.SOFTRST){}      /* Freeze Mode */ //The HALT and FRZ bits in CANx_MCR are set  CAN_B.MCR.B.FRZ=1;  CAN_B.MCR.B.HALT=1;  while(!CAN_B.MCR.B.FRZACK){}; //wait for acknowledgement    //Determine bit timing parameters: PROPSEG, PSEG1, PSEG2, RJW.    //Bitrate=Input Clock/((PRESDIV + 1)·(4+PROPSEG+PSEG1 + PSEG2))  // 100 K = 8 000K    /((    4   + 1).(4+   2   +  6   +   4  ))  // 100 K = 12 000K   /((    5   + 1).(4+   3   +  7   +   6  )) SYS CLOCK  // 100 K = 4 000K    /((    1   + 1).(4+   3   +  7   +   6  ))  //PROPSEG - Propagation segment. Defines the length of the   //propagation segment in the bit time. The valid programmable values are 0–7.  //Propagation Segment Time = (PROPSEG + 1) × Time Quanta  CAN_B.CR.B.PROPSEG=3;         //PSEG1-Phase segment 1. idem for 2   //Defines the length of phase buffer segment 1 in the bit time.   //The valid programmable values are 0–7.1-7 for PSEG2  //Phase Buffer Segment 1 = (PSEG1 + 1)× Time Quanta  CAN_B.CR.B.PSEG1=7;      CAN_B.CR.B.PSEG2=6;         //RJW  //Resync jump width. Defines the maximum number of time quanta   //that a bit time can be changed by one re-synchronization.   //The valid programmable values are 0–3.  //Resync Jump Width = RJW + 1      CAN_B.CR.B.RJW=2;       //Determine the bit rate by programming the PRESDIV field.  // S-clock frequency= CPI clock frequency/PRESDIV + 1  CAN_B.CR.B.PRESDIV=5;   //Determine internal arbitration mode (LBUF bit).  //Lowest buffer transmitted first. This bit defines the ordering  //mechanism for message buffer transmission.  //0 Buffer with lowest ID is transmitted first  //1 Lowest number buffer is transmitted first  CAN_B.CR.B.LBUF=1;  /* Initialize message buffers. */  // The control and status word of all message buffers may be written either as active or inactive.  //Other entries in each message buffer should be initialized as required.  //Initialize CANx_RXGMASK, CANx_RX14MASK, and CANx_RX15MASK registers for acceptance mask as needed.  CAN_B.RXGMASK.B.MI=0;   CAN_B.RX15MASK.B.MI=0;      /*************************************************/  /*************************************************/  /*************************************************/  CAN_B.CR.B.LPB=0; //Loop Back mode for self Test                    // Tx linked on Rx                    //1 for activation  CAN_B.CR.B.LOM=0; //Listen Only Mode  /*************************************************/        /*************************************************/  /*************************************************/    /*********************/  /* Enable CAN IT     */  /*********************/      //Bus off mask. Provides a mask for the bus off interrupt, enabled  CAN_B.CR.B.BOFFMSK=0;  INTC.PSR[280].R = 4; /* Enabled & IRQ priority  */  //Error mask  CAN_B.CR.B.ERRMSK=1;  INTC.PSR[281].R = 5; /* Enabled & IRQ priority */      /**********************/  /* Deactivate Buffers */  /**********************/  for (i=0;i<63;i++)    CAN_B.BUF[i].CS.B.CODE   = 0x0;                     /*******************/  /*Msg Buffer 15: Rx*/  /*******************/  //The corresponding buffer Interrupt is enabled  CAN_B.IMRL.B.BUF15M=1;  INTC.PSR[298].R =3 ; /* Enabled & IRQ priority */    /*********************/  /* Enter Normal Mode */  /*********************/     CAN_B.MCR.B.HALT=0;   CAN_B.MCR.B.FRZ=0; //Disable Freeze Mode}void write_CANB(void){  // Write the CODE field of the control and status word   // to keep the TX MB inactive (code = 1000).  CAN_B.BUF[0].CS.B.CODE   = 0x08;  //Write the ID word.  /*ID Frame identifier. In standard frame format,   only the 11 most significant bits (28 to 18) are used for  frame identification in both receive and transmit cases.   The 18 least significant bits are ignored.   In extended frame format, all bits are used for frame identification   in both receive and transmit cases.*/  CAN_B.BUF[0].ID=0x456<<18; //18=0x12 & standard format  //Frame format is standard (not extended)  CAN_B.BUF[0].CS.B.IDE=0;  CAN_B.BUF[0].CS.B.LENGTH=8;  // Write the DATA  CAN_B.BUF[0].DATA.W[0] = 0x98765432;  //Transmit remote frame unconditionally once. After transmission,   //the MB automatically becomes and RX MB with the same ID.  /******************/  /* Transmit Frame */  /******************/  CAN_B.BUF[0].CS.B.RTR   = 0x0; //Disable Remote Transmission Request  CAN_B.BUF[0].CS.B.CODE  = 0x0C; //}void ReceiveCANB (void){  CAN_B.BUF[15].CS.B.CODE   = 0x00;  CAN_B.BUF[15].CS.B.LENGTH=8;    //Frame format is standard (not extended)  CAN_B.BUF[15].CS.B.IDE=0;      //Write the ID word.  CAN_B.BUF[15].ID=0x456<<18; //18 standard format    //Write the CODE field of the control and status word   //to mark the MB as ‘receive active and empty  CAN_B.BUF[15].CS.B.CODE   = 0x04; }