uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd);
uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd);
uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd);
+uint32_t SDMMC_CmdSetBlockCount(SDIO_TypeDef *SDIOx, uint32_t appCmdArg, uint32_t blockCount);
uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd);
uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd);
uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd);
return HAL_ERROR;
}
+ if(NumberOfBlocks > 1U && hsd->SdCard.CardType == CARD_SDHC_SDXC)
+ {
+ /* MM: Prepare for write */
+ errorstate = SDMMC_CmdSetBlockCount(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd) << 16, NumberOfBlocks);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+
hsd->State = HAL_SD_STATE_BUSY;
/* Initialize data control register */
{
hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
- /* MM: Prepare for write */
-/* TODO
- SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->RCA << 16));
- SDIO_CmdInitTypeDef mm_cmdinit;
- mm_cmdinit.Argument = (uint32_t)NumberOfBlocks;
- mm_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCK_COUNT;
- mm_cmdinit.Response = SDIO_RESPONSE_SHORT;
- mm_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- mm_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- (void)SDIO_SendCommand(hsd->Instance, &mm_cmdinit);
- SDMMC_GetCmdResp1(hsd->Instance, SDMMC_CMD_SET_BLOCK_COUNT, SDIO_CMDTIMEOUT);*/
-
/* Write Multi Block command */
errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
}
HAL_SD_ErrorCallback(hsd);
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
}
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
+
+ hsd->State = HAL_SD_STATE_READY;
+ hsd->Context = SD_CONTEXT_NONE;
}
if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
{
return errorstate;
}
+/**
+ * @brief Set the count of a multi-block write command
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSetBlockCount(SDIO_TypeDef *SDIOx, uint32_t appCmdArg, uint32_t blockCount)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate;
+
+ errorstate = SDMMC_CmdAppCommand(SDIOx, appCmdArg);
+ if(errorstate == HAL_SD_ERROR_NONE)
+ {
+ sdmmc_cmdinit.Argument = blockCount;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCK_COUNT;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCK_COUNT, SDIO_CMDTIMEOUT);
+ }
+
+ return errorstate;
+}
+
/**
* @brief Send the Write Multi Block command and check the response
* @param SDIOx: Pointer to SDIO register base
else
{
SD_state = MSD_OK;
+
+// Clock bypass mode is broken on STM32F205
+// This just corrupts data for now.
+//#ifdef STM32F4xx
+#if 0
+ uint8_t SD_hs[64] = {0};
+ //uint32_t SD_scr[2] = {0, 0};
+ //uint32_t SD_SPEC = 0 ;
+ uint32_t count = 0;
+ uint32_t *tempbuff = (uint32_t *)SD_hs;
+
+ // Prepare to read 64 bytes training data
+ SDIO_DataInitTypeDef config;
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = 64;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ (void)SDIO_ConfigData(hsd.Instance, &config);
+
+ // High speed switch.
+ // SDR25 (25MB/s) mode 0x80FFFF01
+ // Which is the max without going to 1.8v
+ uint32_t errorstate = SDMMC_CmdSwitch(hsd.Instance, 0x80FFFF01);
+
+ // Low-level init for the bypass. Changes registers only
+ hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_ENABLE;
+ SDIO_Init(hsd.Instance, hsd.Init);
+
+ // Now we read some training data
+
+ if (errorstate == HAL_SD_ERROR_NONE)
+ {
+ while(!__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND/* | SDIO_FLAG_STBITERR*/))
+ {
+ if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXFIFOHF))
+ {
+ for (count = 0; count < 8; count++)
+ {
+ *(tempbuff + count) = SDIO_ReadFIFO(hsd.Instance);
+ }
+
+ tempbuff += 8;
+ }
+ }
+
+ if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_DTIMEOUT);
+ SD_state = MSD_ERROR;
+ }
+ else if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_DCRCFAIL);
+ SD_state = MSD_ERROR;
+ }
+ else if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXOVERR))
+ {
+ __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_RXOVERR);
+ SD_state = MSD_ERROR;
+ }
+ /*else if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_STBITERR))
+ {
+ __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_STBITERR);
+ SD_state = MSD_ERROR;
+ }*/
+ else
+ {
+ count = SD_DATATIMEOUT;
+
+ while ((__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXDAVL)) && (count > 0))
+ {
+ *tempbuff = SDIO_ReadFIFO(hsd.Instance);
+ tempbuff++;
+ count--;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(&hsd, SDIO_STATIC_FLAGS);
+ }
+ }
+#endif
}
}
#endif
{
SD_state = MSD_OK;
}
+
+ while (HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_PROGRAMMING) {}
}
return SD_state;
int enableParity = scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY;\r
\r
uint32_t maxSectors = sizeof(scsiDev.data) / SD_SECTOR_SIZE;\r
- #ifdef STM32F4xx\r
- // TODO fix this hack\r
- // corruption occurs with 65536 byte transfers but not 32768\r
- // works fine on STM32F2 (or at least it did with older firmware ?\r
- if (maxSectors > 64) maxSectors = 64;\r
- #endif\r
\r
static_assert(SCSI_XFER_MAX >= sizeof(scsiDev.data), "Assumes SCSI_XFER_MAX >= sizeof(scsiDev.data)");\r
\r
{\r
// Wait while keeping BSY.\r
}\r
- HAL_SD_GetCardState(&hsd); // TODO check error response\r
+ while (HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_PROGRAMMING) \r
+ {\r
+ // Wait while the SD card is writing buffer to flash\r
+ }\r
\r
if (underrun && (!parityError || !enableParity))\r
{\r