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

can: add CAN FD support to STM32G4 and native architecture #20428

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Commits on Nov 3, 2024

  1. can: use frame len instead of can_dlc

    RIOT implementation of CAN bus relies on SocketCAN model.
    Since commit c398e56 (can: add optional DLC element to Classical CAN
    frame structure), '__u8 can_dlc' attribute of struct can_frame is
    considered as deprecated in SocketCAN and kept for legacy support.
    Attribute '__u8 len' should be used instead.
    
    	union {
    		/* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
    		 * was previously named can_dlc so we need to carry that
    		 * name for legacy support
    		 */
    		__u8 len;
    		__u8 can_dlc; /* deprecated */
    	};
    
    Moreover, CAN FD frame structure does not support legacy attribute
    'can_dlc', making 'len' mandatory for incoming CAN FD support in RIOT.
    
    	struct canfd_frame {
    		canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
    		__u8    len;     /* frame payload length in byte */
    		__u8    flags;   /* additional flags for CAN FD */
    		__u8    __res0;  /* reserved / padding */
    		__u8    __res1;  /* reserved / padding */
    		__u8    data[CANFD_MAX_DLEN]
    __attribute__((aligned(8)));
    	};
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    80aee7b View commit details
    Browse the repository at this point in the history
  2. can: introduce typedef can_frame_t

    Whole CAN code in RIOT is using 'struct can_frame' to represent a CAN
    frame.
    However incoming CAN FD support will bring 'struct canfd_frame' to
    represent CAN FD frames.
    Even if the 'struct canfd_frame' has additional flags and a bigger
    payload, it is aligned on 'struct can_frame' and thus they can be
    referenced by the same pointers in the code.
    
    As it is impossible to predict which one will be used in RIOT, just
    define a new type 'can_frame_t' which will map to the right struct
    according to the MCU CAN supported format.
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    99d7cb3 View commit details
    Browse the repository at this point in the history
  3. makefiles: introduce fdcan pseudomodule

    This pseudomodule is used to enable code depending on CAN FD support.
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    0b03226 View commit details
    Browse the repository at this point in the history
  4. can: add CAN FD configuration

    Add CAN FD specifities to CAN system library in RIOT:
    * 64 bytes payload
    * Bit rate switching
    * Error State Indicator
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    f1163c3 View commit details
    Browse the repository at this point in the history
  5. can: introduce loop_delay

    During the data phase of a FDCAN transmission only one node is
    transmitting, all others are receivers. The length of the bus line has
    no impact.
    When transmitting via pin FDCAN_TX the protocol controller receives the
    transmitted data from its local CAN transceiver via pin FDCAN_RX. The
    received data is delayed by the CAN transceiver loop delay.
    If this delay is greater than TSEG1 (time segment before sample point),
    a bit error is detected. Without transceiver delay compensation, the bit
    rate in the data phase of a FDCAN frame is limited by the transceiver's
    loop delay.
    
    Since this parameter is related to the transceiver used, there cannot be
    a default value, and it must be explicitly defined with the
    configuration variable CONFIG_FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY.
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    6c02337 View commit details
    Browse the repository at this point in the history
  6. cpu/stm32: add FDCAN support to STM32G4 family

    Until now, STM32 MCUs classic CAN support is coded in can.c file.
    However CAN FD in STM32G4 family is designed in a very different way:
    * CAN FD channels are independant
    * CAN FD channel configuration is done in a dedicated RAM block called
      message RAM, with one message RAM per channel
    * Each message RAM is divided this way:
      - 11-bit filter (28 elements / 28 words)
      - 29-bit filter (8 elements / 16 words)
      - Rx FIFO 0 (3 elements / 54 words)
      - Rx FIFO 1 (3 elements / 54 words)
      - Tx event FIFO (3 elements / 6 words)
      - Tx buffers (3 elements / 54 words)
    
    Due to these design differences with other STM32 MCUs, the choice is
    made to split the driver in two files:
    * classiccan.c for STM32 MCUs that support classical CAN. This file
      has just been renamed (previously can.c) to avoid build conflicts
      but does not introduce changes
    * fdcan.c for STM32 MCUs that support CAN FD
    
    Message RAM definitions is not provided in CMSIS headers of the STM32G4
    family, they are defined in fdcandev_stm32.h. Those definitions could be
    extracted to a new file for each STM32 families as some differences
    exist with other STM32 families that support CAN FD (for instance
    STM32H7). This could be done in a futher commit, according to new
    families requirements.
    
    CAN hardware parameters stay similar and are kept in can_params.h.
    
    There are 36 filters per channel:
    * 28 first filters are standard ID (11 bit) filters
    * 8 last filters are extended ID (29 bit) filters
    
    On each Tx frame sent, the STM32G4 can store Tx events in a dedicated
    FIFO. This feature is not yet implemented and Tx event FIFO is disabled
    by default.
    Automatic retransmission on arbitration loss is enabled by default by
    the STM32G4.
    
    About Rx, if no filter is configured, all frames are accepted by
    default.
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    42da782 View commit details
    Browse the repository at this point in the history
  7. cpu/native: enable CAN FD support

    As CAN FD is already supported by SocketCAN on Linux, just enable the
    fdcan pseudomodule and allow CAN FD frames.
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    e826ec8 View commit details
    Browse the repository at this point in the history
  8. boards/nucleo-g431rb: enable periph_can

    Enable periph_can to add CAN FD support to nucleo-g431rb.
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    1d31978 View commit details
    Browse the repository at this point in the history
  9. tests/conn_can: make test support CAN FD

    Increase Shell buffer size for 64 bytes payload length of CAN FD frame.
    This also implies to increase main thread stack size and especially for
    native architectures.
    Add two new sub-commands to test_can command:
    * fdsend: to send a CAN FD frame
    * fdsendrtr: to send a CAN FD RTR frame (payload length = 0).
    
    Signed-off-by: Gilles DOFFE <[email protected]>
    gdoffe committed Nov 3, 2024
    Configuration menu
    Copy the full SHA
    3347170 View commit details
    Browse the repository at this point in the history