From: Michael McMaster Date: Sun, 11 Sep 2016 11:40:33 +0000 (+1000) Subject: Fixed fsmc timing some more so it's stable X-Git-Tag: v6.0.10~1 X-Git-Url: http://git.codesrc.com/gitweb.cgi?a=commitdiff_plain;h=fb9c26453038f15ec98eb0e151e23d2af38327b2;p=SCSI2SD-V6.git Fixed fsmc timing some more so it's stable - fsmc interface is now 16bits --- diff --git a/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c b/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c index d01e9c33..8386762a 100755 --- a/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c +++ b/STM32CubeMX/SCSI2SD-V6/Src/fsmc.c @@ -55,7 +55,7 @@ void MX_FSMC_Init(void) hsram1.Init.NSBank = FSMC_NORSRAM_BANK1; hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_ENABLE; hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_PSRAM; - hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_8; + hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; @@ -67,18 +67,17 @@ 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; + // 1 clock to read the address, + 3 for the synchroniser + Timing.AddressSetupTime = 4; 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 + // 3 for synchroniser, 1 to skip hold time, 1 to process read, 1 to output + Timing.DataSetupTime = 6; - // Allow a clock for us to release signals, or else we'll read - // our own output data as an address. - Timing.BusTurnAroundDuration = 1; + // 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 + // on the multiplexed lines at the same time. + Timing.BusTurnAroundDuration = 4; Timing.CLKDivision = 16; // Ignored for async Timing.DataLatency = 17; // Ignored for async @@ -108,6 +107,11 @@ static void HAL_FSMC_MspInit(void){ PE8 ------> FSMC_DA5 PE9 ------> FSMC_DA6 PE10 ------> FSMC_DA7 + PE11 ------> FSMC_DA8 + PE12 ------> FSMC_DA9 + PE13 ------> FSMC_DA10 + PE14 ------> FSMC_DA11 + PE15 ------> FSMC_DA12 PD14 ------> FSMC_DA0 PD15 ------> FSMC_DA1 PD0 ------> FSMC_DA2 @@ -115,10 +119,15 @@ static void HAL_FSMC_MspInit(void){ PD4 ------> FSMC_NOE PD5 ------> FSMC_NWE PD7 ------> FSMC_NE1 + PD8 ------> FSMC_DA13 + PD9 ------> FSMC_DA14 + PD10 ------> FSMC_DA15 PB7 ------> FSMC_NL + PE0 ------> FSMC_NBL0 + PE1 ------> FSMC_NBL1 */ /* GPIO_InitStruct */ - GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10; + 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; @@ -128,7 +137,7 @@ static void HAL_FSMC_MspInit(void){ /* GPIO_InitStruct */ GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1 - |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7; + |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; @@ -178,6 +187,11 @@ static void HAL_FSMC_MspDeInit(void){ PE8 ------> FSMC_DA5 PE9 ------> FSMC_DA6 PE10 ------> FSMC_DA7 + PE11 ------> FSMC_DA8 + PE12 ------> FSMC_DA9 + PE13 ------> FSMC_DA10 + PE14 ------> FSMC_DA11 + PE15 ------> FSMC_DA12 PD14 ------> FSMC_DA0 PD15 ------> FSMC_DA1 PD0 ------> FSMC_DA2 @@ -185,13 +199,18 @@ static void HAL_FSMC_MspDeInit(void){ PD4 ------> FSMC_NOE PD5 ------> FSMC_NWE PD7 ------> FSMC_NE1 + PD8 ------> FSMC_DA13 + PD9 ------> FSMC_DA14 + PD10 ------> FSMC_DA15 PB7 ------> FSMC_NL + PE0 ------> FSMC_NBL0 + PE1 ------> FSMC_NBL1 */ - HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10); + HAL_GPIO_DeInit(GPIOE, 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); HAL_GPIO_DeInit(GPIOD, GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1 - |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7); + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10); HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7); diff --git a/rtl/fpga_bitmap.o b/rtl/fpga_bitmap.o index 5d95ad37..604983ff 100644 Binary files a/rtl/fpga_bitmap.o and b/rtl/fpga_bitmap.o differ diff --git a/src/firmware/disk.c b/src/firmware/disk.c index be912166..7d6d4757 100755 --- a/src/firmware/disk.c +++ b/src/firmware/disk.c @@ -619,13 +619,16 @@ void scsiDiskPoll() dmaBytes = bytesPerSector % SD_SECTOR_SIZE; if (dmaBytes == 0) dmaBytes = SD_SECTOR_SIZE; } - for (int k = 0; k < dmaBytes; ++k) + + uint16_t* scsiDmaData = (uint16_t*) &(scsiDev.data[SD_SECTOR_SIZE * (i % buffers)]); + for (int k = 0; k < (dmaBytes + 1) / 2; ++k) { - scsiPhyTx(scsiDev.data[SD_SECTOR_SIZE * (i % buffers) + k]); + scsiPhyTx(scsiDmaData[k]); } i++; while (!scsiPhyComplete() && !scsiDev.resetFlag) {} scsiPhyFifoFlip(); + scsiSetDataCount(dmaBytes); } #endif } diff --git a/src/firmware/scsiPhy.c b/src/firmware/scsiPhy.c index ba71f659..7b4e4633 100755 --- a/src/firmware/scsiPhy.c +++ b/src/firmware/scsiPhy.c @@ -109,8 +109,8 @@ static void assertFail() } } -static void -startScsiRx(uint32_t count) +void +scsiSetDataCount(uint32_t count) { *SCSI_DATA_CNT_HI = count >> 8; *SCSI_DATA_CNT_LO = count & 0xff; @@ -126,7 +126,7 @@ scsiReadByte(void) assertFail(); } #endif - startScsiRx(1); + scsiSetDataCount(1); trace(trace_spinPhyRxFifo); while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {} @@ -151,9 +151,10 @@ scsiReadByte(void) static void scsiReadPIO(uint8_t* data, uint32_t count) { - for (int i = 0; i < count; ++i) + uint16_t* fifoData = (uint16_t*)data; + for (int i = 0; i < (count + 1) / 2; ++i) { - data[i] = scsiPhyRx(); + fifoData[i] = scsiPhyRx(); // TODO ASSUMES LITTLE ENDIAN } // TODO scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read(); } @@ -168,7 +169,11 @@ scsiReadDMA(uint8_t* data, uint32_t count) scsiTxDMAComplete = 1; // TODO not used much scsiRxDMAComplete = 0; // TODO not used much - HAL_DMA_Start(&fsmcToMem, (uint32_t) SCSI_FIFO_DATA, (uint32_t) data, count); + HAL_DMA_Start( + &fsmcToMem, + (uint32_t) SCSI_FIFO_DATA, + (uint32_t) data, + (count + 1) / 2); } int @@ -209,7 +214,7 @@ scsiRead(uint8_t* data, uint32_t count) chunk = chunk & 0xFFFFFFF8; } #endif - startScsiRx(chunk); + scsiSetDataCount(chunk); while (i < count && likely(!scsiDev.resetFlag)) { @@ -226,7 +231,7 @@ scsiRead(uint8_t* data, uint32_t count) #endif if (nextChunk > 0) { - startScsiRx(nextChunk); + scsiSetDataCount(nextChunk); } #ifdef SCSI_FSMC_DMA @@ -278,6 +283,8 @@ scsiWriteByte(uint8_t value) scsiPhyTx(value); scsiPhyFifoFlip(); + scsiSetDataCount(1); + trace(trace_spinTxComplete); while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {} @@ -292,9 +299,10 @@ scsiWriteByte(uint8_t value) static void scsiWritePIO(const uint8_t* data, uint32_t count) { - for (int i = 0; i < count; ++i) + uint16_t* fifoData = (uint16_t*)data; + for (int i = 0; i < (count + 1) / 2; ++i) { - scsiPhyTx(data[i]); + scsiPhyTx(fifoData[i]); } } @@ -383,6 +391,7 @@ scsiWrite(const uint8_t* data, uint32_t count) #endif scsiPhyFifoFlip(); + scsiSetDataCount(chunk); i += chunk; } while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) @@ -486,7 +495,7 @@ void scsiPhyReset() *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING; // DMA Benchmark code - // Currently 6.6MB/s. Assume 13MB/s is achievable with 16 bits + // Currently 11MB/s. #ifdef DMA_BENCHMARK while(1) { @@ -551,7 +560,7 @@ void scsiPhyReset() &fsmcToMem, (uint32_t) SCSI_FIFO_DATA, (uint32_t) &scsiDev.data[0], - SCSI_FIFO_DEPTH); + SCSI_FIFO_DEPTH / 2); HAL_DMA_PollForTransfer( &fsmcToMem, @@ -598,11 +607,11 @@ static void scsiPhyInitDMA() memToFSMC.Init.PeriphInc = DMA_PINC_ENABLE; memToFSMC.Init.MemInc = DMA_MINC_DISABLE; memToFSMC.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; - memToFSMC.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + memToFSMC.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; memToFSMC.Init.Mode = DMA_NORMAL; memToFSMC.Init.Priority = DMA_PRIORITY_LOW; // FIFO mode is needed to allow conversion from 32bit words to the - // 8bit FSMC interface. + // 16bit FSMC interface. memToFSMC.Init.FIFOMode = DMA_FIFOMODE_ENABLE; // We only use 1 word (4 bytes) in the fifo at a time. Normally it's @@ -622,7 +631,7 @@ static void scsiPhyInitDMA() fsmcToMem.Init.Direction = DMA_MEMORY_TO_MEMORY; fsmcToMem.Init.PeriphInc = DMA_PINC_DISABLE; fsmcToMem.Init.MemInc = DMA_MINC_ENABLE; - fsmcToMem.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + fsmcToMem.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; fsmcToMem.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; fsmcToMem.Init.Mode = DMA_NORMAL; fsmcToMem.Init.Priority = DMA_PRIORITY_LOW; diff --git a/src/firmware/scsiPhy.h b/src/firmware/scsiPhy.h index fa7e1684..718b25fb 100755 --- a/src/firmware/scsiPhy.h +++ b/src/firmware/scsiPhy.h @@ -18,25 +18,25 @@ #define SCSIPHY_H #define SCSI_CTRL_IDMASK ((volatile uint8_t*)0x60000000) -#define SCSI_CTRL_PHASE ((volatile uint8_t*)0x60000001) -#define SCSI_CTRL_BSY ((volatile uint8_t*)0x60000002) -#define SCSI_FIFO_SEL ((volatile uint8_t*)0x60000003) -#define SCSI_DATA_CNT_HI ((volatile uint8_t*)0x60000004) -#define SCSI_DATA_CNT_LO ((volatile uint8_t*)0x60000005) -#define SCSI_DATA_CNT_SET ((volatile uint8_t*)0x60000006) -#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 SCSI_STS_FIFO_COMPLETE ((volatile uint8_t*)0x60000012) -#define SCSI_STS_SELECTED ((volatile uint8_t*)0x60000013) -#define SCSI_STS_SCSI ((volatile uint8_t*)0x60000014) -#define SCSI_STS_DBX ((volatile uint8_t*)0x60000015) - -#define SCSI_FIFO_DATA ((volatile uint8_t*)0x60000020) +#define SCSI_CTRL_PHASE ((volatile uint8_t*)0x60000002) +#define SCSI_CTRL_BSY ((volatile uint8_t*)0x60000004) +#define SCSI_FIFO_SEL ((volatile uint8_t*)0x60000006) +#define SCSI_DATA_CNT_HI ((volatile uint8_t*)0x60000008) +#define SCSI_DATA_CNT_LO ((volatile uint8_t*)0x6000000A) +#define SCSI_DATA_CNT_SET ((volatile uint8_t*)0x6000000C) +#define SCSI_CTRL_DBX ((volatile uint8_t*)0x6000000E) +#define SCSI_CTRL_SYNC_OFFSET ((volatile uint8_t*)0x60000010) +#define SCSI_CTRL_TIMING ((volatile uint8_t*)0x60000012) +#define SCSI_CTRL_TIMING2 ((volatile uint8_t*)0x60000014) + +#define SCSI_STS_FIFO ((volatile uint8_t*)0x60000020) +#define SCSI_STS_ALTFIFO ((volatile uint8_t*)0x60000022) +#define SCSI_STS_FIFO_COMPLETE ((volatile uint8_t*)0x60000024) +#define SCSI_STS_SELECTED ((volatile uint8_t*)0x60000026) +#define SCSI_STS_SCSI ((volatile uint8_t*)0x60000028) +#define SCSI_STS_DBX ((volatile uint8_t*)0x6000002A) + +#define SCSI_FIFO_DATA ((volatile uint16_t*)0x60000040) #define SCSI_FIFO_DEPTH 512 @@ -74,6 +74,8 @@ void scsiPhyReset(void); void scsiEnterPhase(int phase); void scsiEnterBusFree(void); +void scsiSetDataCount(uint32_t count); + void scsiWrite(const uint8_t* data, uint32_t count); void scsiRead(uint8_t* data, uint32_t count); void scsiWriteByte(uint8_t value); @@ -82,12 +84,6 @@ uint8_t scsiReadByte(void); void sdTmpRead(uint8_t* data, uint32_t lba, int sectors); void sdTmpWrite(uint8_t* data, uint32_t lba, int sectors); -#if 0 - -// Contains the odd-parity flag for a given 8-bit value. -extern const uint8_t Lookup_OddParity[256]; - -#endif extern volatile uint8_t scsiRxDMAComplete; extern volatile uint8_t scsiTxDMAComplete;