Driver API for CAN Bus Peripheral (Driver_CAN.h) More...
ARM_DRIVER_VERSION ARM_CAN_GetVersion (void) Get driver version. More...Driver API for CAN Bus Peripheral (Driver_CAN.h)
The Controller Area Network Interface Bus (CAN) implements a multi-master serial bus for connecting microcontrollers and devices, also known as nodes, to communicate with each other in applications without a host computer. CAN is a message-based protocol, designed originally for automotive applications, but meanwhile used also in many other surroundings. The complexity of the node can range from a simple I/O device up to an embedded computer with a CAN interface and sophisticated software. The node may also be a gateway allowing a standard computer to communicate over a USB or Ethernet port to the devices on a CAN network. Devices are connected to the bus through a host processor, a CAN controller, and a CAN transceiver.
The CAN Driver API allows to implement CAN Interfaces that conform to the CAN specifications available from BOSCH:
Wikipedia offers more information about the CAN Bus.
CAN 2.0B** Every CAN CMSIS-Driver supports the CAN 2.0B standard
CAN 2.0B supports:
Support for CAN FD depends on the hardware. A CMSIS-Driver that supports CAN FD has the capability ARM_CAN_CAPABILITIES data field fd_mode = 1, which can be retrieved with the function ARM_CAN_GetCapabilities.
CAN FD supports:
CAN FD does not support Remote Frame requests.
Block Diagram
The CAN Driver API defines a CAN interface for middleware components. The CAN Driver supports multiple nodes, which are able to send and receive messages, but not simultaneously.
CAN Node Schematic
CAN APIThe following header files define the Application Programming Interface (API) for the CAN interface:
The driver implementation is a typical part of the Device Family Pack (DFP) that supports the peripherals of the microcontroller family.
Driver Functions
The driver functions are published in the access struct as explained in Common Driver Functions
Example Code
The following example code shows the usage of the CAN interface.
#include <stdio.h>
#include <string.h>
#include "cmsis_os.h"
#define CAN_CONTROLLER 1 // CAN Controller number
#define _CAN_Driver_(n) Driver_CAN##n
#define CAN_Driver_(n) _CAN_Driver_(n)
#define ptrCAN (&CAN_Driver_(CAN_CONTROLLER))
uint32_t rx_obj_idx = 0xFFFFFFFFU;
uint8_t rx_data[8];
uint32_t tx_obj_idx = 0xFFFFFFFFU;
uint8_t tx_data[8];
static void Error_Handler (void) { while (1); }
void CAN_SignalUnitEvent (uint32_t event) {}
void CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event) {
if (obj_idx == rx_obj_idx) {
if (ptrCAN->MessageRead(rx_obj_idx, &rx_msg_info, rx_data, 8U) > 0U) {
}
}
}
if (obj_idx == tx_obj_idx) {
}
}
}
int main (void) {
int32_t status;
uint32_t i, num_objects;
can_cap = ptrCAN->GetCapabilities ();
status = ptrCAN->Initialize (CAN_SignalUnitEvent, CAN_SignalObjectEvent);
100000U,
for (i = 0U; i < num_objects; i++) {
can_obj_cap = ptrCAN->ObjectGetCapabilities (i);
if((rx_obj_idx == 0xFFFFFFFFU) && (can_obj_cap.
rx== 1U)) { rx_obj_idx = i; }
else if((tx_obj_idx == 0xFFFFFFFFU) && (can_obj_cap.
tx== 1U)) { tx_obj_idx = i;
break; }
}
if ((rx_obj_idx == 0xFFFFFFFFU) || (tx_obj_idx == 0xFFFFFFFFU)) { Error_Handler(); }
tx_data[0] = 0xFFU;
while (1) {
tx_data[0]++;
status = ptrCAN->MessageSend(tx_obj_idx, &tx_msg_info, tx_data, 1U);
if (status != 1U) { Error_Handler(); }
for (i = 0U; i < 1000000U; i++) { __nop(); }
}
}
CAN Message ObjectsThe CMSIS-Driver for the CAN interface provides multiple CAN message objects, which can be seen as individual communication channels. The number of available CAN message objects depends on the CAN peripheral. The function ARM_CAN_GetCapabilities returns the maximum number of available CAN message objects. The number is encoded in the structure ARM_CAN_CAPABILITIES in the data field num_objects. CAN message objects are addressed with the functions listed below, whereby the parameter obj_idx addresses an individual object. The valid range for obj_idx is [0 .. (num_objects - 1)].
Each CAN message object may have different capabilities. Before using a CAN message object, call the function ARM_CAN_ObjectGetCapabilities to verify the available features.
CAN Message FilteringThe CMSIS-Driver for the CAN interface supports ID filtering for the receiving message objects. The receiving CAN node examines the identifier to decide if it was relevant. This filtering is done by the CAN peripheral according the settings configured with the function ARM_CAN_ObjectSetFilter.
The function ARM_CAN_ObjectGetCapabilities retrieves the filter capabilities of the CAN message objects stored in ARM_CAN_OBJ_CAPABILITIES.
CAN message filtering using an exact ID
Example: accept in message object #1 only frames with extended ID = 0x1567.
Example: accept in message object #2 frames with extended ID = 0x3167 and extended ID = 0x42123.
CAN message filtering using a range ID
Example: accept in message object #3 only frames with extended ID >= 0x1567 and extended ID <= 0x1577.
CAN message filtering using a mask ID
Using the function ARM_CAN_ObjectSetFilter with control = ARM_CAN_FILTER_ID_MASKABLE_ADD allows to specify with arg a mask value.
Example: accept in message object #0 only frames with extended IDs 0x1560 to 0x156F.
Example: accept in message object #2 only frames with extended IDs 0x35603, 0x35613, 0x35623, and 0x35633.
Example: accept any message in object #4 regardless of the ID.
Remote FrameIn general, data transmission is performed on an autonomous basis with the data source node sending out Data Frames.
However, sending a Remote Frame allows a destination node to request the data from the source node. The examples below shows the data exchange using a Remote Transmission Request (RTR).
Example for automatic Data Message response on RTR
For automatic data message response on an RTR, the object is configured with the function ARM_CAN_ObjectConfigure obj_cfg = ARM_CAN_OBJ_RX_RTR_TX_DATA.
In this case, the function ARM_CAN_MessageSend sets a data message that is transmitted when an RTR with a matching CAN ID is received. If ARM_CAN_MessageSend was not called before the RTR is received, the response is hardware dependent (either last data message is repeated or no data message is sent until ARM_CAN_MessageSend is called).
After data transmission is completed, the driver calls a callback function ARM_CAN_SignalObjectEvent with event = ARM_CAN_EVENT_SEND_COMPLETE and the related obj_idx.
Example:
data_buf[0] = '1'; data_buf[1] = '2';
data_buf[2] = '3'; data_buf[3] = '4';
data_buf[4] = '5'; data_buf[5] = '6';
data_buf[6] = '7'; data_buf[7] = '8';
ptrCAN->MessageSend(0, &tx_msg_info, data_buf, 8);
Example for automatic Data Message reception using RTR
For automatic data message reception on an RTR, the object is configured with the function ARM_CAN_ObjectConfigure obj_cfg = ARM_CAN_OBJ_TX_RTR_RX_DATA.
The receiver or consumer requests data with transmission of an RTR with the ARM_CAN_MessageSend. This RTR requests from the transmitter or producer to send the data message. Once the data message is received, the driver calls a callback function ARM_CAN_SignalObjectEvent with event = ARM_CAN_EVENT_RECEIVE and the related obj_idx. The received data message can then be read with the function ARM_CAN_MessageRead.
Example:
ptrCAN->MesageSend(0, &tx_msg_info, 0, 0);
ptrCAN->MessageRead(0, &rx_msg_info, data_buf, 8);
Access structure of the CAN Driver.
The functions of the CAN are accessed by function pointers exposed by this structure. Refer to Common Driver Functions for overview information.
Each instance of a CAN provides such an access structure. The instance is identified by a postfix number in the symbol name of the access structure, for example:
A configuration setting in the middleware allows you to connect the middleware to a specific driver instance Driver_CANn.
Data Fields ARM_DRIVER_VERSION(* GetVersion )(void) Pointer to ARM_CAN_GetVersion : Get driver version. More...Pointer to ARM_CAN_GetClock : Retrieve CAN base clock frequency.
int32_t(* Control)(uint32_t control, uint32_t arg)Pointer to ARM_CAN_Control : Control CAN interface.
struct ARM_CAN_CAPABILITIESCAN Device Driver Capabilities.
A CAN driver can be implemented with different capabilities encoded in the data fields of this structure.
Returned by:
CAN Status.
Structure with information about the status of the CAN unit state and errors. The data fields encode the unit bus state, last error code, transmitter error count, and receiver error count.
Returned by:
Data Fields uint32_t unit_state: 4 Unit bus state. uint32_t last_error_code: 4 Last error code. uint32_t tx_error_count: 8 Transmitter error count. uint32_t rx_error_count: 8 Receiver error count. uint32_t reserved: 8CAN Message Information.
Structure with information about the CAN message.
In CAN mode, the following ARM_CAN_MSG_INFO data fields are ignored: edl, brs, esi.
In CAN FD mode, the following ARM_CAN_MSG_INFO data field is ignored: rtr.
Parameter for:
CAN Object Capabilities.
A CAN object can be implemented with different capabilities encoded in the data fields of this structure.
Returned by:
Get driver version.
The function ARM_CAN_GetVersion returns version information of the driver implementation in ARM_DRIVER_VERSION
Example:
void setup_can (void) {
drv_info = &Driver_CAN0;
if(version.
api< 0x10A) {
return;
}
}
Get driver capabilities.
The function ARM_CAN_GetCapabilities returns information about the capabilities in this driver implementation. The data fields of the structure ARM_CAN_CAPABILITIES encode various capabilities.
Example:
void read_capabilities (void) {
drv_info = &Driver_CAN0;
}
Initialize CAN interface and register signal (callback) functions.
The function initializes the CAN interface.
The function performs the following operations:
The parameter cb_unit_event is a pointer to the ARM_CAN_SignalUnitEvent callback function; use a NULL pointer when no callback signals are required.
The parameter cb_object_event is a pointer to the ARM_CAN_SignalObjectEvent callback function; use a NULL pointer when no callback signals are required.
Example:
De-initialize CAN interface.
The function ARM_CAN_Uninitialize de-initializes the resources of the CAN interface. It is called to release the software resources used by the interface such as deallocate any RTOS objects, dynamic memory and pin de-configuration.
Control CAN interface power.
The function ARM_CAN_PowerControl controls the power modes of the CAN interface.
The parameter state can be:
Retrieve CAN base clock frequency.
The function ARM_CAN_GetClock returns the CAN base clock frequency in [Hz]. This value may be used to validate the bitrate for the function ARM_CAN_SetBitrate.
Example:
Set bitrate for CAN interface.
The function ARM_CAN_SetBitrate sets the CAN communication bit rate.
The parameter select selects the bit rate affected by function call as defined in ARM_CAN_BITRATE_SELECT and listed in the table below.
The parameter bitrate is the bit rate for the selected CAN mode.
The parameter bit_segments is used to setup the time quanta for sampling (see picture below). The values listed in the table below are ORed and specify the various sampling segments. The CAN controller samples each bit on the bus at the Sample Point.
Parameter bit_segments Bit for select = ARM_CAN_BITRATE_NOMINALThe picture shows a Nominal Bit Time with 10 time quanta.
CAN Bit Timing
The time quanta (N) per bit is:
N = 1 + PROP_SEG + PHASE_SEG1 + PHASE_SEG2;
The driver uses this value and the CAN clock to calculate a suitable prescaler value (P). If the driver cannot achieve the requested bitrate it returns with ARM_CAN_INVALID_BITRATE. The formula for the bitrate is:
bitrate = (CAN_Clock / P) / N;
Example:
In this example, N = 8 and with a CAN_Clock = 8MHz the prescaler (P) is calculated by the driver to 8.
Set operating mode for CAN interface.
The function ARM_CAN_SetMode sets the CAN bus communication mode using the parameter mode.
The table lists the values for mode.
Parameter mode Bus Communication Mode supported when ARM_CAN_OBJ_CAPABILITIES data field ARM_CAN_MODE_INITIALIZATION Initialization mode; Used to setup communication parameters for the reception objects and global filtering, while peripheral is not active on the bus. Refer to CAN Message Filtering for details. always supported ARM_CAN_MODE_NORMAL Normal operation mode. Used when peripheral is in active mode to receive, transmit, and acknowledge messages on the bus. Depending on the current unit state, it can generate error or overload messages. Verify the unit state with ARM_CAN_GetStatus. always supported ARM_CAN_MODE_RESTRICTED Restricted operation mode. Used for monitoring the bus communication non-intrusively without transmitting. restricted_mode = 1 ARM_CAN_MODE_MONITOR Bus monitoring mode. monitor_mode = 1 ARM_CAN_MODE_LOOPBACK_INTERNAL Test mode; loopback of CAN transmission to its receiver. No transmission visible on CAN bus. internal_loopback = 1 ARM_CAN_MODE_LOOPBACK_EXTERNAL Test mode; loopback of CAN transmission to its receiver. Transmission is visible on CAN bus. external_loopback = 1Add or remove filter for message reception.
The function ARM_CAN_ObjectSetFilter sets or removes the filter for message reception. Refer to CAN Message Filtering for details on filtering.
The parameter obj_idx is the message object index.
The parameter operation is the operation on the filter as listed in the table below and which are defined in the structure ARM_CAN_FILTER_OPERATION.
The parameter id is the identifier of the filter or defines the start of the filter range (depends on the filter operation).
The parameter arg is the mask of the filter or defines the end of the filter range (depends on the filter operation).
Configure object.
The function ARM_CAN_ObjectConfigure configures the message object, which can be a mailbox or FIFO. Refer to CAN Message Filtering for details.
The parameter obj_idx specifies the message object index.
The parameter obj_cfg configures the object with values as shown in the following table.
When the object is deactivated, it is not used for data communication.
Send message on CAN bus.
The function ARM_CAN_MessageSend sends a CAN message on the CAN bus, or sets data message that will be automatically returned upon RTR reception with matching CAN ID.
Only one message can be sent with a call to this function (for CAN up to 8 bytes; for CAN FD up to 64 bytes of data). A message transmission can be terminated with a call to the function ARM_CAN_Control with control = ARM_CAN_ABORT_MESSAGE_SEND.
The parameter obj_idx specifies the message object index.
The parameter msg_info is a pointer to the structure ARM_CAN_MSG_INFO, which contains the following relevant data fields for sending message:
The parameter data is a pointer to the data buffer.
The parameter size is the number of data bytes to send.
The function returns the number of bytes accepted to be sent or ARM_DRIVER_ERROR_BUSY if the hardware is not ready to accept a new message for transmission.
When the message is sent, the callback function ARM_CAN_SignalObjectEvent is called signalling ARM_CAN_EVENT_SEND_COMPLETE on specified object.
Example:
data_buf[0] = '1'; data_buf[1] = '2';
data_buf[2] = '3'; data_buf[3] = '4';
data_buf[4] = '5'; data_buf[5] = '6';
data_buf[6] = '7'; data_buf[7] = '8';
status = ptrCAN->MesageSend(0, &tx_msg_info, data_buf, 8);
int32_t ARM_CAN_MessageRead ( uint32_t obj_idx, ARM_CAN_MSG_INFO * msg_info, uint8_t * data, uint8_t size )Read message received on CAN bus.
The function ARM_CAN_MessageRead reads the message received on the CAN bus, if obj_idx was configured for reception or for automatic Data Message reception using RTR and the callback function ARM_CAN_SignalObjectEvent was called signalling ARM_CAN_EVENT_RECEIVE. If the message was overrun by another received message, then the callback function ARM_CAN_SignalObjectEvent will be called signalling ARM_CAN_EVENT_RECEIVE_OVERRUN.
The function can read a maximum of 8 data bytes for CAN and 64 bytes for CAN FD.
The parameter obj_idx specifies the message object index.
The parameter msg_info is a pointer to the CAN information structure.
The parameter data is a pointer to the data buffer for reading data.
The parameter size is data buffer size in bytes and indicates the maximum number of bytes that can be read.
The function returns the number of read data in bytes or the Status Error Codes.
All data fields of the structure ARM_CAN_MSG_INFO are updated as described below:
Message reception can be disabled by de-configuring the receive object with the function ARM_CAN_ObjectConfigure.
int32_t ARM_CAN_Control ( uint32_t control, uint32_t arg )Control CAN interface.
The function ARM_CAN_Control controls the CAN interface settings and executes various operations.
The parameter control specifies various operations that are listed in the table below.
The parameters arg provides, depending on the control value, additional information or set values.
Verify the CAN interface capabilities with ARM_CAN_GetCapabilities.
Get CAN status.
The function ARM_CAN_GetStatus retrieves runtime information on CAN bus and CAN unit state.
The following defines give information about the current unit involvement in bus communication:
The following defines are error codes of the last error that happened on the bus:
void ARM_CAN_SignalUnitEvent ( uint32_t event )Signal CAN unit event.
The function ARM_CAN_SignalUnitEvent is a callback function registered by the function ARM_CAN_Initialize.
The parameter event indicates unit event that occurred during driver operation.
The following callback notifications are generated:
Signal CAN object event.
The function ARM_CAN_SignalObjectEvent is a callback function registered by the function ARM_CAN_Initialize and signals a CAN message object event.
The parameter obj_idx is the index of the message object.
The parameter event indicates object event that occurred during driver operation.
The following events can be generated:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4