We have a software were we use the CAN Library. We receive every 20ms a message. We also send and receive messages on a diffrent can id. After a while (10s to 30min) the CANLibMCP2515TransmitMessage Function stops to works and returns false. Receiving CAN message still works. When we close an reopen the CAN it works again.
The CANLibMCP2515GetStatus Function sometimes returns 0x00, somtimes 0x20.
What could be the reason for this transmit failure? How can we find out the error source?
We got reported a similar issue recently. We made fix for this one but it is not released yet. We uploaded a preview version of the lib here that fixes this issue. Let us know if this also helps you.
I tried the new libraries. Compilation was successfull. But when I run the programm the following error occurs: CANLibMCP2515 SetCanMode - Failed to change mode!
After this the CANLibMCP2515WriteDescriptor failes but the CANLibMCP2515SetBaudrate works.
Can you help me with this problem?
do you have any clue why the failure happens as described below?
Since the preview version did not work for us, can you tell when the Update of the Library will be released?
I would like to focus on the state when
CANLibMCP2515TransmitMessage() stops working and
CANLibMCP2515GetStatus() returns 0x20.
Please activate and monitor the debug output on the serial port. Here is a description how to do that:
For the explanations below it I take reference to the MCP2515 datasheet.
- The return value of 0x20 indicates an error reported by the MCP2515 CAN controller (ERRIF). In this case the library reads the MCP2515 register EFLG to retrieve more detailed error information.
- If there was a receive buffer overflow (RX0OVR or RX1OVR), a debug message is printed to the serial debug port.
- For other errors, the current library implementation prints no debug message. it would be helpful if you then call the undocumented function
void DumpMcp2515(DWORD device);. It dumps the MCP2515 registers to a console window, including EFLG.
What is the value of EFLG?
The output varies, we encounter the following values:
EFLG= 0x45 (most time),
EFLG= 0x40 (some time),
EFLG= 0x55 (rarely),
EFLG= 0x05 (rarely)
The error flags show two different errors (description in the MCP2515 datasheet: MCP2515 datasheet)
Bit 2 and Bit 0 (set in EFLG = 0x45, 0x55 and 0x05) indicates that there were more than 96 Transmit errors detected by the CAN controller. Typical reasons for this error are
- No other CAN device connected to the bus
- Missing bus termination
- Inconsistent baud rate setting between CAN devices.
Bit 6 (set in EFLG = 0x45, 0x40 and 0x55)
This is a performance issue of the CAN/SPI libraries. It is a known problem that the MCP2515 CAN controller has a very small input buffer, which causes high performance requirements to the host system in order to not lose any incoming CAN message.
It is possible that the performance issue is related to the CAN errors. Therefore I recommend to first analyze the transmit errors (e.g. with a CAN analyzer).
Optimizing the performance would probably mean to rewrite large portions of the CanLib and SpiLib.
Thank you for the information. We’ll analyze the trasmit errors.
Is there a way to read the EFLG in Code, since
void DumpMcp2515(DWORD device); isn’t very helpful in finding the error?
You can call the internal function
/// Read the MCP2515 CAN Controller register through SPI
/// @param[in] sspNumber SPI port number
/// @param[in] address Register address
/// @param[out] spiReadData Data read from MCP registers
/// @retval TRUE Success
/// @retval FALSE Failure
BOOL CANLibMCP2515BaseGetRegister(DWORD sspNumber, const BYTE address, DWORD *spiReadData);
with address = 0x2D.
Please note that reading the register blocks the SPI bus. This potentially causes delays in reading incoming CAN messages from the MCP2515 and hence lead to lost messages.
I get a linker error if I try to call this function. I don’t find the definition in a header. I also tried to define as extern, same linker error. Can you help me with this?