Skip to content
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

Updates for ARKFPV board to use Cyphal-CAN-FD #1

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

jwwaite
Copy link

@jwwaite jwwaite commented Jan 5, 2025

While both DroneCAN and Cyphal are protocol (rather than driver) specifications, they interconnect with physical layer CAN device drivers in different ways. Both protocols are implemented in PX4, but the physical layer connections are board dependent. Currently, ARKFPV supports DroneCAN, and the goal of this PR is to add a Cyphal board configuration option for ARKFPV.

My experiments show that Cyphal "nearly" works for the relatively minor config file changes documented in commit [c5086c3](https://github.com/PX4/PX4-Autopilot/commit/c5086c346f82490a2c50aa362a2ee6fa5578caab). The key change is that the STM32H7 socketCAN drivers must be selected. This is already supported in the PX4 cyphal source code and is turned on by defconfig updates (see the commit). While I disabled DroneCAN in my experiments, this may not be necessary, except to save flash memory since both Cyphal and DroneCAN implementations each consume about 5% of program flash.

Upon starting can0 manually in nsh (or automatically in rc.board_defaults): ifup can0, all CAN-FD reads occur without error, at the CAN-FD rates I tested: 1Mb (arbitration) and 4Mb (data). We used a cyphal-compliant sensor that broadcasts messages on the bus, and from a nuttx shell these messages can be monitored using the candump utility (turned on in defconfig).

However, a problem exists for CAN-FD writes. Initially I noticed that the very first Cyphal heartbeat (first transmit from ARKFPV) would crash the CAN subsystem such that no further reads occur. A CAN analyzer shows that the sensor broadcasts remain as before, but ARKFPV cannot read them, and a subsequent invocation of candump hangs. The CAN analyzer doesn't recognize the transmit packet at all, and it is not present in the logged output.

But after further investigation, this problem is not related to Cyphal at all, and seems inherent in the socketCAN driver, or the ARKFPV socketCAN implementation. CAN-FD writes can be invoked from the nuttx command line using cansend, for example:
cansend can0 107D553B##F000000E3

As soon as that command is issued, CAN-FD reads are no longer possible from candump (although the sensor on the bus continues to send data, as seen in this scope screenshot (2-channel scope with chan1=CAN+, chan2=CAN-):

cansend_crash

Three distinct messages are broadcast at roughly once per second (200 ms/div scope plot). The cansend message seems to cause a signal offset in the differential CAN signal. I tried both properly 120 ohm terminations, as well as removing the terminations, with no change.

There is enough subtlety in the socketCAN configuration that I may have missed a crucial parameter. I would appreciate some feedback on how to further isolate this behavior. As I said above, Cyphal-CAN "almost" works by configuration changes without source code change on ARKFPV.

@jwwaite
Copy link
Author

jwwaite commented Jan 6, 2025

Narrowing this down further, using /platforms/nuttx/NuttX/apps/canutils/cansend/cansend.c as a testbed, the raw write() on line 161 causes this problem. This is the same functionality used by the PX4-Cyphal socketcan implementation in the send_msg() function.

I still don't know why, and the CAN analyzer reports nothing at the time of this write. Maybe a logic analyzer is needed for debug.

@jwwaite
Copy link
Author

jwwaite commented Jan 6, 2025

I have identified the problem, but don't know how to fix. For some reason, the CAN utility "cansend" can only successfully send classic can 2.0 frames, but "candump" only reads both classic CAN and CAN-FD frames. This explains why "cansend can0 123##1DEADBEEF" hangs the system, but "cansend can0 123#DEADBEEF" does not. When the latter command is issued in the ARKFPV nsh shell, it appears on a connected CAN analyzer. But candump receives both Classic and CAN-FD frames properly (see candump screenshot). I have searched for a missing NuttX config parameter, or PX4 parameter, that might control this, without success. The PR lists the defconfig changes that I made, and the attached screenshot shows menuconfig's view of the socketcan setup. All the signals are clean, both for Classic CAN and CAN-FD. This is clearly a setup issue, and the problem exhibited by cansend is exactly the same behavior when PX4 Cyphal is sending any data, such as the once per second heartbeat. Any ideas?

both classic and fd
CAN-FD socketcan support

@jwwaite
Copy link
Author

jwwaite commented Jan 6, 2025

Added one new CONFIG parameter, but no change. Any CAN-FD transmit hangs the CAN subsystem. The CONFIG list to enable socketcan on ARKFPV is now:
updated config list

But there must be something I'm missing.

@jwwaite
Copy link
Author

jwwaite commented Jan 7, 2025

It's working now. I dropped the data rate down to the arbitration rate (1 Mbps) and the CAN-FD transmit works as it should. I probably would have done this sooner were it not for the fact that ARKFPV was reading CAN-FD data at 4 Mbps just fine. But apparently, it cannot transmit at those rates, or maybe does not support CAN-FD acceleration.

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

Successfully merging this pull request may close these issues.

1 participant