rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
link_can.c File Reference

Maps link messages onto CAN frames and back; see link_can.h. More...

#include "link_can.h"
#include <string.h>
#include "link_pages.h"

Functions

static bool op_is_known (uint8_t op)
 Test whether an op is one the protocol defines.
static bool op_carries_payload (uint8_t op)
 A READ says how many registers it wants and carries none of them; every other op carries the registers it is about.
link_can_prio_t link_can_priority (uint8_t page, uint8_t op)
 The arbitration class a page and op belong to.
uint32_t link_can_id (link_can_prio_t prio, uint8_t op, uint8_t page, uint8_t offset, uint8_t count)
 Build a 29-bit identifier from its fields.
void link_can_id_split (uint32_t id, link_can_prio_t *prio, uint8_t *op, uint8_t *page, uint8_t *offset, uint8_t *count)
 Split an identifier back into its fields.
size_t link_can_encode (const link_msg_t *msg, link_can_frame_t *out, size_t cap)
 Render a message as one or more CAN frames.
bool link_can_decode (const link_can_frame_t *f, link_msg_t *out)
 Turn one received frame back into a message carrying up to four registers.
bool link_can_decode_counted (const link_can_frame_t *f, link_msg_t *out, uint32_t *refused)
 link_can_decode(), and a count of the frames it refuses.

Detailed Description

Maps link messages onto CAN frames and back; see link_can.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ link_can_decode()

bool link_can_decode ( const link_can_frame_t * f,
link_msg_t * out )

Turn one received frame back into a message carrying up to four registers.

False if the identifier describes something impossible: an unknown op, a count past the end of a page, a payload that disagrees with the count. The layer above accumulates the parts into the transfer it asked for, because only it knows what it asked.

Parameters
fThe received frame.
outReceives the message.
Returns
true when the frame is a valid message, else false.

◆ link_can_decode_counted()

bool link_can_decode_counted ( const link_can_frame_t * f,
link_msg_t * out,
uint32_t * refused )

link_can_decode(), and a count of the frames it refuses.

A refused frame adds 1 to refused, modulo 2^32; NULL counts nothing. A NULL frame or message is not a frame received and is not counted. The IOmcu publishes the count on the STATUS page (LINK_ST_REFUSED_LO and _HI, protocol 4.21).

Parameters
fThe received frame.
outReceives the message.
refusedRefused-frame counter; may be NULL.
Returns
true when the frame is a valid message, else false.

◆ link_can_encode()

size_t link_can_encode ( const link_msg_t * msg,
link_can_frame_t * out,
size_t cap )

Render a message as one or more CAN frames.

Returns how many were written, or 0 if the message is malformed or would not fit. A READ carries no registers and is always one frame.

Parameters
msgThe message to render.
outReceives the frames.
capNumber of frames out can hold.
Returns
The number of frames written, or 0.

◆ link_can_id()

uint32_t link_can_id ( link_can_prio_t prio,
uint8_t op,
uint8_t page,
uint8_t offset,
uint8_t count )

Build a 29-bit identifier from its fields.

Each field is masked to its width before it is shifted into place.

Parameters
prioThe arbitration class.
opThe op, a link_op_t; masked to 4 bits.
pageThe page number; masked to 8 bits.
offsetFirst register the frame carries; masked to 8 bits.
countRegisters the frame is about; masked to 6 bits, 0..63.
Returns
The 29-bit identifier.

◆ link_can_id_split()

void link_can_id_split ( uint32_t id,
link_can_prio_t * prio,
uint8_t * op,
uint8_t * page,
uint8_t * offset,
uint8_t * count )

Split an identifier back into its fields.

Any pointer may be NULL.

Parameters
idThe 29-bit identifier.
prioReceives the arbitration class; may be NULL.
opReceives the op; may be NULL.
pageReceives the page number; may be NULL.
offsetReceives the first register; may be NULL.
countReceives the register count; may be NULL.

◆ link_can_priority()

link_can_prio_t link_can_priority ( uint8_t page,
uint8_t op )

The arbitration class a page and op belong to.

Derived rather than chosen per call site, so a new page cannot be added at the wrong priority. The control, limits, failsafe and supply pages stop a bench – the supply's OFF switches off a powered load – and everything that touches them outranks everything else, their own acknowledgements included.

Parameters
pageThe page number.
opThe op, a link_op_t.
Returns
LINK_CAN_PRIO_CONTROL for the control, failsafe, limits and supply pages; LINK_CAN_PRIO_BULK for the update pages; else LINK_CAN_PRIO_NORMAL.

◆ op_carries_payload()

bool op_carries_payload ( uint8_t op)
static

A READ says how many registers it wants and carries none of them; every other op carries the registers it is about.

A property of the protocol, not of the transport.

Parameters
opThe op to test.
Returns
false for READ, true for the other ops.

◆ op_is_known()

bool op_is_known ( uint8_t op)
static

Test whether an op is one the protocol defines.

Parameters
opThe op to test.
Returns
true for READ, WRITE, DATA, ACK and NACK.