#include <stdint.h>
#include <stdbool.h>


Go to the source code of this file.
Data Structures | |
union | can_data_t |
struct | __attribute__ |
struct | __attribute__ |
struct | __attribute__ |
struct | can_std_grp_id_t |
struct | __attribute__ |
struct | can_ext_grp_id_t |
Typedefs | |
typedef void(* | can_void_func_t) (uint32_t) |
Enumerations | |
enum | can_t { can1, can2, can_max } |
The CAN BUS type. More... | |
Functions | |
bool | CAN_init (can_t can, uint32_t baudrate_kbps, uint16_t rxq_size, uint16_t txq_size, can_void_func_t bus_off_cb, can_void_func_t data_ovr_cb) |
bool | CAN_rx (can_t can, can_msg_t *msg, uint32_t timeout_ms) |
bool | CAN_tx (can_t can, can_msg_t *msg, uint32_t timeout_ms) |
uint16_t | CAN_get_rx_dropped_count (can_t can) |
void | CAN_bypass_filter_accept_all_msgs (void) |
bool | CAN_fullcan_add_entry (can_t can, can_std_id_t id1, can_std_id_t id2) |
can_fullcan_msg_t * | CAN_fullcan_get_entry_ptr (can_std_id_t fc_id) |
bool | CAN_fullcan_read_msg_copy (can_fullcan_msg_t *fc_msg_ptr, can_fullcan_msg_t *msg_copy_ptr) |
uint8_t | CAN_fullcan_get_num_entries (void) |
bool | CAN_setup_filter (const can_std_id_t *std_id_list, uint16_t sid_cnt, const can_std_grp_id_t *std_group_id_list, uint16_t sgp_cnt, const can_ext_id_t *ext_id_list, uint16_t eid_cnt, const can_ext_grp_id_t *ext_group_id_list, uint16_t egp_cnt) |
bool | CAN_is_bus_off (can_t can) |
void | CAN_reset_bus (can_t can) |
uint16_t | CAN_get_rx_watermark (can_t can) |
RX FreeRTOS Queue watermark. More... | |
uint16_t | CAN_get_tx_watermark (can_t can) |
TX FreeRTOS Queue watermark. More... | |
uint16_t | CAN_get_tx_count (can_t can) |
Number of messages written to the CAN HW. More... | |
uint16_t | CAN_get_rx_count (can_t can) |
Number of messages successfully queued from CAN interrupt (not including dropped) More... | |
can_std_id_t | CAN_gen_sid (can_t can, uint16_t id) |
can_ext_id_t | CAN_gen_eid (can_t can, uint32_t id) |
Detailed Description
This is a simple CAN driver that optionally utilizes the FullCAN capability. FullCAN is hardware filtering of the CAN messages and the configured messages are stored directly into the CAN RAM (separate 2K RAM) without CPU intervention.
FullCAN feature summary :
- Messages go straight into dedicated RAM, SW never needs to be interrupted
- Each FullCAN entry can generate an interrupt (up to 64 messages)
- FullCAN entry can only be 11-bit NOT 29-bit type.
- Note that FullCAN is for BOTH CANs. If you wish to have separate message reads of individual CANs, you can enable non FullCAN filters because the implementation provides queues of separate CAN channels.
When the CAN bus is initialized, we initially configure it to not accept any messages until filtering or bypass option is used. For the filtering, in addition to the FullCAN, you can configure explicit 11-bit and 29-bit IDs (including groups) and only these messages will be accepted.
Note that if you send a message, and no other node acknowledges the message sent, then the CAN BUS may enter "Bus off" state due to error(s). You must correct this situation and reset the CAN BUS.
Typedef Documentation
typedef void(* can_void_func_t) (uint32_t) |
CAN function pointer type The 32-bit parameter is the value of the ICR register of CANbus
Enumeration Type Documentation
enum can_t |
Function Documentation
void CAN_bypass_filter_accept_all_msgs | ( | void | ) |
Enables CAN bypass mode to accept all messages on the bus. Either CAN filters need to be setup or this method should be called to accept CAN messages otherwise no messages will be capture at the CAN HW registers.
- Note
- The filter is for BOTH CANs
bool CAN_fullcan_add_entry | ( | can_t | can, |
can_std_id_t | id1, | ||
can_std_id_t | id2 | ||
) |
Adds two FullCAN entries to the acceptance filter and enables the FullCAN reception. The entries must be added in groups of 2. If the second entry is not needed, simply pass 0xFFFF to CAN_gen_sid() to generate a disabled entry.
- Returns
- true if successful.
- Note
- Only 11-bit IDs can use FullCAN.
- Warning
- This must be done BEFORE setting up other filters using CAN_setup_filter()
- CAN BUS should not be enabled to do this because the CAN Filter is put to OFF mode while the entry is added.
- Note
- TO DO: Enabling fc_intr bit (FullCAN interrupts) is not yet supported
can_fullcan_msg_t* CAN_fullcan_get_entry_ptr | ( | can_std_id_t | fc_id | ) |
Once all the FulLCAN entries are added, and CAN filters are setup, you can get the pointer in memory where the actual CAN message (FullCAN entry) is stored in memory.
- Parameters
-
fc_id The FullCAN entry originally passed to CAN_fullcan_add_entry()
uint8_t CAN_fullcan_get_num_entries | ( | void | ) |
- Returns
- the number of FullCAN entries being used
bool CAN_fullcan_read_msg_copy | ( | can_fullcan_msg_t * | fc_msg_ptr, |
can_fullcan_msg_t * | msg_copy_ptr | ||
) |
FullCAN entries may update at any time by the HW, so this method provides a means to safely read the copy of the FullCAN message.
- Parameters
-
msg_copy_ptr The same message returned from CAN_fullcan_get_entry_ptr() fc_msg_ptr The copy of the message you wish to read the data to
- Returns
- true if a NEW message has been captured since the last call to this method. false if HW did not receive a new message
can_ext_id_t CAN_gen_eid | ( | can_t | can, |
uint32_t | id | ||
) |
can_std_id_t CAN_gen_sid | ( | can_t | can, |
uint16_t | id | ||
) |
Generate and return the ID used to create the standard and extended id list member.
- See also
- CAN_setup_filter()
To generate a disabled slot, just pass 0xFFFF (id) as the message id, which will disable the message. This is used to generate an empty slot to make an even number of entries as required by the standard id filter.
uint16_t CAN_get_rx_count | ( | can_t | can | ) |
Number of messages successfully queued from CAN interrupt (not including dropped)
uint16_t CAN_get_rx_dropped_count | ( | can_t | can | ) |
- Returns
- The number of CAN messages dropped Messages can be dropped out either if the receive queue is too small, or if there is no consumer or task that dequeues the received messages quickly enough from the CAN_rx() API
uint16_t CAN_get_rx_watermark | ( | can_t | can | ) |
RX FreeRTOS Queue watermark.
Watermark and counter API
uint16_t CAN_get_tx_count | ( | can_t | can | ) |
Number of messages written to the CAN HW.
uint16_t CAN_get_tx_watermark | ( | can_t | can | ) |
TX FreeRTOS Queue watermark.
bool CAN_init | ( | can_t | can, |
uint32_t | baudrate_kbps, | ||
uint16_t | rxq_size, | ||
uint16_t | txq_size, | ||
can_void_func_t | bus_off_cb, | ||
can_void_func_t | data_ovr_cb | ||
) |
Initializes the CAN controller with the given baud-rate.
- Warning
- This leaves the CAN BUS DISABLED!!! The next steps are :
- Optionally, configure the FullCAN.
- See also
- CAN_fullcan_add_entry()
- Optionally, configure CAN filters.
-
CAN_setup_filter()
- If filters are not configured, and you wish to accept all messages, call CAN_bypass_filter_accept_all_msgs()
- Call CAN_reset_bus() to enable the CAN BUS
- Parameters
-
can The can bus type.
- See also
- can_t
- Parameters
-
baudrate_kbps The CAN Bus baud-rate, such as 100, 250, 500, 1000 Precise, external crystal should be used for higher than 100kbps rxq_size The size of the received messages queue txq_size The size of the transmit messages queue bus_off_cb The callback function when CAN BUS enters BUS error state data_ovr_cb The callback function when CAN BUS encounters data-overrun
- Note
- Both bus_off_cb and data_ovr_cb are optional. BUS overrun callback should be used because if user doesn't correct this, the CAN BUS will never recover once the BUS error state is entered.
- Each CAN BUS has separate receive and transmit queues
- Postcondition
- The CAN bus is initialized, and by default, no messages are accepted until CAN filter is setup, and CAN_reset_bus() is called.
About the AFMR register : B0 B1 Filter Mode | AccOff bit | AccBP bit | CAN Rx interrupt Off Mode 1 0 No messages accepted Bypass Mode X 1 All messages accepted FullCAN 0 0 HW acceptance filtering
bool CAN_is_bus_off | ( | can_t | can | ) |
CAN Bus Error and Reset API If the CAN BUS encounters error(s), it may turn off, in which case no more transmissions will take place. This must be corrected by the user.
void CAN_reset_bus | ( | can_t | can | ) |
bool CAN_rx | ( | can_t | can, |
can_msg_t * | msg, | ||
uint32_t | timeout_ms | ||
) |
Receive a message of the given CAN BUS.
- Parameters
-
can The can bus type.
- See also
- can_t
- Parameters
-
msg The CAN message timeout_ms If FreeRTOS is running, the task will block until a message arrives. Otherwise we will poll and wait this timeout to receive a message.
- Returns
- true if message was captured within the given timeout.
bool CAN_setup_filter | ( | const can_std_id_t * | std_id_list, |
uint16_t | sid_cnt, | ||
const can_std_grp_id_t * | std_group_id_list, | ||
uint16_t | sgp_cnt, | ||
const can_ext_id_t * | ext_id_list, | ||
uint16_t | eid_cnt, | ||
const can_ext_grp_id_t * | ext_group_id_list, | ||
uint16_t | egp_cnt | ||
) |
Enable CAN filter for BOTH CANs; hardware doesn't allow to enable for just ONE CAN controller.
- Parameters
-
std_id_list List of 11-bit IDs to generate an ACK for (can be NULL) sid_cnt The size of the can_std_id_t array std_group_id_list List of 11-bit ID groups to generate an ACK for (can be NULL) sgp_cnt The size of the can_std_grp_id_t array ext_id_list List of 29-bit IDs to generate an ACK for (can be NULL) eid_cnt The size of the can_ext_id_t array ext_group_id_list List of 29-bit ID groups to generate an ACK for (can be NULL) egp_cnt The size of the can_ext_grp_id_t array
- Warning
- The list must be in ASCENDING order (lowest first, then highest). The hardware carries out its search taking for granted that the IDs are ordered from lowest to highest. If filters are wrong, CAN ISR will enter a loop and your board will restart (due to watchdog).
- CAN BUS should not be enabled to do this because the CAN Filter is put to OFF mode while the entry is added.
- Note
- The CAN filter must be setup after the CAN controller(s) is initialized.
-
The size entries is limited to 2K bytes. Each entry size in bytes is :
- can_std_id_t : 2
- can_std_grp_id_t : 4
- can_ext_id_t : 4
- can_ext_grp_id_t : 8
Here is sample code that enables HW filtering of selected CAN messages. Note that some messages are for CAN2 while most are for CAN1
Standard ID list and group list need to swapped otherwise setting the wrong filter will make the CAN ISR go into a loop for no apparent reason. It looks like the filter data is motorolla big-endian format. See "configuration example 5" in CAN chapter.
bool CAN_tx | ( | can_t | can, |
can_msg_t * | msg, | ||
uint32_t | timeout_ms | ||
) |
Send a CAN message over the CAN BUS
- Parameters
-
can The can bus type.
- See also
- can_t
- Parameters
-
msg The CAN message timeout_ms If FreeRTOS is running, the task will block for timeout_ms if HW buffers and the transmit queue is full. If FreeRTOS is not running the timeout is simply, ignored, and false is returned if all three HW buffers are full.
The transmit queue is only used if all three buffers of the CAN hardware are busy, in which case, the transmission complete interrupt will later send the queued msg.
- Returns
- If CAN message was either sent, or queued, true is returned. If all the hardware buffers are full, and the queue is full, then false is returned if timeout occurs waiting for the queue to empty.