Repository navigation
MicroPython CAN API #7892
Description
Activity
Would be great if ESP32 CAN(TWAI) driver works with interrupts, doing a function/method callback when a new data comes, and/or the FIFO is full, and so on, like as STM32 CAN driver https://docs.micropython.org/en/latest/library/pyb.CAN.html#pyb.CAN.rxcallback
It's not built into the TWAI interface. I have brought this up with the folks over at Expressif and I was told that it would be added to the next major release
@kdschlosser it is good news
If you need some help with it or details on how it "should" work let me know. I had started to mess about with making a common API but making the STM32 side of things work with it is the problem that I have.
One of the thing that I found with the STM32 CAN is the "mailboxes" This is simply the RX and TX buffer slots and this doesn't need to be exposed to the user. The mailboxes can be set to a FIFO arrangement making the need to specify what box to get the data from irrelevant. The tx mail boxes should send whatever message has the lowest arbitration id (frame id) first as this is how the CAN specification is written. frames with the lowest arbitration ID get priority.
We know the documentation for the TWAI interface is so so at best. The documentation for the STM32 is worse. I am talking about the API documentation from the manufacturer and not MicroPython's
I also wrote a c version of the bitrate timing calculator. I wrote it so it can be used by any MCU that supports can interfaces.
You can view the code here if you like.
https://esp32.com/viewtopic.php?f=18&t=23719
It's fast on the ESP32 an has a pretty small memory footprint of 512 bytes for 1 result and 1792 bytes for 8 results which of course can be garbage collected.
I did also want to make a comment with regards to memory use with the CAN interface on the ESP32. I suggest moving the declaration of the twai_message_t structure to the bottom level instead of inside of the
sensandrecvfunctions. by having it at the bottom level the structure can also be shared between those functions. Because of how fast can messages are going to need to be read having to do garbage collection to clean up memory fragmentation all the time is going to slow down the code enough so frames will be missed. Anything that can be declared at import time would be ideal to reduce the number of garbage collections that need to be done.I haven't tested that aspect of it just yet as I believe once the structure gets passed to the twai function to send it actually loads it into a hardware buffer and the structure is no longer in use to actually transmit the frame.
Here is the CircuitPython
canioAPI doc for reference: https://circuitpython.readthedocs.io/en/7.0.x/shared-bindings/canio/index.htmlThanks for the link. I went poking about the CircuitPython code and checked out what they have done.
Because of the large number of differences in how an MCU has it's API for a CAN interface I think it would be best to have a a CAN binding be it's own module like what is done in CircuitPython. The one thing I think that should be done is an import error should get raised for MCUs that does not support CAN. The module should exist and only the import error gets raised with a message of "Not supported by x MCU" where x is the MCU model. This way at least there is an informative message as to why the import error has occurred. A user would then be able to react on that import error so their software would be able to operate differently if needs be.
It's not built into the TWAI interface. I have brought this up with the folks over at Expressif and I was told that it would be added to the next major release
ESP32 documentation state that TWAI peripheral support interrupt handling, and in particular it has support for rx and tx interrupts. Please look at section 21.5.3 Interrupt Management.
However, I'm not familiar with uPython and I don't know how to put it in code. In ESP-IDF you have to deal with the intr_flags of the peripheral config struct, which ultimately sets the appropriate registers here.
Hope this helpsWe've opened a new issue to collect the requirements and plan for implementing a cross-platform
machine.CANinterface - please see #12337 . The discussion here is really helpful in framing the requirements, thanks!I'm going to close this in favour of the linked issue.
There has been a request to create a CAN API for adding CAN support for MCU's. The STM32 and the ESP32 are the 2 MCU's that have CAN support. I have become pretty familiar with the ESP32 side of things and if there is someone that is willing to spear head the STM32 side of things we can get CAN support added to MicroPython for the ESP32.