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

The IOmcu's decision to arm, once a pass and at every CONTROL write. More...

#include <stdbool.h>
#include <stdint.h>
#include "heartbeat.h"
#include "link_dev.h"

Go to the source code of this file.

Data Structures

struct  safety_gate_t
 What a pass decided. More...

Functions

bool safety_gate_may_arm (const heartbeat_mon_t *beat, const link_dev_t *dev)
 Whether a write of ARM is taken: heartbeat trusted, link out of failsafe, latch clear.
bool safety_gate_supply_ok (const heartbeat_mon_t *beat, const link_dev_t *dev)
 Whether the supply's output may be on: heartbeat trusted and link out of failsafe.
safety_gate_t safety_gate_step (heartbeat_mon_t *beat, bool line_edge, link_dev_t *dev, uint16_t *control, uint32_t now_ms)
 One pass of the main loop, after the link has been served.
bool safety_gate_arm_now (bool gate_arm, uint16_t quiet_mask, bool update_holds)
 Whether the bank is armed for this pass: the pass's decision (safety_gate_t.arm, gate_arm) and two holds only the firmware can see.
uint8_t safety_gate_control_write (uint16_t *control, uint8_t off, uint8_t n, const uint16_t *in, const heartbeat_mon_t *beat, link_dev_t *dev)
 A write to the CONTROL page: link_control_write() with this end's answer to whether the bench may arm, and the CLEAR acted on.
void safety_gate_status (const heartbeat_mon_t *beat, const link_dev_t *dev, const uint16_t *control, uint16_t *state, uint16_t *faults)
 The STATUS page's state register and the two fault bits this decision owns (LINK_FAULT_LINK_SILENT, LINK_FAULT_HEARTBEAT).
bool safety_gate_line_trusted (uint16_t faults)
 The panel's reading of a STATUS fault bitmap: whether the far end trusts the heartbeat.

Detailed Description

The IOmcu's decision to arm, once a pass and at every CONTROL write.

The bank is armed while four things hold: the ARM register is set, the heartbeat is trusted, the link is out of failsafe and the arm latch is clear. The latch is what keeps a cause that took the outputs down from being undone by the ARM the panel goes on writing every 50ms:

set      at start-up (link_dev_init()), on the edge into link silence,
         on the edge where the heartbeat stops being trusted, and by
         an ARM that is refused
cleared by CLEAR on the control page, and by nothing else

The supply's ON and the STATUS page do not read the latch. They read the link failsafe and the heartbeat, so an IOmcu that has just started takes a supply ON and reports no fault.

Pure C with the clock passed in; the firmware's main loop samples the pin and acts on what is returned.

SPDX-License-Identifier: MIT

Function Documentation

◆ safety_gate_arm_now()

bool safety_gate_arm_now ( bool gate_arm,
uint16_t quiet_mask,
bool update_holds )

Whether the bank is armed for this pass: the pass's decision (safety_gate_t.arm, gate_arm) and two holds only the firmware can see.

Not while a programming port is out of PWM (quiet_mask, the ports kst_port_quiet_mask() names, non-zero): programming and an armed bank are exclusive at this end too, and the port takes no ENTER while the bank is armed.

Nor while a firmware update runs or its image waits for BUY (update_holds): the control page refuses the ARM, and this holds the bank down for an ARM written before the session began.

True only when gate_arm is true, quiet_mask is 0 and update_holds is false.

Parameters
gate_armThe pass's arm decision.
quiet_maskProgramming ports out of PWM; 0 when none.
update_holdstrue while a firmware update holds the bank down.
Returns
true when the bank may be armed.

◆ safety_gate_control_write()

uint8_t safety_gate_control_write ( uint16_t * control,
uint8_t off,
uint8_t n,
const uint16_t * in,
const heartbeat_mon_t * beat,
link_dev_t * dev )

A write to the CONTROL page: link_control_write() with this end's answer to whether the bench may arm, and the CLEAR acted on.

An ARM refused with LINK_NACK_NOT_ARMED sets the latch. A CLEAR acknowledged while the heartbeat is not yet trusted is followed by such a refusal, and the line becoming trusted a few milliseconds later would otherwise leave this end unlatched with nobody armed.

Returns 0 when the window is stored, else the NACK reason.

Parameters
controlCONTROL page, LINK_CT_COUNT registers.
offFirst register of the window.
nRegisters in the window.
inThe window's values.
beatHeartbeat monitor.
devLink device state.
Returns
0 when the window is stored, else the NACK reason.

◆ safety_gate_line_trusted()

bool safety_gate_line_trusted ( uint16_t faults)

The panel's reading of a STATUS fault bitmap: whether the far end trusts the heartbeat.

Parameters
faultsSTATUS fault bitmap.
Returns
true when the heartbeat is trusted.

◆ safety_gate_may_arm()

bool safety_gate_may_arm ( const heartbeat_mon_t * beat,
const link_dev_t * dev )

Whether a write of ARM is taken: heartbeat trusted, link out of failsafe, latch clear.

Parameters
beatHeartbeat monitor.
devLink device state.
Returns
true when an ARM is taken.

◆ safety_gate_status()

void safety_gate_status ( const heartbeat_mon_t * beat,
const link_dev_t * dev,
const uint16_t * control,
uint16_t * state,
uint16_t * faults )

The STATUS page's state register and the two fault bits this decision owns (LINK_FAULT_LINK_SILENT, LINK_FAULT_HEARTBEAT).

The latch is not reported: after a start the state is idle and both bits are clear.

Parameters
beatHeartbeat monitor.
devLink device state.
controlCONTROL page, LINK_CT_COUNT registers.
stateReceives the state register.
faultsReceives the fault bitmap.

◆ safety_gate_step()

safety_gate_t safety_gate_step ( heartbeat_mon_t * beat,
bool line_edge,
link_dev_t * dev,
uint16_t * control,
uint32_t now_ms )

One pass of the main loop, after the link has been served.

line_edge is whether the heartbeat pin changed level since the last pass. control is the CONTROL page, LINK_CT_COUNT registers: on an off edge ARM and THROTTLE are zeroed there, so a read shows what the bank holds. Both watchdogs are judged before the arm, so a pass never arms on the answer of the pass before.

Parameters
beatHeartbeat monitor.
line_edgetrue when the heartbeat pin changed level.
devLink device state.
controlCONTROL page, LINK_CT_COUNT registers.
now_msCurrent time, in milliseconds.
Returns
The decision of this pass.

◆ safety_gate_supply_ok()

bool safety_gate_supply_ok ( const heartbeat_mon_t * beat,
const link_dev_t * dev )

Whether the supply's output may be on: heartbeat trusted and link out of failsafe.

The arm latch is not part of it.

Parameters
beatHeartbeat monitor.
devLink device state.
Returns
true when the supply may be on.