Fixed scsi timing error and added glitch filter.
authorMichael McMaster <michael@codesrc.com>
Thu, 22 Sep 2016 09:21:55 +0000 (19:21 +1000)
committerMichael McMaster <michael@codesrc.com>
Thu, 22 Sep 2016 09:21:55 +0000 (19:21 +1000)
13 files changed:
CHANGELOG
STM32CubeMX/SCSI2SD-V6/Src/main.c
STM32CubeMX/SCSI2SD-V6/Src/sdio.c
STM32CubeMX/SCSI2SD-V6/Src/spi.c
include/scsi2sd.h
rtl/fpga_bitmap.o
src/firmware/config.c
src/firmware/fpga.c
src/firmware/scsiPhy.c
src/firmware/scsiPhy.h
src/scsi2sd-util6/BoardPanel.cc
src/scsi2sd-util6/BoardPanel.hh
src/scsi2sd-util6/ConfigUtil.cc

index 18309e9..a6cd8c6 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+20160922               6.0.??
+       - Fixed SCSI timing issue
+       - Added glitch filter on SCSI signals.
+
 20160912               6.0.10
        - Fixed write issue with UHS-I Speed Class 3 SD cards.
        - More stability bug fixes
index 45f98d9..5433bbf 100755 (executable)
@@ -91,7 +91,7 @@ int main(void)
   MX_FSMC_Init();
   MX_SDIO_SD_Init();
   MX_SPI1_Init();
-  MX_TIM4_Init();
+  // TODO re-enable MX_TIM4_Init();
   // TODO re-enable MX_USART3_UART_Init();
   // TODO re-enable MX_USB_HOST_Init();
 
index 678a9e7..0f9a34b 100755 (executable)
@@ -88,7 +88,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
-    // No pullup on CMD
+    // No pullup on CLK
     GPIO_InitStruct.Pin = GPIO_PIN_12;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
index bef2045..25e0745 100755 (executable)
@@ -54,7 +54,8 @@ void MX_SPI1_Init(void)
   hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
   hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
   hspi1.Init.NSS = SPI_NSS_SOFT;
-  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
+  // (96MHz / 2) / 4 = 12MHz. FPGA device allows up to 25MHz write
+  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
   hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
index a59fd38..e15d0b0 100755 (executable)
@@ -53,7 +53,7 @@ typedef enum
        S2S_CFG_ENABLE_UNIT_ATTENTION = 1,
        S2S_CFG_ENABLE_PARITY = 2,
        S2S_CFG_ENABLE_SCSI2 = 4,
-       // OBSOLETE S2S_CFG_DISABLE_GLITCH = 8,
+       S2S_CFG_DISABLE_GLITCH = 8,
        S2S_CFG_ENABLE_CACHE = 16,
        S2S_CFG_ENABLE_DISCONNECT = 32,
        S2S_CFG_ENABLE_SEL_LATCH = 64,
@@ -203,7 +203,8 @@ typedef enum
 typedef enum
 {
        S2S_CFG_STATUS_GOOD,
-       S2S_CFG_STATUS_ERR
+       S2S_CFG_STATUS_ERR,
+       S2S_CFG_STATUS_BUSY
 } S2S_CFG_STATUS;
 
 
index 604983f..20717db 100644 (file)
Binary files a/rtl/fpga_bitmap.o and b/rtl/fpga_bitmap.o differ
index 6430d57..7ab2001 100755 (executable)
@@ -37,7 +37,7 @@
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x060A;\r
+static const uint16_t FIRMWARE_VERSION = 0x060B;\r
 \r
 // 1 flash row\r
 static const uint8_t DEFAULT_CONFIG[128] =\r
index 441d785..bc1782d 100755 (executable)
@@ -39,10 +39,8 @@ void s2s_fpgaInit()
        HAL_GPIO_WritePin(
                nFGPA_CRESET_B_GPIO_Port, nFGPA_CRESET_B_Pin, GPIO_PIN_SET);
 
-       // 800uS for iCE40HX1K. 1200uS for HX4K according to Appendix A of
-       // TN1248 - iCE40 Programming and Configuration. Note that the
-       // earlier text of the document says 300uS.
-       s2s_delay_us(1200); // Be generous
+       // 800uS for iCE40HX1K. tCR_SCK parameter in datasheet.
+       s2s_delay_us(800);
 
        uint8_t* fpgaData = &_fpga_bitmap_start;
        uint32_t fpgaBytes = (uint32_t) &_fpga_bitmap_size;
index 7b4e463..ca3b494 100755 (executable)
 \r
 #include <string.h>\r
 \r
-// 5MB/s\r
+// Slowest timing. Aim for 1.5MB/s, but it's likely to be faster.\r
+// Assumes a 96MHz fpga clock.\r
+#define SCSI_SCSI1_DESKEW 0x7\r
+#define SCSI_SCSI1_TIMING ((0x7 << 4) | 0xF)\r
+\r
+// 5MB/s sync and async.\r
 // Assumes a 96MHz fpga clock.\r
 // 2:0 Deskew count, 55ns\r
 // 6:4 Hold count, 53ns\r
 // 3:0 Assertion count, 80ns\r
-#define SCSI_DEFAULT_DESKEW 0x6\r
-#define SCSI_DEFAULT_TIMING ((0x5 << 4) | 0x8)\r
+#define SCSI_SCSI2_DESKEW 0x6\r
+#define SCSI_SCSI2_TIMING ((0x5 << 4) | 0x8)\r
 \r
 // 10MB/s\r
 // 2:0 Deskew count, 25ns\r
@@ -441,23 +446,32 @@ void scsiEnterPhase(int phase)
                        if (scsiDev.target->syncPeriod == 12)\r
                        {\r
                                // SCSI2 FAST-20 Timing. 20MB/s.\r
-                               *SCSI_CTRL_TIMING = SCSI_FAST20_DESKEW;\r
-                               *SCSI_CTRL_TIMING2 = SCSI_FAST20_TIMING;\r
+                               *SCSI_CTRL_DESKEW = SCSI_FAST20_DESKEW;\r
+                               *SCSI_CTRL_TIMING = SCSI_FAST20_TIMING;\r
                        }\r
                        else if (scsiDev.target->syncPeriod == 25)\r
                        {\r
                                // SCSI2 FAST Timing. 10MB/s.\r
-                               *SCSI_CTRL_TIMING = SCSI_FAST10_DESKEW;\r
-                               *SCSI_CTRL_TIMING2 = SCSI_FAST10_TIMING;\r
+                               *SCSI_CTRL_DESKEW = SCSI_FAST10_DESKEW;\r
+                               *SCSI_CTRL_TIMING = SCSI_FAST10_TIMING;\r
                        } else {\r
                                // 5MB/s Timing\r
-                               *SCSI_CTRL_TIMING = SCSI_DEFAULT_DESKEW;\r
-                               *SCSI_CTRL_TIMING2 = SCSI_DEFAULT_TIMING;\r
+                               *SCSI_CTRL_DESKEW = SCSI_SCSI2_DESKEW;\r
+                               *SCSI_CTRL_TIMING = SCSI_SCSI2_TIMING;\r
                        }\r
+\r
                        *SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;\r
                } else {\r
                        *SCSI_CTRL_SYNC_OFFSET = 0;\r
-                       *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+\r
+                       if (scsiDev.compatMode >= COMPAT_SCSI2) {\r
+                               // 5MB/s Timing\r
+                               *SCSI_CTRL_DESKEW = SCSI_SCSI2_DESKEW;\r
+                               *SCSI_CTRL_TIMING = SCSI_SCSI2_TIMING;\r
+                       } else {\r
+                               *SCSI_CTRL_DESKEW = SCSI_SCSI1_DESKEW;\r
+                               *SCSI_CTRL_TIMING = SCSI_SCSI1_TIMING;\r
+                       }\r
                }\r
 \r
                *SCSI_CTRL_PHASE = newPhase;\r
@@ -492,7 +506,8 @@ void scsiPhyReset()
        *SCSI_CTRL_DBX = 0;\r
 \r
        *SCSI_CTRL_SYNC_OFFSET = 0;\r
-       *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+       *SCSI_CTRL_DESKEW = SCSI_SCSI1_DESKEW;\r
+       *SCSI_CTRL_TIMING = SCSI_SCSI1_TIMING;\r
 \r
        // DMA Benchmark code\r
        // Currently 11MB/s.\r
@@ -658,7 +673,8 @@ void scsiPhyInit()
        *SCSI_CTRL_DBX = 0;\r
 \r
        *SCSI_CTRL_SYNC_OFFSET = 0;\r
-       *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+       *SCSI_CTRL_DESKEW = SCSI_SCSI1_DESKEW;\r
+       *SCSI_CTRL_TIMING = SCSI_SCSI1_TIMING;\r
 \r
 }\r
 \r
@@ -684,6 +700,10 @@ void scsiPhyConfig()
                }\r
        }\r
        *SCSI_CTRL_IDMASK = idMask;\r
+\r
+       *SCSI_CTRL_FLAGS =\r
+               (scsiDev.boardCfg.flags & S2S_CFG_DISABLE_GLITCH) ? 1 : 0;\r
+\r
 }\r
 \r
 \r
index 718b25f..7f52280 100755 (executable)
@@ -26,8 +26,9 @@
 #define SCSI_DATA_CNT_SET ((volatile uint8_t*)0x6000000C)
 #define SCSI_CTRL_DBX ((volatile uint8_t*)0x6000000E)
 #define SCSI_CTRL_SYNC_OFFSET ((volatile uint8_t*)0x60000010)
-#define SCSI_CTRL_TIMING ((volatile uint8_t*)0x60000012)
-#define SCSI_CTRL_TIMING2 ((volatile uint8_t*)0x60000014)
+#define SCSI_CTRL_DESKEW ((volatile uint8_t*)0x60000012)
+#define SCSI_CTRL_TIMING ((volatile uint8_t*)0x60000014)
+#define SCSI_CTRL_FLAGS ((volatile uint8_t*)0x60000016)
 
 #define SCSI_STS_FIFO ((volatile uint8_t*)0x60000020)
 #define SCSI_STS_ALTFIFO ((volatile uint8_t*)0x60000022)
index 90fd6cd..54ea235 100644 (file)
@@ -53,7 +53,7 @@ BoardPanel::BoardPanel(wxWindow* parent, const S2S_BoardCfg& initialConfig) :
        myParent(parent),
        myDelayValidator(new wxIntegerValidator<uint8_t>)
 {
-       wxFlexGridSizer *fgs = new wxFlexGridSizer(10, 2, 9, 25);
+       wxFlexGridSizer *fgs = new wxFlexGridSizer(11, 2, 9, 25);
 
        fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
        myTermCtrl =
@@ -118,6 +118,15 @@ BoardPanel::BoardPanel(wxWindow* parent, const S2S_BoardCfg& initialConfig) :
        myScsi2Ctrl->SetToolTip(_("Enable high-performance mode. May cause problems with SASI/SCSI1 hosts."));
        fgs->Add(myScsi2Ctrl);
 
+       fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
+       myGlitchCtrl =
+               new wxCheckBox(
+                       this,
+                       ID_glitchCtrl,
+                       _("Disable glitch filter"));
+       myGlitchCtrl->SetToolTip(_("Improve performance at the cost of noise immunity. Only use with short cables."));
+       fgs->Add(myGlitchCtrl);
+
        fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
        myCacheCtrl =
                new wxCheckBox(
@@ -176,6 +185,7 @@ BoardPanel::getConfig() const
                (myParityCtrl->IsChecked() ? S2S_CFG_ENABLE_PARITY : 0) |
                (myUnitAttCtrl->IsChecked() ? S2S_CFG_ENABLE_UNIT_ATTENTION : 0) |
                (myScsi2Ctrl->IsChecked() ? S2S_CFG_ENABLE_SCSI2 : 0) |
+               (myGlitchCtrl->IsChecked() ? S2S_CFG_DISABLE_GLITCH : 0) |
                (myCacheCtrl->IsChecked() ? S2S_CFG_ENABLE_CACHE: 0) |
                (myDisconnectCtrl->IsChecked() ? S2S_CFG_ENABLE_DISCONNECT: 0) |
                (mySelLatchCtrl->IsChecked() ? S2S_CFG_ENABLE_SEL_LATCH : 0) |
@@ -196,6 +206,7 @@ BoardPanel::setConfig(const S2S_BoardCfg& config)
        myParityCtrl->SetValue(config.flags & S2S_CFG_ENABLE_PARITY);
        myUnitAttCtrl->SetValue(config.flags & S2S_CFG_ENABLE_UNIT_ATTENTION);
        myScsi2Ctrl->SetValue(config.flags & S2S_CFG_ENABLE_SCSI2);
+       myGlitchCtrl->SetValue(config.flags & S2S_CFG_DISABLE_GLITCH);
        myTermCtrl->SetValue(config.flags6 & S2S_CFG_ENABLE_TERMINATOR);
        myCacheCtrl->SetValue(config.flags & S2S_CFG_ENABLE_CACHE);
        myDisconnectCtrl->SetValue(config.flags & S2S_CFG_ENABLE_DISCONNECT);
index 06fadf3..8a8bc04 100644 (file)
@@ -55,6 +55,7 @@ private:
                ID_parityCtrl = wxID_HIGHEST + 1,
                ID_unitAttCtrl,
                ID_scsi2Ctrl,
+               ID_glitchCtrl,
                ID_termCtrl,
                ID_cacheCtrl,
                ID_disconnectCtrl,
@@ -71,6 +72,7 @@ private:
        wxCheckBox* myParityCtrl;
        wxCheckBox* myUnitAttCtrl;
        wxCheckBox* myScsi2Ctrl;
+       wxCheckBox* myGlitchCtrl;
        wxCheckBox* myTermCtrl;
        wxCheckBox* myCacheCtrl;
        wxCheckBox* myDisconnectCtrl;
index 1b68f5d..9db2ded 100755 (executable)
@@ -319,6 +319,18 @@ ConfigUtil::toXML(const S2S_BoardCfg& config)
                        (config.flags & S2S_CFG_ENABLE_CACHE ? "true" : "false") <<
                        "</enableCache>\n" <<
 
+               "       <!-- ********************************************************\n" <<
+               "       Setting to 'true' will result in increased performance at the\n" <<
+               "       cost of lower noise immunity.\n" <<
+               "       Only set to true when using short cables with only 1 or two\n" <<
+               "       devices. This should remain off when using external SCSI1 DB25\n" <<
+               "       cables.\n" <<
+               "       ********************************************************* -->\n" <<
+               "       <disableGlitchFilter>" <<
+                       (config.flags & S2S_CFG_DISABLE_GLITCH ? "true" : "false") <<
+                       "</disableGlitchFilter>\n" <<
+
+
                "       <enableDisconnect>" <<
                        (config.flags & S2S_CFG_ENABLE_DISCONNECT ? "true" : "false") <<
                        "</enableDisconnect>\n" <<
@@ -532,6 +544,18 @@ parseBoardConfig(wxXmlNode* node)
                                result.flags = result.flags & ~S2S_CFG_ENABLE_SCSI2;
                        }
                }
+               else if (child->GetName() == "disableGlitchFilter")
+               {
+                       std::string s(child->GetNodeContent().mb_str());
+                       if (s == "true")
+                       {
+                               result.flags |= S2S_CFG_DISABLE_GLITCH;
+                       }
+                       else
+                       {
+                               result.flags = result.flags & ~S2S_CFG_DISABLE_GLITCH;
+                       }
+               }
                else if (child->GetName() == "enableTerminator")
                {
                        std::string s(child->GetNodeContent().mb_str());