From ee820792749ec3e5fc8d29a6f713f9638ef27efd Mon Sep 17 00:00:00 2001 From: Michael McMaster Date: Sun, 30 Apr 2017 22:12:38 +1000 Subject: [PATCH] Add turbo sync mode --- CHANGELOG | 12 ++++++++++-- STM32CubeMX/SCSI2SD-V6/Src/fsmc.c | 17 ++++++++++------- rtl/fpga_bitmap.o | Bin 32724 -> 32724 bytes src/firmware/config.c | 3 ++- src/firmware/main.c | 5 ++--- src/firmware/scsi.c | 15 +++++++++------ src/firmware/scsiPhy.c | 15 ++++++++++++--- 7 files changed, 45 insertions(+), 22 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1a82b9d2..92cf01db 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,13 @@ -20170429 6.1.1 - - Add new "turbo" speed mode to get faster async transfers. +201705XX 6.1.1 + - Add new "turbo" speed option to boost speeds. + - May not be reliable, and use is not supported. + - Async timings trimmed + - Sync speeds boosted to theoretical 15.625MB/s, with 12.0MB/s measured + read througput. + - SD card put in "high speed" mode. + - USB for configuration/firmware updates is disabled in turbo mode when + processing SCSI commands. A power cycle may be required to connect + via USB to reset the 48MHz clock back to 48MHz. - Fix scsi2sd-util6 size and sector-size inputs - Fix crash when configured scsi disk starting sector is less than SD card size diff --git a/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c b/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c index 8386762a..8a7bf907 100755 --- a/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c +++ b/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c @@ -67,12 +67,12 @@ void MX_FSMC_Init(void) hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; /* Timing */ - // 1 clock to read the address, + 3 for the synchroniser - Timing.AddressSetupTime = 4; + // 1 clock to read the address, + 1 for synchroniser skew + Timing.AddressSetupTime = 2; Timing.AddressHoldTime = 1; - // 3 for synchroniser, 1 to skip hold time, 1 to process read, 1 to output - Timing.DataSetupTime = 6; + // 1 for synchroniser skew, 1 to skip hold time, 1 to process read, 1 to output + Timing.DataSetupTime = 5;//4 doesn't work ? ?? ? // Allow a clock for us to release signals, plus 3 for the synchroniser to // realise the cycle has ended. Need to avoid both devices acting as outputs @@ -126,11 +126,14 @@ static void HAL_FSMC_MspInit(void){ PE0 ------> FSMC_NBL0 PE1 ------> FSMC_NBL1 */ + // MM: GPIO_SPEED_FREQ_MEDIUM is rated up to 50MHz, which is fine as all the + // fsmc timings are > 1 (ie. so clock speed / 2 is around 50MHz). + /* GPIO_InitStruct */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; //HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); @@ -140,7 +143,7 @@ static void HAL_FSMC_MspInit(void){ |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; //HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); @@ -149,7 +152,7 @@ static void HAL_FSMC_MspInit(void){ GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;//HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); diff --git a/rtl/fpga_bitmap.o b/rtl/fpga_bitmap.o index c7f26cf18d87115c81f093ca4db32b9547ff81bf..c535bdbd2776567e28eb6c23d61000ac3b2ae2f6 100644 GIT binary patch literal 32724 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 P-TRQX_$hbFCB=%=8UfP$7{+TsIV{M#+-{! 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 UA^cJ0(ehfrcM51Z$jSTv0Pyct-T(jq diff --git a/src/firmware/config.c b/src/firmware/config.c index e5451ec1..eaa31b00 100755 --- a/src/firmware/config.c +++ b/src/firmware/config.c @@ -193,7 +193,8 @@ scsiDevInfoCommand() sdDev.capacity >> 24, sdDev.capacity >> 16, sdDev.capacity >> 8, - sdDev.capacity + sdDev.capacity, + 1 // useSdConfig, always true for V6. }; hidPacket_send(response, sizeof(response)); } diff --git a/src/firmware/main.c b/src/firmware/main.c index 2bb7d78f..fcada36b 100755 --- a/src/firmware/main.c +++ b/src/firmware/main.c @@ -117,11 +117,11 @@ void mainLoop() // run if the SD card is present at startup. // Don't use VBUS monitoring because that just tells us about // power, which could be from a charger -#if 0 if ((blockDev.state & DISK_PRESENT) && isUsbStarted && (scsiDev.cmdCount > 0) && // no need for speed without scsi - !USBD_Composite_IsConfigured(&hUsbDeviceFS)) + !USBD_Composite_IsConfigured(&hUsbDeviceFS) && + (scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_TURBO)) { if (HAL_SD_HighSpeed(&hsd) == SD_OK) { @@ -130,7 +130,6 @@ void mainLoop() isUsbStarted = 0; } } -#endif else if (!(blockDev.state & DISK_PRESENT) && !isUsbStarted) { diff --git a/src/firmware/scsi.c b/src/firmware/scsi.c index 854707d5..19fb4764 100755 --- a/src/firmware/scsi.c +++ b/src/firmware/scsi.c @@ -807,14 +807,17 @@ static void process_MessageOut() // FAST20 / 50ns / 20MHz is disabled for now due to // data corruption while reading data. We can count the // ACK's correctly, but can't save the data to a register - // before it changes. - // TODO work out the fastest sync period that will work - /* - if (transferPeriod <= 12) + // before it changes. (ie. transferPeriod == 12) + if ((scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_TURBO) && + (transferPeriod <= 16)) { - scsiDev.target->syncPeriod = 12; // 50ns, 20MB/s + scsiDev.target->syncPeriod = 16; // 15.6MB/s } - else */if (transferPeriod <= 25 && + else if (scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_TURBO) + { + scsiDev.target->syncPeriod = transferPeriod; + } + else if (transferPeriod <= 25 && ((scsiDev.boardCfg.scsiSpeed == S2S_CFG_SPEED_NoLimit) || (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_SYNC_10))) { diff --git a/src/firmware/scsiPhy.c b/src/firmware/scsiPhy.c index 488c33c6..58d56f66 100755 --- a/src/firmware/scsiPhy.c +++ b/src/firmware/scsiPhy.c @@ -60,6 +60,12 @@ static uint8_t asyncTimings[][4] = #define SCSI_FAST10_HOLD 3 // 33ns #define SCSI_FAST10_ASSERT 3 // 30ns +// Fastest possible timing, probably not 20MB/s +#define SCSI_FAST20_DESKEW 1 +#define SCSI_FAST20_HOLD 2 +#define SCSI_FAST20_ASSERT 2 + + #define syncDeskew(period) ((period) < 45 ? \ SCSI_FAST10_DESKEW : SCSI_FAST5_DESKEW) @@ -493,8 +499,11 @@ void scsiEnterPhase(int phase) if ((newPhase == DATA_IN || newPhase == DATA_OUT) && scsiDev.target->syncOffset) { - - if (scsiDev.target->syncPeriod <= 25) + if (scsiDev.target->syncPeriod < 23) + { + scsiSetTiming(SCSI_FAST20_ASSERT, SCSI_FAST20_DESKEW, SCSI_FAST20_HOLD, 1); + } + else if (scsiDev.target->syncPeriod <= 25) { scsiSetTiming(SCSI_FAST10_ASSERT, SCSI_FAST10_DESKEW, SCSI_FAST10_HOLD, 1); } @@ -539,7 +548,7 @@ void scsiEnterPhase(int phase) } else if (scsiDev.boardCfg.scsiSpeed >= S2S_CFG_SPEED_ASYNC_33) { asyncTiming = asyncTimings[SCSI_ASYNC_33]; - + } else { asyncTiming = asyncTimings[SCSI_ASYNC_15]; } -- 2.38.5