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

The sensor bus. More...

#include "sense_bus.h"
#include <string.h>

Functions

void sense_bus_init (sense_bus_t *b, const sense_i2c_t *io)
 Set up a bus over a wire.
static sense_err_t settle (sense_bus_t *b, sense_err_t e)
 Every transaction that reaches the wire comes back through here: the failure count, and the stuck decision.
static bool may_send (const sense_bus_t *b)
 Whether a transaction may go out: not while stuck, except the one test after a recovery.
sense_err_t sense_bus_read (sense_bus_t *b, uint8_t addr, uint8_t reg, uint8_t *buf, size_t n)
 A register read: n bytes, most significant first, into buf.
sense_err_t sense_bus_write16 (sense_bus_t *b, uint8_t addr, uint8_t reg, uint16_t value)
 A 16-bit register write.
void sense_bus_note (sense_bus_t *b, sense_err_t e)
 A transaction made on the wire without this module – an address scan – and what it came to, for the stuck decision: a held line or a timeout counts as one of this module's would, and marks the bus stuck by the same rule.
bool sense_bus_recovery_due (const sense_bus_t *b, uint32_t now_ms)
 Whether a recovery is to be run now: the bus is stuck, and none has run since, or the last ran SENSE_RECOVER_MS or more ago without a transaction proving the bus free.
void sense_bus_recovered (sense_bus_t *b, uint32_t now_ms)
 The caller has run a recovery.
void sense_part_init (sense_part_t *p, sense_bus_t *bus, uint8_t addr)
 Set up a part record on a bus.
bool sense_part_probe_due (sense_part_t *p, uint32_t now_ms)
 Every tick, with the time: whether the part is to be probed now.
void sense_part_probed (sense_part_t *p, sense_state_t state)
 The probe's result; a part left anything but online is probed again SENSE_RETRY_MS on.
static sense_err_t count (sense_part_t *p, sense_err_t e)
 Count a part's transaction result against the failure limit.
sense_err_t sense_part_read (sense_part_t *p, uint8_t reg, uint8_t *buf, size_t n)
 A read or write of an online part, counted towards taking it offline.
sense_err_t sense_part_write16 (sense_part_t *p, uint8_t reg, uint16_t value)
 Write a 16-bit register of a part, counted towards taking it offline.
void sense_part_sample_failed (sense_part_t *p, uint8_t before)
 After a sample of two reads whose second failed: the failure run is before plus one, as if the first read had not reset it. before is the part's fails count taken ahead of the sample.
void sense_part_lost (sense_part_t *p)
 An online part that answers and no longer holds the set-up written to it: offline, and probed again SENSE_RETRY_MS on.
uint16_t sense_be16 (const uint8_t *b)
 Big-endian register contents, most significant byte first.
uint32_t sense_be24 (const uint8_t *b)
 Read a big-endian 24-bit value.
uint64_t sense_be40 (const uint8_t *b)
 Read a big-endian 40-bit value.
int32_t sense_sext32 (uint32_t v, unsigned bits)
 Two's complement by subtraction rather than a signed shift, which C leaves to the implementation for negative numbers.
int64_t sense_sext64 (uint64_t v, unsigned bits)
 The same for up to 64 bits.
int64_t sense_muldiv (int64_t a, uint32_t mul, uint64_t div)
 a × mul / div without the product overflowing, truncated towards zero.

Detailed Description

The sensor bus.

See sense_bus.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ count()

sense_err_t count ( sense_part_t * p,
sense_err_t e )
static

Count a part's transaction result against the failure limit.

Parameters
pThe part.
eThe result of the transaction.
Returns
e, unchanged.

◆ may_send()

bool may_send ( const sense_bus_t * b)
static

Whether a transaction may go out: not while stuck, except the one test after a recovery.

Parameters
bThe bus.
Returns
true when the bus is not stuck, or a recovery has run and the next transaction is the test.

◆ sense_be16()

uint16_t sense_be16 ( const uint8_t * b)

Big-endian register contents, most significant byte first.

Parameters
bTwo bytes, most significant first.
Returns
The value.

◆ sense_be24()

uint32_t sense_be24 ( const uint8_t * b)

Read a big-endian 24-bit value.

Parameters
bThree bytes, most significant first.
Returns
The value.

◆ sense_be40()

uint64_t sense_be40 ( const uint8_t * b)

Read a big-endian 40-bit value.

Parameters
bFive bytes, most significant first.
Returns
The value.

◆ sense_bus_init()

void sense_bus_init ( sense_bus_t * b,
const sense_i2c_t * io )

Set up a bus over a wire.

Parameters
bThe bus state to set up.
ioThe wire callbacks; kept, not copied.

◆ sense_bus_note()

void sense_bus_note ( sense_bus_t * b,
sense_err_t e )

A transaction made on the wire without this module – an address scan – and what it came to, for the stuck decision: a held line or a timeout counts as one of this module's would, and marks the bus stuck by the same rule.

An OK or a NACK shows the lines working and ends a run of timeouts; a NACK is a missing address and is not counted as an error. Any other code reached nothing and changes nothing.

Parameters
bThe bus.
eThe result of the transaction.

◆ sense_bus_read()

sense_err_t sense_bus_read ( sense_bus_t * b,
uint8_t addr,
uint8_t reg,
uint8_t * buf,
size_t n )

A register read: n bytes, most significant first, into buf.

Parameters
bThe bus.
addrI2C address of the part.
regRegister address.
bufReceives n bytes.
nRegister width in bytes.
Returns
SENSE_OK, a wire error, or SENSE_STUCK while the bus is stuck.

◆ sense_bus_recovered()

void sense_bus_recovered ( sense_bus_t * b,
uint32_t now_ms )

The caller has run a recovery.

The next transaction goes out as the test; on a bus that is not stuck this only counts it.

Parameters
bThe bus.
now_msThe current time, in ms.

◆ sense_bus_recovery_due()

bool sense_bus_recovery_due ( const sense_bus_t * b,
uint32_t now_ms )

Whether a recovery is to be run now: the bus is stuck, and none has run since, or the last ran SENSE_RECOVER_MS or more ago without a transaction proving the bus free.

Parameters
bThe bus.
now_msThe current time, in ms.
Returns
true when the caller should run a recovery.

◆ sense_bus_write16()

sense_err_t sense_bus_write16 ( sense_bus_t * b,
uint8_t addr,
uint8_t reg,
uint16_t value )

A 16-bit register write.

Parameters
bThe bus.
addrI2C address of the part.
regRegister address.
valueThe 16-bit value, most significant byte sent first.
Returns
SENSE_OK, a wire error, or SENSE_STUCK while the bus is stuck.

◆ sense_muldiv()

int64_t sense_muldiv ( int64_t a,
uint32_t mul,
uint64_t div )

a × mul / div without the product overflowing, truncated towards zero.

Exact while |a / div × mul| and div × mul fit 63 bits.

Parameters
aThe multiplicand.
mulThe multiplier.
divThe divisor, not zero.
Returns
a × mul / div, truncated towards zero.

◆ sense_part_init()

void sense_part_init ( sense_part_t * p,
sense_bus_t * bus,
uint8_t addr )

Set up a part record on a bus.

Parameters
pThe part record.
busThe bus the part sits on.
addrI2C address of the part.

◆ sense_part_lost()

void sense_part_lost ( sense_part_t * p)

An online part that answers and no longer holds the set-up written to it: offline, and probed again SENSE_RETRY_MS on.

Nothing for a part that is not online.

Parameters
pThe part record.

◆ sense_part_probe_due()

bool sense_part_probe_due ( sense_part_t * p,
uint32_t now_ms )

Every tick, with the time: whether the part is to be probed now.

Parameters
pThe part record.
now_msThe current time, in ms.
Returns
true when the part is due a probe.

◆ sense_part_probed()

void sense_part_probed ( sense_part_t * p,
sense_state_t state )

The probe's result; a part left anything but online is probed again SENSE_RETRY_MS on.

Parameters
pThe part record.
stateThe state the probe reached.

◆ sense_part_read()

sense_err_t sense_part_read ( sense_part_t * p,
uint8_t reg,
uint8_t * buf,
size_t n )

A read or write of an online part, counted towards taking it offline.

A part that is not online is not addressed: SENSE_OFFLINE.

Parameters
pThe part record.
regRegister address.
bufReceives n bytes.
nRegister width in bytes.
Returns
SENSE_OK, SENSE_OFFLINE, or the bus error.

◆ sense_part_sample_failed()

void sense_part_sample_failed ( sense_part_t * p,
uint8_t before )

After a sample of two reads whose second failed: the failure run is before plus one, as if the first read had not reset it. before is the part's fails count taken ahead of the sample.

A part that the failed read took offline is left as it is.

Parameters
pThe part record.
beforeThe part's fails count taken ahead of the sample.

◆ sense_part_write16()

sense_err_t sense_part_write16 ( sense_part_t * p,
uint8_t reg,
uint16_t value )

Write a 16-bit register of a part, counted towards taking it offline.

Parameters
pThe part record.
regRegister address.
valueThe 16-bit value.
Returns
SENSE_OK, SENSE_OFFLINE, or the bus error.

◆ sense_sext32()

int32_t sense_sext32 ( uint32_t v,
unsigned bits )

Two's complement by subtraction rather than a signed shift, which C leaves to the implementation for negative numbers.

The low bits of v as a two's complement number (1 to 32 bits).

Two's complement by subtraction rather than a signed shift, which C leaves to the implementation for negative numbers.

Parameters
vThe value.
bitsWidth of the field, 1 to 32.
Returns
The signed value.

◆ sense_sext64()

int64_t sense_sext64 ( uint64_t v,
unsigned bits )

The same for up to 64 bits.

Parameters
vThe value.
bitsWidth of the field, 1 to 64.
Returns
The signed value.

◆ settle()

sense_err_t settle ( sense_bus_t * b,
sense_err_t e )
static

Every transaction that reaches the wire comes back through here: the failure count, and the stuck decision.

Parameters
bThe bus.
eThe result of the transaction.
Returns
e, unchanged.