diff --git a/drivers/include/can/candev.h b/drivers/include/can/candev.h index 59f3e0e3ca..cddfb5f2b1 100644 --- a/drivers/include/can/candev.h +++ b/drivers/include/can/candev.h @@ -80,6 +80,9 @@ struct candev { void *isr_arg; /**< argument to pass on isr event */ struct can_bittiming bittiming; /**< device bittimings */ enum can_state state; /**< device state */ +#ifdef MODULE_FDCAN + struct can_bittiming fd_data_bittiming;/**< device bittimings for FD CAN only */ +#endif }; /** diff --git a/sys/include/can/can.h b/sys/include/can/can.h index 0795e1758e..08e0a14560 100644 --- a/sys/include/can/can.h +++ b/sys/include/can/can.h @@ -40,9 +40,13 @@ extern "C" { #else /** - * @brief Max data length for a CAN frame + * @brief Max data length for classic and FD CAN frames (compliant with + * libsocketcan macros) + * @{ */ -#define CAN_MAX_DLEN (8) +#define CAN_MAX_DLEN (8) /**< Classic CAN maximum data length */ +#define CANFD_MAX_DLEN (64) /**< CAN FD maximum data length */ +/** @} */ /** * @name CAN_ID flags and masks @@ -59,6 +63,15 @@ extern "C" { #define CAN_ERR_MASK (0x1FFFFFFFU) /**< omit EFF, RTR, ERR flags */ /** @} */ +/** + * @name CAN FD flags extracted from libsocketcan + * @{ + */ +#define CANFD_BRS 0x01 /**< bit rate switch (second bitrate for payload data) */ +#define CANFD_ESI 0x02 /**< error state indicator of the transmitting node */ +#define CANFD_FDF 0x04 /**< mark CAN FD for dual use of struct canfd_frame */ +/** @} */ + /** * @brief CAN operational and error states */ @@ -86,15 +99,30 @@ typedef uint32_t canid_t; * @brief Controller Area Network frame */ struct can_frame { - canid_t can_id; /**< 32 bit CAN_ID + EFF/RTR/ERR flags */ - uint8_t can_dlc; /**< frame payload length in byte (0 .. CAN_MAX_DLEN) */ - uint8_t __pad; /**< padding */ - uint8_t __res0; /**< reserved / padding */ - uint8_t __res1; /**< reserved / padding */ + canid_t can_id; /**< 32 bit CAN_ID + EFF/RTR/ERR flags */ + union { + uint8_t len; /**< frame payload length in byte (0 .. CAN_MAX_DLEN) */ + uint8_t can_dlc;/**< deprecated - see SocketCAN documentation */ + }; + uint8_t __pad; /**< padding */ + uint8_t __res0; /**< reserved / padding */ + uint8_t __res1; /**< reserved / padding */ /** Frame data */ uint8_t data[CAN_MAX_DLEN] __attribute__((aligned(8))); }; +#ifdef MODULE_FDCAN +struct canfd_frame { + canid_t can_id; /**< 32 bit CAN_ID + EFF/RTR/ERR flags */ + uint8_t len; /**< frame payload length in byte (0 .. CAN_MAX_DLEN) */ + uint8_t flags; /**< additional flags for CAN FD */ + uint8_t __res0; /**< reserved / padding */ + uint8_t __res1; /**< reserved / padding */ + /** Frame data */ + uint8_t data[CANFD_MAX_DLEN] __attribute__((aligned(8))); +}; +#endif + /** * @brief Controller Area Network filter */ @@ -142,7 +170,15 @@ struct can_bittiming_const { #endif /* defined(__linux__) */ +/** + * @brief CAN frame + */ +#ifdef MODULE_FDCAN +typedef struct canfd_frame can_frame_t; +#else typedef struct can_frame can_frame_t; +#endif + #ifdef __cplusplus } #endif diff --git a/sys/include/can/common.h b/sys/include/can/common.h index 80babfa4e0..ba56f31b25 100644 --- a/sys/include/can/common.h +++ b/sys/include/can/common.h @@ -39,6 +39,15 @@ extern "C" { #include "mbox.h" #endif +/** + * @brief Default CAN maximum data length + */ +#ifdef MODULE_FDCAN +#define DEFAULT_CAN_MAX_DLEN CANFD_MAX_DLEN +#else +#define DEFAULT_CAN_MAX_DLEN CAN_MAX_DLEN +#endif + /** * @brief CAN options */ @@ -51,6 +60,10 @@ typedef enum { CANOPT_CLOCK, /**< controller main clock */ CANOPT_BITTIMING_CONST, /**< controller bittiming parameters */ CANOPT_STATE, /**< set controller state @ref canopt_state_t */ +#ifdef MODULE_FDCAN + CANOPT_FD_BITTIMING, /**< bit timing parameter for FDCAN data payload */ + CANOPT_FD_BITTIMING_CONST, /**< controller bit timing parameter for FDCAN data payload */ +#endif } canopt_t; /**