From afa59329436a78eee18470709184ca97407ca977 Mon Sep 17 00:00:00 2001 From: Michael McMaster Date: Tue, 9 Mar 2021 11:39:23 +1000 Subject: [PATCH] Improved reliability of USB config interface (port from V5 branch) --- include/hidpacket.h | 5 +++++ src/firmware/config.c | 38 +++++++++++++++++++++++++++----------- src/firmware/hidpacket.c | 17 +++++++++++++++++ src/firmware/main.c | 23 ----------------------- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/include/hidpacket.h b/include/hidpacket.h index 384956f8..21592b48 100644 --- a/include/hidpacket.h +++ b/include/hidpacket.h @@ -54,6 +54,11 @@ void hidPacket_send(const uint8_t* bytes, size_t len); // NULL if there's nothing to send. const uint8_t* hidPacket_getHIDBytes(uint8_t* hidBuffer); +// Returns 1 if hidPacket_getHIDBytes will return non-null +int hidPacket_getHIDBytesReady(); + +void hidPacket_reset(); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/firmware/config.c b/src/firmware/config.c index e0f034ef..70ba16f7 100755 --- a/src/firmware/config.c +++ b/src/firmware/config.c @@ -331,26 +331,33 @@ void s2s_configPoll() if (!USBD_Composite_IsConfigured(&configUsbDev)) { usbInEpState = USB_IDLE; + hidPacket_reset(); goto out; } if (USBD_HID_IsReportReady(&configUsbDev)) { - s2s_ledOn(); - - // The host sent us some data! - uint8_t hidBuffer[USBHID_LEN]; - int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer)); - hidPacket_recv(hidBuffer, byteCount); + // Check if we have a previous command outstanding + // before accepting another + size_t cmdSize; + if (hidPacket_peekPacket(&cmdSize) == NULL) + { + uint8_t hidBuffer[USBHID_LEN]; + int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer)); + hidPacket_recv(hidBuffer, byteCount); + } + } + if (hidPacket_getHIDBytesReady() == 0) // Nothing queued to send + { size_t cmdSize; const uint8_t* cmd = hidPacket_getPacket(&cmdSize); if (cmd && (cmdSize > 0)) { + s2s_ledOn(); processCommand(cmd, cmdSize); + s2s_ledOff(); } - - s2s_ledOff(); } switch (usbInEpState) @@ -391,10 +398,19 @@ void s2s_debugTimer() if (USBD_HID_IsReportReady(&configUsbDev)) { - uint8_t hidBuffer[USBHID_LEN]; - int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer)); - hidPacket_recv(hidBuffer, byteCount); + // Check if we have a previous command outstanding + // before accepting another + size_t cmdSize; + if (hidPacket_peekPacket(&cmdSize) == NULL) + { + uint8_t hidBuffer[USBHID_LEN]; + int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer)); + hidPacket_recv(hidBuffer, byteCount); + } + } + if (hidPacket_getHIDBytesReady() == 0) // Nothing queued to send + { size_t cmdSize; const uint8_t* cmd = hidPacket_peekPacket(&cmdSize); // This is called from an ISR, only process simple commands. diff --git a/src/firmware/hidpacket.c b/src/firmware/hidpacket.c index 85c42220..1f79402a 100644 --- a/src/firmware/hidpacket.c +++ b/src/firmware/hidpacket.c @@ -46,6 +46,12 @@ txReset() tx.offset = 0; } +void hidPacket_reset() +{ + rxReset(); + txReset(); +} + void hidPacket_recv(const uint8_t* bytes, size_t len) { if (len < 2) @@ -141,6 +147,17 @@ void hidPacket_send(const uint8_t* bytes, size_t len) } } +int +hidPacket_getHIDBytesReady() +{ + if ((tx.state != PARTIAL) || (tx.offset <= 0)) + { + return 0; + } + + return 1; +} + const uint8_t* hidPacket_getHIDBytes(uint8_t* hidBuffer) { diff --git a/src/firmware/main.c b/src/firmware/main.c index cb118edb..d2d88166 100755 --- a/src/firmware/main.c +++ b/src/firmware/main.c @@ -139,29 +139,6 @@ void mainLoop() } } - else - { - // TODO this hurts performance significantly! Work out why __WFI() - // doesn't wake up immediately ! -#if 0 - // Wait for our 1ms timer to save some power. - // There's an interrupt on the SEL signal to ensure we respond - // quickly to any SCSI commands. The selection abort time is - // only 250us, and new SCSI-3 controllers time-out very - // not long after that, so we need to ensure we wake up quickly. - uint32_t interruptState = __get_PRIMASK(); - __disable_irq(); - - if (!*SCSI_STS_SELECTED) - { - //__WFI(); // Will wake on interrupt, regardless of mask - } - if (!interruptState) - { - __enable_irq(); - } -#endif - } } else if ((scsiDev.phase >= 0) && (blockDev.state & DISK_PRESENT)) { -- 2.38.5