Improved reliability when writing data to flash over USB
authorMichael McMaster <michael@codesrc.com>
Mon, 8 Mar 2021 11:46:23 +0000 (21:46 +1000)
committerMichael McMaster <michael@codesrc.com>
Mon, 8 Mar 2021 11:46:23 +0000 (21:46 +1000)
software/SCSI2SD/src/config.c
software/SCSI2SD/src/hidpacket.c
software/SCSI2SD/src/main.c
software/SCSI2SD/src/sd.c
software/SCSI2SD/v5.2/SCSI2SD.cydsn/SCSI2SD.cyfit
software/include/hidpacket.h

index e7176e8e23e9e59f3e8d1bd718dd153da7985a8c..23bdf474fc4c7a222b6afe0de3a4d6f0f2974c54 100755 (executable)
@@ -58,6 +58,7 @@ enum USB_STATE
 };\r
 \r
 static uint8_t hidBuffer[USBHID_LEN];\r
+static uint8_t dbgHidBuffer[USBHID_LEN];\r
 \r
 static int usbInEpState;\r
 static int usbDebugEpState;\r
@@ -356,6 +357,7 @@ void configPoll()
 \r
        if (reset)\r
        {\r
+        hidPacket_reset();\r
                USBFS_EnableOutEP(USB_EP_OUT);\r
                USBFS_EnableOutEP(USB_EP_COMMAND);\r
                usbInEpState = usbDebugEpState = USB_IDLE;\r
@@ -363,24 +365,32 @@ void configPoll()
 \r
        if(USBFS_GetEPState(USB_EP_OUT) == USBFS_OUT_BUFFER_FULL)\r
        {\r
-               ledOn();\r
-\r
                // The host sent us some data!\r
                int byteCount = USBFS_GetEPCount(USB_EP_OUT);\r
                USBFS_ReadOutEP(USB_EP_OUT, hidBuffer, sizeof(hidBuffer));\r
                hidPacket_recv(hidBuffer, byteCount);\r
-\r
+        \r
+        size_t cmdSize;\r
+        if (hidPacket_peekPacket(&cmdSize) == NULL)\r
+        {\r
+            // Allow the host to send us another updated config.\r
+                   USBFS_EnableOutEP(USB_EP_OUT);\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
+            ledOn();\r
                        processCommand(cmd, cmdSize);\r
+            ledOff();\r
+            \r
+            // Allow the host to send us another updated config.\r
+                   USBFS_EnableOutEP(USB_EP_OUT);\r
                }\r
-\r
-               // Allow the host to send us another updated config.\r
-               USBFS_EnableOutEP(USB_EP_OUT);\r
-\r
-               ledOff();\r
        }\r
 \r
        switch (usbInEpState)\r
@@ -418,10 +428,10 @@ void debugPoll()
        {\r
                // The host sent us some data!\r
                int byteCount = USBFS_GetEPCount(USB_EP_COMMAND);\r
-               USBFS_ReadOutEP(USB_EP_COMMAND, (uint8 *)&hidBuffer, byteCount);\r
+               USBFS_ReadOutEP(USB_EP_COMMAND, (uint8 *)&dbgHidBuffer, byteCount);\r
 \r
                if (byteCount >= 1 &&\r
-                       hidBuffer[0] == 0x01)\r
+                       dbgHidBuffer[0] == 0x01)\r
                {\r
                        // Reboot command.\r
                        Bootloadable_1_Load();\r
@@ -435,36 +445,36 @@ void debugPoll()
        switch (usbDebugEpState)\r
        {\r
        case USB_IDLE:\r
-               memcpy(&hidBuffer, &scsiDev.cdb, 12);\r
-               hidBuffer[12] = scsiDev.msgIn;\r
-               hidBuffer[13] = scsiDev.msgOut;\r
-               hidBuffer[14] = scsiDev.lastStatus;\r
-               hidBuffer[15] = scsiDev.lastSense;\r
-               hidBuffer[16] = scsiDev.phase;\r
-               hidBuffer[17] = SCSI_ReadFilt(SCSI_Filt_BSY);\r
-               hidBuffer[18] = SCSI_ReadFilt(SCSI_Filt_SEL);\r
-               hidBuffer[19] = SCSI_ReadFilt(SCSI_Filt_ATN);\r
-               hidBuffer[20] = SCSI_ReadFilt(SCSI_Filt_RST);\r
-               hidBuffer[21] = scsiDev.rstCount;\r
-               hidBuffer[22] = scsiDev.selCount;\r
-               hidBuffer[23] = scsiDev.msgCount;\r
-               hidBuffer[24] = scsiDev.cmdCount;\r
-               hidBuffer[25] = scsiDev.watchdogTick;\r
-               hidBuffer[26] = 0; // OBSOLETE. Previously media state\r
-               hidBuffer[27] = scsiDev.lastSenseASC >> 8;\r
-               hidBuffer[28] = scsiDev.lastSenseASC;\r
-               hidBuffer[29] = scsiReadDBxPins();\r
-               hidBuffer[30] = LastTrace;\r
-\r
-               hidBuffer[58] = sdCard.capacity >> 24;\r
-               hidBuffer[59] = sdCard.capacity >> 16;\r
-               hidBuffer[60] = sdCard.capacity >> 8;\r
-               hidBuffer[61] = sdCard.capacity;\r
-\r
-               hidBuffer[62] = FIRMWARE_VERSION >> 8;\r
-               hidBuffer[63] = FIRMWARE_VERSION;\r
-\r
-               USBFS_LoadInEP(USB_EP_DEBUG, (uint8 *)&hidBuffer, sizeof(hidBuffer));\r
+               memcpy(&dbgHidBuffer, &scsiDev.cdb, 12);\r
+               dbgHidBuffer[12] = scsiDev.msgIn;\r
+               dbgHidBuffer[13] = scsiDev.msgOut;\r
+               dbgHidBuffer[14] = scsiDev.lastStatus;\r
+               dbgHidBuffer[15] = scsiDev.lastSense;\r
+               dbgHidBuffer[16] = scsiDev.phase;\r
+               dbgHidBuffer[17] = SCSI_ReadFilt(SCSI_Filt_BSY);\r
+               dbgHidBuffer[18] = SCSI_ReadFilt(SCSI_Filt_SEL);\r
+               dbgHidBuffer[19] = SCSI_ReadFilt(SCSI_Filt_ATN);\r
+               dbgHidBuffer[20] = SCSI_ReadFilt(SCSI_Filt_RST);\r
+               dbgHidBuffer[21] = scsiDev.rstCount;\r
+               dbgHidBuffer[22] = scsiDev.selCount;\r
+               dbgHidBuffer[23] = scsiDev.msgCount;\r
+               dbgHidBuffer[24] = scsiDev.cmdCount;\r
+               dbgHidBuffer[25] = scsiDev.watchdogTick;\r
+               dbgHidBuffer[26] = 0; // OBSOLETE. Previously media state\r
+               dbgHidBuffer[27] = scsiDev.lastSenseASC >> 8;\r
+               dbgHidBuffer[28] = scsiDev.lastSenseASC;\r
+               dbgHidBuffer[29] = scsiReadDBxPins();\r
+               dbgHidBuffer[30] = LastTrace;\r
+\r
+               dbgHidBuffer[58] = sdCard.capacity >> 24;\r
+               dbgHidBuffer[59] = sdCard.capacity >> 16;\r
+               dbgHidBuffer[60] = sdCard.capacity >> 8;\r
+               dbgHidBuffer[61] = sdCard.capacity;\r
+\r
+               dbgHidBuffer[62] = FIRMWARE_VERSION >> 8;\r
+               dbgHidBuffer[63] = FIRMWARE_VERSION;\r
+\r
+               USBFS_LoadInEP(USB_EP_DEBUG, (uint8 *)&dbgHidBuffer, sizeof(dbgHidBuffer));\r
                usbDebugEpState = USB_DATA_SENT;\r
                break;\r
 \r
index 8fe484a5f4364fa1a0215a01a7cd9ea83f4b544d..36d14c4cc2cc04eb928c0d1b4bff9501ef3b0a7c 100644 (file)
@@ -45,6 +45,12 @@ txReset()
        tx.offset = 0;
 }
 
+void hidPacket_reset()
+{
+    rxReset();
+    txReset();
+}
+
 void hidPacket_recv(const uint8_t* bytes, size_t len)
 {
        if (len < 2)
@@ -94,6 +100,21 @@ void hidPacket_recv(const uint8_t* bytes, size_t len)
        }
 }
 
+const uint8_t*
+hidPacket_peekPacket(size_t* len)
+{
+       if (rx.state == COMPLETE)
+       {
+               *len = rx.offset;
+               return rx.buffer;
+       }
+       else
+       {
+               *len = 0;
+               return NULL;
+       }
+}
+
 const uint8_t*
 hidPacket_getPacket(size_t* len)
 {
@@ -125,6 +146,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 5e93e7021b6ba0239e533da57383d4bf30944c39..b9a6215797b16779e817d16e119412a796ed1a65 100755 (executable)
@@ -18,6 +18,7 @@
 #include "scsi.h"\r
 #include "scsiPhy.h"\r
 #include "config.h"\r
+#include "debug.h"\r
 #include "disk.h"\r
 #include "led.h"\r
 #include "time.h"\r
@@ -79,7 +80,11 @@ int main()
                                scsiPhyConfig();\r
                                scsiInit();\r
                        }\r
-                       else\r
+            \r
+            // If USB is connected we could be busy transferring data\r
+            // Note: The same flag is used for the config USB interface and\r
+            // therefore SPI flash writes\r
+                       else if (!isDebugEnabled())\r
                        {\r
                                // Wait for our 1ms timer to save some power.\r
                                // There's an interrupt on the SEL signal to ensure we respond\r
index 536318a3af921774515764ef033dcf4cd189fc28..e1056abd54826412e6a2ef30287d8ba88f8c17bc 100755 (executable)
@@ -993,10 +993,10 @@ void sdCheckPresent()
                SD_CS_Write(0);\r
                SD_CS_SetDriveMode(SD_CS_DM_DIG_HIZ);\r
 \r
-               // Delay extended to work with 60cm cables running cards at 2.85V\r
-               CyDelayCycles(128);\r
+               // Delay reduced for v5.2 board, no support for extension cables.\r
+               CyDelayCycles(32);\r
                uint8_t cs = SD_CS_Read();\r
-               SD_CS_SetDriveMode(SD_CS_DM_STRONG)     ;\r
+               SD_CS_SetDriveMode(SD_CS_DM_STRONG);\r
 \r
                if (cs && !(sdCard.dev.mediaState & MEDIA_PRESENT))\r
                {\r
index 735b8f8afe87f5bc6bb8e5126485b298229bc156..76c7733007fe7149e50924855f69045538ee0650 100644 (file)
Binary files a/software/SCSI2SD/v5.2/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v5.2/SCSI2SD.cydsn/SCSI2SD.cyfit differ
index d0ea3d89fd7210bed7fc675ca09b3de09db2fcfe..85a833486de8bfb52a223c9005a71fc79f5df9aa 100644 (file)
@@ -42,6 +42,10 @@ void hidPacket_recv(const uint8_t* bytes, size_t len);
 // available.
 const uint8_t* hidPacket_getPacket(size_t* len);
 
+// Returns the received packet contents, or NULL if a complete packet isn't
+// available. Does not modify state
+const uint8_t* hidPacket_peekPacket(size_t* len);
+
 // Call this with packet data to send. len <= USBHID_LEN
 // Overwrites any packet currently being sent.
 void hidPacket_send(const uint8_t* bytes, size_t len);
@@ -50,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