KevinOConnor / can2040

Software CAN bus implementation for rp2040 micro-controllers
GNU General Public License v3.0
686 stars 68 forks source link

CAN stuck during transmissions #41

Closed daniqsilva25 closed 1 year ago

daniqsilva25 commented 1 year ago

I am using the library to perform some CAN transmissions between two RP2040-based devices. Before transmitting any CAN message, I verify whether it is possible to perform the transmission with "can2040_check_transmit" function. This works fine from the beginning, but after some random time the function "can2040_check_transmit" starts to return as there is no space available to transmit, making the transmission impossible.

I believe this is due to some messages that were transmitted and never acknowledged back. I am trying to find a solution like restarting the CAN on RP2040 and I noticed the presence of a "can2040_shutdown" function, however that one is empty ...

Do you have any solution or any workaround for this issue?

Thanks in advance.

KevinOConnor commented 1 year ago

Every node on the canbus is required to acknowledge every message on the canbus. So, if a message has gone unacknowledged, it means all messages are going unacknowledged. The can2040 code will continually retransmit a message until it is acknowledged.

Make sure you're running on the latest code, as there were some retransmit fixes a couple of months ago.

You may also want to double check your wiring and resistors - https://github.com/KevinOConnor/can2040/blob/master/docs/Tools.md

The can2040_shutdown() code could be implemented, but I'm not sure how it will help you (if the bus isn't running correctly, then the very next transmit will not be acknowledged either).

Cheers, -Kevin

daniqsilva25 commented 1 year ago

Thank you for your answer.

I am trying to transmit data frames of 800/900 bytes through CAN. To do so, I divide each frame into chunks of 8 bytes in order to transmit each chunk by CAN. I started to noticed that I have data losses, as when I send 800 bytes in one node, the other node most of the times does not receive all data. I am running CAN at 500kbit/s and RP2040 at 125MHz, so I suppose that, in terms of timing, this use case should be possible to implement with your library.

My concern is that I am not doing the message acknowledgement correctly. That is done in the callback, right?

KevinOConnor commented 1 year ago

I'm not really sure what you are asking. The application code doesn't need to do anything special for acknowledgement nor is it necessary to call can2040_check_transmit() before transmitting. You can look at how the Klipper code utilizes can2040 (though that may be more complex than you need): https://github.com/Klipper3d/klipper/blob/master/src/rp2040/can.c

Cheers, -Kevin

daniqsilva25 commented 1 year ago

Every node on the canbus is required to acknowledge every message on the canbus. So, if a message has gone unacknowledged, it means all messages are going unacknowledged. The can2040 code will continually retransmit a message until it is acknowledged.

When you said the above information I started to think that the application code needed to do something specific for acknowledgement.

I also noticed your pull request about adding support to stop processing of CAN messages, so thank you for that!