From a4cf3516e7aca866a0cc3e7c8d4fa5d2eb6a3057 Mon Sep 17 00:00:00 2001 From: Lephe Date: Sat, 3 Dec 2022 11:05:35 +0100 Subject: [PATCH] usb: fix some messages being lost after a post-world-switch reconnect --- src/usb/configure.c | 12 ++++++++---- src/usb/pipes.c | 3 +++ src/usb/usb.c | 3 +++ src/usb/usb_private.h | 18 +++++++++++++++--- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/usb/configure.c b/src/usb/configure.c index 26aef0f..38cf14f 100644 --- a/src/usb/configure.c +++ b/src/usb/configure.c @@ -77,7 +77,6 @@ static int find_pipe(int type) return -1; } -/* usb_configure_solve(): Allocate resources for all activated interfaces */ int usb_configure_solve(usb_interface_t const **interfaces) { /* Reset the previous configuration */ @@ -177,7 +176,6 @@ int usb_configure_solve(usb_interface_t const **interfaces) return 0; } -/* usb_configure_log(): Print configuration results in the USB_LOG() */ void usb_configure_log(void) { #ifdef GINT_USB_DEBUG @@ -200,7 +198,6 @@ void usb_configure_log(void) #endif } -/* usb_configure(): Load the generated configuration to the USB module */ void usb_configure(void) { for(int i = 0; i < 32; i++) @@ -208,11 +205,18 @@ void usb_configure(void) if(!conf_ep[i].intf) continue; int address = (i & 0xf) + (i >= 16 ? 0x80 : 0); usb_pipe_configure(address, &conf_ep[i]); + } +} + +void usb_configure_clear_pipes(void) +{ + for(int i = 0; i < 32; i++) + { + if(!conf_ep[i].intf) continue; usb_pipe_clear(conf_ep[i].pipe); } } -/* usb_configure_interfaces(): List configures interfaces */ usb_interface_t const * const *usb_configure_interfaces(void) { return conf_if; diff --git a/src/usb/pipes.c b/src/usb/pipes.c index 5300056..ef788ad 100644 --- a/src/usb/pipes.c +++ b/src/usb/pipes.c @@ -49,7 +49,10 @@ void usb_pipe_clear(int pipe) usb_while(!USB.PIPECTR[pipe-1].BSTS); USB.PIPECTR[pipe-1].PID = 0; + usb_while(USB.PIPECTR[pipe-1].CSSTS || USB.PIPECTR[pipe-1].PBUSY); + USB.PIPECTR[pipe-1].SQCLR = 1; + usb_while(USB.PIPECTR[pipe-1].SQMON != 0); } //--- diff --git a/src/usb/usb.c b/src/usb/usb.c index 79f84a7..18a7827 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -175,6 +175,7 @@ int usb_open(usb_interface_t const **interfaces, gint_call_t callback) /* Configure other pipes to use activated interfaces */ usb_configure(); + usb_configure_clear_pipes(); /* Initialize transfer tracker for multi-part transfers */ usb_pipe_init_transfers(); @@ -244,6 +245,8 @@ static void usb_interrupt_handler(void) /* When configured, run the callback for usb_open() */ if(USB.INTSTS0.DVSQ == 3) { + usb_configure_clear_pipes(); + usb_open_status = true; if(usb_open_callback.function) { diff --git a/src/usb/usb_private.h b/src/usb/usb_private.h index 8e997ff..2057409 100644 --- a/src/usb/usb_private.h +++ b/src/usb/usb_private.h @@ -27,18 +27,30 @@ Returns an USB_* error code. */ int usb_configure_solve(usb_interface_t const **interfaces); -/* usb_configure_log(): Print configuration results in the usb_log() +/* usb_configure_log(): Print configuration results with USB_LOG() This function can be called even if usb_configure_solve() fails. */ void usb_configure_log(void); -/* usb_configure(): Load the generated configuration to the USB module +/* usb_configure(): Load the solved configuration to the USB module This function configures the USB module's pipes and FIFO memory to prepare handling requests to the interfaces activated in usb_configure_solve(). This configuration step is un-done by either another configuration through a - successful usb_open(), or a context restore in the USB driver. */ + successful usb_open(), or a context restore in the USB driver. + + This function loads all of the "static" data for the pipes, ie. PIPCFG, + PIPEBUF, PIPEMAXP, and PIPERI, and doesn't change the "dynamic" data in + PIPECTR. */ void usb_configure(void); +/* usb_configure_clear_pipes(): Clear configured pipes + + This function clears configured pipes' dynamic data in PIPECTR. It shoud be + used when initializing the module but also when resetting the connection to + the host (eg. after a world switch), since a renewed host will not expect + any leftover data, non-zero sequence bits, etc. */ +void usb_configure_clear_pipes(void); + /* endpoint_t: Driver information for each open endpoint in the device There is one such structure for all 16 configurable endpoints, for each