diff --git a/firmware/firmware.cpp b/firmware/firmware.cpp index 2d850ce..829f427 100644 --- a/firmware/firmware.cpp +++ b/firmware/firmware.cpp @@ -33,5 +33,6 @@ int main() { w6300::open_socket(sn, w6300::protocol::udp6, w6300::port_num{PICOMAP_DISCOVERY_PORT}, w6300::sock_flag::multi_enable); - dispatch_run(handlers); + w6300::socket_id sockets[] = {sn}; + dispatch_run(handlers, sockets); } diff --git a/firmware/include/dispatch.h b/firmware/include/dispatch.h index 02816e5..868270d 100644 --- a/firmware/include/dispatch.h +++ b/firmware/include/dispatch.h @@ -1,12 +1,14 @@ #pragma once #include #include -#include "usb_cdc.h" +#include +#include "w6300.h" struct handler_entry { int8_t type_id; - void (*handle)(usb_cdc&, uint32_t); + std::vector> (*handle)(uint32_t message_id); }; void dispatch_init(); -[[noreturn]] void dispatch_run(std::span handlers); +[[noreturn]] void dispatch_run(std::span handlers, + std::span sockets = {}); diff --git a/firmware/include/handlers.h b/firmware/include/handlers.h index ae6774a..30ebe7b 100644 --- a/firmware/include/handlers.h +++ b/firmware/include/handlers.h @@ -1,9 +1,10 @@ #pragma once +#include #include +#include #include "wire.h" -#include "usb_cdc.h" extern std::string_view firmware_name; -void handle_picoboot(usb_cdc& usb, uint32_t message_id); -void handle_info(usb_cdc& usb, uint32_t message_id); +std::vector> handle_picoboot(uint32_t message_id); +std::vector> handle_info(uint32_t message_id); diff --git a/firmware/lib/dispatch.cpp b/firmware/lib/dispatch.cpp index b5dff0b..b65d064 100644 --- a/firmware/lib/dispatch.cpp +++ b/firmware/lib/dispatch.cpp @@ -1,8 +1,10 @@ #include "dispatch.h" #include #include "pico/stdlib.h" +#include "pico/bootrom.h" #include "tusb.h" #include "wire.h" +#include "usb_cdc.h" #include "timer_queue.h" #include "net.h" @@ -11,15 +13,20 @@ void dispatch_init() { net_init(); } -[[noreturn]] void dispatch_run(std::span handlers) { - std::unordered_map handler_map; +[[noreturn]] void dispatch_run(std::span handlers, + std::span sockets) { + std::unordered_map> (*)(uint32_t)> handler_map; for (auto& entry : handlers) { handler_map[entry.type_id] = entry.handle; } static usb_cdc usb; static timer_queue timers; - static static_vector rx_buf; + static static_vector usb_rx_buf; + + for (auto sn : sockets) { + w6300::set_socket_io_mode(sn, w6300::sock_io_mode::nonblock); + } while (true) { tud_task(); @@ -31,19 +38,44 @@ void dispatch_init() { uint8_t byte; if (tud_cdc_read(&byte, 1) != 1) break; - rx_buf.push_back(byte); + usb_rx_buf.push_back(byte); - auto msg = try_decode(rx_buf); + auto msg = try_decode(usb_rx_buf); if (!msg) { - if (rx_buf.full()) rx_buf.clear(); + if (usb_rx_buf.full()) usb_rx_buf.clear(); continue; } - rx_buf.clear(); + usb_rx_buf.clear(); auto it = handler_map.find(msg->type_id); if (it != handler_map.end()) { - it->second(usb, msg->message_id); + for (auto& response : it->second(msg->message_id)) { + usb.send(response); + } + if (msg->type_id == RequestPICOBOOT::ext_id) { + sleep_ms(100); + reset_usb_boot(0, 1); + } + } + } + + for (auto sn : sockets) { + static uint8_t udp_rx_buf[512]; + w6300::ip_address src_addr = {}; + w6300::port_num src_port{0}; + + auto result = w6300::recvfrom(sn, std::span{udp_rx_buf}, src_addr, src_port); + if (!result) continue; + + auto msg = try_decode(udp_rx_buf, *result); + if (!msg) continue; + + auto it = handler_map.find(msg->type_id); + if (it != handler_map.end()) { + for (auto& response : it->second(msg->message_id)) { + w6300::sendto(sn, std::span{response}, src_addr, src_port); + } } } diff --git a/firmware/lib/handlers.cpp b/firmware/lib/handlers.cpp index 7468941..95195f6 100644 --- a/firmware/lib/handlers.cpp +++ b/firmware/lib/handlers.cpp @@ -1,16 +1,12 @@ #include "handlers.h" -#include "pico/stdlib.h" -#include "pico/bootrom.h" #include "pico/unique_id.h" #include "w6300.h" -void handle_picoboot(usb_cdc& usb, uint32_t message_id) { - usb.send(encode_response(message_id, ResponsePICOBOOT{})); - sleep_ms(100); - reset_usb_boot(0, 1); +std::vector> handle_picoboot(uint32_t message_id) { + return {encode_response(message_id, ResponsePICOBOOT{})}; } -void handle_info(usb_cdc& usb, uint32_t message_id) { +std::vector> handle_info(uint32_t message_id) { ResponseInfo resp; pico_unique_board_id_t uid; pico_get_unique_board_id(&uid); @@ -19,5 +15,5 @@ void handle_info(usb_cdc& usb, uint32_t message_id) { resp.mac = ninfo.mac; resp.link_local = ninfo.lla; resp.firmware_name = firmware_name; - usb.send(encode_response(message_id, resp)); + return {encode_response(message_id, resp)}; }