Implementation of CAN Driver on LPC1768

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Implementation of CAN Driver on LPC1768

895 Views
Laxmi_Gangal
Contributor I

I am implementing a CAN driver for the LPC1768 microcontroller. During simulation there is no error, but while testing , I am encountering an ERRBIT : start of frame (SOF) in CAN  interrupt and capture status register(CANxICR) and in CAN1GSR TXERR: 0x7F TCS:0. 

My setup:

Software: keil u4

Microcontroller: LPC1768( ARM Cortex M3)

Baud rate: 500kbps

pin configuration: TD1(P0.1), RD1(P0.0)

CANxBTR register value: 0x00070004;

 

Init function:

void CAN_Init(uint8 CAN_Controller) {
volatile uint32 *powercontrol = (volatile uint32 *)PowerControl_Addr;
volatile uint32 *PCLKSEL0 = (volatile uint32 *)PCLKSEL0_Addr;
*PCLKSEL0 = 0x14000001;
if (CAN_Controller == 1) {
*powercontrol |= (0x01 << 13); // Power ON CAN1
} else if (CAN_Controller == 2) {
*powercontrol |= (0x01 << 14); // Power ON CAN2
}
}

 

baudrate snippet:


void CAN_Set_BaudRate(uint8 CAN_idx, uint32 baudrate_Kbps, uint32 PCLK_MHz, uint8 BRP, uint8 TSEG1, uint8 TSEG2) {
uint32 brp, btr_value;

btr_value = ((TSEG2 - 1) << 20) | ((TSEG1 - 1) << 16) | (0 << 14) | ((BRP-1)<<0);

if (CAN_idx == 1) {
CAN1->MOD = 1; // Enter Reset Mode
CAN1->BTR = btr_value; // Set BTR register
CAN1->MOD = 0; // ExIT
} else if (CAN_idx == 2) {
CAN2->MOD = 1; // Enter Reset Mode
CAN2->BTR = btr_value; // Set BTR register
CAN2->MOD = 0; // Exit Reset Mode
}
}

transmitter snippet:

void CAN_Transmit(uint8 CAN_Controller, CAN_msg *msg) {
if(CAN_Controller==1){
while (!(CAN1->SR & (0x01 << 2))); // Wait until TX buffer is empty
 
CAN1->TFI1 = ((msg->len &0xf)<< 16); // Set data length
CAN1->TID1 = msg->id; // Set identifier
 
CAN1->TDA1 = (msg->data[0]) | (msg->data[1] << | (msg->data[2] << 16) | (msg->data[3] << 24);
    CAN1->TDB1 = (msg->data[4]) | (msg->data[5] << | (msg->data[6] << 16) | (msg->data[7] << 24);
CAN1->CMR = (0x01 << 5) | (0x01 << 0); // Request transmission
 
CAN1->GSR=(1<<3);
 
}
else if(CAN_Controller==2){
while (!(CAN2->SR & (0x01 << 2))); // Wait until TX buffer is empty
 
CAN2->TFI1 = ((msg->len&0xf) << 16); // Set data length
CAN2->TID1 = msg->id; // Set identifier
 
CAN2->TDA1 = (msg->data[0]) | (msg->data[1] << | (msg->data[2] << 16) | (msg->data[3] << 24);
    CAN2->TDB1 = (msg->data[4]) | (msg->data[5] << | (msg->data[6] << 16) | (msg->data[7] << 24);
CAN2->CMR = (0x01 << 5) | (0x01 << 0); // Request transmission
CAN2->GSR=(1<<3);
}
}
 
receive snippet:
void CAN_Receive(uint8 CAN_Controller, CAN_msg *msg)
{
    if (CAN_Controller == 1)
    {
        while (!(CAN1->SR & (0x01 << 0))); // Check if a new message is received
        
        msg->len = (CAN1->RFS & 0x000F0000) >> 16; // Extract DLC
     
        msg->id =CAN1->RID;
/* Read first 4 data bytes */
 
*((uint8 *) &msg->data[0])= CAN1->RDA & 0x000000FF;
*((uint8 *) &msg->data[1])= (CAN1->RDA & 0x0000FF00)>>8;;
*((uint8 *) &msg->data[2])= (CAN1->RDA & 0x00FF0000)>>16;
*((uint8 *) &msg->data[3])= (CAN1->RDA & 0xFF000000)>>24;
 
/* Read second 4 data bytes */
 
*((uint8 *) &msg->data[4])= CAN1->RDB & 0x000000FF;
*((uint8 *) &msg->data[5])= (CAN1->RDB & 0x0000FF00)>>8;;
*((uint8 *) &msg->data[6])= (CAN1->RDB & 0x00FF0000)>>16;
*((uint8 *) &msg->data[7])= (CAN1->RDB & 0xFF000000)>>24;
 
        CAN1->CMR = (0x01 << 2); // Release receive buffer
    }
 
    else if (CAN_Controller == 2)
    {
        while (!(CAN2->GSR & (1 << 0))); // Check if a new message is received
        
        msg->len = (CAN2->RFS &  0x000F0000) >> 16; // Extract DLC
    
         msg->id = CAN2->RID;
*((uint8 *) &msg->data[0])= CAN2->RDA & 0x000000FF;
*((uint8 *) &msg->data[1])= (CAN2->RDA & 0x0000FF00)>>8;;
*((uint8 *) &msg->data[2])= (CAN2->RDA & 0x00FF0000)>>16;
*((uint8 *) &msg->data[3])= (CAN2->RDA & 0xFF000000)>>24;
 
/* Read second 4 data bytes */
 
*((uint8 *) &msg->data[4])= CAN2->RDB & 0x000000FF;
*((uint8 *) &msg->data[5])= (CAN2->RDB & 0x0000FF00)>>8;;
*((uint8 *) &msg->data[6])= (CAN2->RDB & 0x00FF0000)>>16;
*((uint8 *) &msg->data[7])= (CAN2->RDB & 0xFF000000)>>24;
      
        CAN2->CMR = (0x01 << 2); // Release receive buffer
    }
}
 

I have verified my pin configuration and CAN settings but cannot identify why the error is persisting.

Request:
Could anyone suggest what might be causing the ERRBIT: Start of Frame, TXERR:0x0F and how to resolve it? 

Labels (1)
0 Kudos
Reply
3 Replies

871 Views
Pablo_Ramos
NXP Employee
NXP Employee

Hi @Laxmi_Gangal,

ERRBIT is when the CAN controller detects a bus error.

TXERR is the value of the Tx error counter, if a bus-off event occurs the TX error Counter is initialized to 127 (0x7F)

TCS: is the transmit complete status, when is on 0 it means that at least one requested transmission has not been successfully completed yet.

Could you help me checking the following?

What is the frame when reading it with a logic analyzer?

Are there other devices connected to the bus?

Also, you can take as reference the CAN demo based on lpc1769 under LPCopen.

LPCOpen Software for LPC17XX | NXP Semiconductors

0 Kudos
Reply

848 Views
Laxmi_Gangal
Contributor I

This is the frame it is reading.

I have not connected the receiver. I am reading the frame on port P0.1. Only Logic analyzer is connected to the LPC1768.
 
is both LPC1768 and LPC1769 is same or different?
0 Kudos
Reply

253 Views
Pablo_Ramos
NXP Employee
NXP Employee

Hi,

The main difference between LPC1768 and LPC1769 is the CPU frequency, however, you should be able to refer to LPC1769 in the CAN configuration.

Also, I recommend you to take a look to the following documentation regarding CAN

101: Controller Area Network (CAN) standard - NXP Community

If you connect the receiver do the frame stay the same?

0 Kudos
Reply