-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Esp32 can driver #5310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Esp32 can driver #5310
Conversation
Added quick commands for CAN usage
I do not expect any increase in basic firmware. All changes are applied to ports/esp32. |
I'm a noob, so I can't help... Except to maybe draw some attention to this. It sets off the 'wut' meter that MicroPython made a 1.0 release without this... This is in desperate need. Why it isn't a high priority for the uPython peeps, I don't understand. |
hi @nos86 thanks for sending this! I know a lot of people are keen to see CAN support on ESP32. I've made some basic comments on the code, but you'll also need to do some minor coding convention fixes too (things like newline at EOF, spaces around operators, spaces after But the bigger question here is compatibility with the STM32 CAN driver. Ideally they would be identical APIs (and we'd move pyb.CAN into machine.CAN on the STM32 port) however I know that there needs to be some compromise and the STM32 version will need to change when it's moved to machine.CAN. But as the first implementation of machine.CAN this PR is kind of setting a precedent for what the API will look like. I've posted some simple questions inline in the code, but I don't know much about CAN so perhaps you or others have some thoughts on how to proceed.
@camosoul I'm sure you're aware that the ESP32 port came a long time after MicroPython 1.0 and that everyone's priorities are different. Like I said above though, it's great to see this PR. |
Hey @chrismas9 do you have any opinions on this PR? I recall that you've worked with CAN quite a lot... |
Nope, didn't realize that. I'm a noob. I don't know the full history of the universe in every detail. I wasn't here for the Big Bang, either... Makes sense. I appreciate being rid of (a portion of) my derpage. Glad to see this is getting attention and might be making some movement soon! |
Hello @jimmo, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the fixes! I've added some more comments. Sorry for the nitpicks, it's mostly just style stuff, but consistency is important.
Other than that, I think this is looking pretty good. Need someone with more CAN + STM32 experience to comment on whether this is going to be feasible to implement the same API on STM32.
Hello @jimmo, Regarding STM32 harmonization, I think the point is complex and it should be discussed together with the developer of STM32 CAN device. |
I agree it would be really good if there was an automated tool for this and it has been discussed before. You might want to take a look at astyle or clang-format (I'm not sure if there's an existing configuration for either, but see #4223 for some notes). But for any given thing, there'll be a line somewhere else in the codebase you can copy the style from. And you can do most of these fixups with find/replace, i.e. Just a note on the rebase / commit squashing. The idea is to end up with it being a small number of commits where each does a single thing with a clear description. e.g.
|
FWIW -- here's a sample
|
Hi @jimmo, |
...so? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an interesting PR, thank you! I like that it comes with docs and an example :-) !
Things I would like to see improved:
- make it truly compatible with the stm32 CAN driver, not mostly. I don't mean exact feature parity, but not having different arg lists, etc.
- make the docs generic and point out esp specific stuff as notes
- use check_esp_err to raise OS errors
See :ref:`machine.CAN <machine.CAN>` :: | ||
|
||
The CAN driver is based on hardware implementation. | ||
Any available output-capablepins can be used for SCL and SDA. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/output-capablepins/output-capable pins/ (space missing)
I know almost nothing about CAN, but I do find "SCL" and "SDA" suspicious names. The Esp-IDF docs state "The CAN controller’s interface consists of 4 signal lines known as TX, RX, BUS-OFF, and CLKOUT."...
@@ -108,4 +108,4 @@ Constants | |||
.. data:: esp32.WAKEUP_ALL_LOW | |||
esp32.WAKEUP_ANY_HIGH | |||
|
|||
Selects the wake level for pins. | |||
Selects the wake level for pins. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this change?
|
||
.. class:: machine.CAN(bus, ...) | ||
|
||
Construct a CAN object on the given bus. *bus* can be 0 or 1 (for compatibility with STM32). It will point at the same device |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "It will point at the same device" [missing punctuation] mean? If the esp32 only has one CAN controller then IMHO it should only accept bus==0. Also, these docs are for all ports, so esp32 peculiarities should be noted as such.
Methods | ||
------- | ||
|
||
.. method:: CAN.init(mode, extframe=False, baudrate, prescaler, \*, sjw=1, bs1=6, bs2=8, auto_restart=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tx_io, rx_io, tx_queue, rx_queue are missing
it can be between 1 and 1024 inclusive | ||
- *bs2* defines the location of the transmit point in units of the time quanta; | ||
it can be between 1 and 16 inclusive | ||
- *tx_io* defines the gpio used for transmission |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop the _io suffix. No other drivers do that. The uart uses tx and rx, i2c uses sda and scl (not sda_io, and scl_io), etc.
The esp-idf docs mention 4 signal lines, two of which are optional. Can those not be used with this driver? What are the implications?
Specifying the pins is only supported on the esp32, right? Docs should note that.
|
||
// Clear TX Queue | ||
STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in) { | ||
return mp_obj_new_bool(can_clear_transmit_queue() == ESP_OK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why return a boolean instead of raising an error that provides info about the failure?
#define ESP_STATUS_CHECK(status) \ | ||
if (status != ESP_OK) { \ | ||
mp_raise_OSError(-status); \ | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use check_esp_err()
STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { | ||
machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); | ||
if (self->config->initialized) { | ||
ESP_LOGW(DEVICE_NAME, "Device is already initialized"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this not raise an error? MP doesn't use ESP_LOGW in general...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@twe @dpgeorge @jimmo
I find it difficult to choose the type of error in cases
"Device is already initialized" and "Device is not initialized"
I can raise
mp_raise_ValueError(msg);
mp_raise_TypeError(msg);
mp_raise_NotImplementedError(msg);
mp_raise_OSError(errno);
but I don't like them.
In fact, it is an algorithm user program bug.
Twice init, twice deinit etc.
I want to help a user change his program.
I prefer to raise
mp_raise_OSError(EPERM, "Device is already initialized")
with console output like:
>>> OSError: [Errno 1] EPERM: Device is already initialized
if (self->config->initialized) { | ||
// The caller is requesting a reconfiguration of the hardware | ||
// this can only be done if the hardware is in init mode | ||
ESP_LOGW(DEVICE_NAME, "Device is going to be reconfigured"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MP doesn't use the ESP IDF logging facility.
I am guessing that this went stale. 👎 |
Maybe someone can pick it up? I'd give it a shot but don't have any ESP32 boards with CAN - or any CAN peripherals... |
There is an Adafruit circuit python mcp2515 CAN library that was just made a few months ago. It appears to not be finished tho I am not sure and I have not tested it as of yet. I didn't even know that the ESP32 had a built in CAN interface until I came across this PR. I was planning on using an external interface. I have not been able to locate a complete library\module for an external interface. I could probably port one of the C/C++ libraries over to python pretty easily so it would be able to run using MicroPython, my concern with doing something like that would be the speed reduction compared to running it in C code. I am not sure if the speed reduction would be an amount that could cause frames to get missed. I know enough C/CPP code to get me into trouble, defiantly not enough knowledge to complete this kind of a project. It does appear that this PR is mostly complete with only a few small changes needed. |
to @nos86: Dear Salvo, do you have the strength and time to continue working on this PR? Thank you very much for you work. |
WIP: I will try to continue this work from both |
Hello @IhorNehrutsa, Basically, my code is completely working and implements all basic functions. I made two loops of harmonization but it seems that it's not enough yet. If I remember well the esp32-can-driver-harmonization is born from the esp32-can-driver and it is created for the harmonization process with existing STM32 firmware. Please continue from it. |
This PR is obsolete. |
Fix RP2040 I2S: always copy to output buffer
Closing in favour of #7381 -- thanks for your work on this @nos86, and thanks @IhorNehrutsa for continuing it. FWIW, this PR was the original motivation for the work to get automatic code formatting implemented, and the process for submitting PRs has improved dramatically, avoiding the frustration of dealing with style/formatting nit picking. |
This PR adds CAN Device added for ESP32.
see issue #5087