Skip to content

alif/machine_can: CAN support for the OPENMV_AE3 board.#19349

Open
robert-hh wants to merge 11 commits into
micropython:masterfrom
robert-hh:alif_can
Open

alif/machine_can: CAN support for the OPENMV_AE3 board.#19349
robert-hh wants to merge 11 commits into
micropython:masterfrom
robert-hh:alif_can

Conversation

@robert-hh

Copy link
Copy Markdown
Contributor

Summary

Support the CAN feature for the OPEN_MV_AE3 board. It is implemented as an include file for extmod/machine_can.c and supports all required interfaces. The code may work with the Alif_ensemble board as well, but lacking the board and the reference manual it could not be verified.

Testing

Tested with both a MIMXRT Teensy 4.1 and a PyBoard V1.1 as second device, using the test scripts from tests/extmod_hardware and tests/multi_extmod.

The Alif CAN controller does not allow to tell, which slot of the TX queue is used for specific message and does not allow to cancel a specific message. Therefore tests machine_can_04_tx_order.py and machine_can_05_tx_prio_cancel.py must be skipped. All other tests pass with the Alif device both as instance0 and instance1.

Trade-offs and Alternatives

There is a problem with the TX FIFO under heavy load. In an attempt to fill messages faster than they can be sent, the behavior gets corrupted, causing accepted messages to be dropped, sending messages twice or changing the requested message order. As
a workaround, the usable TX queue size is limited from 16 to 8. Then it works.

Generative AI

I did not use generative AI tools when creating this PR.

- mpconfigport.h: Configure the CAN include file.
- alif-mk: Add the fdcan.c driver to the soucr list.
- Makefile: Export $(BOARD) to alif.mk.

Signed-off-by: robert-hh <robert@hammelrath.com>
@robert-hh

Copy link
Copy Markdown
Contributor Author

Just a note about the commits: all commits for the machine_can.c file can later be squashed into one. They just reflect the development & test process. There is not good reason to keep them apart.

@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.51%. Comparing base (d901e98) to head (baa88cf).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #19349   +/-   ##
=======================================
  Coverage   98.51%   98.51%           
=======================================
  Files         176      176           
  Lines       22903    22903           
=======================================
  Hits        22562    22562           
  Misses        341      341           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dpgeorge

Copy link
Copy Markdown
Member

Fantastic work @robert-hh ! I will test on ALIF_ENSEMBLE.

Comment thread ports/alif/Makefile

$(BUILD)/M55_HP/firmware.bin:
$(MAKE) -f alif.mk BUILD=$(BUILD)/M55_HP MCU_CORE=M55_HP MICROPY_PY_OPENAMP_MODE=0
$(MAKE) -f alif.mk BUILD=$(BUILD)/M55_HP MCU_CORE=M55_HP MICROPY_PY_OPENAMP_MODE=0 BOARD=$(BOARD)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change needed?

@robert-hh robert-hh Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was needed with using GNUmakefile. Without that change, the setting for BOARD in the GNUmakefile would not appear in alif.mk. But if coarse this not not mandatory for CAN support.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I see.

Comment thread tests/multi_extmod/machine_can_04_tx_order.py
Comment thread tests/multi_extmod/machine_can_05_tx_prio_cancel.py
@robert-hh

Copy link
Copy Markdown
Contributor Author

I added the board file changes for ALIF_ENSEMBLE. The firmware builds. Pin settings are P0_4 for RX and P0_5 for TX.

@dpgeorge

Copy link
Copy Markdown
Member

I added the board file changes for ALIF_ENSEMBLE. The firmware builds. Pin settings are P0_4 for RX and P0_5 for TX.

I tested with ALIF_ENSEMBLE, but needed to change the pins to P12_4 and P12_5, because they are the only ones that can be made to work with 3.3V on this board (and the CAN tranceivers I have are 3.3V).

With these pins, I get the 6 multi CAN tests working when run against a PYBV10 (2 are skipped as expected). And the extmod_hardware/machine_can_timings.py test also passes. Very good!

@robert-hh did you use 3.3V tranceivers when testing OPENMV_AE3?

#define MICROPY_HW_NUM_CAN (1)

#define MICROPY_HW_CAN1_TX (pin_P0_5)
#define MICROPY_HW_CAN1_RX (pin_P0_4)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two defines are never actually used! The code uses pin_CAN_RXD and pin_CAN_TXD instead.

@robert-hh robert-hh Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I know. I removed them.

@robert-hh

robert-hh commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for testing with the ALIF_ENSEMBLE board. Yes, I used 3.3V transceiver with the OPENMV_AE3 board. But at this board, P0_4 and P0_5 are labeled as 3.3V tolerant. For ALIF_ENSEMBLE I well change then the Pin numbers and combine the two commit for board definitions.

Edit: looking into the data sheet and the OPENMV_schematics, it shows that P0_4 and P0_5 are at the 1.8V rail, but that the board has level converters for these pins.

robert-hh added 10 commits June 18, 2026 16:20
- mpconfigboard.h: Specify the CAN name "CAN1" and numbers.
- pins.csv: Add the CAN_RXD and CAN_TXD pin names.
- ensemble_pin_alt.csv: Add the CAN pin ALT symbols
- mphalport.h: Add the CAN enum symbols.

Signed-off-by: robert-hh <robert@hammelrath.com>
The CAN interface is at P12_4 for RX and P12_5 for TX.

Signed-off-by: robert-hh <robert@hammelrath.com>
Just one device, no arguments.

Signed-off-by: robert-hh <robert@hammelrath.com>
- multi_extmod/machine_can_04_tx_order.py: Skip for Alif, since
  the Alif port has an opaque send queue which provides no information
  of the slot number of a message in the TX queue.
- multi_extmod/machine_can_05_tx_prio_cancel.py: Skip for Alif, since
  the Alif port has an opaque send queue which does not allow specific
  cancels and provides no information of the slot number of a
  message in the TX queue.
- tests/multi_extmod/machine_can_07_error_states.py: Swap the order of
  resetting the baud rate and restart(). If restart() happens before
  resetting the baud rate, then the REC counter increases fast and the
  bus state switched to PASSIVE before the baud rate can be fixed.
- multi_extmod/machine_can_08_init_mode.py: Cater for error frames not
  being reported in SILENT mode.

Signed-off-by: robert-hh <robert@hammelrath.com>
Supporting CAN 2.0.

At the moment, the focuses is for OPENMV_SE3 board. But it may work as
well with the ALIF_ENSEMBLE board. When the same changes to the board
files are applied, the build passes.

The send and receive FIFOs of the Alif CAN controller are opaque and
provide no information, which message slot is used for a specific
message. Therefore, specific messages cannot be removed from the FIFO.
Some of the CAN tests should therefore fail.

Signed-off-by: robert-hh <robert@hammelrath.com>
- Even if the 160M clock is used, the 38M4 clock has to be enabled.
- Bit timing was off by 1 clock cycle. Use tseg1 - 1 for S_SEG1 instead
  of tseg1 - 2, which seems to be suggested by the data sheet.
- Disable TX and RX interrupts during init for testing. TX interrupts
  will anyhow be enabled when send() is called.

Signed-off-by: robert-hh <robert@hammelrath.com>
IRQs are re-triggered as long as the respective flags is set, even if
the IRQ source is disabled. Therefore all IRQ events have to be handled
in the IRQ handler and accumulated for being reported in the callback.

Do not run the IRQ handler when no IRQ flag is set.

The CAN device is deinit'ed on soft reset, disabling all IRQs and
clearing all acceptance masks.

Signed-off-by: robert-hh <robert@hammelrath.com>
Acceptance filter can only be enabled in reset state. Therefore that
filter setting are collected, and when done init() is called to
activate the filters. As a side effect, the error numbers are cleared.

Signed-off-by: robert-hh <robert@hammelrath.com>
The bus state transitions are now properly signalled and the test
scripts work with minor changes.

Signed-off-by: robert-hh <robert@hammelrath.com>
There is a problem with the TX FIFO under heavy load. In an attempt to
fill messages faster than they can be sent, the behaviour gets strange.
Instead of just rejecting messages when the FIFO is full, the following
appears:

- messages were told to be accepted for sending, but they never were
  sent
- messages were sent twice, but other messages were missing.
- the priority rule was broken by messages not being sent in proper
  sequence.

It seems that the "full" state is the problem. As a fix the can.send()
now refuses messages if the FIFO is more than half full. Then the
situation seems stable.

Changed the reporting of the TX queue length in can.get_counters():

0   Queue empty
1   Queue length 1 - 8
9   Queoe length 9 - 15
16  Queue length 16

Changed the upper limits for seg1, seg2 and sjw timings following the
reference manual.

Signed-off-by: robert-hh <robert@hammelrath.com>
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.

2 participants