Improved reliability of USB config interface (port from V5 branch)
authorMichael McMaster <michael@codesrc.com>
Tue, 9 Mar 2021 01:39:23 +0000 (11:39 +1000)
committerMichael McMaster <michael@codesrc.com>
Tue, 9 Mar 2021 01:39:23 +0000 (11:39 +1000)
include/hidpacket.h
src/firmware/config.c
src/firmware/hidpacket.c
src/firmware/main.c

index 384956f8e19cdbf1e57097218f1e09fbc696c400..21592b4828e048e15b028ce59661fe2769ea5fea 100644 (file)
@@ -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
index e0f034ef374aaa642eb1ce6cf06903aef6acbff3..70ba16f78b4eda689b645a958e5a34490489facb 100755 (executable)
@@ -331,26 +331,33 @@ void s2s_configPoll()
        if (!USBD_Composite_IsConfigured(&configUsbDev))\r
        {\r
                usbInEpState = USB_IDLE;\r
+               hidPacket_reset();\r
                goto out;\r
        }\r
 \r
        if (USBD_HID_IsReportReady(&configUsbDev))\r
        {\r
-               s2s_ledOn();\r
-\r
-               // The host sent us some data!\r
-               uint8_t hidBuffer[USBHID_LEN];\r
-               int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer));\r
-               hidPacket_recv(hidBuffer, byteCount);\r
+               // Check if we have a previous command outstanding\r
+               // before accepting another\r
+               size_t cmdSize;\r
+               if (hidPacket_peekPacket(&cmdSize) == NULL)\r
+               {\r
+                       uint8_t hidBuffer[USBHID_LEN];\r
+                       int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer));\r
+                       hidPacket_recv(hidBuffer, byteCount);\r
+               }\r
+       }\r
 \r
+       if (hidPacket_getHIDBytesReady() == 0) // Nothing queued to send\r
+       {\r
                size_t cmdSize;\r
                const uint8_t* cmd = hidPacket_getPacket(&cmdSize);\r
                if (cmd && (cmdSize > 0))\r
                {\r
+                       s2s_ledOn();\r
                        processCommand(cmd, cmdSize);\r
+                       s2s_ledOff();\r
                }\r
-\r
-               s2s_ledOff();\r
        }\r
 \r
        switch (usbInEpState)\r
@@ -391,10 +398,19 @@ void s2s_debugTimer()
 \r
        if (USBD_HID_IsReportReady(&configUsbDev))\r
        {\r
-               uint8_t hidBuffer[USBHID_LEN];\r
-               int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer));\r
-               hidPacket_recv(hidBuffer, byteCount);\r
+               // Check if we have a previous command outstanding\r
+               // before accepting another\r
+               size_t cmdSize;\r
+               if (hidPacket_peekPacket(&cmdSize) == NULL)\r
+               {\r
+                       uint8_t hidBuffer[USBHID_LEN];\r
+                       int byteCount = USBD_HID_GetReport(&configUsbDev, hidBuffer, sizeof(hidBuffer));\r
+                       hidPacket_recv(hidBuffer, byteCount);\r
+               }\r
+       }\r
 \r
+       if (hidPacket_getHIDBytesReady() == 0) // Nothing queued to send\r
+       {\r
                size_t cmdSize;\r
                const uint8_t* cmd = hidPacket_peekPacket(&cmdSize);\r
                // This is called from an ISR, only process simple commands.\r
index 85c42220b36b419e1232ee207f12eb53da7897ee..1f79402a039f57c0685381a0b49f4896b78a959e 100644 (file)
@@ -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)
 {
index cb118edb0dd7bbf62363b573cf28b88975bea3d0..d2d881660e162f5c58e01cbac1cf66116062803c 100755 (executable)
@@ -139,29 +139,6 @@ void mainLoop()
                        }\r
 \r
                }\r
-               else\r
-               {\r
-                       // TODO this hurts performance significantly! Work out why __WFI()\r
-                       // doesn't wake up immediately !\r
-#if 0\r
-                       // Wait for our 1ms timer to save some power.\r
-                       // There's an interrupt on the SEL signal to ensure we respond\r
-                       // quickly to any SCSI commands. The selection abort time is\r
-                       // only 250us, and new SCSI-3 controllers time-out very\r
-                       // not long after that, so we need to ensure we wake up quickly.\r
-                       uint32_t interruptState = __get_PRIMASK();\r
-                       __disable_irq();\r
-\r
-                       if (!*SCSI_STS_SELECTED)\r
-                       {\r
-                               //__WFI(); // Will wake on interrupt, regardless of mask\r
-                       }\r
-                       if (!interruptState)\r
-                       {\r
-                               __enable_irq();\r
-                       }\r
-#endif\r
-               }\r
        }\r
        else if ((scsiDev.phase >= 0) && (blockDev.state & DISK_PRESENT))\r
        {\r