#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" void dispatch_init() { tusb_init(); net_init(); } [[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 usb_rx_buf; for (auto sn : sockets) { w6300::set_socket_io_mode(sn, w6300::sock_io_mode::nonblock); } while (true) { tud_task(); usb.drain(); timers.run(); while (tud_cdc_available()) { uint8_t byte; if (tud_cdc_read(&byte, 1) != 1) break; usb_rx_buf.push_back(byte); auto msg = try_decode(usb_rx_buf); if (!msg) { if (usb_rx_buf.full()) usb_rx_buf.clear(); continue; } usb_rx_buf.clear(); auto it = handler_map.find(msg->type_id); if (it != handler_map.end()) { 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); } } } __wfi(); } }