SDK for TESAIoT Dev Kit
API reference & tutorials (ModusToolbox)
Loading...
Searching...
No Matches
radio_scheduler.h
Go to the documentation of this file.
1/*
2 * File: radio_scheduler.h
3 *
4 * Description: Single-radio scheduler for the BentoClaw Playground variant.
5 * The CYW55513 silicon can run BLE + Wi-Fi concurrently via its
6 * on-die COEX time-division multiplexer, but the Playground
7 * firmware deliberately does not enable COEX so MicroPython
8 * keeps its 64 KB GC heap free of WHD's transient buffers.
9 * Instead, this scheduler arbitrates the radio between two
10 * mutually-exclusive modes and exposes a verb-level API for the
11 * Desktop Buddy + LCD to switch between them.
12 *
13 * Mode transitions:
14 * BLE_ADV → user/desktop requests Wi-Fi
15 * WIFI_CONNECTING → cy_wcm_connect_ap in flight
16 * WIFI_ACTIVE → joined; BLE adv off, stack still resident
17 * WIFI_FAILED → 3 consecutive connect failures
18 * → fall back to BLE_ADV automatically
19 *
20 * Persistence: the last requested mode + presence of saved
21 * Wi-Fi credentials drive the boot decision so a reset on a
22 * configured board comes back to Wi-Fi without user action.
23 */
24
25#pragma once
26
27#include <stdbool.h>
28#include <stdint.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34typedef enum {
35 RADIO_MODE_UNKNOWN = 0, /* pre-init */
36 RADIO_MODE_BLE_ADV, /* BLE advertising, Wi-Fi off */
37 RADIO_MODE_BLE_PAIRED, /* BLE link up (NUS connected) */
38 RADIO_MODE_SWITCHING_TO_WIFI, /* Wi-Fi connect in flight */
39 RADIO_MODE_WIFI_ACTIVE, /* Wi-Fi joined, BLE stack resident but adv off */
40 RADIO_MODE_SWITCHING_TO_BLE, /* Wi-Fi disconnect in flight, BLE re-arming */
41 RADIO_MODE_WIFI_FAILED, /* fallback transient — re-arms BLE next */
43
44typedef enum {
45 /* User-locked default: try Wi-Fi if creds saved, else BLE. */
47 /* User forced BLE permanently — survives reboot. */
49 /* User forced Wi-Fi — boot path tries Wi-Fi even if connect previously
50 * failed (escape from the 3-fail-fallback loop on a router move). */
53
54/* Explicit struct tag so headers that want a callback signature can
55 * forward-declare `struct radio_status_s` without pulling this whole
56 * header (nus_commands.h does exactly that). */
57typedef struct radio_status_s {
59 /* Optional fields, populated when relevant. NULL/zero when not. */
60 const char *ssid; /* current Wi-Fi SSID (UTF-8, NUL-terminated) */
61 uint32_t ipv4; /* current IPv4 in network byte order, 0 if none */
62 bool ble_paired; /* NUS link up */
65
66/* Persisted across the radio_set_boot_mode call — written to LittleFS
67 * at /.radio_boot_mode (a one-byte file). */
70
71typedef struct {
72 /* Persistence hooks — supplied by the project so this library does not
73 * need to link the MicroPython VFS. Pass NULL to disable persistence
74 * (boot will always default to AUTO). */
78
79/* Initialise the scheduler. Honours saved boot_mode + presence of saved
80 * Wi-Fi creds to pick the initial mode:
81 *
82 * boot_mode = FORCE_BLE → BLE_ADV
83 * boot_mode = FORCE_WIFI + creds → WIFI_CONNECTING
84 * boot_mode = AUTO + creds → WIFI_CONNECTING
85 * boot_mode = AUTO + no creds → BLE_ADV
86 *
87 * Returns true on success. False if the underlying BLE / Wi-Fi subsystem
88 * refuses to come up (caller should fall back to a REPL-only safe mode).
89 */
91
92/* Switch radio mode. Idempotent — calling with the current mode is a
93 * no-op. Returns true if the transition was queued, false if rejected
94 * (e.g. switch to Wi-Fi without saved creds).
95 *
96 * NOTE: actual mode change is async — callers should listen to the
97 * radio:state event (or poll radio_scheduler_get_mode) for confirmation.
98 */
100
101/* Save Wi-Fi credentials. When auto_switch=true, also queue a transition
102 * to WIFI_CONNECTING after the save completes. Returns false on validation
103 * failure (ssid too long, etc.) or LFS write failure. */
104bool radio_scheduler_set_wifi_creds(const char *ssid,
105 const char *password,
106 const char *security,
107 bool auto_switch);
108
109/* Inspector: returns the live mode without blocking. Safe from any task. */
111
112/* Fill the supplied status struct atomically. The `ssid` field points
113 * into scheduler-owned storage — valid until the next mode transition.
114 * The caller MUST copy out before relinquishing the calling context. */
116
117/* Optional: persist a new boot_mode. The default boot_mode is AUTO; a
118 * user who long-presses the LCD toggle gets FORCE_BLE (or FORCE_WIFI
119 * via the Desktop Buddy). */
121
122/* Optional: get the boot_mode currently persisted. Useful for the UI
123 * to render an "override" badge. */
125
126/* Event hook — called from the scheduler whenever mode changes. The
127 * project wires this to emit a NUS event (bento.radio.state) and to
128 * push an IPC frame to CM55 so the LCD page redraws. */
131
132/* Stringise a mode for log / event payloads. Returns a const literal —
133 * never NULL, never dynamically allocated. */
135
136#ifdef __cplusplus
137}
138#endif
radio_boot_mode_t radio_scheduler_get_boot_mode(void)
The persisted boot mode; with the shipped NULL hooks every boot loads as AUTO.
bool radio_scheduler_request_mode(radio_mode_t target)
Queue an asynchronous mode transition; confirm via the hook or by polling the mode.
void radio_scheduler_set_on_state(radio_scheduler_on_state_fn_t cb)
Install the state hook; must precede radio_scheduler_init() or the first transition is missed.
void radio_scheduler_set_boot_mode(radio_boot_mode_t mode)
Persist a boot preference through the persist hook; with NULL hooks nothing survives reboot.
void radio_scheduler_get_status(radio_status_t *out)
Full status snapshot under the scheduler mutex, 50 ms timeout; copy ssid out.
bool radio_scheduler_init(const radio_scheduler_config_t *cfg)
Create the arbiter (legal pre-scheduler); true on success or double-init.
radio_mode_t radio_scheduler_get_mode(void)
Lock-free mode read — the canonical single-RF Wi-Fi/BLE exclusivity guard.
bool radio_scheduler_set_wifi_creds(const char *ssid, const char *password, const char *security, bool auto_switch)
Save Wi-Fi credentials through the consumer's LFS hook, optionally queueing the switch.
const char * radio_mode_str(radio_mode_t m)
Pure mode-to-string map; static literal, out-of-range returns "invalid" — s is safe.
radio_mode_t
Definition radio_scheduler.h:34
@ RADIO_MODE_WIFI_FAILED
Definition radio_scheduler.h:41
@ RADIO_MODE_UNKNOWN
Definition radio_scheduler.h:35
@ RADIO_MODE_SWITCHING_TO_WIFI
Definition radio_scheduler.h:38
@ RADIO_MODE_SWITCHING_TO_BLE
Definition radio_scheduler.h:40
@ RADIO_MODE_WIFI_ACTIVE
Definition radio_scheduler.h:39
@ RADIO_MODE_BLE_ADV
Definition radio_scheduler.h:36
@ RADIO_MODE_BLE_PAIRED
Definition radio_scheduler.h:37
void(*) radio_scheduler_on_state_fn_t(const radio_status_t *st)
Definition radio_scheduler.h:129
bool(*) radio_boot_mode_load_fn_t(radio_boot_mode_t *out)
Definition radio_scheduler.h:69
struct radio_status_s radio_status_t
void(*) radio_boot_mode_persist_fn_t(radio_boot_mode_t mode)
Definition radio_scheduler.h:68
radio_boot_mode_t
Definition radio_scheduler.h:44
@ RADIO_BOOT_FORCE_WIFI
Definition radio_scheduler.h:51
@ RADIO_BOOT_FORCE_BLE
Definition radio_scheduler.h:48
@ RADIO_BOOT_AUTO
Definition radio_scheduler.h:46
Definition radio_scheduler.h:71
radio_boot_mode_load_fn_t load_boot_mode
Definition radio_scheduler.h:76
radio_boot_mode_persist_fn_t persist_boot_mode
Definition radio_scheduler.h:75
Definition radio_scheduler.h:57
uint8_t wifi_fail_count
Definition radio_scheduler.h:63
radio_mode_t mode
Definition radio_scheduler.h:58
const char * ssid
Definition radio_scheduler.h:60
bool ble_paired
Definition radio_scheduler.h:62
uint32_t ipv4
Definition radio_scheduler.h:61