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

Which meter measures the servo rail: the INA3221's CH1, the PD mini (the WeAct PD Power Mini supply) or the panel's model. More...

#include <stdbool.h>
#include <stdint.h>
#include "sense_link.h"

Go to the source code of this file.

Data Structures

struct  servo_source_t
 The state of which meter measures the servo rail. More...

Macros

#define SERVO_SOURCE_FRESH_MS   200u
 A SENSE read, and the newest window's number, count for this long.
#define SERVO_SOURCE_SETTLE_MS   1000u
 Conditions 1 to 6 hold this long before the INA3221 is the meter.
#define SERVO_SOURCE_EVENT_GAP_MS   5000u
 One event has the alert band this long before the next is handed out.

Enumerations

enum  servo_source_id_t { SERVO_SOURCE_PDMINI = 0 , SERVO_SOURCE_INA3221 = 1 , SERVO_SOURCE_MODEL = 2 }
 The servo rail's meter. More...
enum  servo_source_why_t {
  SERVO_SOURCE_WHY_NONE = 0 , SERVO_SOURCE_WHY_NO_LINK , SERVO_SOURCE_WHY_OFF , SERVO_SOURCE_WHY_OLD ,
  SERVO_SOURCE_WHY_NOT_HELD , SERVO_SOURCE_WHY_SILENT , SERVO_SOURCE_WHY_NO_WINDOW , SERVO_SOURCE_WHY_RESET ,
  SERVO_SOURCE_WHY_SETTLING
}
 Why the INA3221 is not the meter: the first condition that fails. More...
enum  { SERVO_SOURCE_EV_OLD = 0x01 , SERVO_SOURCE_EV_RESET = 0x02 }
 Things the caller tells the operator about, each once. More...

Functions

void servo_source_init (servo_source_t *s)
 The meter is the model until a step says otherwise.
servo_source_id_t servo_source_step (servo_source_t *s, uint32_t now_ms, bool link_up, uint16_t minor, const sense_link_meter_t *m)
 One poll: the conditions judged at now_ms from link_up, the IOmcu's protocol minor minor and m, sense_link_meter()'s answer of the same poll.
servo_source_id_t servo_source_id (const servo_source_t *s)
 The meter as of the last step.
uint32_t servo_source_changes (const servo_source_t *s)
 How many times the meter has changed since servo_source_init(), modulo 2^32.
servo_source_why_t servo_source_why (const servo_source_t *s)
 Why the INA3221 is not the meter, as of the last step.
servo_source_why_t servo_source_dropped (const servo_source_t *s, uint32_t *at)
 Why the INA3221 last stopped being the meter: SERVO_SOURCE_WHY_RESET when its reset count moved in that step, else the condition that failed in it, or SERVO_SOURCE_WHY_NO_LINK.
uint32_t servo_source_event (servo_source_t *s, uint32_t now_ms)
 One event for the alert band, the older IOmcu before the reset, cleared; 0 while none waits or while the last one handed out is younger than SERVO_SOURCE_EVENT_GAP_MS at now_ms.
void servo_source_event_back (servo_source_t *s, uint32_t ev)
 Put back an event servo_source_event() handed out that never reached the band, so it is handed out again after the gap.

Detailed Description

Which meter measures the servo rail: the INA3221's CH1, the PD mini (the WeAct PD Power Mini supply) or the panel's model.

One answer, decided here once per poll by the control task. A consumer reads the answer and never tests the conditions itself.

The INA3221 is the meter while all of these hold:

  1. SETUP INTERFACES has the INA3221 on with CH1 among its channels;
  2. the IOmcu speaks protocol 4.11 or newer, the one with the window ring (SERVO_WIN) and SENSE's RESETS;
  3. the IOmcu's SENSE page holds that set-up: registers 0 to 11 equal, no write owed, no frame refused;
  4. the last SENSE read is younger than SERVO_SOURCE_FRESH_MS and its FLAGS have the INA3221 ONLINE and ID_OK and the bus not stuck;
  5. SERVO_WIN's newest CH1 window holds current samples and its number moved less than SERVO_SOURCE_FRESH_MS ago, four windows;
  6. the INA3221's reset count has not moved since the step before;
  7. conditions 1 to 6 have held for SERVO_SOURCE_SETTLE_MS without a break, 20 windows.

The meter drops to the PD mini in the first step in which one of 1 to 6 fails, and returns SERVO_SOURCE_SETTLE_MS after they all hold again: a part on a loose wire does not change the meter 20 times a second. With no IOmcu answering the meter is the model.

A clipped reading and a negative current are readings: neither is a condition here.

Why the INA3221 last stopped being the meter is kept with the change count it happened at (servo_source_dropped()), so a consumer that saw the meter change after the step that changed it still learns the condition: a reset shows as a condition for one step only. A reset count that moved in that step is the reason kept, whichever condition failed first: the IOmcu takes a part it found reset offline in the read that counts the reset.

Two things are said to the operator, each once (servo_source_event()): the INA3221 is on with CH1 and the IOmcu has SENSE and is older than 4.11, at the link-up and when the part is switched on while such an IOmcu answers; and the INA3221's reset count moved.

Pure C, no link and no clock of its own. Control task only.

SPDX-License-Identifier: MIT

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Things the caller tells the operator about, each once.

Enumerator
SERVO_SOURCE_EV_OLD 

The INA3221 is on with CH1 and the IOmcu is older than 4.11: the PD mini is the meter.

SERVO_SOURCE_EV_RESET 

The INA3221 reset itself: its reset count moved.

◆ servo_source_id_t

The servo rail's meter.

Enumerator
SERVO_SOURCE_MODEL 

no IOmcu answers

◆ servo_source_why_t

Why the INA3221 is not the meter: the first condition that fails.

Enumerator
SERVO_SOURCE_WHY_NONE 

it is the meter

SERVO_SOURCE_WHY_NO_LINK 

no IOmcu answers

SERVO_SOURCE_WHY_OFF 

1: not on with CH1 in SETUP

SERVO_SOURCE_WHY_OLD 

2: the IOmcu is older than 4.11

SERVO_SOURCE_WHY_NOT_HELD 

3: the page does not hold the set-up

SERVO_SOURCE_WHY_SILENT 

4: no fresh SENSE read with the part online, identified, the bus free

SERVO_SOURCE_WHY_NO_WINDOW 

5: no fresh window with current

SERVO_SOURCE_WHY_RESET 

6: the reset count moved

SERVO_SOURCE_WHY_SETTLING 

7: 1 to 6 hold, not yet for long enough

Function Documentation

◆ servo_source_changes()

uint32_t servo_source_changes ( const servo_source_t * s)

How many times the meter has changed since servo_source_init(), modulo 2^32.

It orders two answers taken at different polls: of two counts the one that is ahead by less than 2^31 is the later.

Parameters
sThe source state.
Returns
The change count, modulo 2^32.

◆ servo_source_dropped()

servo_source_why_t servo_source_dropped ( const servo_source_t * s,
uint32_t * at )

Why the INA3221 last stopped being the meter: SERVO_SOURCE_WHY_RESET when its reset count moved in that step, else the condition that failed in it, or SERVO_SOURCE_WHY_NO_LINK.

at, when not NULL, takes servo_source_changes() as that step left it. SERVO_SOURCE_WHY_NONE while the INA3221 has not stopped being the meter since servo_source_init().

Parameters
sThe source state.
atReceives the change count of that step, or NULL.
Returns
The reason the INA3221 last stopped being the meter, or SERVO_SOURCE_WHY_NONE.

◆ servo_source_event()

uint32_t servo_source_event ( servo_source_t * s,
uint32_t now_ms )

One event for the alert band, the older IOmcu before the reset, cleared; 0 while none waits or while the last one handed out is younger than SERVO_SOURCE_EVENT_GAP_MS at now_ms.

Parameters
sThe source state.
now_msThe time, in ms.
Returns
The event for the alert band, or 0 for none.

◆ servo_source_event_back()

void servo_source_event_back ( servo_source_t * s,
uint32_t ev )

Put back an event servo_source_event() handed out that never reached the band, so it is handed out again after the gap.

Not once the link has gone: both events are about the IOmcu that answered.

Parameters
sThe source state.
evThe event to put back.

◆ servo_source_id()

servo_source_id_t servo_source_id ( const servo_source_t * s)

The meter as of the last step.

Parameters
sThe source state.
Returns
The meter as of the last step.

◆ servo_source_init()

void servo_source_init ( servo_source_t * s)

The meter is the model until a step says otherwise.

Parameters
sThe source state.

◆ servo_source_step()

servo_source_id_t servo_source_step ( servo_source_t * s,
uint32_t now_ms,
bool link_up,
uint16_t minor,
const sense_link_meter_t * m )

One poll: the conditions judged at now_ms from link_up, the IOmcu's protocol minor minor and m, sense_link_meter()'s answer of the same poll.

Returns the meter.

Parameters
sThe source state.
now_msThe time, in ms.
link_uptrue while the IOmcu link is up.
minorThe IOmcu's protocol minor version.
mThe sense_link_meter() answer of this poll.
Returns
The meter, a servo_source_id_t.

◆ servo_source_why()

servo_source_why_t servo_source_why ( const servo_source_t * s)

Why the INA3221 is not the meter, as of the last step.

Parameters
sThe source state.
Returns
Why the INA3221 is not the meter, as of the last step.