Stability fixes and SD UHS-I Speed class 3 fix.
authorMichael McMaster <michael@codesrc.com>
Sat, 10 Sep 2016 09:22:36 +0000 (19:22 +1000)
committerMichael McMaster <michael@codesrc.com>
Sat, 10 Sep 2016 09:22:36 +0000 (19:22 +1000)
15 files changed:
CHANGELOG
STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c
STM32CubeMX/SCSI2SD-V6/SCSI2SD-V6.ioc
STM32CubeMX/SCSI2SD-V6/Src/fsmc.c
STM32CubeMX/SCSI2SD-V6/Src/main.c
STM32CubeMX/SCSI2SD-V6/Src/sdio.c
rtl/fpga_bitmap.o
src/firmware/config.c
src/firmware/disk.c
src/firmware/scsiPhy.c
src/firmware/scsiPhy.h
src/firmware/sd.c
src/firmware/sd.h
src/scsi2sd-util6/SCSI2SD_HID.cc
src/scsi2sd-util6/scsi2sd-util.cc

index b11680d..6165e3c 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+201609XX               6.0.10
+       - Fixed write issue with UHS-I Speed Class 3 SD cards.
+       - More stability bug fixes
+
 20160827               6.0.8
        - Fixed "protocol error" issues when saving configuration to SD cards.
        - Synchronous transfers supported ! 5MB/s and 10MB/s supported.
index 8511aa7..9d2062d 100755 (executable)
@@ -892,7 +892,7 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead
                                 SDIO_IT_STBITERR));
   
   /* Enable SDIO DMA transfer */
-  __HAL_SD_SDIO_DMA_ENABLE();
+  // MM disabled, as this fails on fast cards. __HAL_SD_SDIO_DMA_ENABLE();
   
   /* Configure DMA user callbacks */
   hsd->hdmarx->XferCpltCallback  = SD_DMA_RxCplt;
@@ -901,26 +901,29 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead
   /* Enable the DMA Stream */
   HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks)/4);
   
+  sdio_cmdinitstructure.Response         = SDIO_RESPONSE_SHORT;
+  sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+  sdio_cmdinitstructure.CPSM             = SDIO_CPSM_ENABLE;
+  
   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
   {
     BlockSize = 512;
     ReadAddr /= 512;
-  }
+  } else {
   
-  /* Set Block Size for Card */ 
-  sdio_cmdinitstructure.Argument         = (uint32_t)BlockSize;
-  sdio_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;
-  sdio_cmdinitstructure.Response         = SDIO_RESPONSE_SHORT;
-  sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
-  sdio_cmdinitstructure.CPSM             = SDIO_CPSM_ENABLE;
-  SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+    /* Set Block Size for Card */ 
+    sdio_cmdinitstructure.Argument         = (uint32_t)BlockSize;
+    sdio_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;
+
+    SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
   
-  /* Check for error conditions */
-  errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+    /* Check for error conditions */
+    errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
   
-  if (errorstate != SD_OK)
-  {
-    return errorstate;
+    if (errorstate != SD_OK)
+    {
+      return errorstate;
+    }
   }
   
   /* Configure the SD DPSM (Data Path State Machine) */ 
@@ -930,6 +933,11 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead
   sdio_datainitstructure.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
   sdio_datainitstructure.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
   sdio_datainitstructure.DPSM          = SDIO_DPSM_ENABLE;
+
+  // We cannot enable DMA too early on UHS-I class 3 SD cards, or else the
+  // data is just discarded before the dpsm is started.
+  __HAL_SD_SDIO_DMA_ENABLE();
+
   SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
   
   /* Check number of blocks command */
@@ -1016,28 +1024,30 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri
   HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pWriteBuffer, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BlockSize * NumberOfBlocks)/4);
 
   /* Enable SDIO DMA transfer */
-  __HAL_SD_SDIO_DMA_ENABLE();
+  // MM disabled, as this fails on fast cards. __HAL_SD_SDIO_DMA_ENABLE();
+  
+  sdio_cmdinitstructure.Response         = SDIO_RESPONSE_SHORT;
+  sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
+  sdio_cmdinitstructure.CPSM             = SDIO_CPSM_ENABLE;
   
   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
   {
     BlockSize = 512;
     WriteAddr /= 512;
-  }
+  } else {
+       /* Set Block Size for Card */ 
+    sdio_cmdinitstructure.Argument         = (uint32_t)BlockSize;
+    sdio_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;
 
-  /* Set Block Size for Card */ 
-  sdio_cmdinitstructure.Argument         = (uint32_t)BlockSize;
-  sdio_cmdinitstructure.CmdIndex         = SD_CMD_SET_BLOCKLEN;
-  sdio_cmdinitstructure.Response         = SDIO_RESPONSE_SHORT;
-  sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO;
-  sdio_cmdinitstructure.CPSM             = SDIO_CPSM_ENABLE;
-  SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
+    SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
 
-  /* Check for error conditions */
-  errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
+    /* Check for error conditions */
+    errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
 
-  if (errorstate != SD_OK)
-  {
-    return errorstate;
+    if (errorstate != SD_OK)
+    {
+      return errorstate;
+    }
   }
   
   /* Check number of blocks command */
@@ -1049,7 +1059,6 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri
   else
   {
     /* MM: Prepare for write */
-    /* Set Block Size for Card */ 
     sdio_cmdinitstructure.Argument         = (uint32_t)(hsd->RCA << 16);
     sdio_cmdinitstructure.CmdIndex         = SD_CMD_APP_CMD;
     SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
@@ -1072,10 +1081,11 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri
     /* Send CMD25 WRITE_MULT_BLOCK with argument data address */
     sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
   }
-  
+
   sdio_cmdinitstructure.Argument         = (uint32_t)WriteAddr;
   SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
 
+
   /* Check for error conditions */
   if(NumberOfBlocks > 1)
   {
@@ -1098,6 +1108,11 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri
   sdio_datainitstructure.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
   sdio_datainitstructure.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
   sdio_datainitstructure.DPSM          = SDIO_DPSM_ENABLE;
+
+  // We cannot enable DMA too early on UHS-I class 3 SD cards, or else the
+  // data is just discarded before the dpsm is started.
+  __HAL_SD_SDIO_DMA_ENABLE();
+
   SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure);
   
   hsd->SdTransferErr = errorstate;
index ed61a35..056fddb 100755 (executable)
@@ -455,38 +455,37 @@ ProjectManager.ProjectName=SCSI2SD-V6
 ProjectManager.TargetToolchain=TrueSTUDIO
 ProjectManager.ToolChainLocation=
 RCC.48MHZClocksFreq_Value=48000000
-RCC.AHBFreq_Value=120000000
+RCC.AHBFreq_Value=96000000
 RCC.APB1CLKDivider=RCC_HCLK_DIV4
-RCC.APB1Freq_Value=30000000
-RCC.APB1TimFreq_Value=60000000
+RCC.APB1Freq_Value=24000000
+RCC.APB1TimFreq_Value=48000000
 RCC.APB2CLKDivider=RCC_HCLK_DIV2
-RCC.APB2Freq_Value=60000000
-RCC.APB2TimFreq_Value=120000000
-RCC.CortexFreq_Value=120000000
-RCC.EthernetFreq_Value=120000000
-RCC.FCLKCortexFreq_Value=120000000
+RCC.APB2Freq_Value=48000000
+RCC.APB2TimFreq_Value=96000000
+RCC.CortexFreq_Value=96000000
+RCC.EthernetFreq_Value=96000000
+RCC.FCLKCortexFreq_Value=96000000
 RCC.FamilyName=M
-RCC.HCLKFreq_Value=120000000
+RCC.HCLKFreq_Value=96000000
 RCC.HSE_VALUE=20000000
 RCC.HSI_VALUE=16000000
-RCC.I2SClocksFreq_Value=120000000
-RCC.IPParameters=FamilyName,LSE_VALUE,HSI_VALUE,SYSCLKFreq_VALUE,AHBFreq_Value,CortexFreq_Value,APB1Freq_Value,APB2Freq_Value,HSE_VALUE,RTCHSEDivFreq_Value,LSI_VALUE,RTCFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,PLLCLKFreq_Value,48MHZClocksFreq_Value,VCOI2SOutputFreq_Value,VcooutputI2S,I2SClocksFreq_Value,RCC_MCO1Source,SYSCLKSource,HCLKFreq_Value,FCLKCortexFreq_Value,APB1TimFreq_Value,APB2TimFreq_Value,EthernetFreq_Value,MCO2PinFreq_Value,APB1CLKDivider,APB2CLKDivider,MCO1PinFreq_Value,PLLQ,RCC_MCODiv1
+RCC.I2SClocksFreq_Value=96000000
+RCC.IPParameters=FamilyName,LSE_VALUE,HSI_VALUE,SYSCLKFreq_VALUE,AHBFreq_Value,CortexFreq_Value,APB1Freq_Value,APB2Freq_Value,HSE_VALUE,RTCHSEDivFreq_Value,LSI_VALUE,RTCFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,PLLCLKFreq_Value,48MHZClocksFreq_Value,VCOI2SOutputFreq_Value,VcooutputI2S,I2SClocksFreq_Value,RCC_MCO1Source,HCLKFreq_Value,FCLKCortexFreq_Value,APB1TimFreq_Value,APB2TimFreq_Value,EthernetFreq_Value,MCO2PinFreq_Value,APB1CLKDivider,APB2CLKDivider,MCO1PinFreq_Value,SYSCLKSource,PLLM
 RCC.LSE_VALUE=32768
 RCC.LSI_VALUE=32000
-RCC.MCO1PinFreq_Value=60000000
-RCC.MCO2PinFreq_Value=120000000
-RCC.PLLCLKFreq_Value=120000000
-RCC.PLLQ=5
+RCC.MCO1PinFreq_Value=96000000
+RCC.MCO2PinFreq_Value=96000000
+RCC.PLLCLKFreq_Value=96000000
+RCC.PLLM=20
 RCC.RCC_MCO1Source=RCC_MCO1SOURCE_PLLCLK
-RCC.RCC_MCODiv1=RCC_MCODIV_2
 RCC.RTCFreq_Value=32000
 RCC.RTCHSEDivFreq_Value=10000000
-RCC.SYSCLKFreq_VALUE=120000000
+RCC.SYSCLKFreq_VALUE=96000000
 RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
-RCC.VCOI2SOutputFreq_Value=240000000
-RCC.VCOInputFreq_Value=1250000
-RCC.VCOOutputFreq_Value=240000000
-RCC.VcooutputI2S=120000000
+RCC.VCOI2SOutputFreq_Value=192000000
+RCC.VCOInputFreq_Value=1000000
+RCC.VCOOutputFreq_Value=192000000
+RCC.VcooutputI2S=96000000
 SDIO.BusWide=SDIO_BUS_WIDE_1B
 SDIO.IPParameters=BusWide,WideMode
 SDIO.WideMode=SDIO_BUS_WIDE_4B
@@ -499,7 +498,7 @@ SH.S_TIM4_CH1.ConfNb=1
 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16
 SPI1.CLKPhase=SPI_PHASE_2EDGE
 SPI1.CLKPolarity=SPI_POLARITY_HIGH
-SPI1.CalculateBaudRate=3.75 MBits/s
+SPI1.CalculateBaudRate=3.0 MBits/s
 SPI1.IPParameters=Mode,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase
 SPI1.Mode=SPI_MODE_MASTER
 USB_DEVICE.CLASS_NAME-HID_FS=HID
index de40c34..d01e9c3 100755 (executable)
@@ -67,19 +67,21 @@ void MX_FSMC_Init(void)
   hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
   /* Timing */
 
-/*
+  // 1 clock to read the address, but since the signals aren't stable
+  // at 96MHz we wait two more clocks
   Timing.AddressSetupTime = 3;
-  Timing.AddressHoldTime = 2;
+  Timing.AddressHoldTime = 1;
+
   Timing.DataSetupTime = 5;
-*/
+  // +1 clock hold time, +2 clock to let the bus settle (unstable at 96MHz)
+  // +1 clock to process read, 1 clock to output
 
-  Timing.AddressSetupTime = 2;
-  Timing.AddressHoldTime = 1;
-  Timing.DataSetupTime = 4;
+  // Allow a clock for us to release signals, or else we'll read
+  // our own output data as an address.
+  Timing.BusTurnAroundDuration = 1;
 
-  Timing.BusTurnAroundDuration = 0;
-  Timing.CLKDivision = 16;
-  Timing.DataLatency = 17;
+  Timing.CLKDivision = 16; // Ignored for async
+  Timing.DataLatency = 17; // Ignored for async
   Timing.AccessMode = FSMC_ACCESS_MODE_A;
   /* ExtTiming */
 
index bf352ac..45f98d9 100755 (executable)
@@ -128,10 +128,11 @@ void SystemClock_Config(void)
   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
-  RCC_OscInitStruct.PLL.PLLM = 16;
+
+  RCC_OscInitStruct.PLL.PLLM = 20;
   RCC_OscInitStruct.PLL.PLLN = 192;
   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
-  RCC_OscInitStruct.PLL.PLLQ = 5;
+  RCC_OscInitStruct.PLL.PLLQ = 4;
   HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
@@ -142,7 +143,7 @@ void SystemClock_Config(void)
   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
 
-  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_2);
+  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_1);
 
   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
index d1bb9dc..678a9e7 100755 (executable)
@@ -81,18 +81,23 @@ void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
     PC12     ------> SDIO_CK
     PD2     ------> SDIO_CMD 
     */
-    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 
-                          |GPIO_PIN_12;
+    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-    //GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Pull = GPIO_PULLUP; // MM
     GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
+    // No pullup on CMD
+    GPIO_InitStruct.Pin = GPIO_PIN_12;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
+    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
     GPIO_InitStruct.Pin = GPIO_PIN_2;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-    //GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Pull = GPIO_PULLUP; // MM
     GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
@@ -135,6 +140,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
     __HAL_LINKDMA(hsd,hdmarx,hdma_sdio_rx);
 
     /* Peripheral interrupt init*/
+       HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
     HAL_NVIC_SetPriority(SDIO_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(SDIO_IRQn);
   /* USER CODE BEGIN SDIO_MspInit 1 */
index 56551b3..5d95ad3 100644 (file)
Binary files a/rtl/fpga_bitmap.o and b/rtl/fpga_bitmap.o differ
index 7acb083..6430d57 100755 (executable)
@@ -37,7 +37,7 @@
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x0608;\r
+static const uint16_t FIRMWARE_VERSION = 0x060A;\r
 \r
 // 1 flash row\r
 static const uint8_t DEFAULT_CONFIG[128] =\r
index 2e69d48..be91216 100755 (executable)
@@ -544,19 +544,25 @@ void scsiDiskPoll()
                                transfer.lba);\r
 \r
                const int sdPerScsi = SDSectorsPerSCSISector(bytesPerSector);\r
-               int buffers = sizeof(scsiDev.data) / SD_SECTOR_SIZE;\r
+               const int buffers = sizeof(scsiDev.data) / SD_SECTOR_SIZE;\r
                int prep = 0;\r
                int i = 0;\r
-               int scsiActive = 0;\r
+               int scsiActive __attribute__((unused)) = 0; // unused if DMA disabled\r
                int sdActive = 0;\r
                while ((i < totalSDSectors) &&\r
                        likely(scsiDev.phase == DATA_IN) &&\r
                        likely(!scsiDev.resetFlag))\r
                {\r
-                       if (sdActive && sdReadDMAPoll())\r
+                       int completedDmaSectors;\r
+                       if (sdActive && (completedDmaSectors = sdReadDMAPoll(sdActive)))\r
                        {\r
-                               prep += sdActive;\r
-                               sdActive = 0;\r
+                               prep += completedDmaSectors;\r
+                               sdActive -= completedDmaSectors;\r
+                       } else if (sdActive > 1) {\r
+                               if (scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 511] != 0x33) {\r
+                                       prep += 1;\r
+                                       sdActive -= 1;\r
+                               }\r
                        }\r
 \r
                        if (!sdActive &&\r
@@ -566,25 +572,27 @@ void scsiDiskPoll()
                                // Start an SD transfer if we have space.\r
                                uint32_t startBuffer = prep % buffers;\r
                                uint32_t sectors = totalSDSectors - prep;\r
-#if 0\r
-                               if (!scsiActive && prep == i)\r
-                               {\r
-                                       sectors = 1; // We need to get some data to send ASAP !\r
-                               }\r
-                               else\r
-#endif\r
+\r
+                               uint32_t freeBuffers = buffers - (prep - i);\r
+\r
+                               uint32_t contiguousBuffers = buffers - startBuffer;\r
+                               freeBuffers = freeBuffers < contiguousBuffers\r
+                                       ? freeBuffers : contiguousBuffers;\r
+                               sectors = sectors < freeBuffers ? sectors : freeBuffers;\r
+\r
+                               if (sectors > 128) sectors = 128; // 65536 DMA limit !!\r
+\r
+                               for (int dodgy = 0; dodgy < sectors; dodgy++)\r
                                {\r
-                                       uint32_t freeBuffers = buffers - (prep - i);\r
-                                       uint32_t contiguousBuffers = buffers - startBuffer;\r
-                                       freeBuffers = freeBuffers < contiguousBuffers\r
-                                               ? freeBuffers : contiguousBuffers;\r
-                                       sectors = sectors < freeBuffers ? sectors : freeBuffers;\r
+                                       scsiDev.data[SD_SECTOR_SIZE * (startBuffer + dodgy) + 511] = 0x33;\r
                                }\r
+\r
                                sdReadDMA(sdLBA + prep, sectors, &scsiDev.data[SD_SECTOR_SIZE * startBuffer]);\r
 \r
                                sdActive = sectors;\r
                        }\r
 \r
+#ifdef SCSI_FSMC_DMA\r
                        if (scsiActive && scsiPhyComplete() && scsiWriteDMAPoll())\r
                        {\r
                                scsiActive = 0;\r
@@ -602,6 +610,24 @@ void scsiDiskPoll()
                                scsiWriteDMA(&scsiDev.data[SD_SECTOR_SIZE * (i % buffers)], dmaBytes);\r
                                scsiActive = 1;\r
                        }\r
+#else\r
+                       if ((prep - i) > 0)\r
+                       {\r
+                               int dmaBytes = SD_SECTOR_SIZE;\r
+                               if ((i % sdPerScsi) == (sdPerScsi - 1))\r
+                               {\r
+                                       dmaBytes = bytesPerSector % SD_SECTOR_SIZE;\r
+                                       if (dmaBytes == 0) dmaBytes = SD_SECTOR_SIZE;\r
+                               }\r
+                               for (int k = 0; k < dmaBytes; ++k)\r
+                               {\r
+                                       scsiPhyTx(scsiDev.data[SD_SECTOR_SIZE * (i % buffers) + k]);\r
+                               }\r
+                               i++;\r
+                               while (!scsiPhyComplete() && !scsiDev.resetFlag) {}\r
+                               scsiPhyFifoFlip();\r
+                       }\r
+#endif\r
                }\r
 \r
                // We've finished transferring the data to the FPGA, now wait until it's\r
index f424157..ba71f65 100755 (executable)
 #include <string.h>\r
 \r
 // 5MB/s\r
-// Assumes a 60MHz fpga clock.\r
-// 7:6 Hold count, 45ns\r
-// 5:3 Assertion count, 90ns\r
+// Assumes a 96MHz fpga clock.\r
 // 2:0 Deskew count, 55ns\r
-#define SCSI_DEFAULT_TIMING ((0x3 << 6) | (0x6 << 3) | 0x4)\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
 \r
 // 10MB/s\r
-// 7:6 Hold count, 17ns\r
-// 5:3 Assertion count, 30ns\r
 // 2:0 Deskew count, 25ns\r
-#define SCSI_FAST10_TIMING ((0x1 << 6) | (0x2 << 3) | 0x2)\r
+// 6:4 Hold count, 33ns\r
+// 3:0 Assertion count, 30ns\r
+#define SCSI_FAST10_DESKEW 3\r
+#define SCSI_FAST10_TIMING ((0x3 << 4) | 0x3)\r
 \r
 // 20MB/s\r
-// 7:6 Hold count, 17ns\r
-// 5:3 Assertion count, 17ns\r
-// 2:0 Deskew count, 17ns\r
-#define SCSI_FAST20_TIMING ((0x1 << 6) | (0x1 << 3) | 0x1)\r
+// 2:0 Deskew count, 12ns\r
+// 6:4 Hold count, 17ns\r
+// 3:0 Assertion count, 15ns\r
+#define SCSI_FAST20_DESKEW 2\r
+#define SCSI_FAST20_TIMING ((0x2 << 4) | 0x2)\r
 \r
 // Private DMA variables.\r
 static int dmaInProgress = 0;\r
@@ -199,11 +202,13 @@ scsiRead(uint8_t* data, uint32_t count)
 \r
        uint32_t chunk = ((count - i) > SCSI_FIFO_DEPTH)\r
                ? SCSI_FIFO_DEPTH : (count - i);\r
+#ifdef SCSI_FSMC_DMA\r
        if (chunk >= 16)\r
        {\r
                // DMA is doing 32bit transfers.\r
                chunk = chunk & 0xFFFFFFF8;\r
        }\r
+#endif\r
        startScsiRx(chunk);\r
 \r
        while (i < count && likely(!scsiDev.resetFlag))\r
@@ -213,19 +218,24 @@ scsiRead(uint8_t* data, uint32_t count)
 \r
                uint32_t nextChunk = ((count - i - chunk) > SCSI_FIFO_DEPTH)\r
                        ? SCSI_FIFO_DEPTH : (count - i - chunk);\r
+#ifdef SCSI_FSMC_DMA\r
                if (nextChunk >= 16)\r
                {\r
                        nextChunk = nextChunk & 0xFFFFFFF8;\r
                }\r
+#endif\r
                if (nextChunk > 0)\r
                {\r
                        startScsiRx(nextChunk);\r
                }\r
 \r
+#ifdef SCSI_FSMC_DMA\r
                if (chunk < 16)\r
+#endif\r
                {\r
                        scsiReadPIO(data + i, chunk);\r
                }\r
+#ifdef SCSI_FSMC_DMA\r
                else\r
                {\r
                        scsiReadDMA(data + i, chunk);\r
@@ -236,12 +246,13 @@ scsiRead(uint8_t* data, uint32_t count)
                        {\r
                        };\r
                }\r
+#endif\r
 \r
 \r
                i += chunk;\r
                chunk = nextChunk;\r
        }\r
-#if 1\r
+#if FIFODEBUG\r
                if (!scsiPhyFifoEmpty() || !scsiPhyFifoAltEmpty()) {\r
                        int j = 0;\r
                        while (!scsiPhyFifoEmpty()) { scsiPhyRx(); ++j; }\r
@@ -339,10 +350,13 @@ scsiWrite(const uint8_t* data, uint32_t count)
                }\r
 #endif\r
 \r
+#ifdef SCSI_FSMC_DMA\r
                if (chunk < 16)\r
+#endif\r
                {\r
                        scsiWritePIO(data + i, chunk);\r
                }\r
+#ifdef SCSI_FSMC_DMA\r
                else\r
                {\r
                        // DMA is doing 32bit transfers.\r
@@ -355,6 +369,7 @@ scsiWrite(const uint8_t* data, uint32_t count)
                        {\r
                        }\r
                }\r
+#endif\r
 \r
                while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
                {\r
@@ -417,15 +432,18 @@ void scsiEnterPhase(int phase)
                        if (scsiDev.target->syncPeriod == 12)\r
                        {\r
                                // SCSI2 FAST-20 Timing. 20MB/s.\r
-                               *SCSI_CTRL_TIMING = SCSI_FAST20_TIMING;\r
+                               *SCSI_CTRL_TIMING = SCSI_FAST20_DESKEW;\r
+                               *SCSI_CTRL_TIMING2 = SCSI_FAST20_TIMING;\r
                        }\r
                        else if (scsiDev.target->syncPeriod == 25)\r
                        {\r
                                // SCSI2 FAST Timing. 10MB/s.\r
-                               *SCSI_CTRL_TIMING = SCSI_FAST10_TIMING;\r
+                               *SCSI_CTRL_TIMING = SCSI_FAST10_DESKEW;\r
+                               *SCSI_CTRL_TIMING2 = SCSI_FAST10_TIMING;\r
                        } else {\r
                                // 5MB/s Timing\r
-                               *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
+                               *SCSI_CTRL_TIMING = SCSI_DEFAULT_DESKEW;\r
+                               *SCSI_CTRL_TIMING2 = SCSI_DEFAULT_TIMING;\r
                        }\r
                        *SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;\r
                } else {\r
@@ -455,33 +473,6 @@ void scsiPhyReset()
 \r
                dmaInProgress = 0;\r
        }\r
-#if 0\r
-\r
-       // Set the Clear bits for both SCSI device FIFOs\r
-       scsiTarget_AUX_CTL = scsiTarget_AUX_CTL | 0x03;\r
-\r
-       // Trigger RST outselves.  It is connected to the datapath and will\r
-       // ensure it returns to the idle state.  The datapath runs at the BUS clk\r
-       // speed (ie. same as the CPU), so we can be sure it is active for a sufficient\r
-       // duration.\r
-       SCSI_RST_ISR_Disable();\r
-       SCSI_SetPin(SCSI_Out_RST);\r
-\r
-       SCSI_CTL_PHASE_Write(0);\r
-       SCSI_ClearPin(SCSI_Out_ATN);\r
-       SCSI_ClearPin(SCSI_Out_BSY);\r
-       SCSI_ClearPin(SCSI_Out_ACK);\r
-       SCSI_ClearPin(SCSI_Out_RST);\r
-       SCSI_ClearPin(SCSI_Out_SEL);\r
-       SCSI_ClearPin(SCSI_Out_REQ);\r
-\r
-       // Allow the FIFOs to fill up again.\r
-       SCSI_ClearPin(SCSI_Out_RST);\r
-       SCSI_RST_ISR_Enable();\r
-       scsiTarget_AUX_CTL = scsiTarget_AUX_CTL & ~(0x03);\r
-\r
-       SCSI_Parity_Error_Read(); // clear sticky bits\r
-#endif\r
 \r
        *SCSI_CTRL_PHASE = 0x00;\r
        *SCSI_CTRL_BSY = 0x00;\r
@@ -495,7 +486,7 @@ void scsiPhyReset()
        *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
 \r
        // DMA Benchmark code\r
-       // Currently 10MB/s. Assume 20MB/s is achievable with 16 bits.\r
+       // Currently 6.6MB/s. Assume 13MB/s is achievable with 16 bits\r
        #ifdef DMA_BENCHMARK\r
        while(1)\r
        {\r
index b70ff7b..fa7e168 100755 (executable)
@@ -27,6 +27,7 @@
 #define SCSI_CTRL_DBX ((volatile uint8_t*)0x60000007)
 #define SCSI_CTRL_SYNC_OFFSET ((volatile uint8_t*)0x60000008)
 #define SCSI_CTRL_TIMING ((volatile uint8_t*)0x60000009)
+#define SCSI_CTRL_TIMING2 ((volatile uint8_t*)0x6000000A)
 
 #define SCSI_STS_FIFO ((volatile uint8_t*)0x60000010)
 #define SCSI_STS_ALTFIFO ((volatile uint8_t*)0x60000011)
 #define scsiStatusSEL() ((*SCSI_STS_SCSI & 0x08) == 0x08)
 #define scsiStatusACK() ((*SCSI_STS_SCSI & 0x10) == 0x10)
 
+// Disable DMA due to errate with the STM32F205 DMA2 controller when
+// concurrently transferring FSMC (with FIFO) and APB (ie. sdio)
+// peripherals.
+#undef SCSI_FSMC_DMA
+
 extern uint8_t scsiPhyFifoSel;
 
 void scsiPhyInit(void);
index c9832d0..204936d 100755 (executable)
@@ -38,21 +38,31 @@ SdDevice sdDev;
 static int sdCmdActive = 0;\r
 \r
 int\r
-sdReadDMAPoll()\r
+sdReadDMAPoll(uint32_t remainingSectors)\r
 {\r
+       // TODO DMA byte counting disabled for now as it's not\r
+       // working.\r
+       // We can ask the SDIO controller how many bytes have been\r
+       // processed (SDIO_GetDataCounter()) but I'm not sure if that\r
+       // means the data has been transfered via dma to memory yet.\r
+//     uint32_t dmaBytesRemaining = __HAL_DMA_GET_COUNTER(hsd.hdmarx) * 4;\r
+\r
        if (hsd.DmaTransferCplt ||\r
                hsd.SdTransferCplt ||\r
+\r
+//     if (dmaBytesRemaining == 0 ||\r
                (HAL_SD_ErrorTypedef)hsd.SdTransferErr != SD_OK)\r
        {\r
                HAL_SD_CheckReadOperation(&hsd, (uint32_t)SD_DATATIMEOUT);\r
                // DMA transfer is complete\r
                sdCmdActive = 0;\r
-               return 1;\r
+               return remainingSectors;\r
        }\r
-       else\r
+/*     else\r
        {\r
-               return 0;\r
-       }\r
+               return remainingSectors - ((dmaBytesRemaining + (SD_SECTOR_SIZE - 1)) / SD_SECTOR_SIZE);\r
+       }*/\r
+       return 0;\r
 }\r
 \r
 void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer)\r
@@ -244,9 +254,12 @@ static void sdInitDMA()
                init = 1;\r
 \r
                //TODO MM SEE STUPID SD_DMA_RxCplt that require the SD IRQs to preempt\r
-               // Configured with 4 bits preemption, NO sub priority.\r
+               // Ie. priority must be geater than the SDIO_IRQn priority.\r
+               // 4 bits preemption, NO sub priority.\r
+               HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);\r
                HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 8, 0);\r
                HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);\r
+               HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);\r
                HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 8, 0);\r
                HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);\r
        }\r
index 1ca1080..74f89a6 100755 (executable)
@@ -40,7 +40,7 @@ void sdWriteMultiSectorDMA(uint8_t* outputBuffer);
 int sdWriteSectorDMAPoll();
 
 void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer);
-int sdReadDMAPoll();
+int sdReadDMAPoll(uint32_t remainingSectors);
 void sdCompleteTransfer();
 
 void sdPoll();
index 9b6cb51..94db8b5 100644 (file)
@@ -196,7 +196,7 @@ std::string
 HID::getFirmwareVersionStr() const
 {
        std::stringstream ver;
-       ver << std::hex <<
+       ver <<
                (myFirmwareVersion >> 8) <<
                '.' << ((myFirmwareVersion & 0xF0) >> 4);
 
index 4f1209f..8209476 100644 (file)
@@ -888,7 +888,7 @@ private:
                for (size_t i = 0; i < 2; ++i)
                {
                        std::stringstream ss;
-                       ss << "Programming sector flash array " << sector;
+                       ss << "Writing SD sector " << sector;
                        mmLogStatus(ss.str());
                        currentProgress += 1;