10#define APPL_BARRIER() __asm volatile ("dmb" ::: "memory")
12#define APPL_BARRIER() __sync_synchronize()
15#define QMASK (APPL_QUEUE_LEN - 1u)
16#if (APPL_QUEUE_LEN & QMASK) != 0
17#error "APPL_QUEUE_LEN must be a power of 2"
43 if (!d || len == 0u)
return;
51 const uint8_t op = d[0];
56 if (len < 11u)
return;
72 const uint32_t head =
s_head;
76 memcpy(c->
b, d, c->
len);
87 const uint32_t tail =
s_tail;
88 if (
s_head == tail)
return 0;
105 if (!
s_ever)
return UINT32_MAX;
107 if (
s > 0x80000000u)
s = 0u;
108 if (
s_down &&
s < down_floor_ms)
s = down_floor_ms;
115 for (
int tries = 0; tries < 4; ++tries) {
117 if (s0 & 1u)
continue;
122 if (
s_rc_seq == s0) { *out = v;
if (t_ms) *t_ms = t;
return 1; }
void appl_on_disconnect(void)
static volatile uint8_t s_down
static volatile uint32_t s_rc_ms
void appl_on_cmd_write(const uint8_t *d, uint16_t len, uint32_t now_ms)
static volatile uint32_t s_last_ms
static volatile uint32_t s_qdrop
uint32_t appl_silence_ms(uint32_t now_ms, uint32_t down_floor_ms)
Silence seen by the failsafe: now - last CMD frame, at least 'down_floor_ms' while the link is report...
static volatile uint32_t s_head
static volatile uint32_t s_tail
uint8_t appl_link_down(void)
GAP disconnected since then
uint8_t appl_ever(void)
1 once any CMD frame arrived
static volatile uint8_t s_rc_ever
int appl_rc_read(appl_rc_t *out, uint32_t *t_ms)
Latest RC values and their arrival time.
int appl_pop(appl_cmd_t *out)
1 if a command was taken
static appl_cmd_t s_q[APPL_QUEUE_LEN]
void appl_on_connect(void)
uint32_t appl_last_ms(void)
time of the last CMD frame
uint32_t appl_queue_dropped(void)
static volatile uint8_t s_ever
static volatile uint32_t s_rc_seq
Receive side of the ACwing Pilot link (HANDOVER_FW.md §2 and §6).
#define APPL_QUEUE_LEN
power of 2, >= 8 required by the handover
ACwing Pilot app protocol v2: identifiers and frame layouts.
static int16_t pv2_rd_i16(const uint8_t *p)
int16_t roll
-1000..1000: thr -1000 = stick bottom