WFI with interrupt-driven wakeup for USB and W6300

This commit is contained in:
Ian Gulliver
2026-04-10 12:55:04 +09:00
parent 3d20bf4c33
commit 0c11cbb1d1
4 changed files with 27 additions and 4 deletions

View File

@@ -8,6 +8,7 @@
#include "timer_queue.h" #include "timer_queue.h"
#include "net.h" #include "net.h"
#include "debug_log.h" #include "debug_log.h"
#include "hardware/sync.h"
static timer_queue timers; static timer_queue timers;
@@ -39,6 +40,8 @@ void dispatch_schedule_ms(uint32_t ms, std::function<void()> fn) {
}); });
while (true) { while (true) {
uint32_t save = save_and_disable_interrupts();
dlog_if_slow("tud_task", 1000, [&]{ tud_task(); }); dlog_if_slow("tud_task", 1000, [&]{ tud_task(); });
dlog_if_slow("drain", 1000, [&]{ usb.drain(); }); dlog_if_slow("drain", 1000, [&]{ usb.drain(); });
dlog_if_slow("timers", 1000, [&]{ timers.run(); }); dlog_if_slow("timers", 1000, [&]{ timers.run(); });
@@ -76,6 +79,7 @@ void dispatch_schedule_ms(uint32_t ms, std::function<void()> fn) {
} }
} }
// __wfi(); __wfi();
restore_interrupts(save);
} }
} }

View File

@@ -283,6 +283,10 @@ bool net_init() {
w6300::open_socket(raw_socket, w6300::protocol::macraw, w6300::port_num{0}, w6300::sock_flag::none); w6300::open_socket(raw_socket, w6300::protocol::macraw, w6300::port_num{0}, w6300::sock_flag::none);
w6300::set_socket_io_mode(raw_socket, w6300::sock_io_mode::nonblock); w6300::set_socket_io_mode(raw_socket, w6300::sock_io_mode::nonblock);
// CHECK START
w6300::set_socket_interrupt_mask(raw_socket, 0x04);
w6300::set_interrupt_mask(w6300::ik_sock_0);
// CHECK END
return true; return true;
} }
@@ -296,6 +300,7 @@ void net_set_handler(net_handler handler) {
} }
void net_poll() { void net_poll() {
w6300::clear_interrupt(w6300::ik_int_all);
if (w6300::get_socket_recv_buf(raw_socket) == 0) return; if (w6300::get_socket_recv_buf(raw_socket) == 0) return;
static uint8_t rx_buf[1518]; static uint8_t rx_buf[1518];
w6300::ip_address dummy_addr = {}; w6300::ip_address dummy_addr = {};

View File

@@ -71,11 +71,15 @@ void pio_init() {
gpio_put(pin, false); gpio_put(pin, false);
} }
gpio_init(PIN_CS); gpio_init(PIN_CS);
// CHECK START
gpio_set_dir(PIN_CS, GPIO_OUT); gpio_set_dir(PIN_CS, GPIO_OUT);
gpio_put(PIN_CS, true); gpio_put(PIN_CS, true);
gpio_init(PIN_INT); gpio_init(PIN_INT);
gpio_set_dir(PIN_INT, GPIO_IN); gpio_set_dir(PIN_INT, GPIO_IN);
gpio_set_pulls(PIN_INT, false, false); gpio_pull_up(PIN_INT);
gpio_set_irq_enabled_with_callback(PIN_INT, GPIO_IRQ_EDGE_FALL, true,
[](uint, uint32_t){});
// CHECK END
pio_hw_t *pios[2] = {pio0, pio1}; pio_hw_t *pios[2] = {pio0, pio1};
uint pio_index = 1; uint pio_index = 1;
@@ -822,11 +826,15 @@ inline uint16_t get_sn_rx_wr(uint8_t sn) { return ((uint16_t)reg_read(REG_SN_RX_
static critical_section_t g_cris_sec; static critical_section_t g_cris_sec;
void cris_enter() { void cris_enter() {
critical_section_enter_blocking(&g_cris_sec); // CHECK START
// critical_section_enter_blocking(&g_cris_sec);
// CHECK END
} }
void cris_exit() { void cris_exit() {
critical_section_exit(&g_cris_sec); // CHECK START
// critical_section_exit(&g_cris_sec);
// CHECK END
} }
static uint8_t make_opcode(uint32_t addr, uint8_t rw) { static uint8_t make_opcode(uint32_t addr, uint8_t rw) {
@@ -1647,6 +1655,11 @@ void init_net(const net_info& info) {
set_net_info(info); set_net_info(info);
} }
void enable_interrupt_pin() {
chip_unlock();
set_sycr1(get_sycr1() | SYCR1_IEN);
}
std::expected<void, sock_error> set_socket_io_mode(socket_id sid, sock_io_mode mode) { std::expected<void, sock_error> set_socket_io_mode(socket_id sid, sock_io_mode mode) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
if (sn >= sock_count) FAIL(sock_num); if (sn >= sock_count) FAIL(sock_num);

View File

@@ -195,6 +195,7 @@ int8_t init_buffers(std::span<const uint8_t> txsize, std::span<const uint8_t> rx
void clear_interrupt(intr_kind intr); void clear_interrupt(intr_kind intr);
intr_kind get_interrupt(); intr_kind get_interrupt();
void set_interrupt_mask(intr_kind intr); void set_interrupt_mask(intr_kind intr);
void enable_interrupt_pin();
intr_kind get_interrupt_mask(); intr_kind get_interrupt_mask();
int8_t get_phy_link(); int8_t get_phy_link();