+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.
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;
/* 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) */
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 */
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 */
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);
/* 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)
{
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;
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
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
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 */
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
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);
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;
__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 */
\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
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
// 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
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
#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
\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
\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
{\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
}\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
{\r
}\r
}\r
+#endif\r
\r
while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
{\r
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
\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
*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
#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);
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
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
int sdWriteSectorDMAPoll();
void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer);
-int sdReadDMAPoll();
+int sdReadDMAPoll(uint32_t remainingSectors);
void sdCompleteTransfer();
void sdPoll();
HID::getFirmwareVersionStr() const
{
std::stringstream ver;
- ver << std::hex <<
+ ver <<
(myFirmwareVersion >> 8) <<
'.' << ((myFirmwareVersion & 0xF0) >> 4);
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;