Core
Loading...
Searching...
No Matches
can.h File Reference

Core FDCAN library. More...

#include "clock.h"
#include "timestamp.h"
#include "core_config.h"
#include <stdbool.h>
#include <stdint.h>
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
#include "message_buffer.h"

Go to the source code of this file.

Data Structures

struct  CanMessage_s
 
struct  CanExtendedMessage_s
 
struct  core_CAN_module_s
 
struct  core_CAN_head_s
 Header for a CAN packet. More...
 
struct  core_CAN_msg_s
 
struct  core_CAN_errors_s
 

Macros

#define core_CAN_enable_timestamps   core_timestamp_init
 

Typedefs

typedef struct core_CAN_module_s core_CAN_module_t
 
typedef struct core_CAN_head_s core_CAN_head_t
 
typedef struct core_CAN_msg_s core_CAN_msg_t
 
typedef struct core_CAN_errors_s core_CAN_errors_t
 

Functions

bool core_CAN_init (FDCAN_GlobalTypeDef *fdcan, uint32_t baudrate)
 Initialize an FDCAN module, the RX and TX pins, the TX queue (if enabled), and the RX queue or message buffer (if enabled).
 
core_CAN_module_tcore_CAN_convert (FDCAN_GlobalTypeDef *fdcan)
 
bool core_CAN_send_message (FDCAN_GlobalTypeDef *can, uint32_t id, uint8_t dlc, uint64_t data)
 Add a CAN message to the hardware FIFO.
 
bool core_CAN_send_fd_message (FDCAN_GlobalTypeDef *can, uint32_t id, uint8_t dlc, uint8_t *data)
 Add an FDCAN message to the hardware FIFO.
 
bool core_CAN_add_message_to_tx_queue (FDCAN_GlobalTypeDef *can, uint32_t id, uint8_t dlc, uint64_t data)
 Add a CAN frame to the TX queue. This function is only available if CORE_CAN_DISABLE_TX_QUEUE is set to 0.
 
bool core_CAN_add_extended_message_to_tx_queue (FDCAN_GlobalTypeDef *can, uint32_t id, uint8_t dlc, uint8_t *data)
 Add a CAN frame to the TX queue. This function is only available if CORE_CAN_DISABLE_TX_QUEUE is set to 0.
 
bool core_CAN_send_from_tx_queue_task (FDCAN_GlobalTypeDef *can)
 Loop for sending data in the TX queue over CAN. This function must be run in its own task. This function is only available if CORE_CAN_DISABLE_TX_QUEUE is set to 0.
 
bool core_CAN_receive_from_queue (FDCAN_GlobalTypeDef *can, CanMessage_s *received_message)
 If a frame is waiting in the RX queue, copy it to the given location.
 
bool core_CAN_receive_extended_from_queue (FDCAN_GlobalTypeDef *can, CanExtendedMessage_s *received_message)
 If a frame is waiting in the RX queue, copy it to the given location.
 
bool core_CAN_add_filter (FDCAN_GlobalTypeDef *can, bool isExtended, uint32_t id1, uint32_t id2)
 Add an RX filter for the given FDCAN module.
 

Variables

const uint8_t core_CAN_dlc_lookup [16]
 
core_CAN_errors_t core_CAN_errors
 

Detailed Description

Core FDCAN library.

This core library component is used to interface with the FDCAN hardware.

Initialization

An FDCAN module is initialized by calling the core_CAN_init() function. The CAN bitrate is set to CORE_CAN_BITRATE, which is given in bits/second and defined in core_config.h. If CORE_FDCANx_AUTO_RETRANSMISSION is set to 1 in core_config.h, the FDCANx module will be cofigured to automatically retransmit packets that were not acknowledged. If CORE_FDCANx_USE_FD is set to 1 in core_config.h, the FDCANx module will be able to send and receive FD CAN frames as well as standard CAN frames.

Transmitting

Transmission on the CAN bus is managed by a FreeRTOS queue and occurs in two parts. First, the user code adds a CAN frame to the queue with core_CAN_add_message_to_tx_queue() (classic and FD CAN) or with core_CAN_add_extended_message_to_tx_queue() (FD CAN only).

The user code must also run core_CAN_send_from_tx_queue_task() in a dedicated FreeRTOS task. If core_CAN_send_from_tx_queue_task(), an error has occurred while transmitting.

Internally, a FreeRTOS semaphore is used to ensure only one message sits in the hardware CAN queue at a time. The semaphore is given whenever a transmission completes (or fails) and is taken whenever a message is added to the hardware queue.

Alternatively, the user can disable the FreeRTOS queue by defining CORE_CAN_DISABLE_TX_QUEUE in core_config.h. This is useful if the user needs finer control over the transmission, wants to synchronize CAN transmissions between FDCAN modules, or would like to save SRAM space. The RX queue is not affected and the user can access the semaphore using core_CAN_convert(), but will be responsible for taking the semaphore.

Receiving

In order to enable receiving CAN frames, the user code must first set up one or more filters using the core_CAN_add_filter() function. When a frame matching any of the applied filters is received, the FDCAN hardware triggers an interrupt that processes the received data.

There are two options for processing received frames: queues or message buffers. If CORE_CAN_USE_MSGBUF is not set, then one RX queue is created for each initialized CAN module. When the receive interrupt is triggered, the received frame is inserted into the corresponding queue. Queues are preferred when data from different busses is processed separately and when different busses are assigned different priorities. However, a queue can only store a fixed number of elements, and a fixed amount of space will be allocated for each message, regardless of the message's size.

If CORE_CAN_USE_MSGBUF is set to 1, then up to three RX message buffers can be created. Each FDCAN module can then be connected to one of the three message buffers. This allows data from multiple busses to be combined into one message buffer, which is helpful if data from all busses is processed identically. Furthermore, message will only take up as much space in the message buffer as needed, allowing the space to be used more efficiently.

If not using message buffers, the user code must define a task that repeatedly calls core_CAN_receive_from_queue() (classic CAN) or core_CAN_receive_extended_from_queue() (FD CAN only). If using message buffers, the user code must define a task that repeatedly calls core_CAN_receive_from_msgbuf(). These functions will wait up to CORE_CAN_RX_TIMEOUT for a message to appear in the buffer before returning.

Function Documentation

◆ core_CAN_add_extended_message_to_tx_queue()

bool core_CAN_add_extended_message_to_tx_queue ( FDCAN_GlobalTypeDef * can,
uint32_t id,
uint8_t dlc,
uint8_t * data )

Add a CAN frame to the TX queue. This function is only available if CORE_CAN_DISABLE_TX_QUEUE is set to 0.

Parameters
canFDCAN module for which the frame is being enqueued
idID of the CAN frame
dlcNumber of data bytes in the CAN frame
dataPointer to an array of data bytes
Return values
0if the queue is full, if the FDCAN is not configured for FD operation, or if dlc > 64
1otherwise

◆ core_CAN_add_filter()

bool core_CAN_add_filter ( FDCAN_GlobalTypeDef * can,
bool isExtended,
uint32_t id1,
uint32_t id2 )

Add an RX filter for the given FDCAN module.

All frames with IDs greater than or equal to id1 and less than or equal to id2 will be placed in the RX queue

Parameters
canFDCAN module for which the filter should be created
isExtendedSpecifies whether the IDs are extended CAN IDs
id1Lower bound (inclusive)
id2Upper bound (inclusive)
Return values
1if the filter was added successfully
0otherwise

◆ core_CAN_add_message_to_tx_queue()

bool core_CAN_add_message_to_tx_queue ( FDCAN_GlobalTypeDef * can,
uint32_t id,
uint8_t dlc,
uint64_t data )

Add a CAN frame to the TX queue. This function is only available if CORE_CAN_DISABLE_TX_QUEUE is set to 0.

Parameters
canFDCAN module for which the frame is being enqueued
idID of the CAN frame
dlcNumber of data bytes in the CAN frame
dataData bytes, encoded LSB-first as a uint64
Return values
0if the queue is full
1otherwise

◆ core_CAN_init()

bool core_CAN_init ( FDCAN_GlobalTypeDef * fdcan,
uint32_t baudrate )

Initialize an FDCAN module, the RX and TX pins, the TX queue (if enabled), and the RX queue or message buffer (if enabled).

Return values
0if the given FDCAN is not valid or the initialization failed
1otherwise

◆ core_CAN_receive_extended_from_queue()

bool core_CAN_receive_extended_from_queue ( FDCAN_GlobalTypeDef * can,
CanExtendedMessage_s * received_message )

If a frame is waiting in the RX queue, copy it to the given location.

If no frame is waiting in the RX queue, this function will wait up to CORE_CAN_RX_TIMEOUT milliseconds for one to enter the queue. This function is only defined if CORE_CAN_USE_MSGBUF and CORE_CAN_DISABLE_RX_QUEUE are set to 0.

Parameters
canFDCAN module from which the frame is read
received_messagePointer to the location where the received frame would be stored
Return values
1if a frame was copied from the queue into the given location
0otherwise

◆ core_CAN_receive_from_queue()

bool core_CAN_receive_from_queue ( FDCAN_GlobalTypeDef * can,
CanMessage_s * received_message )

If a frame is waiting in the RX queue, copy it to the given location.

If no frame is waiting in the RX queue, this function will wait up to CORE_CAN_RX_TIMEOUT milliseconds for one to enter the queue. This function is only defined if CORE_CAN_USE_MSGBUF and CORE_CAN_DISABLE_RX_QUEUE are set to 0.

Parameters
canFDCAN module from which the frame is read
received_messagePointer to the location where the received frame would be stored
Return values
1if a frame was copied from the queue into the given location
0otherwise

◆ core_CAN_send_fd_message()

bool core_CAN_send_fd_message ( FDCAN_GlobalTypeDef * can,
uint32_t id,
uint8_t dlc,
uint8_t * data )

Add an FDCAN message to the hardware FIFO.

Parameters
canFDCAN module
idID of the message to be transmitted. If this value is greater than 2047, then an extended ID is automatically selected. Only the lowest 29 bits are kept, so setting the MSB will force an extended ID even if the ID is less than or equal to 2047
dlcLength of the packet. If the length does not correspond to a valid FDCAN packet length,
dataPointer to the data to be transmitted
Return values
0if an error occurred while adding the message to the queue
1otherwise

◆ core_CAN_send_from_tx_queue_task()

bool core_CAN_send_from_tx_queue_task ( FDCAN_GlobalTypeDef * can)

Loop for sending data in the TX queue over CAN. This function must be run in its own task. This function is only available if CORE_CAN_DISABLE_TX_QUEUE is set to 0.

Parameters
canFDCAN module

◆ core_CAN_send_message()

bool core_CAN_send_message ( FDCAN_GlobalTypeDef * can,
uint32_t id,
uint8_t dlc,
uint64_t data )

Add a CAN message to the hardware FIFO.

Parameters
canFDCAN module
idID of the message to be transmitted. If this value is greater than 2047, then an extended ID is automatically selected. Only the lowest 29 bits are kept, so setting the MSB will force an extended ID even if the ID is less than or equal to 2047
dlcLength of the packet (0-8)
dataData encoded as a uint64_t
Return values
0if an error occurred while adding the message to the queue
1otherwise