feat(wake): add controller-free USB serial wake beacon
Add a standalone Pico2W image reusing the configured nonconnectable wake burst without Bluepad32, controller-host profiles, Classic/LE-central roles, connection pools, pairing or writable TLV storage. Explicitly disable and verify Classic inquiry/page scan before declaring readiness. Keep the original controller firmware and captured wake identity unchanged. Expose bounded SPWB1 CDC commands with exactly-once request IDs, explicit failures and radio progress independent of serial backpressure. Add the cross-platform switch-pico-wake script with strict preflight, bounded I/O, no automatic rebroadcast, status-only mode and preserved uncertain-outcome metadata. Standard USB serial requires no WinUSB/Zadig binding. Add isolated --wake-only build/publication selection and document setup, backup and physical-BOOTSEL recovery. Validate776 tests, focused framing and lifecycle cases, ELF isolation and actual CDC operation on only the new board. One burst completed in2.095s; malformed/status/reconnect input and same-ID replay caused no additional broadcast. Original Pico untouched. Private firmware images, console configuration and backups are excluded.
This commit is contained in:
parent
e277d34c20
commit
bed71f77f1
14 changed files with 2042 additions and 3 deletions
62
tools/switch2_wake_beacon/beacon_protocol.h
Normal file
62
tools/switch2_wake_beacon/beacon_protocol.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "input/switch2_wake.h"
|
||||
|
||||
namespace wake_beacon {
|
||||
|
||||
struct RadioStatus {
|
||||
bool ready = false;
|
||||
bool failed = false;
|
||||
bool initialized = false;
|
||||
Switch2WakeDiagnostics wake{};
|
||||
};
|
||||
|
||||
// Owned entirely by Core 0. Parsing only queues a request; the radio owner calls
|
||||
// dispatch_pending()/dispatched() separately, outside USB callbacks and IRQs.
|
||||
class Protocol {
|
||||
public:
|
||||
static constexpr size_t kMaxLineBytes = 64; // Excludes LF, includes optional CR.
|
||||
static constexpr size_t kResponseBytes = 512;
|
||||
|
||||
void connected(bool connected);
|
||||
bool can_receive() const;
|
||||
bool receive(uint8_t byte);
|
||||
const char* output_data() const;
|
||||
size_t output_size() const;
|
||||
void consume_output(size_t count);
|
||||
|
||||
void observe(const RadioStatus& radio);
|
||||
bool dispatch_pending() const;
|
||||
void dispatched(bool accepted);
|
||||
|
||||
private:
|
||||
enum class State : uint8_t {
|
||||
Idle, Queued, Broadcasting, Complete, Unconfigured, Failed,
|
||||
};
|
||||
|
||||
bool active() const;
|
||||
bool busy() const;
|
||||
const char* state_name() const;
|
||||
void command();
|
||||
void respond(const char* error);
|
||||
|
||||
RadioStatus radio_{};
|
||||
State state_ = State::Idle;
|
||||
uint32_t request_id_ = 0;
|
||||
uint32_t accepted_requests_ = 0;
|
||||
uint32_t local_failures_ = 0;
|
||||
uint32_t start_completed_ = 0;
|
||||
uint32_t start_failures_ = 0;
|
||||
bool connected_ = false;
|
||||
bool invalid_line_ = false;
|
||||
char line_[kMaxLineBytes]{};
|
||||
size_t line_size_ = 0;
|
||||
char response_[kResponseBytes]{};
|
||||
size_t response_size_ = 0;
|
||||
size_t response_offset_ = 0;
|
||||
};
|
||||
|
||||
} // namespace wake_beacon
|
||||
Loading…
Add table
Add a link
Reference in a new issue