Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Closed
wants to merge 62 commits into from
Closed

Esp32 can driver #5310

wants to merge 62 commits into from

Conversation

nos86
Copy link

@nos86 nos86 commented Nov 8, 2019

This PR adds CAN Device added for ESP32.
see issue #5087

@nos86
Copy link
Author

nos86 commented Nov 8, 2019

The command "ls -l ports/minimal/build/firmware.bin" exited with 0.
0.01s$ tools/check_code_size.sh
Old size: 68848 new size: 68852
Validation failure: Core code size increased
The command "tools/check_code_size.sh" exited with 1.

Full log at https://travis-ci.org/micropython/micropython/jobs/609232858?utm_medium=notification&utm_source=github_status

I do not expect any increase in basic firmware. All changes are applied to ports/esp32.
What I have to check to pass this test?

@camosoul
Copy link

camosoul commented Nov 18, 2019

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.

@jimmo
Copy link
Member

jimmo commented Dec 3, 2019

I do not expect any increase in basic firmware. All changes are applied to ports/esp32.
What I have to check to pass this test?

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 // in comments, etc). Just to keep consistency with the rest of the code base.

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.

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.

@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.

@mattytrentini
Copy link
Contributor

Hey @chrismas9 do you have any opinions on this PR? I recall that you've worked with CAN quite a lot...
For reference, the STM32 implementation is currently in pyb.CAN.

@camosoul
Copy link

camosoul commented Dec 3, 2019

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.

@camosoul I'm sure you're aware that the ESP32 port came a long time after MicroPython 1.0...

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!

@nos86
Copy link
Author

nos86 commented Dec 9, 2019

Hello @jimmo,
I'll work on your comments in the incoming days in order to align the code with your expectation.
In a general way, I'll do a cross check between STM32 and ESP32 in order to guaratee the harmonization between method signatures.
In any case, please consider that this code is related to ESP32 hardware, so in same case the complete harmonization will be not possible (e.g. CAN Modes is the same defined in the ESP32 framework).

Copy link
Member

@jimmo jimmo left a 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.

@nos86
Copy link
Author

nos86 commented Feb 4, 2020

Hello @jimmo,
I have reviewed my code. Unfortunately the missing availability of an automatic beautifier on VSCode makes the cosmetic aspects so hard and time consuming.

Regarding STM32 harmonization, I think the point is complex and it should be discussed together with the developer of STM32 CAN device.

@jimmo
Copy link
Member

jimmo commented Feb 5, 2020

Hello @jimmo,
I have reviewed my code. Unfortunately the missing availability of an automatic beautifier on VSCode makes the cosmetic aspects so hard and time consuming.

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.

esp32: Add machine.CAN driver.
docs: Add docs for machine.CAN.

@jimmo
Copy link
Member

jimmo commented Feb 6, 2020

FWIW -- here's a sample astyle invocation that does a pretty good job of taking care of the remaining issues:

astyle --style=google --suffix=none --indent=spaces=4 --attach-closing-while --add-brackets --indent-switches --indent-after-parens --indent-continuation=1 --indent-labels --indent-preproc-define --indent-preproc-cond --pad-header --unpad-paren --add-braces --convert-tabs --keep-one-line-statements --max-code-length=200 ports/esp32/machine_can.c

@nos86
Copy link
Author

nos86 commented Feb 9, 2020

Hi @jimmo,
thank you very much for the beautifier hint. I have applied it and reviewed other open points.
Can you review it and give me a feedback?
If everything is ok, I'll proceed to rebase the code closing the last open points and grouping all commits in one.

@camosoul
Copy link

...so?

@nos86 nos86 requested a review from jimmo June 10, 2020 14:55
@nos86
Copy link
Author

nos86 commented Jun 10, 2020

@dpgeorge, @jimmo,
I'm receiving a lot of request of compiled firmware for CAN device and I'm not able to manage all problems come.

Can you please check the code and merge it?

Copy link
Contributor

@tve tve left a 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.
Copy link
Contributor

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.
Copy link
Contributor

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
Copy link
Contributor

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)
Copy link
Contributor

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
Copy link
Contributor

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);
Copy link
Contributor

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); \
}
Copy link
Contributor

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");
Copy link
Contributor

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...

Copy link
Contributor

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");
Copy link
Contributor

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.

@kdschlosser
Copy link

I am guessing that this went stale. 👎

@mattytrentini
Copy link
Contributor

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...

@kdschlosser
Copy link

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.

@IhorNehrutsa
Copy link
Contributor

to @nos86: Dear Salvo, do you have the strength and time to continue working on this PR? Thank you very much for you work.

@IhorNehrutsa
Copy link
Contributor

IhorNehrutsa commented Jun 11, 2021

@nos86
Copy link
Author

nos86 commented Jun 11, 2021

Hello @IhorNehrutsa,
unfortunately, I have no time for the moment and also the man project that asked me to develop this functionality on Micropython has been concluded.

Basically, my code is completely working and implements all basic functions.
The major problems are related to the harmonization and cosmetic aspects.

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.

@IhorNehrutsa
Copy link
Contributor

This PR is obsolete.
Work is continued in
WIP: esp32 CAN(TWAI) driver #7381

tannewt pushed a commit to tannewt/circuitpython that referenced this pull request Sep 8, 2021
Fix RP2040 I2S: always copy to output buffer
@jimmo
Copy link
Member

jimmo commented Nov 15, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants