Quellcode durchsuchen

Stability fixes and SD UHS-I Speed class 3 fix.

Michael McMaster vor 9 Jahren
Ursprung
Commit
195b7fa687

+ 4 - 0
lib/SCSI2SD/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.

+ 45 - 30
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c

@@ -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;

+ 21 - 22
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/SCSI2SD-V6.ioc

@@ -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

+ 11 - 9
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c

@@ -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 */
 

+ 4 - 3
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Src/main.c

@@ -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);
 

+ 10 - 4
lib/SCSI2SD/STM32CubeMX/SCSI2SD-V6/Src/sdio.c

@@ -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 */

BIN
lib/SCSI2SD/rtl/fpga_bitmap.o


+ 1 - 1
lib/SCSI2SD/src/firmware/config.c

@@ -37,7 +37,7 @@
 
 #include <string.h>
 
-static const uint16_t FIRMWARE_VERSION = 0x0608;
+static const uint16_t FIRMWARE_VERSION = 0x060A;
 
 // 1 flash row
 static const uint8_t DEFAULT_CONFIG[128] =

+ 43 - 17
lib/SCSI2SD/src/firmware/disk.c

@@ -544,19 +544,25 @@ void scsiDiskPoll()
 				transfer.lba);
 
 		const int sdPerScsi = SDSectorsPerSCSISector(bytesPerSector);
-		int buffers = sizeof(scsiDev.data) / SD_SECTOR_SIZE;
+		const int buffers = sizeof(scsiDev.data) / SD_SECTOR_SIZE;
 		int prep = 0;
 		int i = 0;
-		int scsiActive = 0;
+		int scsiActive __attribute__((unused)) = 0; // unused if DMA disabled
 		int sdActive = 0;
 		while ((i < totalSDSectors) &&
 			likely(scsiDev.phase == DATA_IN) &&
 			likely(!scsiDev.resetFlag))
 		{
-			if (sdActive && sdReadDMAPoll())
+			int completedDmaSectors;
+			if (sdActive && (completedDmaSectors = sdReadDMAPoll(sdActive)))
 			{
-				prep += sdActive;
-				sdActive = 0;
+				prep += completedDmaSectors;
+				sdActive -= completedDmaSectors;
+			} else if (sdActive > 1) {
+				if (scsiDev.data[SD_SECTOR_SIZE * (prep % buffers) + 511] != 0x33) {
+					prep += 1;
+					sdActive -= 1;
+				}
 			}
 
 			if (!sdActive &&
@@ -566,25 +572,27 @@ void scsiDiskPoll()
 				// Start an SD transfer if we have space.
 				uint32_t startBuffer = prep % buffers;
 				uint32_t sectors = totalSDSectors - prep;
-#if 0
-				if (!scsiActive && prep == i)
-				{
-					sectors = 1; // We need to get some data to send ASAP !
-				}
-				else
-#endif
+
+				uint32_t freeBuffers = buffers - (prep - i);
+
+				uint32_t contiguousBuffers = buffers - startBuffer;
+				freeBuffers = freeBuffers < contiguousBuffers
+					? freeBuffers : contiguousBuffers;
+				sectors = sectors < freeBuffers ? sectors : freeBuffers;
+
+				if (sectors > 128) sectors = 128; // 65536 DMA limit !!
+
+				for (int dodgy = 0; dodgy < sectors; dodgy++)
 				{
-					uint32_t freeBuffers = buffers - (prep - i);
-					uint32_t contiguousBuffers = buffers - startBuffer;
-					freeBuffers = freeBuffers < contiguousBuffers
-						? freeBuffers : contiguousBuffers;
-					sectors = sectors < freeBuffers ? sectors : freeBuffers;
+					scsiDev.data[SD_SECTOR_SIZE * (startBuffer + dodgy) + 511] = 0x33;
 				}
+
 				sdReadDMA(sdLBA + prep, sectors, &scsiDev.data[SD_SECTOR_SIZE * startBuffer]);
 
 				sdActive = sectors;
 			}
 
+#ifdef SCSI_FSMC_DMA
 			if (scsiActive && scsiPhyComplete() && scsiWriteDMAPoll())
 			{
 				scsiActive = 0;
@@ -602,6 +610,24 @@ void scsiDiskPoll()
 				scsiWriteDMA(&scsiDev.data[SD_SECTOR_SIZE * (i % buffers)], dmaBytes);
 				scsiActive = 1;
 			}
+#else
+			if ((prep - i) > 0)
+			{
+				int dmaBytes = SD_SECTOR_SIZE;
+				if ((i % sdPerScsi) == (sdPerScsi - 1))
+				{
+					dmaBytes = bytesPerSector % SD_SECTOR_SIZE;
+					if (dmaBytes == 0) dmaBytes = SD_SECTOR_SIZE;
+				}
+				for (int k = 0; k < dmaBytes; ++k)
+				{
+					scsiPhyTx(scsiDev.data[SD_SECTOR_SIZE * (i % buffers) + k]);
+				}
+				i++;
+				while (!scsiPhyComplete() && !scsiDev.resetFlag) {}
+				scsiPhyFifoFlip();
+			}
+#endif
 		}
 
 		// We've finished transferring the data to the FPGA, now wait until it's

+ 34 - 43
lib/SCSI2SD/src/firmware/scsiPhy.c

@@ -29,23 +29,26 @@
 #include <string.h>
 
 // 5MB/s
-// Assumes a 60MHz fpga clock.
-// 7:6 Hold count, 45ns
-// 5:3 Assertion count, 90ns
+// Assumes a 96MHz fpga clock.
 // 2:0 Deskew count, 55ns
-#define SCSI_DEFAULT_TIMING ((0x3 << 6) | (0x6 << 3) | 0x4)
+// 6:4 Hold count, 53ns
+// 3:0 Assertion count, 80ns
+#define SCSI_DEFAULT_DESKEW 0x6
+#define SCSI_DEFAULT_TIMING ((0x5 << 4) | 0x8)
 
 // 10MB/s
-// 7:6 Hold count, 17ns
-// 5:3 Assertion count, 30ns
 // 2:0 Deskew count, 25ns
-#define SCSI_FAST10_TIMING ((0x1 << 6) | (0x2 << 3) | 0x2)
+// 6:4 Hold count, 33ns
+// 3:0 Assertion count, 30ns
+#define SCSI_FAST10_DESKEW 3
+#define SCSI_FAST10_TIMING ((0x3 << 4) | 0x3)
 
 // 20MB/s
-// 7:6 Hold count, 17ns
-// 5:3 Assertion count, 17ns
-// 2:0 Deskew count, 17ns
-#define SCSI_FAST20_TIMING ((0x1 << 6) | (0x1 << 3) | 0x1)
+// 2:0 Deskew count, 12ns
+// 6:4 Hold count, 17ns
+// 3:0 Assertion count, 15ns
+#define SCSI_FAST20_DESKEW 2
+#define SCSI_FAST20_TIMING ((0x2 << 4) | 0x2)
 
 // Private DMA variables.
 static int dmaInProgress = 0;
@@ -199,11 +202,13 @@ scsiRead(uint8_t* data, uint32_t count)
 
 	uint32_t chunk = ((count - i) > SCSI_FIFO_DEPTH)
 		? SCSI_FIFO_DEPTH : (count - i);
+#ifdef SCSI_FSMC_DMA
 	if (chunk >= 16)
 	{
 		// DMA is doing 32bit transfers.
 		chunk = chunk & 0xFFFFFFF8;
 	}
+#endif
 	startScsiRx(chunk);
 
 	while (i < count && likely(!scsiDev.resetFlag))
@@ -213,19 +218,24 @@ scsiRead(uint8_t* data, uint32_t count)
 
 		uint32_t nextChunk = ((count - i - chunk) > SCSI_FIFO_DEPTH)
 			? SCSI_FIFO_DEPTH : (count - i - chunk);
+#ifdef SCSI_FSMC_DMA
 		if (nextChunk >= 16)
 		{
 			nextChunk = nextChunk & 0xFFFFFFF8;
 		}
+#endif
 		if (nextChunk > 0)
 		{
 			startScsiRx(nextChunk);
 		}
 
+#ifdef SCSI_FSMC_DMA
 		if (chunk < 16)
+#endif
 		{
 			scsiReadPIO(data + i, chunk);
 		}
+#ifdef SCSI_FSMC_DMA
 		else
 		{
 			scsiReadDMA(data + i, chunk);
@@ -236,12 +246,13 @@ scsiRead(uint8_t* data, uint32_t count)
 			{
 			};
 		}
+#endif
 
 
 		i += chunk;
 		chunk = nextChunk;
 	}
-#if 1
+#if FIFODEBUG
 		if (!scsiPhyFifoEmpty() || !scsiPhyFifoAltEmpty()) {
 			int j = 0;
 			while (!scsiPhyFifoEmpty()) { scsiPhyRx(); ++j; }
@@ -339,10 +350,13 @@ scsiWrite(const uint8_t* data, uint32_t count)
 		}
 #endif
 
+#ifdef SCSI_FSMC_DMA
 		if (chunk < 16)
+#endif
 		{
 			scsiWritePIO(data + i, chunk);
 		}
+#ifdef SCSI_FSMC_DMA
 		else
 		{
 			// DMA is doing 32bit transfers.
@@ -355,6 +369,7 @@ scsiWrite(const uint8_t* data, uint32_t count)
 			{
 			}
 		}
+#endif
 
 		while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))
 		{
@@ -417,15 +432,18 @@ void scsiEnterPhase(int phase)
 			if (scsiDev.target->syncPeriod == 12)
 			{
 				// SCSI2 FAST-20 Timing. 20MB/s.
-				*SCSI_CTRL_TIMING = SCSI_FAST20_TIMING;
+				*SCSI_CTRL_TIMING = SCSI_FAST20_DESKEW;
+				*SCSI_CTRL_TIMING2 = SCSI_FAST20_TIMING;
 			}
 			else if (scsiDev.target->syncPeriod == 25)
 			{
 				// SCSI2 FAST Timing. 10MB/s.
-				*SCSI_CTRL_TIMING = SCSI_FAST10_TIMING;
+				*SCSI_CTRL_TIMING = SCSI_FAST10_DESKEW;
+				*SCSI_CTRL_TIMING2 = SCSI_FAST10_TIMING;
 			} else {
 				// 5MB/s Timing
-				*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;
+				*SCSI_CTRL_TIMING = SCSI_DEFAULT_DESKEW;
+				*SCSI_CTRL_TIMING2 = SCSI_DEFAULT_TIMING;
 			}
 			*SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset;
 		} else {
@@ -455,33 +473,6 @@ void scsiPhyReset()
 
 		dmaInProgress = 0;
 	}
-#if 0
-
-	// Set the Clear bits for both SCSI device FIFOs
-	scsiTarget_AUX_CTL = scsiTarget_AUX_CTL | 0x03;
-
-	// Trigger RST outselves.  It is connected to the datapath and will
-	// ensure it returns to the idle state.  The datapath runs at the BUS clk
-	// speed (ie. same as the CPU), so we can be sure it is active for a sufficient
-	// duration.
-	SCSI_RST_ISR_Disable();
-	SCSI_SetPin(SCSI_Out_RST);
-
-	SCSI_CTL_PHASE_Write(0);
-	SCSI_ClearPin(SCSI_Out_ATN);
-	SCSI_ClearPin(SCSI_Out_BSY);
-	SCSI_ClearPin(SCSI_Out_ACK);
-	SCSI_ClearPin(SCSI_Out_RST);
-	SCSI_ClearPin(SCSI_Out_SEL);
-	SCSI_ClearPin(SCSI_Out_REQ);
-
-	// Allow the FIFOs to fill up again.
-	SCSI_ClearPin(SCSI_Out_RST);
-	SCSI_RST_ISR_Enable();
-	scsiTarget_AUX_CTL = scsiTarget_AUX_CTL & ~(0x03);
-
-	SCSI_Parity_Error_Read(); // clear sticky bits
-#endif
 
 	*SCSI_CTRL_PHASE = 0x00;
 	*SCSI_CTRL_BSY = 0x00;
@@ -495,7 +486,7 @@ void scsiPhyReset()
 	*SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;
 
 	// DMA Benchmark code
-	// Currently 10MB/s. Assume 20MB/s is achievable with 16 bits.
+	// Currently 6.6MB/s. Assume 13MB/s is achievable with 16 bits
 	#ifdef DMA_BENCHMARK
 	while(1)
 	{

+ 6 - 0
lib/SCSI2SD/src/firmware/scsiPhy.h

@@ -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)
@@ -59,6 +60,11 @@
 #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);

+ 19 - 6
lib/SCSI2SD/src/firmware/sd.c

@@ -38,21 +38,31 @@ SdDevice sdDev;
 static int sdCmdActive = 0;
 
 int
-sdReadDMAPoll()
+sdReadDMAPoll(uint32_t remainingSectors)
 {
+	// TODO DMA byte counting disabled for now as it's not
+	// working.
+	// We can ask the SDIO controller how many bytes have been
+	// processed (SDIO_GetDataCounter()) but I'm not sure if that
+	// means the data has been transfered via dma to memory yet.
+//	uint32_t dmaBytesRemaining = __HAL_DMA_GET_COUNTER(hsd.hdmarx) * 4;
+
 	if (hsd.DmaTransferCplt ||
 		hsd.SdTransferCplt ||
+
+//	if (dmaBytesRemaining == 0 ||
 		(HAL_SD_ErrorTypedef)hsd.SdTransferErr != SD_OK)
 	{
 		HAL_SD_CheckReadOperation(&hsd, (uint32_t)SD_DATATIMEOUT);
 		// DMA transfer is complete
 		sdCmdActive = 0;
-		return 1;
+		return remainingSectors;
 	}
-	else
+/*	else
 	{
-		return 0;
-	}
+		return remainingSectors - ((dmaBytesRemaining + (SD_SECTOR_SIZE - 1)) / SD_SECTOR_SIZE);
+	}*/
+	return 0;
 }
 
 void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer)
@@ -244,9 +254,12 @@ static void sdInitDMA()
 		init = 1;
 
 		//TODO MM SEE STUPID SD_DMA_RxCplt that require the SD IRQs to preempt
-		// Configured with 4 bits preemption, NO sub priority.
+		// Ie. priority must be geater than the SDIO_IRQn priority.
+		// 4 bits preemption, NO sub priority.
+		HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 		HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 8, 0);
 		HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
+		HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 		HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 8, 0);
 		HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
 	}

+ 1 - 1
lib/SCSI2SD/src/firmware/sd.h

@@ -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();

+ 1 - 1
lib/SCSI2SD/src/scsi2sd-util6/SCSI2SD_HID.cc

@@ -196,7 +196,7 @@ std::string
 HID::getFirmwareVersionStr() const
 {
 	std::stringstream ver;
-	ver << std::hex <<
+	ver <<
 		(myFirmwareVersion >> 8) <<
 		'.' << ((myFirmwareVersion & 0xF0) >> 4);
 

+ 1 - 1
lib/SCSI2SD/src/scsi2sd-util6/scsi2sd-util.cc

@@ -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;