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

Touch events that never arrived, and an arm that must not outlive one. More...

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

Go to the source code of this file.

Data Structures

struct  touch_seq_rx_t
 The consumer's side of one numbered stream. More...
struct  arm_watch_t
 Whether an arm stands until the render loop has seen it. More...

Functions

void touch_seq_rx_init (touch_seq_rx_t *rx)
 Nothing taken yet: the first event is expected to carry 1.
uint32_t touch_seq_take (touch_seq_rx_t *rx, uint32_t seq)
 An event numbered seq has been taken off the queue.
uint32_t touch_seq_tail (touch_seq_rx_t *rx, uint32_t published)
 The queue has been drained.
bool stop_mark_keeps (uint32_t mark, uint32_t cur, bool cur_is_event)
 Whether the mark of a STOP the control task applied stays across a loss the render loop has found.
bool arm_watch_take_ok (uint32_t loss_gen_stamp, uint32_t loss_gen_now, uint32_t lost_notice_seq, uint32_t consumed_seq)
 May an arm taken now go ahead?
void arm_watch_begin (arm_watch_t *w, uint32_t loss_gen_stamp, uint32_t drv_gaps_at_take, uint32_t arm_gen)
 An arm was applied: watch it from here.
bool arm_watch_lost (arm_watch_t *w, uint32_t loss_gen_now, uint32_t drv_gaps_now, uint32_t acked_arm_gen)
 One look, once the snapshot has been published.
void arm_watch_end (arm_watch_t *w)
 The bench disarmed for any reason: nothing is left to watch.

Detailed Description

Touch events that never arrived, and an arm that must not outlive one.

Two queues carry touch on the panel: the GT911 driver's, from its task to the control task, and the control task's, from there to the render loop on the other core. Each drops its oldest entry when the consumer is behind, and a screen that misses an event holds a press that is no longer on the glass: a hold that completes on a timer then finishes on a finger that has gone.

Each queue has one producer, and the producer numbers every event it offers, in order. The consumer sees a loss as a gap in the numbers – on the first event after it, before that event is dispatched – and, for a loss at the end of the stream with nothing after it, against the number the producer last published. Nothing is counted on one core and compared on the other, so no ordering between the two decides whether a loss is seen before a surviving event is handled.

The arm watch is the other half. An arm the render loop posted is retired by any loss from its posting until the render loop has seen the bench armed; after that a loss is answered by the screens, against an armed bench.

Pure C, no ESP-IDF (Espressif Internet-of-Things Development Framework).

SPDX-License-Identifier: MIT

Function Documentation

◆ arm_watch_begin()

void arm_watch_begin ( arm_watch_t * w,
uint32_t loss_gen_stamp,
uint32_t drv_gaps_at_take,
uint32_t arm_gen )

An arm was applied: watch it from here.

Parameters
wWatch state.
loss_gen_stampRender loop loss count at posting.
drv_gaps_at_takeControl task gap count when the arm was taken.
arm_genNumber of this arm.

◆ arm_watch_end()

void arm_watch_end ( arm_watch_t * w)

The bench disarmed for any reason: nothing is left to watch.

Parameters
wWatch state.

◆ arm_watch_lost()

bool arm_watch_lost ( arm_watch_t * w,
uint32_t loss_gen_now,
uint32_t drv_gaps_now,
uint32_t acked_arm_gen )

One look, once the snapshot has been published.

Returns true when the arm has to be undone: a loss of either kind since it was taken, before the render loop acknowledged arm_gen. A loss is looked for before the acknowledgement, so one that arrives with it still retires the arm. The watch ends either way it resolves.

Parameters
wWatch state.
loss_gen_nowRender loop loss count now.
drv_gaps_nowControl task gap count now.
acked_arm_genArm number the render loop acknowledged.
Returns
true when the arm has to be undone.

◆ arm_watch_take_ok()

bool arm_watch_take_ok ( uint32_t loss_gen_stamp,
uint32_t loss_gen_now,
uint32_t lost_notice_seq,
uint32_t consumed_seq )

May an arm taken now go ahead?

False when the render loop has dropped gestures since it posted the arm (loss_gen_now differs from loss_gen_stamp), or when a loss notice for the render loop was queued after the last event it had consumed when it posted (lost_notice_seq is later than consumed_seq; both 0 means none).

Parameters
loss_gen_stampRender loop loss count stamped on the arm.
loss_gen_nowRender loop loss count now.
lost_notice_seqSequence of the last loss notice queued; 0 for none.
consumed_seqSequence of the last event the render loop consumed; 0 for none.
Returns
true when the arm may go ahead.

◆ stop_mark_keeps()

bool stop_mark_keeps ( uint32_t mark,
uint32_t cur,
bool cur_is_event )

Whether the mark of a STOP the control task applied stays across a loss the render loop has found.

The control task applies a STOP at its press and marks the press with the number it gives it in the render loop's queue, so the router's latch of the same press does not stop the bench a second time. A loss cancels the router's gestures. A press the router has yet to take still latches after that, and needs the mark: one queued after the item that shows the loss, or the event whose arrival showed it, which is dispatched after the cancel. A press numbered before that item was taken already or is among the lost, and the cancel decides it. The numbers wrap.

Parameters
markThe marked press's number; 0 for none.
curThe number of the item that showed the loss: the notice or the event after a gap, or the last published number for a loss at the end of a drain.
cur_is_eventWhether that item is an event the router takes next.
Returns
True to keep the mark.

◆ touch_seq_rx_init()

void touch_seq_rx_init ( touch_seq_rx_t * rx)

Nothing taken yet: the first event is expected to carry 1.

Parameters
rxConsumer state to initialise.

◆ touch_seq_tail()

uint32_t touch_seq_tail ( touch_seq_rx_t * rx,
uint32_t published )

The queue has been drained.

published is the producer's last published number, read before the drain began: every event up to it had been offered by then, so any of them not taken is lost. Returns how many. Read after the drain instead, it could name an event offered during it and still in the queue.

Parameters
rxConsumer state.
publishedProducer's last published number, read before the drain.
Returns
The number of events offered and not taken.

◆ touch_seq_take()

uint32_t touch_seq_take ( touch_seq_rx_t * rx,
uint32_t seq )

An event numbered seq has been taken off the queue.

Returns how many events before it never arrived; nonzero means the consumer's record of the glass is stale and has to be dropped before this event is handled.

Parameters
rxConsumer state.
seqNumber the event carries.
Returns
The number of events that never arrived before this one.