Here is my context: I connect to automobile drivetrain CAN bus (Volkswagen Passat) and sniffer all the traffic.
The problem is that when MCP2515 got a message from CAN and I read it via SPI, the message remains in the buffer. Here is corresponding code snippet (using autowp/arduino-mcp2515
lib with Teensy 3.2
):
//loop:
can_frame readMsg = {0};
int status = mcp2515.readMessage(buffer, &readMsg);
if (status == MCP2515::ERROR_OK) {
...
}
The code above gets into if
always in the loop since we get the first message from CAN. I see in the mcp2515 lib that it runs modifyRegister(MCP_CANINTF, rxb->CANINTF_RXnIF, 0);
after the message has been read, so it should clear the buffer, or not?
I also tried couple of other libs - nothing changes. Also tried force cleanup after the message has been read, still with no result:
mcp2515.clearRXnOVR();
mcp2515.clearMERR();
mcp2515.clearInterrupts();
Also tried interrupt mode. In this case all goes well when messages from CAN appear not often, so the microprocessor reads them prior to buffer overflow (ex. with filtering just single ID). But since overflow happened the interrupt stops triggering. Here is corresponding code:
volatile int canMessageQueue = 0;
void canBusInterrupt() {
canMessageQueue++;
}
// setup:
attachInterrupt(digitalPinToInterrupt(2), canBusInterrupt, FALLING);
// loop:
if (canMessageQueue > 0) {
uint8_t irq = mcp2515.getInterrupts();
Serial.println(irq);
if (irq & MCP2515::CANINTF_ERRIF)
mcp2515.clearRXnOVR();
if (irq & MCP2515::CANINTF_RX0IF) {
CanRead(MCP2515::RXB0);
canMessageQueue--;
}
if (irq & MCP2515::CANINTF_RX1IF) {
CanRead(MCP2515::RXB1);
canMessageQueue--;
}
if (irq & MCP2515::CANINTF_WAKIF)
mcp2515.clearInterrupts();
if (irq & MCP2515::CANINTF_ERRIF)
mcp2515.clearMERR();
if (irq & MCP2515::CANINTF_MERRF)
mcp2515.clearInterrupts();
if (canMessageQueue > 0) {
Serial.print("! overflow");
canMessageQueue = 0;
}
*The code above taken from CAN Hacker (processInterrupt()
in https://github.com/autowp/arduino-canhacker/blob/master/CanHacker.cpp )
Does anybody has any idea why the rx buffer still not getting clear?
1 Answer 1
I was facing the Rx buffer overflow issue when interfacing with mcp25625. This was caused due the CS pin being held low for a longer duration than it takes for CAN message to be transmitted.The MCP2515 Silicon Errata mentions this scenario and a workaround for it.
Use the SPI RTS command to trigger the transmission instead of using the transmission request bit TXREQ in register. This solved it for me.
-
\$\begingroup\$ How did the code look like after the update? \$\endgroup\$Emanuel Hallgren– Emanuel Hallgren2022年01月25日 20:50:41 +00:00Commented Jan 25, 2022 at 20:50
Teensy 3.2
andArduino Nano
- both produce the same issue. As for bitrate - I set 8MHz clock:mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ)
. \$\endgroup\$