CAN Extended ID not able to receive

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

CAN Extended ID not able to receive

2,529 Views
sridharan
Contributor II

Hi,

I am using CAN sample code to receive CAN packet, I am able to receive std ID packet, however I am not able to receive any extended ID , I am able to see the data loaded into ARB1/2 registed but why CAN handlers is not enter if found.

Can Anyone please help me.

Below is piece of code where I am editing changes for extended ID receive in CAN configure().

/* Mxtd: 1, Mdir: 0, Mask is 0x1FFFFFFF */
LPC_CAN->IF1_MSK1 = ID_EXT_MASK & 0xFFFF;
LPC_CAN->IF1_MSK2 = MASK_MXTD | (ID_EXT_MASK >> 16);

/* MsgVal: 1, Mtd: 1, Dir: 0, ID = 0x100000 */
LPC_CAN->IF1_ARB1 = (RX_EXT_MSG_ID+i) & 0xFFFF;
LPC_CAN->IF1_ARB2 = ID_MVAL | ID_MTD | ((RX_EXT_MSG_ID+i) >> 16);

Labels (1)
11 Replies

1,482 Views
esacademysuppor
Contributor II

Here is a complete example that can receive 11-bit ID 0x003 or 29-bit ID 0x12345678. I've tested this with Keil Realview and a Keil MCB1000 board with an LPC11C24.

#include "lpc11xx.h"
#include "system_lpc11xx.h"

// CAN message objects 0 to CANOBJ_RXTX-1 are used for receive
#define CANOBJ_RXTX 24
// CAN message objects CANOBJ_RXTX to 31 are used for transmit

// various CAN registers
#define CMDREQ_BSY (1UL << 15)

// CAN CTRL register
#define CTRL_INI (1UL << 0)
#define CTRL_IEN (1UL << 1)
#define CTRL_SIE (1UL << 2)
#define CTRL_EIE (1UL << 3)
#define CTRL_DAR (1UL << 5)
#define CTRL_CCE (1UL << 6)
#define CTRL_TST (1UL << 7)

// CAN CMDMASK register
#define CMDMSK_DATB (1UL << 0)
#define CMDMSK_DATA (1UL << 1)
#define CMDMSK_TREQ (1UL << 2)
#define CMDMSK_IPND (1UL << 3)
#define CMDMSK_CTRL (1UL << 4)
#define CMDMSK_ARB (1UL << 5)
#define CMDMSK_MSK (1UL << 6)
#define CMDMSK_WR (1UL << 7)
#define CMDMSK_RD (0UL << 7)

// CAN MCTRL register
#define MCTRL_DLC (0x0F)
#define MCTRL_EOB (1UL << 7)
#define MCTRL_TXRQT (1UL << 8)
#define MCTRL_RMTEN (1UL << 9)
#define MCTRL_RXIE (1UL << 10)
#define MCTRL_TXIE (1UL << 11)
#define MCTRL_UMASK (1UL << 12)
#define MCTRL_IPND (1UL << 13)
#define MCTRL_MSGLT (1UL << 14)
#define MCTRL_NWDAT (1UL << 15)

// CAN ARB2 register
#define ARB_ID (0x1FFF)
#define ARB_DIR (1UL << 13)
#define ARB_XTD (1UL << 14)
#define ARB_MSGVL (1UL << 15)

// CAN MSK2 register
#define MSK2_MXTD (1UL << 15)

// uses 125kbps on CAN bus with a 48MHz peripheral clock
#define CANBitrate125k_48MHz 0x00001C57UL

// transmit a CAN message
static void Transmit
 (
 uint8_t msgObjNum, // object number to use for transmission
 uint32_t Id, // message identifier (11-bit)
 uint8_t Len, // length of message in bytes
 uint8_t *pData // message data
 )
{
 if (msgObjNum < CANOBJ_RXTX) return;
 
 while (LPC_CAN->IF1_CMDREQ & CMDREQ_BSY); // wait until previous copy complete

 // prepare registers with message
 LPC_CAN->IF1_CMDMSK = CMDMSK_WR|CMDMSK_ARB|CMDMSK_CTRL|CMDMSK_TREQ|CMDMSK_DATA|CMDMSK_DATB;
 LPC_CAN->IF1_MCTRL = MCTRL_TXRQT|MCTRL_TXIE|MCTRL_EOB|(Len & MCTRL_DLC);
 LPC_CAN->IF1_ARB1 = 0;
 LPC_CAN->IF1_ARB2 = ((Id & 0x7FF) << 2)|ARB_DIR|ARB_MSGVL;

 // copy data
 LPC_CAN->IF1_DA1 = *(uint16_t *)&pData[0];
 LPC_CAN->IF1_DA2 = *(uint16_t *)&pData[2];
 LPC_CAN->IF1_DB1 = *(uint16_t *)&pData[4];
 LPC_CAN->IF1_DB2 = *(uint16_t *)&pData[6];

 LPC_CAN->IF1_CMDREQ = msgObjNum + 1; // copy registers to this message object 
}

// configures a receive filter
static void SetCANFilter
 (
 uint32_t Id, // message identifier to receive
 uint8_t Ext // set to one for 29-bit identifier, 0 for 11-bit identifier
 )
{
 uint8_t lp;
 uint32_t cMsgObj;
 uint32_t msgV;

 msgV = (LPC_CAN->MSGV2 << 16) | LPC_CAN->MSGV1;

 for (lp = 0; lp < CANOBJ_RXTX; lp++) 
 {
 if ((msgV & (1 << lp)) == 0)
 break;
 }
 if (lp < CANOBJ_RXTX)
 {
 cMsgObj = lp + 1; // valid message object number found
 }
 else
 {
 return;
 }

 LPC_CAN->IF1_CMDMSK = CMDMSK_WR|CMDMSK_MSK|CMDMSK_ARB|CMDMSK_CTRL;
 LPC_CAN->IF1_MCTRL = MCTRL_UMASK|MCTRL_RXIE|MCTRL_EOB|MCTRL_DLC;

 if (Ext)
 {
 LPC_CAN->IF1_MSK1 = Id & 0xFFFF;
 LPC_CAN->IF1_MSK2 = ((Id & 0x1FFFFFFF) >> 16) | MSK2_MXTD;
 LPC_CAN->IF1_ARB1 = Id & 0xFFFF;
 LPC_CAN->IF1_ARB2 = ((Id & 0x1FFFFFFF) >> 16) | ARB_MSGVL | ARB_XTD;
 }
 else
 {
 LPC_CAN->IF1_MSK1 = 0;
 LPC_CAN->IF1_MSK2 = ((Id & 0x7FF) << 2);
 LPC_CAN->IF1_ARB1 = 0;
 LPC_CAN->IF1_ARB2 = ((Id & 0x7FF) << 2) | ARB_MSGVL;
 }

 LPC_CAN->IF1_CMDREQ = cMsgObj; // copy registers to message object
 while (LPC_CAN->IF1_CMDREQ & CMDREQ_BSY);
}

// check for a received message
// returns 1 if message received, 0 if no message received
uint8_t PullMessage
 (
 uint32_t *pId, // filled with identifier of received message
 uint8_t *pExt, // set to 1 on return if identifier is 29-bit
 uint8_t *pLen, // filled with length in bytes of received message
 uint8_t *pData // pass an eight-byte array, filled with received data
 )
{
 uint32_t cInt;
 uint8_t cMsgObj;

 cInt = LPC_CAN->INT; // read current interrupt status
 switch (cInt)
 {
 case 0x0000: // no interrupt
 return 0;

 case 0x8000: // status interrupt, status register was updated
 return 0;

 default: // message object interrupt
 cMsgObj = cInt & 0xFF;
 // valid rx object, retrieve data
 if ((cMsgObj >= 1) && (cMsgObj <= CANOBJ_RXTX))
 { 
 while (LPC_CAN->IF2_CMDREQ & CMDREQ_BSY); // wait for object availability
 LPC_CAN->IF2_CMDMSK = CMDMSK_RD|CMDMSK_MSK|CMDMSK_ARB|CMDMSK_CTRL|CMDMSK_IPND|CMDMSK_TREQ|CMDMSK_DATA|CMDMSK_DATB;
 LPC_CAN->IF2_CMDREQ = cMsgObj; // copy this object to registers
 while (LPC_CAN->IF2_CMDREQ & CMDREQ_BSY);

 // receive overrun occured
 if (LPC_CAN->IF2_MCTRL & MCTRL_MSGLT)
 { 
 }

 // XTD bit (extended format), copy message to destination
 if (LPC_CAN->IF2_ARB2 & (1UL << 14))
 { 
 *pId = ((LPC_CAN->IF2_ARB2 & 0x1FFF) << 16) | (LPC_CAN->IF2_ARB1 & 0xFFFF);
 *pExt = 1;
 }
 // regular message (11bit ID), copy message to destination
 else
 { 
 *pId = (LPC_CAN->IF2_ARB2 >> 2) & 0x7FF;
 *pExt = 0;
 }
 *pLen = LPC_CAN->IF2_MCTRL & MCTRL_DLC;
 *(uint16_t *)&pData[0] = LPC_CAN->IF2_DA1;
 *(uint16_t *)&pData[2] = LPC_CAN->IF2_DA2;
 *(uint16_t *)&pData[4] = LPC_CAN->IF2_DB1;
 *(uint16_t *)&pData[6] = LPC_CAN->IF2_DB2;
 
 return 1;
 }
 // tx object
 else
 {
 while (LPC_CAN->IF1_CMDREQ & CMDREQ_BSY); // wait for object availability
 LPC_CAN->IF1_CMDMSK = CMDMSK_IPND;
 LPC_CAN->IF1_CMDREQ = cMsgObj; // copy this object to registers
 while (LPC_CAN->IF1_CMDREQ & CMDREQ_BSY);
 }
 break;
 }

 return 0;
}

// interrupt handler
void CAN_IRQHandler(void)
{
 uint32_t Id;
 uint8_t Ext;
 uint8_t Len;
 uint8_t Data[8];
 
 // check if a message was received
 if (PullMessage(&Id, &Ext, &Len, Data))
 {
 // message received
 Id = Id;
 }
}

// main function
int main(void)
{
 uint32_t btr = CANBitrate125k_48MHz;
 uint16_t lp;
 uint8_t TxData[8];
 uint8_t RxData[8];
 uint32_t RxId;
 uint8_t RxLen;
 uint8_t RxExt;

 SystemInit();

 LPC_SYSCON->PRESETCTRL |= (1UL << 3); // clear the reset signal
 LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 17); // enable CAN power
 LPC_CAN->CLKDIV = 0; // set CAN clk to match systemclock, here 48MHz
 LPC_CAN->CNTL = CTRL_INI; // set CAN to init mode

 LPC_CAN->CNTL |= CTRL_CCE; // start config bit timing
 LPC_CAN->BT = (uint16_t) btr;
 LPC_CAN->BRPE = (uint16_t) (btr >> 16);
 LPC_CAN->CNTL &= ~CTRL_CCE; // end config bit timing

 // initialize CAN message objects
 for (lp = 0; lp < 32; lp++)
 {
 LPC_CAN->IF1_CMDMSK = CMDMSK_WR|CMDMSK_MSK|CMDMSK_ARB|CMDMSK_CTRL|CMDMSK_DATA|CMDMSK_DATB;
 LPC_CAN->IF1_MCTRL = 0;
 LPC_CAN->IF1_MSK1 = 0;
 LPC_CAN->IF1_MSK2 = 0;
 LPC_CAN->IF1_ARB1 = 0;
 LPC_CAN->IF1_ARB2 = 0;
 LPC_CAN->IF1_DA1 = 0;
 LPC_CAN->IF1_DA2 = 0;
 LPC_CAN->IF1_DB1 = 0;
 LPC_CAN->IF1_DB2 = 0;

 LPC_CAN->IF1_CMDREQ = lp+1; // copy from registers to message object
 while (LPC_CAN->IF1_CMDREQ & CMDREQ_BSY);
 }

 LPC_CAN->STAT = 0; // reset CAN status register

 LPC_CAN->CNTL |= CTRL_IEN; // enable interrupts
 
 LPC_CAN->CNTL &= ~CTRL_INI; // normal operating mode 
 
 // want to receive message 0x003 (11-bit ID)
 SetCANFilter(0x003, 0);
 // want to receive message 0x00000004 (29-bit ID)
 SetCANFilter(0x12345678, 1);
 
 NVIC_EnableIRQ(CAN_IRQn);
 
 // send a message
 for (lp = 0; lp < 8; lp++) TxData[lp] = lp;
 Transmit(CANOBJ_RXTX, 0x001, 8, TxData);
 Transmit(CANOBJ_RXTX + 1, 0x002, 8, TxData);
 
 while(1);
}

1,482 Views
sridharan
Contributor II

Hi jeremyzhou:

As said I am using custom board and succefully able to receive standard message and even the message object no and interrupt is updated into CANINT -> INTID, bust this does not happens in extended mode, when I select extended it never detect the message object data. Below is the snap for your ref.

pastedImage_2.png

Pl provide me some technical solution .

0 Kudos

1,482 Views
jeremyzhou
NXP Employee
NXP Employee

Hi sridharan TechM ,

I've created the demo, you can send the send the data which includes the standard or extend frame, the MCU will rebound the data.

2017-04-28_15-56-55.jpg

                                                                       Fig 1


Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,482 Views
sridharan
Contributor II

Hi,

I have tried the same both its same, i am able to tx rx standard ID not extended id, Can I know which CAN Analysiser tool your using, jfyi I am using  KVASER CANking, let me is this compatible or pl suggest, for now i am using Lpcxpresso board

0 Kudos

1,482 Views
jeremyzhou
NXP Employee
NXP Employee

Hi sridharan TechM ,

I use the CANPro and the board is the LPCXpresso LPC11C24 (OM13093).
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,482 Views
sridharan
Contributor II

Hi jeremyzhou,

I got the output, The problem was with the CANAnalyser tool(CANKING) . I need to provide extended data in different format. 

Thanks for your support.

0 Kudos

1,482 Views
jeremyzhou
NXP Employee
NXP Employee

Hi sridharan TechM ,

Thank you for your interest in NXP Semiconductor products and the opportunity to serve you.

I was wondering if you can tell me which chip you use and share the simple demo, then I can replicate the issue on my board.
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,482 Views
sridharan
Contributor II

Hi jeremyzhou ,

I am using LPC11c24 with 10mhz clock customized board. its just same as Xpresso board only clock is 12mhz here.

I have tried with many working sample code, Standard format works fine ,but extended doesn't work with any sample. 

I am currently using CAN demo sample code from "lpc11xx.keil-examples-CMSIS-update"  ->CAN folder.

Will there be any clock issues or HW issue or sample code problem ?

0 Kudos

1,482 Views
jeremyzhou
NXP Employee
NXP Employee

Hi sridharan TechM,

I don't think the demo is suit for the LPCXpresso LPC11C24, the code can't jump to the main code successful when during debug as the demo froze.
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,482 Views
sridharan
Contributor II

Hi jeremyzhou,

I am really disappointed , The demo code is working fine in LPCXpresson 11c24 board, however the same issue persist, I am not able to receive extended ID, I think the Demo code given by NXP itself is wrong. Can you pl check and rectify .

Expecting your response as we have struck up with this issue since 3 week without solution.

PFB, Let me know if this is correct for receiving extended ID 

id = id & _EXT_FORMAT;

LPC_CAN->IF1_MSK1 = (id & _MSK1_MSK);
LPC_CAN->IF1_MSK2 = (id >> 16) | _MSK2_MXTD;

LPC_CAN->IF1_ARB1 = (id & _ARB1_ID);
LPC_CAN->IF1_ARB2 = (id >> 16) | _ARB2_XTD | _ARB2_MSGVAL;

0 Kudos

1,482 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

The demo has already configure the extended frame in the CAN_ConfigureMessages(), and in the RX_TX_Bouncing function, the extended frames also are sent to PC.

In the read-me.txt, you can learn the more information about the running the demo.
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos