This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC11C CAN message interrupt

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.

Parents
  • 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 ?

Reply
  • 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 ?

Children
No data