The SENSE, SERVO_SENSE and SERVO_WIN link pages at the IOmcu: the I2C bus of the two current monitors and the output encoder, its set-up and what they last read, the servo rail's channels with a move capture, and CH1's last four windows.
More...
|
|
#define | SENSE_DEFAULT_SDA 16u |
| | The set-up before anything is written: both parts off; GP16 and GP17, I2C0's SDA and SCL, outside GP0 to GP7 where the guides put outputs; 400kHz; the MATEK I2C-INA-BM's INA228 at 0x45 on its 200 uOhm shunt, ranged for 204.8A; the DAOKAI INA3221 at 0x40 on its 0.1Ohm shunts (1.638A full scale), reading CH1.
|
|
#define | SENSE_DEFAULT_SCL 17u |
|
#define | SENSE_DEFAULT_KHZ LINK_SN_KHZ_BUS |
|
#define | SENSE_DEFAULT_I228_ADDR 0x45u |
|
#define | SENSE_DEFAULT_I228_UOHM 200u |
|
#define | SENSE_DEFAULT_I228_DA 2048u |
|
#define | SENSE_DEFAULT_I3221_ADDR 0x40u |
|
#define | SENSE_DEFAULT_I3221_DMOHM 1000u |
|
#define | SENSE_DEFAULT_I3221_CH 0x01u |
|
#define | SENSE_DEFAULT_MOVE_MA 100u |
| | A capture armed before anything else is written: 100mA of movement and a 50mA band, the servo test's SERVO_TEST_MOVE_A and SERVO_TEST_BAND_A.
|
|
#define | SENSE_DEFAULT_BAND_MA 50u |
|
| void | sense_page_init (sense_page_t *p) |
| | Set a SENSE page to its start-up state.
|
| void | sense_page_defaults (uint16_t *cfg) |
| | The set-up as a page starts, into cfg (LINK_SN_CONFIG_COUNT registers): what a store record from before protocol 4.7 restores.
|
| uint32_t | sense_i3221_full_scale_ma (uint16_t shunt_dmohm) |
| | The INA3221's full scale in mA for a shunt of shunt_dmohm tenths of a milliohm: 163.8mV across it. 1638 at 0.1Ohm. 0 for no shunt.
|
| uint8_t | sense_page_write (sense_page_t *p, uint8_t off, uint8_t n, const uint16_t *in, const outputs_t *o, uint64_t taken) |
| | A SENSE write, validated whole before any of it is stored.
|
| void | sense_page_read (const sense_page_t *p, uint8_t off, uint8_t n, uint16_t *out) |
| | Read SENSE registers into out.
|
| uint8_t | sense_servo_write (sense_page_t *p, uint8_t off, uint8_t n, const uint16_t *in, const outputs_t *o) |
| | A SERVO_SENSE write.
|
| void | sense_page_bound (sense_page_t *p, uint8_t slots) |
| | Which output slots the silicon bound (bit n slot n): a capture arms only on a PWM slot that renders frames.
|
| void | sense_page_ports (sense_page_t *p, uint8_t ports) |
| | Which programming ports render a pulse while the bank drives (bit n port n): bound to the PWM generator, switched on in LINK_PG_PWM and not held by the KST port.
|
| bool | sense_page_port_gone (const sense_page_t *p) |
| | Whether the capture in CAP_ARM names a programming port that renders no pulse now: its PWM switched off, its pin gone, or the KST port on the pin.
|
| void | sense_servo_read (const sense_page_t *p, uint8_t off, uint8_t n, uint16_t *out) |
| | Read SERVO_SENSE registers into out.
|
| void | sense_win_read (const sense_page_t *p, uint8_t off, uint8_t n, uint16_t *out) |
| | A SERVO_WIN read: CH1's ring as last published, and the capture's state, count and clipped bit as SERVO_SENSE reads them at this moment. The page takes no write.
|
| bool | sense_page_step (sense_page_t *p, bool driving) |
| | One pass: a bank that is not driving ends a capture that has not finished – CAP_ARM 0, CAP_STATE idle – and returns true.
|
| void | sense_page_cmd (const sense_page_t *p, sense_cmd_t *cmd) |
| | The order for core 1 from the page: the set-up and its generation, and the capture's.
|
| void | sense_page_publish (sense_page_t *p, const sense_snap_t *s, uint16_t run_gen) |
| | What core 1 read into the read-only registers of both pages, when s was taken under the set-up in force.
|
| void | sense_page_esc (sense_page_t *p, bool v_ok, float volts, bool i_ok, float amps) |
| | The ESC's own telemetry voltage and current, each with its valid bit, into SENSE registers 23 to 25.
|
| void | sense_page_bench (sense_page_t *p, const sense_snap_t *s, uint16_t run_gen, bool driving, bench_state_t *b) |
| | The BENCH page's numbers from the INA228, over what the ESC's telemetry put in b, once the peaks of b are tracked.
|
| uint16_t | sense_page_caps (const sense_page_t *p) |
| | The capability bits the set-up makes true: LINK_CAP_PACK_SENSE while the INA228 is enabled, LINK_CAP_SERVO_SENSE while the INA3221 is – fitted as configured, not online now – or, with SENSE_MAP in force, while a channel it reads watches an output channel or a programming port (sense_map.h).
|
| bool | sense_page_enabled (const sense_page_t *p) |
| | Whether either part is enabled, and so the bus runs.
|
| uint8_t | sense_page_sda (const sense_page_t *p) |
| | The bus's pins and clock.
|
| uint8_t | sense_page_scl (const sense_page_t *p) |
| | The SCL pin of the bus.
|
| uint32_t | sense_page_hz (const sense_page_t *p) |
| | The bus clock in Hz.
|
| uint64_t | sense_page_pins (const sense_page_t *p) |
| | The pins the set-up holds, as a reservation mask; 0 while neither part is enabled.
|
| uint64_t | sense_page_held (const sense_page_t *p) |
| | Those and the pins core 1 has not let go of yet (sense_page_t.held): a bus moved or closed keeps its old pins for about 1ms.
|
| uint8_t | sense_page_slots_check (const sense_page_t *p, const uint16_t *slots) |
| | LINK_NACK_BAD_VALUE for an OUTPUTS page (slots, LINK_OS_COUNT registers) that binds a slot to a pin sense_page_held() names, the refusal the SUPPLY page gives for its own; 0 otherwise.
|
The SENSE, SERVO_SENSE and SERVO_WIN link pages at the IOmcu: the I2C bus of the two current monitors and the output encoder, its set-up and what they last read, the servo rail's channels with a move capture, and CH1's last four windows.
The registers are in link_pages.h (LINK_SN_*, LINK_SS_*, LINK_SW_*).
The set-up is refused while the bank is armed, on pins that are not one I2C block's SDA and SCL, and on pins the board, an output or the SUPPLY page already holds; the pins it takes are reserved from the outputs for as long as any part is enabled (sense_page_pins()). A capture arms only on an armed bank, on INA3221 CH1 while the INA3221 reads it, and for an output channel that is a surface on a PWM slot.
Host-tested. The page holds the contract and the checks. Reading the parts is core 1's (sense_svc.h); the page turns core 0's view of the page into the order core 1 runs (sense_page_cmd()), and what core 1 read into the read-only registers (sense_page_publish()) and into the BENCH page's numbers (sense_page_bench()). Until a snapshot of the set-up in force arrives the read-only registers read 0, FLAGS included: no bus open.
Generations. cfg_gen moves with every change of the set-up, cap_gen with every arm, every disarm and every capture a stopped bank ends. A snapshot taken under an earlier set-up publishes nothing but the pins core 1 still holds (sense_page_held()); one taken under an earlier capture order leaves the capture's registers as the page set them, so CAP_STATE never steps back from armed to the last capture's result.
SPDX-License-Identifier: MIT
What core 1 read into the read-only registers of both pages, when s was taken under the set-up in force.
SENSE: FLAGS, PRESENT, the IDs, ERRORS, the die temperature, DIAG_ALRT, the charge and energy while they are the totals of run run_gen (sense_run_t.totals_ok), 0 otherwise, and RESETS. SERVO_SENSE: each channel's last window and its flags, the window number, and the capture when s was taken under the capture order in force. SERVO_WIN: CH1's ring, a clipped sample counted at the end of the range it read. Values are rounded to their register's step and held to its range.
FLAGS bit 3 (LINK_SN_I228_CLIPPED) is set when the INA228's last window held a clipped current, or the run's peaks lack one.
- Parameters
-
| p | The page, updated in place. |
| s | The snapshot core 1 took. |
| run_gen | The generation of the current run. |
| uint8_t sense_page_write |
( |
sense_page_t * | p, |
|
|
uint8_t | off, |
|
|
uint8_t | n, |
|
|
const uint16_t * | in, |
|
|
const outputs_t * | o, |
|
|
uint64_t | taken ) |
A SENSE write, validated whole before any of it is stored.
Refused: off the page (BAD_RANGE); a read-only register (READ_ONLY); a value out of its range, a reserved register written other than 0, SDA and SCL not one I2C block's pair (link_sn_pins_pair()) whatever is enabled – but for nothing enabled with SDA or SCL 0, a panel's pins that are not set – and while a part is enabled a pin past the bank, reserved, bound to an output or in taken, the two parts on one address while both are enabled, the INA3221 enabled with no channel, an INA228 shunt and maximum ina228_calibrate() refuses (past 163.84mV across the shunt, or a full scale past INA228_FS_MA_LIMIT at the range it chooses), and any change while o is driving (BAD_VALUE). A write of the set-up in force is taken armed or not.
The INA228's calibration is the driver's, ina228_calibrate(), so the page refuses exactly the set-ups the driver could not run.
taken is the pins another page holds: the SUPPLY page's, supply_page_pins(). The bank's reservation covers them on the IOmcu as well; they are named here so the page refuses them by itself.
A set-up taken clears every register core 1 fills – FLAGS, PRESENT, the IDs, ERRORS, the readings, the SERVO_SENSE windows and a finished capture's result, CAP_ARM with it, RESETS and the SERVO_WIN ring – so nothing read under the old set-up shows until core 1 has read under the new one. The ESC's telemetry and CAP_SEQ stay.
- Parameters
-
| p | The page; updated when the write is taken. |
| off | First register of the window. |
| n | Number of registers in the window; 0 applies nothing. |
| in | The n register values to write. |
| o | The outputs model; a change while it drives is refused. |
| taken | Bit n: pin n is held by another page (supply_page_pins()). |
- Returns
- 0 when the write is taken or changes nothing; otherwise LINK_NACK_BAD_RANGE, LINK_NACK_READ_ONLY or LINK_NACK_BAD_VALUE.