Fix up SCSI timing and data corruption on 2021 boards
authorMichael McMaster <michael@codesrc.com>
Fri, 23 Apr 2021 11:39:48 +0000 (21:39 +1000)
committerMichael McMaster <michael@codesrc.com>
Fri, 23 Apr 2021 11:39:48 +0000 (21:39 +1000)
src/firmware/config.c
src/firmware/disk.c
src/firmware/scsiPhy.c
src/firmware/scsiPhyTiming108MHz.h [new file with mode: 0755]
src/firmware/scsiPhyTiming90MHz.h [new file with mode: 0755]

index 564d56942737760d8febfa6f9ce34523be07e5c4..e75be816c4983835776a2fc7ac7ebfef7cdae28d 100755 (executable)
@@ -36,7 +36,7 @@
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x0640;\r
+static const uint16_t FIRMWARE_VERSION = 0x0641;\r
 \r
 // Optional static config\r
 extern uint8_t* __fixed_config;\r
index cdd7c45e20bf78ba7dfe71346811f4fe8f5a7479..72cfeda9c2112bacfa170b7291d6e62aa33a21b7 100755 (executable)
@@ -739,6 +739,12 @@ void scsiDiskPoll()
                int enableParity = scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY;\r
 \r
                uint32_t maxSectors = sizeof(scsiDev.data) / SD_SECTOR_SIZE;\r
+        #ifdef STM32F4xx\r
+        // TODO fix this hack\r
+        // corruption occurs with 65536 byte transfers but not 32768\r
+        // works fine on STM32F2 (or at least it did with older firmware ?\r
+        if (maxSectors > 64) maxSectors = 64;\r
+        #endif\r
 \r
                static_assert(SCSI_XFER_MAX >= sizeof(scsiDev.data), "Assumes SCSI_XFER_MAX >= sizeof(scsiDev.data)");\r
 \r
index 2f925fff3611059f392f112ff57747b592cb0d30..b90fd6c63bb7b9266d41b19a4e2562110e186327 100755 (executable)
 \r
 #include <string.h>\r
 \r
-static uint8_t asyncTimings[][4] =\r
-{\r
-/* Speed,    Assert,    Deskew,    Hold,    Glitch */\r
-{/*1.5MB/s*/ 28,        18,        7,      15},\r
-//{/*1.5MB/s*/ 63,        31,        7,      15},\r
-{/*3.3MB/s*/ 13,        6,         6,       13},\r
-{/*5MB/s*/   9,         6,         6,       6}, // 80ns\r
-{/*safe*/    3,         6,         6,       6}, // Probably safe\r
-{/*turbo*/   3,         3,         3,       2}\r
-};\r
-\r
 #define SCSI_ASYNC_15 0\r
 #define SCSI_ASYNC_33 1\r
 #define SCSI_ASYNC_50 2\r
 #define SCSI_ASYNC_SAFE 3\r
 #define SCSI_ASYNC_TURBO 4\r
 \r
-// 5MB/s synchronous timing\r
-#define SCSI_FAST5_DESKEW 6 // 55ns\r
-#define SCSI_FAST5_HOLD 6 // 53ns\r
-\r
-// 10MB/s synchronous timing\r
-// 2:0 Deskew count, 25ns\r
-// 6:4 Hold count, 33ns\r
-// 3:0 Assertion count, 30ns\r
-// We want deskew + hold + assert + 3 to add up to 11 clocks\r
-// the fpga code has 1 clock of overhead when transitioning from deskew to\r
-// assert to hold\r
-\r
-#define SCSI_FAST10_DESKEW 2 // 25ns\r
-#define SCSI_FAST10_HOLD 3 // 33ns\r
-#define SCSI_FAST10_WRITE_ASSERT 3 // 30ns. Overall clocks only works if fpga overhead is 3.\r
-\r
-// Slow down the cycle to be valid. 2x assert period is TOO FAST when\r
-// reading data. It's ok when writing due to the deskew.\r
-// 50ns. ie. 100ns / 2. Rounded down because there's likely a few extra cycles\r
-// here and there.\r
-#define SCSI_FAST10_READ_ASSERT 5\r
-\r
-// Fastest possible timing, probably not 20MB/s\r
-#define SCSI_FAST20_DESKEW 1\r
-#define SCSI_FAST20_HOLD 2\r
-#define SCSI_FAST20_ASSERT 2\r
-\r
-\r
-#define syncDeskew(period) ((period) < 35 ? \\r
-       SCSI_FAST10_DESKEW : SCSI_FAST5_DESKEW)\r
-\r
-#define syncHold(period) ((period) < 35 ? \\r
-       ((period) == 25 ? SCSI_FAST10_HOLD : 4) /* 25ns/33ns */\\r
-       : SCSI_FAST5_HOLD)\r
-\r
-\r
-// Number of overhead cycles per period.\r
-#define FPGA_OVERHEAD 2\r
-#define FPGA_CYCLES_PER_NS 9\r
-#define SCSI_PERIOD_CLKS(period) ((((int)period * 4) + (FPGA_CYCLES_PER_NS/2)) / FPGA_CYCLES_PER_NS)\r
-\r
-// 3.125MB/s (80 period) to < 10MB/s sync\r
-// Assumes a 108MHz fpga clock. (9 ns)\r
-// 3:0 Assertion count, variable\r
-#define syncAssertionWrite(period,deskew) ((SCSI_PERIOD_CLKS(period) - deskew - FPGA_OVERHEAD + 1) / 2)\r
-#define syncAssertionRead(period) syncAssertionWrite(period,0)\r
-\r
+#ifdef STM32F2xx\r
+#include "scsiPhyTiming108MHz.h"\r
+#endif\r
 \r
-// Time until we consider ourselves selected\r
-// 400ns at 108MHz\r
-#define SCSI_DEFAULT_SELECTION 43\r
-#define SCSI_FAST_SELECTION 5\r
+#ifdef STM32F4xx\r
+#include "scsiPhyTiming90MHz.h"\r
+#endif\r
 \r
 // Private DMA variables.\r
 static int dmaInProgress = 0;\r
diff --git a/src/firmware/scsiPhyTiming108MHz.h b/src/firmware/scsiPhyTiming108MHz.h
new file mode 100755 (executable)
index 0000000..9fa9019
--- /dev/null
@@ -0,0 +1,87 @@
+//     Copyright (C) 2021 Michael McMaster <michael@codesrc.com>
+//
+//     This file is part of SCSI2SD.
+//
+//     SCSI2SD is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+//
+//     SCSI2SD is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+//
+//     You should have received a copy of the GNU General Public License
+//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef S2S_SCSIPHYTIMING
+
+// Timing at a 108MHz clock.
+
+static uint8_t asyncTimings[][4] =
+{
+/* Speed,    Assert,    Deskew,    Hold,    Glitch */
+{/*1.5MB/s*/ 28,        18,        7,      15},
+//{/*1.5MB/s*/ 63,        31,        7,      15},
+{/*3.3MB/s*/ 13,        6,         6,       13},
+{/*5MB/s*/   9,         6,         6,       6}, // 80ns
+{/*safe*/    3,         6,         6,       6}, // Probably safe
+{/*turbo*/   3,         3,         3,       2}
+};
+
+// 5MB/s synchronous timing
+#define SCSI_FAST5_DESKEW 6 // 55ns
+#define SCSI_FAST5_HOLD 6 // 53ns
+
+// 10MB/s synchronous timing
+// 2:0 Deskew count, 25ns
+// 6:4 Hold count, 33ns
+// 3:0 Assertion count, 30ns
+// We want deskew + hold + assert + 3 to add up to 11 clocks
+// the fpga code has 1 clock of overhead when transitioning from deskew to
+// assert to hold
+
+#define SCSI_FAST10_DESKEW 2 // 25ns
+#define SCSI_FAST10_HOLD 3 // 33ns
+#define SCSI_FAST10_WRITE_ASSERT 3 // 30ns. Overall clocks only works if fpga overhead is 3.
+
+// Slow down the cycle to be valid. 2x assert period is TOO FAST when
+// reading data. It's ok when writing due to the deskew.
+// 50ns. ie. 100ns / 2. Rounded down because there's likely a few extra cycles
+// here and there.
+#define SCSI_FAST10_READ_ASSERT 5
+
+// Fastest possible timing, probably not 20MB/s
+#define SCSI_FAST20_DESKEW 1
+#define SCSI_FAST20_HOLD 2
+#define SCSI_FAST20_ASSERT 2
+
+
+#define syncDeskew(period) ((period) < 35 ? \
+       SCSI_FAST10_DESKEW : SCSI_FAST5_DESKEW)
+
+#define syncHold(period) ((period) < 35 ? \
+       ((period) == 25 ? SCSI_FAST10_HOLD : 4) /* 25ns/33ns */\
+       : SCSI_FAST5_HOLD)
+
+
+// Number of overhead cycles per period.
+#define FPGA_OVERHEAD 2
+#define FPGA_CYCLES_PER_NS 9
+#define SCSI_PERIOD_CLKS(period) ((((int)period * 4) + (FPGA_CYCLES_PER_NS/2)) / FPGA_CYCLES_PER_NS)
+
+// 3.125MB/s (80 period) to < 10MB/s sync
+// Assumes a 108MHz fpga clock. (9 ns)
+// 3:0 Assertion count, variable
+#define syncAssertionWrite(period,deskew) ((SCSI_PERIOD_CLKS(period) - deskew - FPGA_OVERHEAD + 1) / 2)
+#define syncAssertionRead(period) syncAssertionWrite(period,0)
+
+
+// Time until we consider ourselves selected
+// 400ns at 108MHz
+#define SCSI_DEFAULT_SELECTION 43
+#define SCSI_FAST_SELECTION 5
+
+
+#endif // S2S_SCSIPHYTIMING
diff --git a/src/firmware/scsiPhyTiming90MHz.h b/src/firmware/scsiPhyTiming90MHz.h
new file mode 100755 (executable)
index 0000000..d1ee2be
--- /dev/null
@@ -0,0 +1,85 @@
+//     Copyright (C) 2021 Michael McMaster <michael@codesrc.com>
+//
+//     This file is part of SCSI2SD.
+//
+//     SCSI2SD is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+//
+//     SCSI2SD is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+//
+//     You should have received a copy of the GNU General Public License
+//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef S2S_SCSIPHYTIMING
+
+// Timing at a 90Hz clock.
+
+static uint8_t asyncTimings[][4] =
+{
+/* Speed,    Assert,    Deskew,    Hold,    Glitch */
+{/*1.5MB/s*/ 23,        15,        6,      12},
+{/*3.3MB/s*/ 11,        5,         5,      11},
+{/*5MB/s*/   8,         5,         5,       5}, // 80ns
+{/*safe*/    2,         5,         5,       5}, // Probably safe
+{/*turbo*/   2,         2,         2,       2}
+};
+
+// 5MB/s synchronous timing
+#define SCSI_FAST5_DESKEW 5 // 55ns
+#define SCSI_FAST5_HOLD 5 // 53ns
+
+// 10MB/s synchronous timing
+// 2:0 Deskew count, 25ns
+// 6:4 Hold count, 33ns
+// 3:0 Assertion count, 30ns
+// We want deskew + hold + assert + 3 to add up to 100ns
+// the fpga code has 1 clock of overhead when transitioning from deskew to
+// assert to hold
+
+#define SCSI_FAST10_DESKEW 2 // 25ns
+#define SCSI_FAST10_HOLD 2 // 33ns
+#define SCSI_FAST10_WRITE_ASSERT 2 // 30ns. Overall clocks only works if fpga overhead is 3.
+
+// Slow down the cycle to be valid. 2x assert period is TOO FAST when
+// reading data. It's ok when writing due to the deskew.
+// 50ns. ie. 100ns / 2. Rounded down because there's likely a few extra cycles
+// here and there.
+#define SCSI_FAST10_READ_ASSERT 4
+
+// Fastest possible timing, probably not 20MB/s
+#define SCSI_FAST20_DESKEW 1
+#define SCSI_FAST20_HOLD 2
+#define SCSI_FAST20_ASSERT 2
+
+
+#define syncDeskew(period) ((period) < 35 ? \
+       SCSI_FAST10_DESKEW : SCSI_FAST5_DESKEW)
+
+#define syncHold(period) ((period) < 35 ? \
+       ((period) == 25 ? SCSI_FAST10_HOLD : 3) /* 25ns/33ns */\
+       : SCSI_FAST5_HOLD)
+
+
+// Number of overhead cycles per period.
+#define FPGA_OVERHEAD 2
+#define FPGA_CYCLES_PER_NS 8
+#define SCSI_PERIOD_CLKS(period) ((((int)period * 4) + (FPGA_CYCLES_PER_NS/2)) / FPGA_CYCLES_PER_NS)
+
+// 3.125MB/s (80 period) to < 10MB/s sync
+// 3:0 Assertion count, variable
+#define syncAssertionWrite(period,deskew) ((SCSI_PERIOD_CLKS(period) - deskew - FPGA_OVERHEAD + 1) / 2)
+#define syncAssertionRead(period) syncAssertionWrite(period,0)
+
+
+// Time until we consider ourselves selected
+// 400ns
+#define SCSI_DEFAULT_SELECTION 36
+#define SCSI_FAST_SELECTION 4
+
+
+#endif // S2S_SCSIPHYTIMING