Synch transfer fix
[SCSI2SD-V6.git] / src / firmware / config.c
index 7ab2001..9bb8b11 100755 (executable)
@@ -25,6 +25,7 @@
 #include "trace.h"\r
 #include "bootloader.h"\r
 #include "bsp.h"\r
+#include "spinlock.h"\r
 \r
 #include "../../include/scsi2sd.h"\r
 #include "../../include/hidpacket.h"\r
@@ -37,7 +38,7 @@
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x060B;\r
+static const uint16_t FIRMWARE_VERSION = 0x060E;\r
 \r
 // 1 flash row\r
 static const uint8_t DEFAULT_CONFIG[128] =\r
@@ -64,6 +65,25 @@ enum USB_STATE
 \r
 static int usbInEpState;\r
 \r
+static void s2s_debugTimer();\r
+\r
+// Debug timer to log via USB.\r
+// Timer 6 & 7 is a simple counter with no external IO supported.\r
+static s2s_lock_t usbDevLock = s2s_lock_init;\r
+TIM_HandleTypeDef htim7;\r
+static int debugTimerStarted = 0;\r
+void TIM7_IRQHandler()\r
+{\r
+       HAL_TIM_IRQHandler(&htim7);\r
+}\r
+void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)\r
+{\r
+       if (s2s_spin_trylock(&usbDevLock)) {\r
+               s2s_debugTimer();\r
+               s2s_spin_unlock(&usbDevLock);\r
+       }\r
+}\r
+\r
 void s2s_configInit(S2S_BoardCfg* config)\r
 {\r
 \r
@@ -108,7 +128,25 @@ void s2s_configInit(S2S_BoardCfg* config)
                        config->flags6 = S2S_CFG_ENABLE_TERMINATOR;\r
                }\r
        }\r
+}\r
 \r
+static void debugInit(void)\r
+{\r
+       if (debugTimerStarted == 1) return;\r
+\r
+       debugTimerStarted = 1;\r
+       // 10ms debug timer to capture logs over USB\r
+       __TIM7_CLK_ENABLE();\r
+       htim7.Instance = TIM7;\r
+       htim7.Init.Prescaler = 10800 - 1; // 16bit. 108MHz down to 10KHz\r
+       htim7.Init.CounterMode = TIM_COUNTERMODE_UP;\r
+       htim7.Init.Period = 100 - 1; // 16bit. 10KHz down to 10ms.\r
+       htim7.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;\r
+       HAL_TIM_Base_Init(&htim7);\r
+       HAL_TIM_Base_Start_IT(&htim7);\r
+\r
+       HAL_NVIC_SetPriority(TIM7_IRQn, 10, 0);\r
+       HAL_NVIC_EnableIRQ(TIM7_IRQn);\r
 }\r
 \r
 \r
@@ -170,10 +208,10 @@ debugCommand()
        response[14] = scsiDev.lastStatus;\r
        response[15] = scsiDev.lastSense;\r
        response[16] = scsiDev.phase;\r
-       response[17] = scsiStatusBSY();\r
-       response[18] = scsiStatusSEL();\r
-       response[19] = scsiStatusATN();\r
-       response[20] = scsiStatusRST();\r
+       response[17] = *SCSI_STS_SCSI;\r
+       response[18] = scsiDev.target != NULL ? scsiDev.target->syncOffset : 0;\r
+       response[19] = scsiDev.target != NULL ? scsiDev.target->syncPeriod : 0;\r
+       response[20] = scsiDev.minSyncPeriod;\r
        response[21] = scsiDev.rstCount;\r
        response[22] = scsiDev.selCount;\r
        response[23] = scsiDev.msgCount;\r
@@ -184,7 +222,7 @@ debugCommand()
        response[28] = scsiDev.lastSenseASC;\r
        response[29] = *SCSI_STS_DBX;\r
        response[30] = LastTrace;\r
-       response[31] = scsiStatusACK();\r
+       response[31] = 0; // Unused\r
        hidPacket_send(response, sizeof(response));\r
 }\r
 \r
@@ -262,6 +300,9 @@ processCommand(const uint8_t* cmd, size_t cmdSize)
                break;\r
 \r
        case S2S_CMD_DEBUG:\r
+               if (debugTimerStarted == 0) {\r
+                       debugInit();\r
+               }\r
                debugCommand();\r
                break;\r
 \r
@@ -273,10 +314,12 @@ processCommand(const uint8_t* cmd, size_t cmdSize)
 \r
 void s2s_configPoll()\r
 {\r
+       s2s_spin_lock(&usbDevLock);\r
+\r
        if (!USBD_Composite_IsConfigured(&hUsbDeviceFS))\r
        {\r
                usbInEpState = USB_IDLE;\r
-               return;\r
+               goto out;\r
        }\r
 \r
        if (USBD_HID_IsReportReady(&hUsbDeviceFS))\r
@@ -322,6 +365,65 @@ void s2s_configPoll()
                break;\r
        }\r
 \r
+out:\r
+       s2s_spin_unlock(&usbDevLock);\r
+}\r
+\r
+void s2s_debugTimer()\r
+{\r
+       if (!USBD_Composite_IsConfigured(&hUsbDeviceFS))\r
+       {\r
+               usbInEpState = USB_IDLE;\r
+               return;\r
+       }\r
+\r
+       if (USBD_HID_IsReportReady(&hUsbDeviceFS))\r
+       {\r
+               uint8_t hidBuffer[USBHID_LEN];\r
+               int byteCount = USBD_HID_GetReport(&hUsbDeviceFS, hidBuffer, sizeof(hidBuffer));\r
+               hidPacket_recv(hidBuffer, byteCount);\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
+               if (cmd && (cmdSize > 0))\r
+               {\r
+                       if (cmd[0] == S2S_CMD_DEBUG)\r
+                       {\r
+                               hidPacket_getPacket(&cmdSize);\r
+                               debugCommand();\r
+                       }\r
+                       else if (cmd[0] == S2S_CMD_PING)\r
+                       {\r
+                               hidPacket_getPacket(&cmdSize);\r
+                               pingCommand();\r
+                       }\r
+               }\r
+       }\r
+\r
+       switch (usbInEpState)\r
+       {\r
+               case USB_IDLE:\r
+               {\r
+                       uint8_t hidBuffer[USBHID_LEN];\r
+                       const uint8_t* nextChunk = hidPacket_getHIDBytes(hidBuffer);\r
+\r
+                       if (nextChunk)\r
+                       {\r
+                               USBD_HID_SendReport (&hUsbDeviceFS, nextChunk, sizeof(hidBuffer));\r
+                               usbInEpState = USB_DATA_SENT;\r
+                       }\r
+               }\r
+               break;\r
+\r
+               case USB_DATA_SENT:\r
+                       if (!USBD_HID_IsBusy(&hUsbDeviceFS))\r
+                       {\r
+                               // Data accepted.\r
+                               usbInEpState = USB_IDLE;\r
+                       }\r
+                       break;\r
+       }\r
 }\r
 \r
 \r