Data Structures | Macros | Typedefs | Functions | Variables
CAN.h File Reference

Detailed Description

Controller Area Network (CAN) Driver Interface.


Overview

The Controller Area Network (CAN) driver is a single instance driver that provides a simple interface to transmit and receive messages on a CAN bus. Messages are broadcast to the entire CAN network and each device is responsible for filtering and handling the received messages as necessary. The application is responsible for interpreting the received data.


Usage

To use the CAN driver to send and receive messages over the CAN bus, the application calls the following APIs:

Synopsis

The following code example initializes the CAN driver with the default configuration, transmits a CAN FD message, and waits to read any received messages.

// Payload data size indexed by Data Length Code (DLC) field.
static const uint32_t DLCtoDataSize[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
// Rx semaphore.
static SemaphoreP_Handle rxSemHandle;
void eventCallback(CAN_Handle handle, uint32_t event, uint32_t data, void *userArg)
{
{
SemaphoreP_post(rxSemHandle);
}
// Handle more events here if enabled via the event mask...
}
void thread(arg0, arg1)
{
int_fast16_t status;
// Initialize driver(s).
// Create callback semaphore.
SemaphoreP_Params semParams;
SemaphoreP_Params_init(&semParams);
semParams.mode = SemaphoreP_Mode_BINARY;
callbackSemHandle = SemaphoreP_create(0, &(semParams));
if (callbackSemHandle == NULL)
{
// SemaphoreP_create() failed.
while (1) {}
}
// Open CAN driver with default configuration.
CAN_Params_init(&canParams);
canParams.eventCbk = eventCallback;
// Setup event mask for events the application is interested in receiving
// the callback for. Typically, only the CAN_EVENT_RX_DATA_AVAIL is required.
canParams.eventMask = CAN_EVENT_RX_DATA_AVAIL;
canHandle = CAN_open(CONFIG_CAN_0, &canParams);
if (canHandle == NULL)
{
// CAN_open() failed.
while (1) {}
}
// Setup Tx buffer element:
// CAN FD without Bit Rate Switching
// Extended Message ID = 0x12345678
// Data Length of 64-bytes
// Message marker = 5
txElem.id = 0x12345678U;
txElem.rtr = 0U;
txElem.xtd = 1U;
txElem.esi = 0U;
txElem.brs = 1U;
txElem.dlc = CAN_DLC_64B;
txElem.fdf = 1U;
txElem.efc = 0U;
txElem.mm = 5U;
// Fill data payload with incrementing values.
for (i = 0; i < DLCtoDataSize[txElem.dlc]; i++)
{
txElem.data[i] = i;
}
// Transmit message.
CAN_write(canHandle, &txElem);
while (1)
{
// Wait for Rx data available event.
SemaphoreP_pend(rxSemHandle, (uint32_t)SemaphoreP_WAIT_FOREVER);
// Read all available messages.
while (CAN_read(canHandle, &rxElem) == CAN_STATUS_SUCCESS)
{
// Process received message.
}
}
}

More details on usage are provided in the following subsections.

Examples

Initializing the CAN Driver

CAN_init() must be called before any other CAN APIs. This function initializes common driver resources and calls the device-specific initialization function to configure the bit rate and message RAM.

Opening the CAN Driver

After initializing the CAN driver by calling CAN_init(), the application can open a CAN instance by calling CAN_open(). This function takes an index into the CAN_config[] array, and a CAN parameters data structure. The CAN instance is specified by the index of the CAN in CAN_config[]. Calling CAN_open() a second time with the same index previously passed to CAN_open() will result in an error. You can, though, re-use the index if the instance is closed via CAN_close().

If no CAN_Params structure is passed to CAN_open(), default values are used. If the open call is successful, it returns a non-NULL value. The CAN driver APIs are non-blocking; there is no configurable return behavior.

Example initializing the CAN driver with a custom message RAM configuration to receive only filtered message IDs:

Note
CAN driver SysConfig must be setup with 'Reject Non-Matching Messages' enabled.
#define STD_MSG_FILTER_NUM 2U
#define EXT_MSG_FILTER_NUM 1U
static MCAN_StdMsgIDFilterElement stdMsgIDFilter[STD_MSG_FILTER_NUM] =
{{.sfid1 = 0x555, .sfid2 = 0x444, .sfec = CAN_FEC_STORE_RXFIFO0, .sft = CAN_FILTER_DUAL_ID},
{.sfid1 = 0x123, .sfid2 = 0U, .sfec = CAN_FEC_STORE_RXBUF, .sft = 0U}};
static MCAN_ExtMsgIDFilterElement extMsgIDFilter[EXT_MSG_FILTER_NUM] =
{{.efid1 = 0x1234578, .efid2 = 0x1234600, .efec = CAN_FEC_STORE_RXFIFO1, .eft = CAN_FILTER_RANGE}};
const CAN_MsgRAMConfig msgRAMConfig = {
.stdFilterNum = STD_MSG_FILTER_NUM,
.extFilterNum = EXT_MSG_FILTER_NUM,
.stdMsgIDFilterList = &stdMsgIDFilter[0],
.extMsgIDFilterList = &extMsgIDFilter[0],
.rxFIFONum[0] = 10U,
.rxFIFONum[1] = 2U,
.rxBufNum = 1U,
.txBufNum = 1U,
.txFIFOQNum = 5U,
.txFIFOQMode = 1U,
};
int_fast16_t status;
// Initialize driver(s).
// Open CAN driver with custom message filters.
CAN_Params_init(&canParams);
canParams.msgRAMConfig = &msgRAMConfig;
canParams.eventCbk = eventCallback;
// Setup event mask for events the application is interested in receiving
// the callback for. Typically, only the CAN_EVENT_RX_DATA_AVAIL is required.
canParams.eventMask = CAN_EVENT_RX_DATA_AVAIL;
canHandle = CAN_open(CONFIG_CAN_0, &canParams);
if (canHandle == NULL)
{
// CAN_open() failed.
while (1) {}
}

Example initializing the CAN driver with a specific raw bit rate timing:

Note
For this example, CAN driver SysConfig should be setup with 'CAN FD Operation' and 'Bit Rate Switching' enabled. The nominal and data bit rates selected in SysConfig will be ignored since raw bit rate timing parameters are provided to CAN_open().
const CAN_DataBitRateTimingRaw rawDataBitRateTiming = {
// 1Mbps with 40MHz clk and 80% sample point ((40E6 / 2) / (15 + 4 + 1) = 1E6)
// Add 1 to each programmed bit time to get functional value and +1 for for prop segment
.dbrp = 1U,
.dtSeg1 = 14U,
.dtSeg2 = 3U,
.dsjw = 3U,
.tdcOffset = 1U,
.tdcFilterWinLen = 2U
};
const CAN_BitRateTimingRaw rawBitTiming = {
// 500kbps nominal with 40MHz clk and 87.5% sample point ((40E6 / 1) / (70 + 9 + 1) = 500E3)
// Add 1 to each programmed bit time to get functional value and +1 for for prop segment
.nbrp = 0U,
.ntSeg1 = 69U,
.ntSeg2 = 8U,
.nsjw = 8U,
.dataTiming = &rawDataBitRateTiming
};
int_fast16_t status;
// Initialize driver(s).
// Open CAN with specific raw bit timing.
CAN_Params_init(&canParams);
canParams.bitTiming = &rawBitTiming;
canParams.eventCbk = eventCallback;
// Setup event mask for events the application is interested in receiving
// the callback for. Typically, only the CAN_EVENT_RX_DATA_AVAIL is required.
canParams.eventMask = CAN_EVENT_RX_DATA_AVAIL;
canHandle = CAN_open(CONFIG_CAN_0, &canParams);
if (canHandle == NULL)
{
// CAN_open() failed.
while (1) {}
}

CAN Message RAM Configuration

The default message RAM configuration is as follows:

The number of default Tx and Rx buffers varies depending on the size of the device's message RAM. Check the doxygen for the device-specific CAN implementation to find the message RAM size. If using a custom message RAM configuration, utilize the entire space by maximizing the number of Rx/Tx buffers for optimal performance.

CAN Write Behavior

CAN_write() will return immediately after the message is loaded into the CAN controller's message RAM and pending transfer; it does not wait for the CAN message to be transmitted on the bus before returning. The CAN controller will automatically handle transmission retries in the event of a failure.

CAN Read Behavior

When a message is received in Rx FIFO0/1 or a dedicated Rx buffer, the CAN driver's IRQ handler automatically reads the Rx buffer element from the CAN controller's message RAM and stores it in a ring buffer whose size is configurable in SysConfig. When CAN_read() is called, the Rx buffer element is copied from the ring buffer to the application. If the ring buffer becomes full, any new messages received will be lost until the application frees space in the ring buffer by calling CAN_read().

#include <stdint.h>
#include <stddef.h>
#include <ti/drivers/utils/StructRingBuf.h>
#include <third_party/mcan/MCAN.h>
Include dependency graph for CAN.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  CAN_MsgRAMConfig
 CAN Message RAM configuration. More...
 
struct  CAN_DataBitRateTimingRaw
 Structure defining the raw MCAN CAN FD data phase bit rate configuration. More...
 
struct  CAN_BitRateTimingRaw
 Structure defining the raw MCAN bit rate configuration. More...
 
struct  CAN_Params
 CAN Parameters. More...
 
struct  CAN_Object
 CAN Object. More...
 
struct  CAN_HWAttrs
 CAN hardware attributes. More...
 
struct  CAN_Config_
 CAN Global configuration. More...
 

Macros

#define CAN_STATUS_SUCCESS   ((int_fast16_t)0)
 Successful status code. More...
 
#define CAN_STATUS_ERROR   ((int_fast16_t)-1)
 Generic error status code. More...
 
#define CAN_STATUS_NOT_SUPPORTED   ((int_fast16_t)-2)
 Not supported status code. More...
 
#define CAN_STATUS_TX_BUF_FULL   ((int_fast16_t)-3)
 Tx buffer full status code. More...
 
#define CAN_STATUS_NO_RX_MSG_AVAIL   ((int_fast16_t)-4)
 No received message available status code. More...
 
#define CAN_EVENT_SPI_XFER_ERROR   (0x200U)
 A SPI transfer error occurred. More...
 
#define CAN_EVENT_BIT_ERR_UNCORRECTED   (0x100U)
 An uncorrected bit error occurred. More...
 
#define CAN_EVENT_RX_RING_BUFFER_FULL   (0x80U)
 The driver's Rx ring buffer was full. More...
 
#define CAN_EVENT_RX_FIFO_MSG_LOST   (0x40U)
 A message was lost for hardware Rx FIFO. More...
 
#define CAN_EVENT_ERR_PASSIVE   (0x20U)
 State change to error passive. More...
 
#define CAN_EVENT_ERR_ACTIVE   (0x10U)
 State change to error active. More...
 
#define CAN_EVENT_BUS_OFF   (0x08U)
 State change to bus off. More...
 
#define CAN_EVENT_BUS_ON   (0x04U)
 State change to bus on. More...
 
#define CAN_EVENT_TX_FINISHED   (0x02U)
 A CAN message transmission was completed. More...
 
#define CAN_EVENT_RX_DATA_AVAIL   (0x01U)
 Received CAN message data is available. More...
 
#define CAN_DLC_0B   ((uint32_t)0U)
 
#define CAN_DLC_1B   ((uint32_t)1U)
 
#define CAN_DLC_2B   ((uint32_t)2U)
 
#define CAN_DLC_3B   ((uint32_t)3U)
 
#define CAN_DLC_4B   ((uint32_t)4U)
 
#define CAN_DLC_5B   ((uint32_t)5U)
 
#define CAN_DLC_6B   ((uint32_t)6U)
 
#define CAN_DLC_7B   ((uint32_t)7U)
 
#define CAN_DLC_8B   ((uint32_t)8U)
 
#define CAN_DLC_12B   ((uint32_t)9U)
 
#define CAN_DLC_16B   ((uint32_t)10U)
 
#define CAN_DLC_20B   ((uint32_t)11U)
 
#define CAN_DLC_24B   ((uint32_t)12U)
 
#define CAN_DLC_32B   ((uint32_t)13U)
 
#define CAN_DLC_48B   ((uint32_t)14U)
 
#define CAN_DLC_64B   ((uint32_t)15U)
 
#define CAN_FEC_DISABLE_FILTER   0U
 
#define CAN_FEC_STORE_RXFIFO0   1U
 
#define CAN_FEC_STORE_RXFIFO1   2U
 
#define CAN_FEC_REJECT_ID   3U
 
#define CAN_FEC_SET_PRIO   4U
 
#define CAN_FEC_SET_PRIO_STORE_RXFIFO0   5U
 
#define CAN_FEC_SET_PRIO_STORE_RXFIFO1   6U
 
#define CAN_FEC_STORE_RXBUF   7U
 
#define CAN_FILTER_RANGE   0U
 
#define CAN_FILTER_DUAL_ID   1U
 
#define CAN_FILTER_WITH_MASK   2U
 
#define CAN_FILTER_DISABLE   3U
 

Typedefs

typedef MCAN_RxBufElement CAN_RxBufElement
 A CAN Rx buffer element struct for CAN_read(). More...
 
typedef MCAN_TxBufElement CAN_TxBufElement
 A CAN Tx buffer element struct for CAN_write() and CAN_writeBuffer(). More...
 
typedef struct CAN_Config_CAN_Handle
 A handle that is returned from a CAN_open() call. More...
 
typedef void(* CAN_EventCbk) (CAN_Handle handle, uint32_t event, uint32_t data, void *userArg)
 The definition of a callback function used by the CAN driver. More...
 
typedef struct CAN_Config_ CAN_Config
 CAN Global configuration. More...
 

Functions

void CAN_init (void)
 This function initializes the CAN module. More...
 
void CAN_Params_init (CAN_Params *params)
 Initializes the CAN_Params struct to its default values. More...
 
CAN_Handle CAN_open (uint_least8_t index, CAN_Params *params)
 Initializes a CAN driver instance and returns a handle. More...
 
void CAN_close (CAN_Handle handle)
 Closes a CAN peripheral specified by handle. More...
 
int_fast16_t CAN_read (CAN_Handle handle, CAN_RxBufElement *elem)
 Reads a received CAN message. More...
 
int_fast16_t CAN_write (CAN_Handle handle, const CAN_TxBufElement *elem)
 Sends CAN message using the Tx FIFO/Queue. More...
 
int_fast16_t CAN_writeBuffer (CAN_Handle handle, uint32_t bufIdx, const CAN_TxBufElement *elem)
 Sends CAN message using a dedicated Tx Buffer. More...
 
int_fast16_t CAN_enableLoopbackExt (CAN_Handle handle)
 Enables external loopback test mode. More...
 
int_fast16_t CAN_enableLoopbackInt (CAN_Handle handle)
 Enables internal loopback test mode. More...
 
int_fast16_t CAN_disableLoopback (CAN_Handle handle)
 Disables loopback test mode. More...
 

Variables

const CAN_Config CAN_config []
 
const uint_least8_t CAN_count
 

Macro Definition Documentation

§ CAN_DLC_0B

#define CAN_DLC_0B   ((uint32_t)0U)

§ CAN_DLC_1B

#define CAN_DLC_1B   ((uint32_t)1U)

§ CAN_DLC_2B

#define CAN_DLC_2B   ((uint32_t)2U)

§ CAN_DLC_3B

#define CAN_DLC_3B   ((uint32_t)3U)

§ CAN_DLC_4B

#define CAN_DLC_4B   ((uint32_t)4U)

§ CAN_DLC_5B

#define CAN_DLC_5B   ((uint32_t)5U)

§ CAN_DLC_6B

#define CAN_DLC_6B   ((uint32_t)6U)

§ CAN_DLC_7B

#define CAN_DLC_7B   ((uint32_t)7U)

§ CAN_DLC_8B

#define CAN_DLC_8B   ((uint32_t)8U)

§ CAN_DLC_12B

#define CAN_DLC_12B   ((uint32_t)9U)

Equivalent to CAN_DLC_8B for classic CAN

§ CAN_DLC_16B

#define CAN_DLC_16B   ((uint32_t)10U)

Equivalent to CAN_DLC_8B for classic CAN

§ CAN_DLC_20B

#define CAN_DLC_20B   ((uint32_t)11U)

Equivalent to CAN_DLC_8B for classic CAN

§ CAN_DLC_24B

#define CAN_DLC_24B   ((uint32_t)12U)

Equivalent to CAN_DLC_8B for classic CAN

§ CAN_DLC_32B

#define CAN_DLC_32B   ((uint32_t)13U)

Equivalent to CAN_DLC_8B for classic CAN

§ CAN_DLC_48B

#define CAN_DLC_48B   ((uint32_t)14U)

Equivalent to CAN_DLC_8B for classic CAN

§ CAN_DLC_64B

#define CAN_DLC_64B   ((uint32_t)15U)

Equivalent to CAN_DLC_8B for classic CAN

§ CAN_FEC_DISABLE_FILTER

#define CAN_FEC_DISABLE_FILTER   0U

§ CAN_FEC_STORE_RXFIFO0

#define CAN_FEC_STORE_RXFIFO0   1U

§ CAN_FEC_STORE_RXFIFO1

#define CAN_FEC_STORE_RXFIFO1   2U

§ CAN_FEC_REJECT_ID

#define CAN_FEC_REJECT_ID   3U

§ CAN_FEC_SET_PRIO

#define CAN_FEC_SET_PRIO   4U

§ CAN_FEC_SET_PRIO_STORE_RXFIFO0

#define CAN_FEC_SET_PRIO_STORE_RXFIFO0   5U

§ CAN_FEC_SET_PRIO_STORE_RXFIFO1

#define CAN_FEC_SET_PRIO_STORE_RXFIFO1   6U

§ CAN_FEC_STORE_RXBUF

#define CAN_FEC_STORE_RXBUF   7U

§ CAN_FILTER_RANGE

#define CAN_FILTER_RANGE   0U

§ CAN_FILTER_DUAL_ID

#define CAN_FILTER_DUAL_ID   1U

§ CAN_FILTER_WITH_MASK

#define CAN_FILTER_WITH_MASK   2U

§ CAN_FILTER_DISABLE

#define CAN_FILTER_DISABLE   3U

Typedef Documentation

§ CAN_RxBufElement

A CAN Rx buffer element struct for CAN_read().

§ CAN_TxBufElement

A CAN Tx buffer element struct for CAN_write() and CAN_writeBuffer().

§ CAN_Handle

typedef struct CAN_Config_* CAN_Handle

A handle that is returned from a CAN_open() call.

§ CAN_EventCbk

typedef void(* CAN_EventCbk) (CAN_Handle handle, uint32_t event, uint32_t data, void *userArg)

The definition of a callback function used by the CAN driver.

Note
The callback can occur in task or interrupt context.
Parameters
[in]handleA CAN_Handle returned from CAN_open
[in]eventCAN_EVENT that has occurred.
[in]dataData is event dependent:
[in]userArgA user supplied argument specified in CAN_Params.

§ CAN_Config

typedef struct CAN_Config_ CAN_Config

CAN Global configuration.

The CAN_Config structure contains a set of pointers used to characterize the CAN driver implementation.

Function Documentation

§ CAN_init()

void CAN_init ( void  )

This function initializes the CAN module.

Precondition
The CAN_config structure must exist and be persistent before this function can be called. This function must also be called before any other CAN driver APIs. This function call does not modify any peripheral registers.
See also
CAN_open

§ CAN_Params_init()

void CAN_Params_init ( CAN_Params params)

Initializes the CAN_Params struct to its default values.

Parameters
paramsAn pointer to CAN_Params structure for initialization

Defaults values are: .msgRAMConfig = NULL .bitTiming = NULL .eventCbk = NULL .eventMask = 0U .userArg = NULL

See also
CAN_open

§ CAN_open()

CAN_Handle CAN_open ( uint_least8_t  index,
CAN_Params params 
)

Initializes a CAN driver instance and returns a handle.

Initializes a CAN driver instance, configures the CAN device in normal operational mode, and returns a handle. Since the MCAN IP is highly configurable, the message RAM configuration and raw bit timings may be provided in the parameter block. Raw bit timings are required to use transmitter delay compensation. Invalid message RAM configuration or bit timing parameters will cause this function to fail.

Precondition
CAN controller has been initialized using CAN_init
Parameters
indexLogical peripheral number for the CAN indexed into the CAN_config table
paramsPointer to a parameter block, if NULL it will use default values.
Returns
A CAN_Handle on success, otherwise, NULL upon error or if it has been opened already.
Precondition
CAN_init
See also
CAN_close

§ CAN_close()

void CAN_close ( CAN_Handle  handle)

Closes a CAN peripheral specified by handle.

Precondition
CAN_open() has to be called first.
Parameters
handleA CAN_Handle returned from CAN_open
Precondition
CAN_open

§ CAN_read()

int_fast16_t CAN_read ( CAN_Handle  handle,
CAN_RxBufElement elem 
)

Reads a received CAN message.

Parameters
handleA CAN_Handle returned from CAN_open
elemA pointer to a CAN_RxBufElement.
Return values
CAN_STATUS_SUCCESSif successful.
CAN_STATUS_NO_RX_MSG_AVAILif no messages are available.
Precondition
CAN_open

§ CAN_write()

int_fast16_t CAN_write ( CAN_Handle  handle,
const CAN_TxBufElement elem 
)

Sends CAN message using the Tx FIFO/Queue.

Parameters
handleA CAN_Handle returned from CAN_open
elemA pointer to a CAN_TxBufElement.
Return values
CAN_STATUS_SUCCESSif successful.
CAN_STATUS_ERRORif no Tx FIFO/Queue is configured.
CAN_STATUS_TX_BUF_FULLif the Tx buffer is full.
Precondition
CAN_open

§ CAN_writeBuffer()

int_fast16_t CAN_writeBuffer ( CAN_Handle  handle,
uint32_t  bufIdx,
const CAN_TxBufElement elem 
)

Sends CAN message using a dedicated Tx Buffer.

Dedicated Tx buffers are intended for message transmission under complete control of the application. A custom message RAM config with dedicated Tx buffer(s) must be provided during CAN_init in order to utilize this function.

Note
The default message RAM configuration uses a Tx Queue in which the message with the highest priority in the queue is transmitted first. If a custom message RAM configuration with Tx FIFO is used, messages are transmitted out in the order they are placed in the FIFO. Adding a dedicated Tx buffer to the custom configuration and calling this function can allow a new higher priority message to be transmitted before the Tx FIFO is empty.
Parameters
handleA CAN_Handle returned from CAN_open
bufIdxIndex of the dedicated Tx buffer.
elemA pointer to a CAN_TxBufElement.
Return values
CAN_STATUS_SUCCESSif successful.
CAN_STATUS_ERRORif the Tx buffer index is invalid or the buffer already has a Tx request pending.
Precondition
CAN_open

§ CAN_enableLoopbackExt()

int_fast16_t CAN_enableLoopbackExt ( CAN_Handle  handle)

Enables external loopback test mode.

Parameters
handleA CAN_Handle returned from CAN_open
Precondition
CAN_open
See also
CAN_enableLoopbackInt
CAN_disableLoopback
Return values
CAN_STATUS_SUCCESSif successful.
CAN_STATUS_NOT_SUPPORTEDif this feature is not supported.

§ CAN_enableLoopbackInt()

int_fast16_t CAN_enableLoopbackInt ( CAN_Handle  handle)

Enables internal loopback test mode.

Parameters
handleA CAN_Handle returned from CAN_open
Precondition
CAN_open
See also
CAN_enableLoopbackExt
CAN_disableLoopback
Return values
CAN_STATUS_SUCCESSif successful.
CAN_STATUS_NOT_SUPPORTEDif this feature is not supported.

§ CAN_disableLoopback()

int_fast16_t CAN_disableLoopback ( CAN_Handle  handle)

Disables loopback test mode.

Parameters
handleA CAN_Handle returned from CAN_open
Precondition
CAN_open
CAN_enableLoopbackExt or CAN_enableLoopbackInt
Return values
CAN_STATUS_SUCCESSif successful.
CAN_STATUS_NOT_SUPPORTEDif this feature is not supported.

Variable Documentation

§ CAN_config

const CAN_Config CAN_config[]

§ CAN_count

const uint_least8_t CAN_count
© Copyright 1995-2023, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale