From 21c7900444e2e3ecad9fafdf5266aadf0ba9b8ce Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 12 Apr 2026 08:27:21 +0900 Subject: [PATCH] Watchdog timer, boot reason tracking, net_poll frame limit, reboot/picoboot CLI commands --- firmware/firmware.cpp | 1 + firmware/include/handlers.h | 1 + firmware/include/wire.h | 1 + firmware/lib/handlers.cpp | 21 +++++++++++++++------ firmware/lib/net.cpp | 2 +- firmware/test.cpp | 1 + lib/client/types.go | 7 +++++-- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/firmware/firmware.cpp b/firmware/firmware.cpp index 1779f94..a622e1b 100644 --- a/firmware/firmware.cpp +++ b/firmware/firmware.cpp @@ -15,5 +15,6 @@ static constexpr handler_entry handlers[] = { int main() { handlers_init(); dispatch_init(); + handlers_start(); dispatch_run(handlers); } diff --git a/firmware/include/handlers.h b/firmware/include/handlers.h index d75be63..776fda3 100644 --- a/firmware/include/handlers.h +++ b/firmware/include/handlers.h @@ -7,6 +7,7 @@ extern std::string_view firmware_name; void handlers_init(); +void handlers_start(); std::optional handle_picoboot(const responder& resp, const RequestPICOBOOT&); std::optional handle_info(const responder& resp, const RequestInfo&); std::optional handle_log(const responder& resp, const RequestLog&); diff --git a/firmware/include/wire.h b/firmware/include/wire.h index 5f42521..5d58808 100644 --- a/firmware/include/wire.h +++ b/firmware/include/wire.h @@ -47,6 +47,7 @@ struct RequestInfo { enum class boot_reason : uint8_t { cold_boot = 0, request_reboot = 1, + watchdog = 2, }; struct ResponseInfo { diff --git a/firmware/lib/handlers.cpp b/firmware/lib/handlers.cpp index 3acff80..ea10442 100644 --- a/firmware/lib/handlers.cpp +++ b/firmware/lib/handlers.cpp @@ -9,16 +9,25 @@ static constexpr uint32_t XIP_BASE_ADDR = 0x10000000; static constexpr uint32_t FLASH_SIZE = 2 * 1024 * 1024; -static constexpr uint32_t REBOOT_MAGIC = 0x504D5242; - static boot_reason detected_boot_reason; +static void poke_watchdog() { + watchdog_update(); + dispatch_schedule_ms(500, poke_watchdog); +} + void handlers_init() { - if (watchdog_hw->scratch[0] == REBOOT_MAGIC) - detected_boot_reason = boot_reason::request_reboot; + auto val = static_cast(watchdog_hw->scratch[0]); + if (val == boot_reason::request_reboot || val == boot_reason::watchdog) + detected_boot_reason = val; else detected_boot_reason = boot_reason::cold_boot; - watchdog_hw->scratch[0] = 0; + watchdog_hw->scratch[0] = static_cast(boot_reason::watchdog); + watchdog_enable(1000, true); +} + +void handlers_start() { + poke_watchdog(); } std::optional handle_picoboot(const responder&, const RequestPICOBOOT&) { @@ -80,7 +89,7 @@ std::optional handle_flash_write(const responder&, const Req std::optional handle_reboot(const responder&, const RequestReboot&) { dispatch_schedule_ms(100, []{ - watchdog_hw->scratch[0] = REBOOT_MAGIC; + watchdog_hw->scratch[0] = static_cast(boot_reason::request_reboot); watchdog_reboot(0, 0, 0); }); return ResponseReboot{}; diff --git a/firmware/lib/net.cpp b/firmware/lib/net.cpp index fb38e98..089ac0e 100644 --- a/firmware/lib/net.cpp +++ b/firmware/lib/net.cpp @@ -140,7 +140,7 @@ void net_poll(std::span tx) { w6300::irq_pending = false; w6300::clear_interrupt(w6300::ik_int_all); static uint8_t rx_buf[1518]; - while (w6300::get_socket_recv_buf(raw_socket) > 0) { + for (int i = 0; i < 16 && w6300::get_socket_recv_buf(raw_socket) > 0; i++) { auto result = w6300::recv(raw_socket, std::span{rx_buf}); if (!result) break; span_writer tx_writer(tx); diff --git a/firmware/test.cpp b/firmware/test.cpp index 5a30c25..9b576f8 100644 --- a/firmware/test.cpp +++ b/firmware/test.cpp @@ -27,6 +27,7 @@ static constexpr handler_entry handlers[] = { int main() { handlers_init(); dispatch_init(); + handlers_start(); gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); diff --git a/lib/client/types.go b/lib/client/types.go index 6dc3e5e..b564206 100644 --- a/lib/client/types.go +++ b/lib/client/types.go @@ -9,8 +9,9 @@ type RequestInfo struct{} type BootReason uint8 const ( - BootCold BootReason = 0 - BootReboot BootReason = 1 + BootCold BootReason = 0 + BootReboot BootReason = 1 + BootWatchdog BootReason = 2 ) func (b BootReason) String() string { @@ -19,6 +20,8 @@ func (b BootReason) String() string { return "cold" case BootReboot: return "reboot" + case BootWatchdog: + return "watchdog" default: return "unknown" }