HardFOC Core
API reference
Loading...
Searching...
No Matches
Classes | Macros | Functions | Variables
CO_driver_hardfoc.c File Reference

Generic CANopenNode v4 driver: one CO_CANmodule over N ports. More...

#include "301/CO_driver.h"
#include <stdatomic.h>
#include <string.h>

Classes

struct  hf_co_rx_elem_t
 
struct  hf_co_rx_ring_t
 
struct  hf_co_stats_atomic_t
 
struct  hf_co_port_slot_t
 
struct  hf_co_driver_t
 

Macros

#define HF_CO_ERR_TRANSIENT   (CO_CAN_ERRTX_OVERFLOW | CO_CAN_ERRTX_PDO_LATE | CO_CAN_ERRRX_OVERFLOW)
 
#define HF_CO_ERR_LEVEL    (CO_CAN_ERRTX_WARNING | CO_CAN_ERRTX_PASSIVE | CO_CAN_ERRTX_BUS_OFF | CO_CAN_ERRRX_WARNING | CO_CAN_ERRRX_PASSIVE)
 

Functions

static void stat_inc (atomic_uint *s)
 
static hf_co_driver_t * driver_of (const CO_CANmodule_t *m)
 
static bool port_live (const hf_co_driver_t *d, uint8_t p)
 
static void lock_create (CO_CANmodule_t *m)
 
void hf_co_lock (CO_CANmodule_t *CANmodule)
 
void hf_co_unlock (CO_CANmodule_t *CANmodule)
 
static void stats_reset (hf_co_stats_atomic_t *s)
 
hf_co_driver_t * hf_co_driver_acquire (void)
 
void hf_co_driver_release (hf_co_driver_t *drv)
 
bool hf_co_driver_attach_port (hf_co_driver_t *drv, uint8_t index, const hf_co_port_ops_t *ops, void *ctx, uint8_t max_len, uint8_t flags)
 
void hf_co_driver_detach_port (hf_co_driver_t *drv, uint8_t index)
 
void hf_co_driver_set_policy (hf_co_driver_t *drv, hf_co_rx_policy_fn rx, hf_co_tx_policy_fn tx, void *ctx)
 
void hf_co_driver_set_wake (hf_co_driver_t *drv, hf_co_wake_fn wake, void *ctx)
 
static void wake_up (hf_co_driver_t *d)
 
static bool ring_push (hf_co_driver_t *drv, uint8_t port, const hf_co_frame_t *frame, bool count_overrun)
 
bool hf_co_driver_rx_push (hf_co_driver_t *drv, uint8_t port, const hf_co_frame_t *frame)
 
bool hf_co_driver_rx_offer (hf_co_driver_t *drv, uint8_t port, const hf_co_frame_t *frame)
 
void hf_co_driver_tx_done (hf_co_driver_t *drv, uint8_t port)
 
uint32_t hf_co_driver_rx_pending (const hf_co_driver_t *drv)
 
uint32_t hf_co_driver_tx_pending (const hf_co_driver_t *drv)
 
void hf_co_driver_get_stats (const hf_co_driver_t *drv, uint8_t port, hf_co_port_stats_t *out)
 
static void dispatch (hf_co_driver_t *d, CO_CANmodule_t *m, uint8_t port, const hf_co_rx_elem_t *e)
 
uint32_t hf_co_driver_rx_drain (hf_co_driver_t *drv, uint32_t max)
 
static void frame_of (const CO_CANtx_t *b, hf_co_frame_t *f)
 
static bool tx_allowed (hf_co_driver_t *d, uint8_t p, uint16_t idx, const hf_co_frame_t *f)
 
CO_ReturnError_t CO_CANsend (CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
 
static void retry_pending (hf_co_driver_t *d, CO_CANmodule_t *m)
 
void CO_CANclearPendingSyncPDOs (CO_CANmodule_t *CANmodule)
 
static uint16_t level_bits (const hf_co_port_status_t *s)
 
static uint8_t update_error_status (hf_co_driver_t *d, CO_CANmodule_t *m)
 
void CO_CANmodule_process (CO_CANmodule_t *CANmodule)
 
void CO_CANsetConfigurationMode (void *CANptr)
 
void CO_CANsetNormalMode (CO_CANmodule_t *CANmodule)
 
CO_ReturnError_t CO_CANmodule_init (CO_CANmodule_t *CANmodule, void *CANptr, CO_CANrx_t rxArray[], uint16_t rxSize, CO_CANtx_t txArray[], uint16_t txSize, uint16_t CANbitRate)
 
void CO_CANmodule_disable (CO_CANmodule_t *CANmodule)
 
CO_ReturnError_t CO_CANrxBufferInit (CO_CANmodule_t *CANmodule, uint16_t index, uint16_t ident, uint16_t mask, bool_t rtr, void *object, void(*CANrx_callback)(void *object, void *message))
 
CO_CANtx_t * CO_CANtxBufferInit (CO_CANmodule_t *CANmodule, uint16_t index, uint16_t ident, bool_t rtr, uint8_t noOfBytes, bool_t syncFlag)
 

Variables

static hf_co_driver_t s_drivers [HF_CO_MAX_DRIVERS]
 

Detailed Description

Generic CANopenNode v4 driver: one CO_CANmodule over N ports.

See hf_co_driver.h for the threading contract. In short:

SPDX-License-Identifier: GPL-3.0-or-later

Macro Definition Documentation

◆ HF_CO_ERR_LEVEL

#define HF_CO_ERR_LEVEL    (CO_CAN_ERRTX_WARNING | CO_CAN_ERRTX_PASSIVE | CO_CAN_ERRTX_BUS_OFF | CO_CAN_ERRRX_WARNING | CO_CAN_ERRRX_PASSIVE)

◆ HF_CO_ERR_TRANSIENT

#define HF_CO_ERR_TRANSIENT   (CO_CAN_ERRTX_OVERFLOW | CO_CAN_ERRTX_PDO_LATE | CO_CAN_ERRRX_OVERFLOW)

Function Documentation

◆ CO_CANclearPendingSyncPDOs()

void CO_CANclearPendingSyncPDOs ( CO_CANmodule_t *  CANmodule)

◆ CO_CANmodule_disable()

void CO_CANmodule_disable ( CO_CANmodule_t *  CANmodule)

◆ CO_CANmodule_init()

CO_ReturnError_t CO_CANmodule_init ( CO_CANmodule_t *  CANmodule,
void *  CANptr,
CO_CANrx_t  rxArray[],
uint16_t  rxSize,
CO_CANtx_t  txArray[],
uint16_t  txSize,
uint16_t  CANbitRate 
)

◆ CO_CANmodule_process()

void CO_CANmodule_process ( CO_CANmodule_t *  CANmodule)

◆ CO_CANrxBufferInit()

CO_ReturnError_t CO_CANrxBufferInit ( CO_CANmodule_t *  CANmodule,
uint16_t  index,
uint16_t  ident,
uint16_t  mask,
bool_t  rtr,
void *  object,
void(*)(void *object, void *message)  CANrx_callback 
)

◆ CO_CANsend()

CO_ReturnError_t CO_CANsend ( CO_CANmodule_t *  CANmodule,
CO_CANtx_t *  buffer 
)

◆ CO_CANsetConfigurationMode()

void CO_CANsetConfigurationMode ( void *  CANptr)

◆ CO_CANsetNormalMode()

void CO_CANsetNormalMode ( CO_CANmodule_t *  CANmodule)

◆ CO_CANtxBufferInit()

CO_CANtx_t * CO_CANtxBufferInit ( CO_CANmodule_t *  CANmodule,
uint16_t  index,
uint16_t  ident,
bool_t  rtr,
uint8_t  noOfBytes,
bool_t  syncFlag 
)

◆ dispatch()

static void dispatch ( hf_co_driver_t *  d,
CO_CANmodule_t *  m,
uint8_t  port,
const hf_co_rx_elem_t *  e 
)
static

◆ driver_of()

static hf_co_driver_t * driver_of ( const CO_CANmodule_t *  m)
inlinestatic

◆ frame_of()

static void frame_of ( const CO_CANtx_t *  b,
hf_co_frame_t *  f 
)
static

◆ hf_co_driver_acquire()

hf_co_driver_t * hf_co_driver_acquire ( void  )

Take a driver instance from the static pool (NULL when all are in use).

◆ hf_co_driver_attach_port()

bool hf_co_driver_attach_port ( hf_co_driver_t *  drv,
uint8_t  index,
const hf_co_port_ops_t *  ops,
void *  ctx,
uint8_t  max_len,
uint8_t  flags 
)

Attach a port at index.

Parameters
max_lenlargest payload the port carries (8 classic, 64 FD)
flagsHF_CO_PORT_* bits
Returns
false on a bad argument or an occupied index

◆ hf_co_driver_detach_port()

void hf_co_driver_detach_port ( hf_co_driver_t *  drv,
uint8_t  index 
)

Detach the port at index. Its pending TX frames are dropped.

◆ hf_co_driver_get_stats()

void hf_co_driver_get_stats ( const hf_co_driver_t *  drv,
uint8_t  port,
hf_co_port_stats_t *  out 
)

Copy the statistics of port.

◆ hf_co_driver_release()

void hf_co_driver_release ( hf_co_driver_t *  drv)

Return drv to the pool. Detach the ports and stop calling CO first.

◆ hf_co_driver_rx_drain()

uint32_t hf_co_driver_rx_drain ( hf_co_driver_t *  drv,
uint32_t  max 
)

Dispatch up to max queued RX frames to CANopenNode (0 = all queued). Thread context. CO_CANmodule_process() calls this; call it directly to drain earlier (for example from an RT thread before CO_process_SYNC).

Returns
frames taken from the rings

◆ hf_co_driver_rx_offer()

bool hf_co_driver_rx_offer ( hf_co_driver_t *  drv,
uint8_t  port,
const hf_co_frame_t *  frame 
)

Like hf_co_driver_rx_push(), for ports that apply back-pressure: a full ring returns false without counting an overrun, and the port offers the frame again later.

◆ hf_co_driver_rx_pending()

uint32_t hf_co_driver_rx_pending ( const hf_co_driver_t *  drv)

Frames waiting in the RX rings.

◆ hf_co_driver_rx_push()

bool hf_co_driver_rx_push ( hf_co_driver_t *  drv,
uint8_t  port,
const hf_co_frame_t *  frame 
)

Store a received frame for dispatch. ISR-safe, lock-free, single producer per port. Frames longer than HF_CO_CAN_MAX_LEN are rejected (counted).

Returns
false if the frame was dropped

◆ hf_co_driver_set_policy()

void hf_co_driver_set_policy ( hf_co_driver_t *  drv,
hf_co_rx_policy_fn  rx,
hf_co_tx_policy_fn  tx,
void *  ctx 
)

Install the router policy (either function may be NULL = allow).

◆ hf_co_driver_set_wake()

void hf_co_driver_set_wake ( hf_co_driver_t *  drv,
hf_co_wake_fn  wake,
void *  ctx 
)

Install the wake hook called after every RX push and TX-done.

◆ hf_co_driver_tx_done()

void hf_co_driver_tx_done ( hf_co_driver_t *  drv,
uint8_t  port 
)

The port has room again (TX-done). ISR-safe: marks the retry and wakes.

◆ hf_co_driver_tx_pending()

uint32_t hf_co_driver_tx_pending ( const hf_co_driver_t *  drv)

CANopenNode TX buffers still pending on at least one port.

◆ hf_co_lock()

void hf_co_lock ( CO_CANmodule_t *  CANmodule)

Take / release the CANmodule lock (recursive; never held across a blocking call).

◆ hf_co_unlock()

void hf_co_unlock ( CO_CANmodule_t *  CANmodule)

◆ level_bits()

static uint16_t level_bits ( const hf_co_port_status_t *  s)
static

◆ lock_create()

static void lock_create ( CO_CANmodule_t *  m)
static

◆ port_live()

static bool port_live ( const hf_co_driver_t *  d,
uint8_t  p 
)
static

◆ retry_pending()

static void retry_pending ( hf_co_driver_t *  d,
CO_CANmodule_t *  m 
)
static

◆ ring_push()

static bool ring_push ( hf_co_driver_t *  drv,
uint8_t  port,
const hf_co_frame_t *  frame,
bool  count_overrun 
)
static

◆ stat_inc()

static void stat_inc ( atomic_uint *  s)
inlinestatic

◆ stats_reset()

static void stats_reset ( hf_co_stats_atomic_t *  s)
static

◆ tx_allowed()

static bool tx_allowed ( hf_co_driver_t *  d,
uint8_t  p,
uint16_t  idx,
const hf_co_frame_t *  f 
)
static

◆ update_error_status()

static uint8_t update_error_status ( hf_co_driver_t *  d,
CO_CANmodule_t *  m 
)
static

◆ wake_up()

static void wake_up ( hf_co_driver_t *  d)
static

Variable Documentation

◆ s_drivers

hf_co_driver_t s_drivers[HF_CO_MAX_DRIVERS]
static