From: Michael McMaster Date: Sat, 10 Sep 2016 09:22:36 +0000 (+1000) Subject: Stability fixes and SD UHS-I Speed class 3 fix. X-Git-Tag: v6.0.10~2 X-Git-Url: http://git.codesrc.com/gitweb.cgi?a=commitdiff_plain;h=6534c041b10accfffc45799d4020e6bbf0c6ac6c;p=SCSI2SD-V6.git Stability fixes and SD UHS-I Speed class 3 fix. --- diff --git a/CHANGELOG b/CHANGELOG index b11680d5..6165e3c4 100644 --- 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. diff --git a/STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c b/STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c index 8511aa7b..9d2062dc 100755 --- a/STM32CubeMX/SCSI2SD-V6/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c +++ b/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; diff --git a/STM32CubeMX/SCSI2SD-V6/SCSI2SD-V6.ioc b/STM32CubeMX/SCSI2SD-V6/SCSI2SD-V6.ioc index ed61a351..056fddb8 100755 --- a/STM32CubeMX/SCSI2SD-V6/SCSI2SD-V6.ioc +++ b/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 diff --git a/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c b/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c index de40c343..d01e9c33 100755 --- a/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c +++ b/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 */ diff --git a/STM32CubeMX/SCSI2SD-V6/Src/main.c b/STM32CubeMX/SCSI2SD-V6/Src/main.c index bf352ace..45f98d9c 100755 --- a/STM32CubeMX/SCSI2SD-V6/Src/main.c +++ b/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); diff --git a/STM32CubeMX/SCSI2SD-V6/Src/sdio.c b/STM32CubeMX/SCSI2SD-V6/Src/sdio.c index d1bb9dca..678a9e7a 100755 --- a/STM32CubeMX/SCSI2SD-V6/Src/sdio.c +++ b/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 */ diff --git a/rtl/fpga_bitmap.o b/rtl/fpga_bitmap.o index 56551b36..5d95ad37 100644 Binary files a/rtl/fpga_bitmap.o and b/rtl/fpga_bitmap.o differ diff --git a/src/firmware/config.c b/src/firmware/config.c index 7acb0831..6430d573 100755 --- a/src/firmware/config.c +++ b/src/firmware/config.c @@ -37,7 +37,7 @@ #include -static const uint16_t FIRMWARE_VERSION = 0x0608; +static const uint16_t FIRMWARE_VERSION = 0x060A; // 1 flash row static const uint8_t DEFAULT_CONFIG[128] = diff --git a/src/firmware/disk.c b/src/firmware/disk.c index 2e69d481..be912166 100755 --- a/src/firmware/disk.c +++ b/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 diff --git a/src/firmware/scsiPhy.c b/src/firmware/scsiPhy.c index f4241573..ba71f659 100755 --- a/src/firmware/scsiPhy.c +++ b/src/firmware/scsiPhy.c @@ -29,23 +29,26 @@ #include // 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) { diff --git a/src/firmware/scsiPhy.h b/src/firmware/scsiPhy.h index b70ff7bc..fa7e1684 100755 --- a/src/firmware/scsiPhy.h +++ b/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); diff --git a/src/firmware/sd.c b/src/firmware/sd.c index c9832d0c..204936db 100755 --- a/src/firmware/sd.c +++ b/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); } diff --git a/src/firmware/sd.h b/src/firmware/sd.h index 1ca10801..74f89a6a 100755 --- a/src/firmware/sd.h +++ b/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(); diff --git a/src/scsi2sd-util6/SCSI2SD_HID.cc b/src/scsi2sd-util6/SCSI2SD_HID.cc index 9b6cb518..94db8b51 100644 --- a/src/scsi2sd-util6/SCSI2SD_HID.cc +++ b/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); diff --git a/src/scsi2sd-util6/scsi2sd-util.cc b/src/scsi2sd-util6/scsi2sd-util.cc index 4f1209f8..82094764 100644 --- a/src/scsi2sd-util6/scsi2sd-util.cc +++ b/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;