help with MCP2515

Hi everyone,

I need help with my MCP2515.
I'm using the seeedstudio MCP2515 spi library and run into an issue I can't figure out. Everything is working perfect with one exception, the interrupt pin on the MCP2515.

My goal is to capture a specific CAN id. Then process it's contents and return it to the CAN bus with a new id. My problem is the interrupt pin on the MCP2515 goes low and is not cleared when I read in the message buffer. My code is dependent on the interrupt to call a function to inspect the received id.

The interrupt section of the MCP2515 spec sheet says --
"It is recommended that the bit modify command be used to reset flag bits in the CANINTF register rather than normal write operations. This is done to prevent unintentionally changing a flag that changes during the write command, potentially causing an interrupt to be missed."

I'm using the following lines to set what I think is the correct bits.

This is set during the MCP2515 initialization
mcp2515_setRegister(MCP_CANINTE, 0x01 | 0x02); // MCP_CANINTE = ADDRESS: 2Bh, 0b00000011

When the message buffer is read
mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0x00); // MCP_CANINTE = ADDRESS: 2Bh, "buffer 0 or 1", 0b00000011

My confusion is are these bits set to '1' automatically when a message is received in the buffer? OR are these bits set manually via code and manually cleared when the buffer is read?

I am also setting the SPI.setBitOrder(MSBFIRST);
So should I be sending the bit order backwards like 0b11000000

When the message buffer is read
mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0x00); // MCP_CANINTE = ADDRESS: 2Bh, "buffer 0 or 1", 0b00000011

That command doesn't read the register but modifies bits in it, so it's exactly what you have to use. With this command you reset the interrupt flag for the receive buffer 0. Before issuing this command you should read the contents of the receive buffer and empty it because the datasheet specifies clearly:

Interrupts are directly associated with one or more status flags in the CANINTF register. Interrupts are pending as long as one of the flags is set. Once an interrupt flag is set by the device, the flag can not be reset by the MCU until the interrupt condition is removed.

Pylon,

Here is what I issue to read the buffers. Unfortunately the interrupt does not release and return HIGH

uint8_t CAN::readMsg()
{
    uint8_t stat, res;

    stat = mcp2515_readStatus();

    if ( stat & MCP_STAT_RX0IF ) {                                                  /* Msg in Buffer 0              */
        mcp2515_read_canMsg( MCP_RXBUF_0);                                 /* pack the data buffer0       */
        mcp2515_modifyRegister(MCP_CANINTF, 0x01, 0x00);     /*clear the interrupt          */
        res = CAN_OK;
    }
    else if ( stat & MCP_STAT_RX1IF ) {                                           /* Msg in Buffer 1              */
        mcp2515_read_canMsg( MCP_RXBUF_1);                                 /* pack the data buffer1       */
        mcp2515_modifyRegister(MCP_CANINTF, 0x02, 0x00);     /*clear the interrupt           */
        res = CAN_OK;
    }
    else {
        res = CAN_NOMSG;
    }
    return res;
}

Here is what I issue to read the buffers. Unfortunately the interrupt does not release and return HIGH

The Interrupt pin INT is active LOW, so after clearing the bit I would expect that the pin is HIGH. Did I misunderstand you?

The Interrupt pin INT is active LOW, so after clearing the bit I would expect that the pin is HIGH. Did I misunderstand you?

The pin goes low and stays low the entire time the bus has activity (this is confirmed on my scope). Once the bus activity stops the pin goes high until the next message. The bus tested on has 8 id's with 10ms between transmissions. If I send a single transmission with 200-300 ms between each transfer the pin functions correctly. It seems the speed the pin can change states is limited.

How fast are you getting messages? Is it possible that as soon as you read the buffer the next one is ready to be read? The manual states clearly that the pin does not change if the reason for it going low still exists.