Ensure debug logs are triggered by a timer to catch firmware hangs
authorMichael McMaster <michael@codesrc.com>
Sat, 8 May 2021 07:20:39 +0000 (17:20 +1000)
committerMichael McMaster <michael@codesrc.com>
Sat, 8 May 2021 07:20:39 +0000 (17:20 +1000)
src/firmware/config.c

index ea9a9f56ff85fa3ed358d586ec13cc5d3c2c798f..47eb504c3f3c6af9c966066eaba987975304f602 100755 (executable)
@@ -1,19 +1,19 @@
-//     Copyright (C) 2014 Michael McMaster <michael@codesrc.com>\r
+//    Copyright (C) 2014 Michael McMaster <michael@codesrc.com>\r
 //\r
-//     This file is part of SCSI2SD.\r
+//    This file is part of SCSI2SD.\r
 //\r
-//     SCSI2SD is free software: you can redistribute it and/or modify\r
-//     it under the terms of the GNU General Public License as published by\r
-//     the Free Software Foundation, either version 3 of the License, or\r
-//     (at your option) any later version.\r
+//    SCSI2SD is free software: you can redistribute it and/or modify\r
+//    it under the terms of the GNU General Public License as published by\r
+//    the Free Software Foundation, either version 3 of the License, or\r
+//    (at your option) any later version.\r
 //\r
-//     SCSI2SD is distributed in the hope that it will be useful,\r
-//     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-//     GNU General Public License for more details.\r
+//    SCSI2SD is distributed in the hope that it will be useful,\r
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+//    GNU General Public License for more details.\r
 //\r
-//     You should have received a copy of the GNU General Public License\r
-//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.\r
+//    You should have received a copy of the GNU General Public License\r
+//    along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.\r
 \r
 #include "config.h"\r
 #include "led.h"\r
@@ -50,12 +50,12 @@ extern uint8_t* __fixed_config;
 // 1 flash row\r
 static const uint8_t DEFAULT_CONFIG[128] =\r
 {\r
-       0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00,\r
-       0x00, 0x02, 0x3F, 0x00, 0xFF, 0x00, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x73,\r
-       0x72, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53,\r
-       0x43, 0x53, 0x49, 0x32, 0x53, 0x44, 0x20, 0x31, 0x2E, 0x30, 0x31, 0x32,\r
-       0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,\r
-       0x37, 0x38, 0x00, 0x00\r
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00,\r
+    0x00, 0x02, 0x3F, 0x00, 0xFF, 0x00, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x73,\r
+    0x72, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53,\r
+    0x43, 0x53, 0x49, 0x32, 0x53, 0x44, 0x20, 0x31, 0x2E, 0x30, 0x31, 0x32,\r
+    0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,\r
+    0x37, 0x38, 0x00, 0x00\r
 };\r
 \r
 \r
@@ -65,8 +65,8 @@ static uint8_t configDmaBuf[512] S2S_DMA_ALIGN; // For SD card writes.
 \r
 enum USB_STATE\r
 {\r
-       USB_IDLE,\r
-       USB_DATA_SENT\r
+    USB_IDLE,\r
+    USB_DATA_SENT\r
 };\r
 \r
 \r
@@ -79,419 +79,424 @@ static void s2s_debugTimer();
 static s2s_lock_t usbDevLock = s2s_lock_init;\r
 TIM_HandleTypeDef htim7;\r
 static int debugTimerStarted = 0;\r
+\r
 void TIM7_IRQHandler()\r
 {\r
-       HAL_TIM_IRQHandler(&htim7);\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
+    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
-       usbInEpState = USB_IDLE;\r
-\r
-       if (memcmp(__fixed_config, "BCFG", 4) == 0)\r
-       {\r
-               // Use hardcoded config\r
-               memcpy(s2s_cfg, __fixed_config, S2S_CFG_SIZE);\r
-               memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
-       }\r
-\r
-       else if ((blockDev.state & DISK_PRESENT) && sdDev.capacity)\r
-       {\r
-               int cfgSectors = (S2S_CFG_SIZE + 511) / 512;\r
-               BSP_SD_ReadBlocks_DMA(\r
-                       &s2s_cfg[0],\r
-                       sdDev.capacity - cfgSectors,\r
-                       cfgSectors);\r
-\r
-               memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
-\r
-               if (memcmp(config->magic, "BCFG", 4))\r
-               {\r
-                       // Invalid SD card config, use default.\r
-                       memset(&s2s_cfg[0], 0, S2S_CFG_SIZE);\r
-                       memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
-                       memcpy(config->magic, "BCFG", 4);\r
-                       config->selectionDelay = 255; // auto\r
-                       config->flags6 = S2S_CFG_ENABLE_TERMINATOR;\r
-\r
-                       memcpy(\r
-                               &s2s_cfg[0] + sizeof(S2S_BoardCfg),\r
-                               DEFAULT_CONFIG,\r
-                               sizeof(S2S_TargetCfg));\r
-               }\r
-       }\r
-       else\r
-       {\r
-               // No SD card, use existing config if valid\r
-               if (memcmp(config->magic, "BCFG", 4))\r
-               {\r
-                       // Not valid, use empty config with no disks.\r
-                       memset(&s2s_cfg[0], 0, S2S_CFG_SIZE);\r
-                       memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
-                       config->selectionDelay = 255; // auto\r
-                       config->flags6 = S2S_CFG_ENABLE_TERMINATOR;\r
-               }\r
-       }\r
+    usbInEpState = USB_IDLE;\r
+\r
+    if (memcmp(__fixed_config, "BCFG", 4) == 0)\r
+    {\r
+        // Use hardcoded config\r
+        memcpy(s2s_cfg, __fixed_config, S2S_CFG_SIZE);\r
+        memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
+    }\r
+\r
+    else if ((blockDev.state & DISK_PRESENT) && sdDev.capacity)\r
+    {\r
+        int cfgSectors = (S2S_CFG_SIZE + 511) / 512;\r
+        BSP_SD_ReadBlocks_DMA(\r
+            &s2s_cfg[0],\r
+            sdDev.capacity - cfgSectors,\r
+            cfgSectors);\r
+\r
+        memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
+\r
+        if (memcmp(config->magic, "BCFG", 4))\r
+        {\r
+            // Invalid SD card config, use default.\r
+            memset(&s2s_cfg[0], 0, S2S_CFG_SIZE);\r
+            memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
+            memcpy(config->magic, "BCFG", 4);\r
+            config->selectionDelay = 255; // auto\r
+            config->flags6 = S2S_CFG_ENABLE_TERMINATOR;\r
+\r
+            memcpy(\r
+                &s2s_cfg[0] + sizeof(S2S_BoardCfg),\r
+                DEFAULT_CONFIG,\r
+                sizeof(S2S_TargetCfg));\r
+        }\r
+    }\r
+    else\r
+    {\r
+        // No SD card, use existing config if valid\r
+        if (memcmp(config->magic, "BCFG", 4))\r
+        {\r
+            // Not valid, use empty config with no disks.\r
+            memset(&s2s_cfg[0], 0, S2S_CFG_SIZE);\r
+            memcpy(config, s2s_cfg, sizeof(S2S_BoardCfg));\r
+            config->selectionDelay = 255; // auto\r
+            config->flags6 = S2S_CFG_ENABLE_TERMINATOR;\r
+        }\r
+    }\r
 }\r
 \r
 static void debugInit(void)\r
 {\r
-       if (debugTimerStarted == 1) return;\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
+    debugTimerStarted = 1;\r
+    // 10ms debug timer to capture logs over USB\r
+    __TIM7_CLK_ENABLE();\r
+    htim7.Instance = TIM7;\r
 #ifdef STM32F2xx\r
-       htim7.Init.Prescaler = 10800 - 1; // 16bit. 108MHz down to 10KHz\r
+    htim7.Init.Prescaler = 10800 - 1; // 16bit. 108MHz down to 10KHz\r
 #else\r
-       htim7.Init.Prescaler = 18000 - 1; // 16bit. 180MHz down to 10KHz\r
+    htim7.Init.Prescaler = 18000 - 1; // 16bit. 180MHz down to 10KHz\r
 #endif\r
 \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
+    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
+    HAL_NVIC_SetPriority(TIM7_IRQn, 10, 0);\r
+    HAL_NVIC_EnableIRQ(TIM7_IRQn);\r
 }\r
 \r
 \r
 static void\r
 pingCommand()\r
 {\r
-       uint8_t response[] =\r
-       {\r
-               S2S_CFG_STATUS_GOOD\r
-       };\r
-       hidPacket_send(response, sizeof(response));\r
+    uint8_t response[] =\r
+    {\r
+        S2S_CFG_STATUS_GOOD\r
+    };\r
+    hidPacket_send(response, sizeof(response));\r
 }\r
 \r
 static void\r
 sdInfoCommand()\r
 {\r
-       uint8_t response[sizeof(sdDev.csd) + sizeof(sdDev.cid)];\r
-       memcpy(response, sdDev.csd, sizeof(sdDev.csd));\r
-       memcpy(response + sizeof(sdDev.csd), sdDev.cid, sizeof(sdDev.cid));\r
+    uint8_t response[sizeof(sdDev.csd) + sizeof(sdDev.cid)];\r
+    memcpy(response, sdDev.csd, sizeof(sdDev.csd));\r
+    memcpy(response + sizeof(sdDev.csd), sdDev.cid, sizeof(sdDev.cid));\r
 \r
-       hidPacket_send(response, sizeof(response));\r
+    hidPacket_send(response, sizeof(response));\r
 }\r
 \r
 \r
 static void\r
 scsiTestCommand()\r
 {\r
-       int resultCode = scsiSelfTest();\r
-       uint8_t response[] =\r
-       {\r
-               resultCode == 0 ? S2S_CFG_STATUS_GOOD : S2S_CFG_STATUS_ERR,\r
-               resultCode\r
-       };\r
-       hidPacket_send(response, sizeof(response));\r
+    int resultCode = scsiSelfTest();\r
+    uint8_t response[] =\r
+    {\r
+        resultCode == 0 ? S2S_CFG_STATUS_GOOD : S2S_CFG_STATUS_ERR,\r
+        resultCode\r
+    };\r
+    hidPacket_send(response, sizeof(response));\r
 }\r
 \r
 static void\r
 scsiDevInfoCommand()\r
 {\r
-       uint8_t response[] =\r
-       {\r
-               FIRMWARE_VERSION >> 8,\r
-               FIRMWARE_VERSION & 0xff,\r
-               sdDev.capacity >> 24,\r
-               sdDev.capacity >> 16,\r
-               sdDev.capacity >> 8,\r
-               sdDev.capacity,\r
-               1 // useSdConfig, always true for V6.\r
-       };\r
-       hidPacket_send(response, sizeof(response));\r
+    uint8_t response[] =\r
+    {\r
+        FIRMWARE_VERSION >> 8,\r
+        FIRMWARE_VERSION & 0xff,\r
+        sdDev.capacity >> 24,\r
+        sdDev.capacity >> 16,\r
+        sdDev.capacity >> 8,\r
+        sdDev.capacity,\r
+        1 // useSdConfig, always true for V6.\r
+    };\r
+    hidPacket_send(response, sizeof(response));\r
 }\r
 \r
 static void\r
 debugCommand()\r
 {\r
-       uint8_t response[32];\r
-       memcpy(&response, &scsiDev.cdb, 12);\r
-       response[12] = scsiDev.msgIn;\r
-       response[13] = scsiDev.msgOut;\r
-       response[14] = scsiDev.lastStatus;\r
-       response[15] = scsiDev.lastSense;\r
-       response[16] = scsiDev.phase;\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
-       response[24] = scsiDev.cmdCount;\r
-       response[25] = scsiDev.watchdogTick;\r
-       response[26] = blockDev.state;\r
-       response[27] = scsiDev.lastSenseASC >> 8;\r
-       response[28] = scsiDev.lastSenseASC;\r
-       response[29] = *SCSI_STS_DBX & 0xff; // What we've read\r
-       response[30] = *SCSI_STS_SELECTED;\r
-       response[31] = *SCSI_STS_DBX >> 8; // What we're writing\r
-       hidPacket_send(response, sizeof(response));\r
+    uint8_t response[32];\r
+    memcpy(&response, &scsiDev.cdb, 12);\r
+    response[12] = scsiDev.msgIn;\r
+    response[13] = scsiDev.msgOut;\r
+    response[14] = scsiDev.lastStatus;\r
+    response[15] = scsiDev.lastSense;\r
+    response[16] = scsiDev.phase;\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
+    response[24] = scsiDev.cmdCount;\r
+    response[25] = scsiDev.watchdogTick;\r
+    response[26] = blockDev.state;\r
+    response[27] = scsiDev.lastSenseASC >> 8;\r
+    response[28] = scsiDev.lastSenseASC;\r
+    response[29] = *SCSI_STS_DBX & 0xff; // What we've read\r
+    response[30] = *SCSI_STS_SELECTED;\r
+    response[31] = *SCSI_STS_DBX >> 8; // What we're writing\r
+    hidPacket_send(response, sizeof(response));\r
 }\r
 \r
 static void\r
 sdWriteCommand(const uint8_t* cmd, size_t cmdSize)\r
 {\r
-       if (cmdSize < 517)\r
-       {\r
-               return; // ignore.\r
-       }\r
-       uint32_t lba =\r
-               (((uint32_t)cmd[1]) << 24) |\r
-               (((uint32_t)cmd[2]) << 16) |\r
-               (((uint32_t)cmd[3]) << 8) |\r
-               ((uint32_t)cmd[4]);\r
-\r
-       memcpy(configDmaBuf, &cmd[5], 512);\r
-       BSP_SD_WriteBlocks_DMA(configDmaBuf, lba, 1);\r
-\r
-       uint8_t response[] =\r
-       {\r
-               S2S_CFG_STATUS_GOOD\r
-       };\r
-       hidPacket_send(response, sizeof(response));\r
+    if (cmdSize < 517)\r
+    {\r
+        return; // ignore.\r
+    }\r
+    uint32_t lba =\r
+        (((uint32_t)cmd[1]) << 24) |\r
+        (((uint32_t)cmd[2]) << 16) |\r
+        (((uint32_t)cmd[3]) << 8) |\r
+        ((uint32_t)cmd[4]);\r
+\r
+    memcpy(configDmaBuf, &cmd[5], 512);\r
+    BSP_SD_WriteBlocks_DMA(configDmaBuf, lba, 1);\r
+\r
+    uint8_t response[] =\r
+    {\r
+        S2S_CFG_STATUS_GOOD\r
+    };\r
+    hidPacket_send(response, sizeof(response));\r
 }\r
 \r
 static void\r
 sdReadCommand(const uint8_t* cmd, size_t cmdSize)\r
 {\r
-       if (cmdSize < 5)\r
-       {\r
-               return; // ignore.\r
-       }\r
-       uint32_t lba =\r
-               (((uint32_t)cmd[1]) << 24) |\r
-               (((uint32_t)cmd[2]) << 16) |\r
-               (((uint32_t)cmd[3]) << 8) |\r
-               ((uint32_t)cmd[4]);\r
-\r
-       BSP_SD_ReadBlocks_DMA(configDmaBuf, lba, 1);\r
-       hidPacket_send(configDmaBuf, 512);\r
+    if (cmdSize < 5)\r
+    {\r
+        return; // ignore.\r
+    }\r
+    uint32_t lba =\r
+        (((uint32_t)cmd[1]) << 24) |\r
+        (((uint32_t)cmd[2]) << 16) |\r
+        (((uint32_t)cmd[3]) << 8) |\r
+        ((uint32_t)cmd[4]);\r
+\r
+    BSP_SD_ReadBlocks_DMA(configDmaBuf, lba, 1);\r
+    hidPacket_send(configDmaBuf, 512);\r
 }\r
 \r
 static void\r
 processCommand(const uint8_t* cmd, size_t cmdSize)\r
 {\r
-       switch (cmd[0])\r
-       {\r
-       case S2S_CMD_PING:\r
-               pingCommand();\r
-               break;\r
-\r
-       case S2S_CMD_REBOOT:\r
-               s2s_enterBootloader();\r
-               break;\r
-\r
-       case S2S_CMD_SDINFO:\r
-               sdInfoCommand();\r
-               break;\r
-\r
-       case S2S_CMD_SCSITEST:\r
-               scsiTestCommand();\r
-               break;\r
-\r
-       case S2S_CMD_DEVINFO:\r
-               scsiDevInfoCommand();\r
-               break;\r
-\r
-       case S2S_CMD_SD_WRITE:\r
-               sdWriteCommand(cmd, cmdSize);\r
-               break;\r
-\r
-       case S2S_CMD_SD_READ:\r
-               sdReadCommand(cmd, cmdSize);\r
-               break;\r
-\r
-       case S2S_CMD_DEBUG:\r
-               if (debugTimerStarted == 0) {\r
-                       debugInit();\r
-               }\r
-               debugCommand();\r
-               break;\r
-\r
-       case S2S_CMD_NONE: // invalid\r
-       default:\r
-               break;\r
-       }\r
+    switch (cmd[0])\r
+    {\r
+    case S2S_CMD_PING:\r
+        pingCommand();\r
+        break;\r
+\r
+    case S2S_CMD_REBOOT:\r
+        s2s_enterBootloader();\r
+        break;\r
+\r
+    case S2S_CMD_SDINFO:\r
+        sdInfoCommand();\r
+        break;\r
+\r
+    case S2S_CMD_SCSITEST:\r
+        scsiTestCommand();\r
+        break;\r
+\r
+    case S2S_CMD_DEVINFO:\r
+        scsiDevInfoCommand();\r
+        break;\r
+\r
+    case S2S_CMD_SD_WRITE:\r
+        sdWriteCommand(cmd, cmdSize);\r
+        break;\r
+\r
+    case S2S_CMD_SD_READ:\r
+        sdReadCommand(cmd, cmdSize);\r
+        break;\r
+\r
+    case S2S_CMD_DEBUG:\r
+        if (debugTimerStarted == 0) {\r
+            debugInit();\r
+            debugCommand();\r
+        }\r
+        // Always triggered from timer for consistent behaviour\r
+\r
+        break;\r
+\r
+    case S2S_CMD_NONE: // invalid\r
+    default:\r
+        break;\r
+    }\r
 }\r
 \r
 void s2s_configPoll()\r
 {\r
-       s2s_spin_lock(&usbDevLock);\r
-\r
-       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
-               // 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
-\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 (&configUsbDev, nextChunk, sizeof(hidBuffer));\r
-                               usbInEpState = USB_DATA_SENT;\r
-                       }\r
-               }\r
-               break;\r
-\r
-       case USB_DATA_SENT:\r
-               if (!USBD_HID_IsBusy(&configUsbDev))\r
-               {\r
-                       // Data accepted.\r
-                       usbInEpState = USB_IDLE;\r
-               }\r
-               break;\r
-       }\r
+    s2s_spin_lock(&usbDevLock);\r
+\r
+    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
+        // 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
+        if (cmd && (cmdSize > 0))\r
+        {\r
+            if (!debugTimerStarted || (cmd[0] != S2S_CMD_DEBUG))\r
+            {\r
+                hidPacket_getPacket(&cmdSize);\r
+                s2s_ledOn();\r
+                processCommand(cmd, cmdSize);\r
+                s2s_ledOff();\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 (&configUsbDev, nextChunk, sizeof(hidBuffer));\r
+                usbInEpState = USB_DATA_SENT;\r
+            }\r
+        }\r
+        break;\r
+\r
+    case USB_DATA_SENT:\r
+        if (!USBD_HID_IsBusy(&configUsbDev))\r
+        {\r
+            // Data accepted.\r
+            usbInEpState = USB_IDLE;\r
+        }\r
+        break;\r
+    }\r
 \r
 out:\r
-       s2s_spin_unlock(&usbDevLock);\r
+    s2s_spin_unlock(&usbDevLock);\r
 }\r
 \r
 void s2s_debugTimer()\r
 {\r
-       if (!USBD_Composite_IsConfigured(&configUsbDev))\r
-       {\r
-               usbInEpState = USB_IDLE;\r
-               return;\r
-       }\r
-\r
-       if (USBD_HID_IsReportReady(&configUsbDev))\r
-       {\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
-               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 (&configUsbDev, nextChunk, sizeof(hidBuffer));\r
-                               usbInEpState = USB_DATA_SENT;\r
-                       }\r
-               }\r
-               break;\r
-\r
-               case USB_DATA_SENT:\r
-                       if (!USBD_HID_IsBusy(&configUsbDev))\r
-                       {\r
-                               // Data accepted.\r
-                               usbInEpState = USB_IDLE;\r
-                       }\r
-                       break;\r
-       }\r
+    if (!USBD_Composite_IsConfigured(&configUsbDev))\r
+    {\r
+        usbInEpState = USB_IDLE;\r
+        hidPacket_reset();\r
+        return;\r
+    }\r
+\r
+    if (USBD_HID_IsReportReady(&configUsbDev))\r
+    {\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
+        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
+\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 (&configUsbDev, nextChunk, sizeof(hidBuffer));\r
+                usbInEpState = USB_DATA_SENT;\r
+            }\r
+        }\r
+        break;\r
+\r
+        case USB_DATA_SENT:\r
+            if (!USBD_HID_IsBusy(&configUsbDev))\r
+            {\r
+                // Data accepted.\r
+                usbInEpState = USB_IDLE;\r
+            }\r
+            break;\r
+    }\r
 }\r
 \r
-\r
-\r
 // Public method for storing MODE SELECT results.\r
 void s2s_configSave(int scsiId, uint16_t bytesPerSector)\r
 {\r
-       S2S_TargetCfg* cfg = (S2S_TargetCfg*) s2s_getConfigById(scsiId);\r
-       cfg->bytesPerSector = bytesPerSector;\r
+    S2S_TargetCfg* cfg = (S2S_TargetCfg*) s2s_getConfigById(scsiId);\r
+    cfg->bytesPerSector = bytesPerSector;\r
 \r
-       BSP_SD_WriteBlocks_DMA(\r
-               &s2s_cfg[0],\r
-               sdDev.capacity - S2S_CFG_SIZE,\r
-               (S2S_CFG_SIZE + 511) / 512);\r
+    BSP_SD_WriteBlocks_DMA(\r
+        &s2s_cfg[0],\r
+        sdDev.capacity - S2S_CFG_SIZE,\r
+        (S2S_CFG_SIZE + 511) / 512);\r
 }\r
 \r
-\r
 const S2S_TargetCfg* s2s_getConfigByIndex(int i)\r
 {\r
-       return (const S2S_TargetCfg*)\r
-               (s2s_cfg + sizeof(S2S_BoardCfg) + (i * sizeof(S2S_TargetCfg)));\r
+    return (const S2S_TargetCfg*)\r
+        (s2s_cfg + sizeof(S2S_BoardCfg) + (i * sizeof(S2S_TargetCfg)));\r
 }\r
 \r
 const S2S_TargetCfg* s2s_getConfigById(int scsiId)\r
 {\r
-       int i;\r
-       for (i = 0; i < S2S_MAX_TARGETS; ++i)\r
-       {\r
-               const S2S_TargetCfg* tgt = s2s_getConfigByIndex(i);\r
-               if ((tgt->scsiId & S2S_CFG_TARGET_ID_BITS) == scsiId)\r
-               {\r
-                       return tgt;\r
-               }\r
-       }\r
-       return NULL;\r
-\r
+    int i;\r
+    for (i = 0; i < S2S_MAX_TARGETS; ++i)\r
+    {\r
+        const S2S_TargetCfg* tgt = s2s_getConfigByIndex(i);\r
+        if ((tgt->scsiId & S2S_CFG_TARGET_ID_BITS) == scsiId)\r
+        {\r
+            return tgt;\r
+        }\r
+    }\r
+    return NULL;\r
 }\r
 \r