Controlled Area Network (CAN)#
Hardware Interface#
Defined in namespace hal
#include <libhal/can.hpp>
-
class can#
Controller Area Network (CAN bus) hardware abstraction interface.
This interface does not provide APIs for CAN message hardware filtering. The hardware implementation for CAN message filter varies wildly across devices and thus a common API is infeasible. So we rely on the concrete classes, the implementations of this interface to provide APIs for setting the CAN filter for the specific hardware. Hardware filtering is a best effort with the resources available. It is often not possible to filter every possible ID in hardware that your application is interested in. Thus, must expect that the CAN message receive buffer.
This interface provides a means to interrupt on every message received. If this behavior is not desirable, consider
hal::buffered_can
instead.Subclassed by hal::lpc40::can, hal::mock::can, hal::soft::inert_can, hal::stm32f1::can
Public Types
-
using id_t = std::uint32_t#
Can message ID type trait.
This was added for backwards API compatibility.
Public Functions
-
inline void configure(settings const &p_settings)#
Configure this can bus port to match the settings supplied.
- Parameters:
p_settings – - settings to apply to can driver
- Throws:
hal::operation_not_supported – - if the settings could not be achieved.
-
inline void bus_on()#
Transition the CAN device from “bus-off” to “bus-on”.
Can devices have two counters to determine system health. These two counters are the “transmit error counter” and the “receive error counter”. Transmission errors can occur when the device attempts to communicate on the bus and either does not get an acknowledge or sees an unexpected or erroneous signal on the bus during its own transmission. When transmission errors reach 255 counts, the device will go into the “bus-off” state.
In the “bus-off” state, the CAN peripheral can no longer communicate on the bus. Any calls to
send()
will throw the errorhal::operation_not_permitted
. If this occurs, this function must be called to re-enable bus communication.Warning
Calling this function when the device is already in “bus-on” will have no effect. This function is not necessary to call after creating the CAN driver as the driver should already be “bus-on” on creation.
-
inline void send(message_t const &p_message)#
Send a can message.
- Parameters:
p_message – - the message to be sent
- Throws:
hal::operation_not_permitted – - if the can device has entered the “bus-off” state. This can happen if a critical fault in the bus has occurred. A call to
bus_on()
will need to be issued to attempt to talk on the bus again. Seebus_on()
for more details.
-
struct message_t#
A standard CAN message.
Public Members
-
uint8_t length = 0#
The number of valid elements in the payload.
Can be between 0 and 8. A length value above 8 should be considered invalid and can be discarded.
-
bool is_remote_request = false#
Determines if the message is a remote request frame.
If true, then length and payload are ignored.
-
uint8_t length = 0#
-
struct settings#
Generic settings for a can peripheral.
Public Members
-
hertz baud_rate = 100.0_kHz#
Bus clock rate in hertz.
CAN Bit Quanta Timing Diagram of:
A can bus bit is separated into the segments:| <--- sjw ---> | ____ ______ __________ __________ _/ SYNC \/ PROP \/ PHASE1 \/ PHASE2 \_ \______/\________/\____________/\____________/ ^ Sample point
Sync Segment (always 1qt): Initial sync transition, the start of a CAN bit.
Propagation Delay (1qt … 8qt): Number of time quanta to compensate for signal/propagation delays across the network.
Phase Segment 1 (1qt … 8qt): phase segment 1 acts as a buffer that can be lengthened to resynchronize with the bit stream via the synchronization jump width.
Phase Segment 2 (1qt … 8qt): Occurs after the sampling point. Phase segment 2. can be shortened to resynchronize with the bit stream via the synchronization jump width.
Synchronization jump width (1qt … 4qt): This is the maximum time by which the bit sampling period may be lengthened or shortened during each cycle to adjust for oscillator mismatch between nodes. This value must be smaller than phase_segment1 and phase_segment2.
The exact value of these segments is calculated for you by the can peripheral based on the input clock to the peripheral and the desired baud rate.
A conformant can bus peripheral driver will either choose from tq starting from 25 and reducing it down to 8 or will have pre-configured timing values for each frequency it supports.
-
hertz baud_rate = 100.0_kHz#
-
using id_t = std::uint32_t#
Utilities#
Utilities for working with CAN, defined in namespace hal
#include <libhal-util/can.hpp>
- group CAN_Utilities
Functions
-
constexpr auto operator==(can_bus_divider_t const &p_lhs, can_bus_divider_t const &p_rhs)#
Compares two CAN bus settings.
- Parameters:
p_lhs – CAN bus settings
p_rhs – A CAN bus setting to compare against another
- Returns:
A boolean if they are the same or not.
-
inline std::optional<can_bus_divider_t> calculate_can_bus_divider(hertz p_operating_frequency, hertz p_target_baud_rate)#
Calculates the can bus divider values.
Preferred method of calculating the bus divider values for a can bus peripheral or device. The algorithm checks each possible time quanta (tq) width from 25tq to 8tq. The algorithm always checks starting with the greatest time quanta in order to achieve the longest bit width and sync jump value. The aim is to provide the most flexibility in the sync jump value which should help in most topologies.
- Parameters:
p_operating_frequency – - frequency of the input clock to the can bus bit timing module.
p_target_baud_rate – - the baud (bit) rate to set the can bus to.
- Returns:
std::optional<can_bus_divider_t> - the resulting dividers for the can bus peripheral. Returns std::nullopt if the target baud rate is not achievable with the provided operating frequency.
-
struct can_bus_divider_t#
- #include <can.hpp>
Generic settings for a can peripheral.
CAN Bit Quanta Timing Diagram of:
| <--- sjw ---> | ____ ______ __________ __________ _/ SYNC \/ PROP \/ PHASE1 \/ PHASE2 \_ \______/\________/\____________/\____________/ ^ Sample point
Public Members
-
std::uint8_t clock_divider#
Bus clock rate in hertz.
-
std::uint8_t propagation_delay#
Propagation Delay (1qt … 8qt)
Propagation time It is used to compensate for signal delays across the network.
-
std::uint8_t phase_segment1#
Length of Phase Segment 1 (1qt … 8qt)
Determines the bit rate, phase segment 1 acts as a buffer that can be lengthened to resynchronize with the bit stream via the synchronization_jump_width. Includes propagation delay
-
std::uint8_t phase_segment2#
Length of Phase Segment 2 (1qt … 8qt)
Determines the bit rate and is like phase segment 1 and occurs after the sampling point. Phase segment 2 can be shortened to resynchronize with the bit stream via the synchronization_jump_width.
-
std::uint8_t synchronization_jump_width#
Synchronization jump width (1qt … 4qt)
This is the maximum time by which the bit sampling period may be lengthened or shortened during each cycle to adjust for oscillator mismatch between nodes.
This value must be smaller than phase_segment1 and phase_segment2
-
std::uint8_t total_tq#
The total tq of the structure.
Public Static Attributes
-
static constexpr std::uint8_t sync_segment = 1#
Sync Segment (always 1qt)
Initial sync transition, the start of a CAN bit
-
std::uint8_t clock_divider#
-
constexpr auto operator==(can_bus_divider_t const &p_lhs, can_bus_divider_t const &p_rhs)#