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);
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);
}
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.
Pl provide me some technical solution .
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.
Fig 1
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
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
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!
-----------------------------------------------------------------------------------------------------------------------
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.
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!
-----------------------------------------------------------------------------------------------------------------------
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 ?
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!
-----------------------------------------------------------------------------------------------------------------------
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;
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!
-----------------------------------------------------------------------------------------------------------------------