We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I am trying to read messages from CAN bus with LPC11C14 uC. I get interrupt when message is transmitted by other CAN device, but the value of LPC_CAN->INT == (1<<15), so I only get interrupt status but dont get message number. I am not sure whether I need to setup something to actually receive message.
definitions
#define IS_BIT_ENABLED(a,b) (((a) & (1U<<(b)))==(1U<<(b))?1:0) #define INT_STATUS 15 #define INT_MSG_NUM_MASK 0x3F #define NO_ERROR_MASK (_BV(0)|_BV(1)|_BV(2)) #define STAT_RX0K 4 #define STAT_EWARN 6 #define STAT_BOFF 7
Here is my interrupt routine
uint32_t stat, canint, msg_no; canint = LPC_CAN->INT; if ( IS_BIT_ENABLED(canint, INT_STATUS) ) { stat = LPC_CAN->STAT; if (IS_BIT_ENABLED(stat, STAT_EWARN)) return; if (IS_BIT_ENABLED(stat, STAT_BOFF)) return; if (IS_BIT_ENABLED(stat, STAT_RX0K)) { if ( (stat & NO_ERROR_MASK) != 0) return; while (IS_BIT_ENABLED(canint, INT_STATUS)); msg_no = canint & INT_MSG_NUM_MASK; if ( (msg_no >= 0x01) && (msg_no <= 0x20) ) { LPC_CAN->STAT &= ~STAT_RX0K; processMessage (msg_no); } } }
and initialisation
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<17); LPC_SYSCON->PRESETCTRL |= (1<<3); LPC_CAN->CNTL |= (1<<0); //init LPC_CAN->CLKDIV = 0x5; //clock divider by 6 48Mhz/6 = 8Mhz LPC_CAN->CNTL |= (1<<6); //configuration change enabled LPC_CAN->BT = 0x2301; //500kBit/s LPC_CAN->BRPE = 0x0; LPC_CAN->CNTL &= ~(1<<6); //configuration change disabled LPC_CAN->CNTL &= ~(1<<0); //init done while (LPC_CAN->CNTL & (1<<0)); NVIC_EnableIRQ (CAN_IRQn); LPC_CAN->CNTL |= (1<<1) | (1<<2) | (1<<3) | (1<<5); //Interrupt enable, Status change int, Error int, disable retransmit
Do I need to "clean" the filter to receive actual msg from the buffer ? I didnt setup filter at all so I would expect that I should see all of the messages on the bus.
Ok, I got interrupt and message num in message buffer, but I cant extract the data. I have set up the message filter to accept all messages:
LPC_CAN->IF2_CMDMSK = WR|MASK|ARB|CTRL|DATAA|DATAB; LPC_CAN->IF2_MCTRL = 0; LPC_CAN->IF2_MSK1 = 0; LPC_CAN->IF2_MSK2 = 0; LPC_CAN->IF2_ARB1 = 0; LPC_CAN->IF2_ARB2 = (1UL << 15); LPC_CAN->IF2_MCTRL = UMSK|RXIE|EOB|DLC; LPC_CAN->IF2_DA1 = 0; LPC_CAN->IF2_DA2 = 0; LPC_CAN->IF2_DB1 = 0; LPC_CAN->IF2_DB2 = 0; LPC_CAN->IF2_CMDREQ = 5; while (LPC_CAN->IF2_CMDREQ & CMDREQ_BUSY);
And now the processMessage function is called, but all the data from buffer is 0.
void canBus::processMessage (uint8_t a_msgNo) { uint32_t msgId; can_msg msg; while (LPC_CAN->IF2_CMDREQ & CMDREQ_BUSY); LPC_CAN->IF2_CMDMSK = WR_RD|MASK|ARB|CTRL|INTPND|TREQ|DATAA|DATAB; LPC_CAN->IF2_CMDREQ = a_msgNo; while (LPC_CAN->IF2_CMDREQ & CMDREQ_BUSY); if (IS_BIT_ENABLED(LPC_CAN->IF2_ARB2, MSG_EXTENDED)) { msgId = (LPC_CAN->IF2_ARB1 | ((LPC_CAN->IF2_ARB2&0x5fff)<<16)); } else { msgId = (LPC_CAN->IF2_ARB2 & ID_STD_MASK) >> 2; } msg.ident = msgId; msg.len = MIN((LPC_CAN->IF2_MCTRL & 0x0f), 8); msg.num = a_msgNo; }
and also msg.len is equal to 8, even though my actual message have only 2 bytes. Any idea ?