CAN communication for LPC1758 gives "Start of Frame error " and resets Controller

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by ihatetoregister on Mon Jan 25 22:47:42 MST 2016
i am trying to setup CAN communication between a couple of LPC device nodes. My setup includes a couple of CAN nodes writing on to the CAN bus. For example LPC 2292 CAN controller can write on to the CAN bus and the LPC1758 can receive the data. This works perfectly fine ( LPC 2292 seems to be able to write to the bus.  Btw I dont have code for LPC 2292. its not under my control and I cant program it and I dont have the code for it. I have only one CAN node 1758 and i want to plug it into an existing network of working CAN devices.  ).

Now LPC1758 has 2 CAN controllers and I have setup one for receiving data and the other for transmitting data on the bus as a response. I also setup interrupt handlers for LPC 1758 CAN 1 transmit & receive and CAN 2 transmit & receive.

My problem is at the LPC1758 side. Here the CAN 1 receiver is able to get the data from the other CAN nodes as i can see the interrupt vector handler being called. I set the Acceptance filter OFF to receive all CAN bus messages.

The problem is when the the LPC 1758 CAN 2 controller writes to the bus , it gets a bus error  - "Start of Frame " . ( I use a Ulink2 debugger). Now reading the CAN specs i know the start frame of the CAN message should start with a low ( dominant) bit .

How do i go about fixing this error ? Its not a configurable register that I can set the first bit to 0 or 1.

I run the default LPC 1758 CAN code that comes with KEIL C:\Keil_v5\ARM\Boards\Keil\MCB1700\CAN I think the code is fine because when i run the code in simulation mode of KEIL i can see the CAN communication work well. Also i did not make any changes to the code except the baudrate.

MCU Speed : 100 Mhz
Baudrate : 100Kbit/s

Is this setting incorrect ?

Is this "Start of Frame" a by product of some other configurations that I am missing ?

I am attaching a screenshot of my CAN  Controller 1 & Controller 2  at the point when the error occurs. As you can see as soon as when i try to write to the command register of the CAN 2 i get a "Start of Frame " error. Also seen is my clock settings .

Here is my code to transmit and receive:

  wite a message to CAN peripheral and transmit it.  CAN controller (1..2)
void CAN_wrMsg (uint32_t ctrl, CAN_msg *msg)  {
  LPC_CAN_TypeDef *pCAN = (ctrl == 1) ? LPC_CAN1 : LPC_CAN2;
  uint32_t CANData;

  CANData = (((uint32_t) msg->len) << 16)     & 0x000F0000 |
            (msg->format == EXTENDED_FORMAT ) * 0x80000000 |
            (msg->type   == REMOTE_FRAME)     * 0x40000000;

  if (pCAN->SR & (1<<2))  {                      /* Transmit buffer 1 free */
    pCAN->TFI1  = CANData;                       /* Write frame informations */
    pCAN->TID1 = msg->id;                        /* Write CAN message identifier */
    pCAN->TDA1 = *(uint32_t *) &msg->data[0];    /* Write first 4 data bytes */
    pCAN->TDB1 = *(uint32_t *) &msg->data[4];    /* Write second 4 data bytes */
    //pCAN->CMR  = 0x31;                           /* Select Tx1 for Self Tx/Rx */
    pCAN->CMR  = 0x21;                           /* Start transmission without loop-back */ -- Here is when "Start of Frame " error happens


Receive code is fine but still posting

  read a message from CAN peripheral and release it.  CAN controller (1..2)
void CAN_rdMsg (uint32_t ctrl, CAN_msg *msg)  {
  LPC_CAN_TypeDef *pCAN = (ctrl == 1) ? LPC_CAN1 : LPC_CAN2;
  uint32_t CANData;

                                                 /* Read frame informations */
  CANData = pCAN->RFS;
  msg->format   = (CANData & 0x80000000) == 0x80000000;
  msg->type     = (CANData & 0x40000000) == 0x40000000;
  msg->len      = ((uint8_t)(CANData >> 16)) & 0x0F;

  msg->id = pCAN->RID;                           /* Read CAN message identifier */

  if (msg->type == DATA_FRAME)  {                /* Read the data if received message was DATA FRAME  */
    *(uint32_t *) &msg->data[0] = pCAN->RDA;
    *(uint32_t *) &msg->data[4] = pCAN->RDB;