#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
\r
#include <string.h>\r
\r
-static const uint16_t FIRMWARE_VERSION = 0x060D;\r
+static const uint16_t FIRMWARE_VERSION = 0x060E;\r
\r
// 1 flash row\r
static const uint8_t DEFAULT_CONFIG[128] =\r
\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
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
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
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
break;\r
\r
case S2S_CMD_DEBUG:\r
+ if (debugTimerStarted == 0) {\r
+ debugInit();\r
+ }\r
debugCommand();\r
break;\r
\r
\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
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