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

STM32H7: Add new FDCAN driver #2987

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

rippetoej
Copy link

Summary

This is a draft PR. Style checks will fail and there is still some code that needs to be cleaned up and reviewed. I want to get this out in the open so others can get eyes on it.

The STM32H7 FDCAN block is a significant departure from the F7 and F4, so a lot has changed here. Fortunately, the SAMv7 series of chips use a nearly identical version of this IP, so that driver served as the starting point. The major difference between this controller and the one present in the F7 and F4 is the presence of the Message RAM. This is a 10 kB block of SRAM dedicated entirely to the FDCAN block and shared by the two independent FDCAN controllers. Each controller instantiates RX/TX FIFOs and buffers here to hold CAN messages. Also instantiated here are separate sets of filters for standard and extended length ID messages. The layout of the message ram is incredibly important to the proper operation of the controllers, so it is imperative that the driver get this right. The layout of the message RAM is fully configurable by the user via menuconfig. To help prevent invalid configurations, each config option has appropriate limits and a compile-time check ensures that the limits of the message RAM are not exceeded.

In its current state, the driver is functioning properly, but there is room for considerable improvement. Things that work:

  • Both controllers function and can be individually configured
  • Blocking and non-blocking operation both work as expected
  • Standard and extended ID messages can be sent and received
  • Hardware FIFOs for RX and TX
  • Hardware loopback mode
  • Classic CAN mode

Impact

Adds a shiny new driver!

Testing

Used the can example app to send a few thousand extended and standard length ID messages per test. I ran several of these tests in both blocking and non-blocking mode. I also tested using the FDCAN controller's built in hardware loopback as well as between two separate boards running the can example app. As as side note, I had to modify the can example app to get this to work properly, so I should probably commit that too.

The driver has also been used to send and receive standard length ID messages to CAN-based device controllers. These were sent alongside extended ID messages passed by UAVCAN without issue.

Important notes and things that need to be worked on

  • There are a number of things that need to be addressed; these items are marked with REVIST comments
  • I am uncertain about whether the message RAM is cacheable. The memory mapped address falls within the peripheral device space, which as far as I can tell is uncacheable. I could be wrong about this, but the driver currently seems to work as expected without any cache coherency operations in play.
  • The fdcan_reserve_buffer() function did not support non-blocking operation in the SAMv7 version of this driver. In that variation, the function utilized the nxsem_wait() function and looped until it was able to grab a buffer semaphore. I changed this over to nxsem_trywait() and then immediately return. The return code is inspected by fdcan_send(); if < 0, that function returns without sending the desired data. This prevents the driver from blocking when the hardware TX FIFO is full.
  • There is a single RCC reset line for the FDCAN block, meaning both controllers are reset together. The fdcan_reset() function currently makes use of this, which is no good if you have another piece of software controlling the device as well (Lookin' at you PX4 UAVCAN :p ). A better approach to resetting a single controller would be to put it into the init state and manually set all registers to the reset value. I have not done this yet.
  • I have not tested the busoff recovery functionality brought over from the SAMv7 driver
  • I have not tested whether IOCTL commands for adding and deleting filters works. I have only tested the driver working in the default "accept everything, reject nothing" mode.
  • I have not tested FD mode or bit rate switching. The code and Kconfig options are present for it.
  • I have not tested whether the TX hardware queue mode works, but the implementation was brought over from the SAMv7 driver
  • Remote request support is not currently implemented

@acassis
Copy link
Contributor

acassis commented Mar 31, 2021

Hi @rippetoej there are some Coding Styles that need to be fixed.

raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 11, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 11, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 11, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 11, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 11, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 12, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 12, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 12, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 12, 2022
raiden00pl added a commit to raiden00pl/nuttx that referenced this pull request Jan 12, 2022
acassis pushed a commit that referenced this pull request Jan 17, 2022
Gary-Hobson pushed a commit to Gary-Hobson/nuttx that referenced this pull request Jan 18, 2022
MTres19 pushed a commit to MTres19/incubator-nuttx that referenced this pull request Mar 1, 2022
JacobCrabill pushed a commit to JacobCrabill/incubator-nuttx that referenced this pull request May 27, 2022
JacobCrabill pushed a commit to JacobCrabill/incubator-nuttx that referenced this pull request Aug 1, 2022
@klxing
Copy link

klxing commented May 5, 2023

Summary

This is a draft PR. Style checks will fail and there is still some code that needs to be cleaned up and reviewed. I want to get this out in the open so others can get eyes on it.

The STM32H7 FDCAN block is a significant departure from the F7 and F4, so a lot has changed here. Fortunately, the SAMv7 series of chips use a nearly identical version of this IP, so that driver served as the starting point. The major difference between this controller and the one present in the F7 and F4 is the presence of the Message RAM. This is a 10 kB block of SRAM dedicated entirely to the FDCAN block and shared by the two independent FDCAN controllers. Each controller instantiates RX/TX FIFOs and buffers here to hold CAN messages. Also instantiated here are separate sets of filters for standard and extended length ID messages. The layout of the message ram is incredibly important to the proper operation of the controllers, so it is imperative that the driver get this right. The layout of the message RAM is fully configurable by the user via menuconfig. To help prevent invalid configurations, each config option has appropriate limits and a compile-time check ensures that the limits of the message RAM are not exceeded.

In its current state, the driver is functioning properly, but there is room for considerable improvement. Things that work:

  • Both controllers function and can be individually configured
  • Blocking and non-blocking operation both work as expected
  • Standard and extended ID messages can be sent and received
  • Hardware FIFOs for RX and TX
  • Hardware loopback mode
  • Classic CAN mode

Impact

Adds a shiny new driver!

Testing

Used the can example app to send a few thousand extended and standard length ID messages per test. I ran several of these tests in both blocking and non-blocking mode. I also tested using the FDCAN controller's built in hardware loopback as well as between two separate boards running the can example app. As as side note, I had to modify the can example app to get this to work properly, so I should probably commit that too.

The driver has also been used to send and receive standard length ID messages to CAN-based device controllers. These were sent alongside extended ID messages passed by UAVCAN without issue.

Important notes and things that need to be worked on

  • There are a number of things that need to be addressed; these items are marked with REVIST comments
  • I am uncertain about whether the message RAM is cacheable. The memory mapped address falls within the peripheral device space, which as far as I can tell is uncacheable. I could be wrong about this, but the driver currently seems to work as expected without any cache coherency operations in play.
  • The fdcan_reserve_buffer() function did not support non-blocking operation in the SAMv7 version of this driver. In that variation, the function utilized the nxsem_wait() function and looped until it was able to grab a buffer semaphore. I changed this over to nxsem_trywait() and then immediately return. The return code is inspected by fdcan_send(); if < 0, that function returns without sending the desired data. This prevents the driver from blocking when the hardware TX FIFO is full.
  • There is a single RCC reset line for the FDCAN block, meaning both controllers are reset together. The fdcan_reset() function currently makes use of this, which is no good if you have another piece of software controlling the device as well (Lookin' at you PX4 UAVCAN :p ). A better approach to resetting a single controller would be to put it into the init state and manually set all registers to the reset value. I have not done this yet.
  • I have not tested the busoff recovery functionality brought over from the SAMv7 driver
  • I have not tested whether IOCTL commands for adding and deleting filters works. I have only tested the driver working in the default "accept everything, reject nothing" mode.
  • I have not tested FD mode or bit rate switching. The code and Kconfig options are present for it.
  • I have not tested whether the TX hardware queue mode works, but the implementation was brought over from the SAMv7 driver
  • Remote request support is not currently implemented

Hi, is there any example code that I can refer to send/receive classic CAN messages on stm32h7?

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.

3 participants