From f2d98ef4f1bfb67478d5d5efc9502d736495f852 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Fri, 10 Apr 2026 22:00:34 +0900 Subject: [PATCH] Skip net_poll and timers unless their interrupt has fired --- firmware/include/timer_queue.h | 10 ++++++++-- firmware/lib/net.cpp | 2 ++ firmware/w6300/w6300.cpp | 4 +++- firmware/w6300/w6300.h | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/firmware/include/timer_queue.h b/firmware/include/timer_queue.h index 4b170fd..1a2ea52 100644 --- a/firmware/include/timer_queue.h +++ b/firmware/include/timer_queue.h @@ -15,6 +15,7 @@ inline bool operator<(const timer_entry& a, const timer_entry& b) { struct timer_queue { sorted_list queue; alarm_id_t alarm = -1; + volatile bool irq_pending = false; void schedule(absolute_time_t when, std::function fn) { queue.insert({when, std::move(fn)}); @@ -26,6 +27,8 @@ struct timer_queue { } void run() { + if (!irq_pending) return; + irq_pending = false; while (!queue.empty()) { auto& front = queue.front(); if (absolute_time_diff_us(get_absolute_time(), front.when) > 0) break; @@ -39,12 +42,15 @@ struct timer_queue { bool empty() const { return queue.empty(); } private: - static int64_t alarm_cb(alarm_id_t, void*) { return 0; } + static int64_t alarm_cb(alarm_id_t, void* user_data) { + static_cast(user_data)->irq_pending = true; + return 0; + } void arm() { if (alarm >= 0) cancel_alarm(alarm); alarm = -1; if (!queue.empty()) - alarm = add_alarm_at(queue.front().when, alarm_cb, nullptr, false); + alarm = add_alarm_at(queue.front().when, alarm_cb, this, false); } }; diff --git a/firmware/lib/net.cpp b/firmware/lib/net.cpp index 0309733..65fca8a 100644 --- a/firmware/lib/net.cpp +++ b/firmware/lib/net.cpp @@ -293,6 +293,8 @@ void net_set_handler(net_handler handler) { } void net_poll() { + if (!w6300::irq_pending) return; + w6300::irq_pending = false; w6300::clear_interrupt(w6300::ik_int_all); if (w6300::get_socket_recv_buf(raw_socket) == 0) return; static uint8_t rx_buf[1518]; diff --git a/firmware/w6300/w6300.cpp b/firmware/w6300/w6300.cpp index f13a950..a8278f9 100644 --- a/firmware/w6300/w6300.cpp +++ b/firmware/w6300/w6300.cpp @@ -78,7 +78,7 @@ void pio_init() { gpio_set_dir(PIN_INT, GPIO_IN); gpio_pull_up(PIN_INT); gpio_set_irq_enabled_with_callback(PIN_INT, GPIO_IRQ_EDGE_FALL, true, - [](uint, uint32_t){}); + [](uint, uint32_t){ irq_pending = true; }); pio_hw_t *pios[2] = {pio0, pio1}; uint pio_index = 1; @@ -490,6 +490,8 @@ std::expected close(socket_id sid) { } // namespace +volatile bool irq_pending = false; + void clear_interrupt(intr_kind intr) { set_irclr((uint8_t)intr); uint8_t sir = (uint8_t)((uint16_t)intr >> 8); diff --git a/firmware/w6300/w6300.h b/firmware/w6300/w6300.h index 1976ceb..00c4037 100644 --- a/firmware/w6300/w6300.h +++ b/firmware/w6300/w6300.h @@ -37,6 +37,8 @@ void reset(); void init(); bool check(); +extern volatile bool irq_pending; + void clear_interrupt(intr_kind intr); void set_interrupt_mask(intr_kind intr);