From 4cd9be44df539e6bae6c8f123d9184cf23e64a12 Mon Sep 17 00:00:00 2001 From: Michael McMaster Date: Fri, 4 Feb 2022 21:22:39 +1000 Subject: [PATCH] Expand direct SD interface to reads over 128 sectors --- src/firmware/disk.c | 34 +++++++++++++--------------------- src/firmware/sd.c | 26 ++++++++++++++++---------- src/firmware/sd.h | 3 ++- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/firmware/disk.c b/src/firmware/disk.c index dac1715b..6069eeb1 100755 --- a/src/firmware/disk.c +++ b/src/firmware/disk.c @@ -38,8 +38,6 @@ #include "time.h" #include "bsp.h" -#include "led.h" - #include // Global @@ -690,7 +688,7 @@ static void diskDataInBuffered(int totalSDSectors, uint32_t sdLBA, int useSlowDa // Only functional for 512 byte sectors. static void diskDataInDirect(uint32_t totalSDSectors, uint32_t sdLBA, int useSlowDataCount, uint32_t* phaseChangeDelayNs) { - sdReadPIO(sdLBA, totalSDSectors); + sdReadCmd(sdLBA, totalSDSectors); // Wait while the SD card starts buffering data if (*phaseChangeDelayNs > 0) @@ -701,11 +699,18 @@ static void diskDataInDirect(uint32_t totalSDSectors, uint32_t sdLBA, int useSlo for (int i = 0; i < totalSDSectors && !scsiDev.resetFlag; ++i) { - // TODO if i %128 == 0, and not in an error state, then do another read. - - if (useSlowDataCount) + if (i % 128 == 0) { - scsiSetDataCount(SD_SECTOR_SIZE); + // SD DPSM has 24 bit limit. Re-use 128 (DMA limit) + uint32_t chunk = totalSDSectors - i > 128 ? 128 : totalSDSectors - i; + sdReadPIOData(chunk); + + if (useSlowDataCount) + { + while (!scsiDev.resetFlag && !scsiPhyComplete()) + {} + scsiSetDataCount(chunk * SD_SECTOR_SIZE); // SCSI_XFER_MAX > 65536 + } } // The SCSI fifo is a full sector so we only need to check once. @@ -735,13 +740,6 @@ static void diskDataInDirect(uint32_t totalSDSectors, uint32_t sdLBA, int useSlo *((volatile uint32_t*)SCSI_FIFO_DATA) = data[1]; *((volatile uint32_t*)SCSI_FIFO_DATA) = data[2]; *((volatile uint32_t*)SCSI_FIFO_DATA) = data[3]; - - /* - scsiPhyTx32(data[0] & 0xFFFF, data[0] >> 16); - scsiPhyTx32(data[1] & 0xFFFF, data[1] >> 16); - scsiPhyTx32(data[2] & 0xFFFF, data[2] >> 16); - scsiPhyTx32(data[3] & 0xFFFF, data[3] >> 16); - */ } byteCount += 64; @@ -784,14 +782,8 @@ static void diskDataInDirect(uint32_t totalSDSectors, uint32_t sdLBA, int useSlo scsiPhyTx32(0, 0); byteCount += 4; } - - while (useSlowDataCount && !scsiDev.resetFlag && !scsiPhyComplete()) - { - } } -//while(1) { s2s_ledOn(); s2s_delay_ms(1000); s2s_ledOff(); s2s_delay_ms(1000); } - /* Send stop transmission command in case of multiblock read */ if(totalSDSectors > 1U) { @@ -838,7 +830,7 @@ static void diskDataIn() #ifdef STM32F4xx // Direct mode requires hardware flow control to be working on the SD peripheral - if (bytesPerSector == SD_SECTOR_SIZE && totalSDSectors < 128) + if (bytesPerSector == SD_SECTOR_SIZE) { diskDataInDirect(totalSDSectors, sdLBA, useSlowDataCount, &phaseChangeDelayNs); } diff --git a/src/firmware/sd.c b/src/firmware/sd.c index 6158e97b..7985b3ef 100755 --- a/src/firmware/sd.c +++ b/src/firmware/sd.c @@ -83,7 +83,7 @@ void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer) } } -void sdReadPIO(uint32_t lba, uint32_t sectors) +void sdReadCmd(uint32_t lba, uint32_t sectors) { uint32_t errorstate; hsd.ErrorCode = HAL_SD_ERROR_NONE; @@ -117,15 +117,6 @@ void sdReadPIO(uint32_t lba, uint32_t sectors) } } - SDIO_DataInitTypeDef config; - config.DataTimeOut = SDMMC_DATATIMEOUT; - config.DataLength = sectors * 512u; - config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; - config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; - config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; - config.DPSM = SDIO_DPSM_ENABLE; - SDIO_ConfigData(hsd.Instance, &config); - if(sectors > 1U) { hsd.Context = SD_CONTEXT_READ_MULTIPLE_BLOCK; @@ -154,6 +145,21 @@ void sdReadPIO(uint32_t lba, uint32_t sectors) } } +void sdReadPIOData(uint32_t sectors) +{ + /* Initialize data control register */ + hsd.Instance->DCTRL = 0U; + + SDIO_DataInitTypeDef config; + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = sectors * 512u; + config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; + config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + config.DPSM = SDIO_DPSM_ENABLE; + SDIO_ConfigData(hsd.Instance, &config); +} + void sdCompleteTransfer() { diff --git a/src/firmware/sd.h b/src/firmware/sd.h index 67dc48c7..35b32e60 100755 --- a/src/firmware/sd.h +++ b/src/firmware/sd.h @@ -37,7 +37,8 @@ int sdInit(void); void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer); int sdReadDMAPoll(uint32_t remainingSectors); -void sdReadPIO(uint32_t lba, uint32_t sectors); +void sdReadCmd(uint32_t lba, uint32_t sectors); +void sdReadPIOData(uint32_t sectors); void sdCompleteTransfer(); void sdKeepAlive(); -- 2.38.5