Controlled Area Network (CAN)#

Hardware Interface#

Defined in namespace hal

#include <libhal/can.hpp>

class can#

Controller Area Network (CAN bus) hardware abstraction interface.

Subclassed by hal::soft::inert_can

Public Types

using id_t = uint32_t#

Can message ID type trait.

using handler = void(const message_t &p_message)#

Receive handler for can messages.

Public Functions

inline void configure(const settings &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 error hal::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(const message_t &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. See bus_on() for more details.

inline void on_receive(hal::callback<handler> p_handler)#

Set the message reception handler.

All messages received before a message handler is installed are dropped.

Parameters:

p_handler – - this handler will be called when a message has been received.

struct message_t#

A CAN message.

Public Members

id_t id#

ID of the message.

std::array<hal::byte, 8> payload = {}#

Message data contents.

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.

struct settings#

Generic settings for a can peripheral.

CAN Bit Quanta Timing Diagram of:

                          | <--- sjw ---> |
    ____    ______    __________    __________
 _/ SYNC \/  PROP  \/   PHASE1   \/   PHASE2   \_
  \______/\________/\____________/\____________/
                                  ^ Sample point

Public Members

hertz baud_rate = 100.0_kHz#

Bus clock rate in hertz.

std::uint8_t propagation_delay = 3#

Propagation Delay (1qt … 8qt)

Propagation time It is used to compensate for signal delays across the network.

std::uint8_t phase_segment1 = 3#

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 = 3#

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 = 1#

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

Public Static Attributes

static constexpr std::uint8_t sync_segment = 1#

Sync Segment (always 1qt)

Initial sync transition, the start of a CAN bit

Utilities#

Utilities for working with CAN, defined in namespace hal

#include <libhal-util/can.hpp>

group CAN_Utilities

Functions

constexpr auto operator==(const can::settings &p_lhs, const can::settings &p_rhs)#

Compares two CAN bus states.

Parameters:
  • p_lhs – A CAN bus.

  • p_rhs – A CAN bus.

Returns:

A boolean if they are the same or not.

constexpr std::optional<std::uint32_t> is_valid(const can::settings &p_settings, hertz p_operating_frequency)#

Validate configuration settings against an operating frequency.

The settings and frequency must follow the following rules:

  1. propagation_delay, phase_segment1, phase_segment2 and synchronization_jump_width must be nonzero.

  2. synchronization_jump_width must be the lesser between phase_segment1 and phase_segment2.

  3. The total bit width must be equal to or greater than 8 Tq/bit; the sum of sync_segment, propagation_delay, phase_segment1 and phase_segment2.

  4. The CAN device’s operating frequency must be at least 8 times the baud rate to give the minimum.

  5. The ratio between the CAN device’s operating frequency and the bit width must be close enough to an integer to produce a usable baud rate prescaler.

Parameters:
  • p_settings – - settings object to check

  • p_operating_frequency – - CAN device operating frequency

Returns:

std::optional<std::uint32_t> - baud rate prescaler

constexpr auto operator==(const can::message_t &p_lhs, const can::message_t &p_rhs)#

Compares two CAN message states.

Parameters:
  • p_lhs – A CAN message.

  • p_rhs – A CAN message.

Returns:

A boolean if they are the same or not.