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!
-----------------------------------------------------------------------------------------------------------------------