Fixed fsmc timing some more so it's stable
authorMichael McMaster <michael@codesrc.com>
Sun, 11 Sep 2016 11:40:33 +0000 (21:40 +1000)
committerMichael McMaster <michael@codesrc.com>
Sun, 11 Sep 2016 11:40:33 +0000 (21:40 +1000)
 - fsmc interface is now 16bits

STM32CubeMX/SCSI2SD-V6/Src/fsmc.c
rtl/fpga_bitmap.o
src/firmware/disk.c
src/firmware/scsiPhy.c
src/firmware/scsiPhy.h

index d01e9c3..8386762 100755 (executable)
@@ -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);
 
index 5d95ad3..604983f 100644 (file)
Binary files a/rtl/fpga_bitmap.o and b/rtl/fpga_bitmap.o differ
index be91216..7d6d475 100755 (executable)
@@ -619,13 +619,16 @@ void scsiDiskPoll()
                                        dmaBytes = bytesPerSector % SD_SECTOR_SIZE;\r
                                        if (dmaBytes == 0) dmaBytes = SD_SECTOR_SIZE;\r
                                }\r
-                               for (int k = 0; k < dmaBytes; ++k)\r
+\r
+                               uint16_t* scsiDmaData = (uint16_t*) &(scsiDev.data[SD_SECTOR_SIZE * (i % buffers)]);\r
+                               for (int k = 0; k < (dmaBytes + 1) / 2; ++k)\r
                                {\r
-                                       scsiPhyTx(scsiDev.data[SD_SECTOR_SIZE * (i % buffers) + k]);\r
+                                       scsiPhyTx(scsiDmaData[k]);\r
                                }\r
                                i++;\r
                                while (!scsiPhyComplete() && !scsiDev.resetFlag) {}\r
                                scsiPhyFifoFlip();\r
+                               scsiSetDataCount(dmaBytes);\r
                        }\r
 #endif\r
                }\r
index ba71f65..7b4e463 100755 (executable)
@@ -109,8 +109,8 @@ static void assertFail()
        }\r
 }\r
 \r
-static void\r
-startScsiRx(uint32_t count)\r
+void\r
+scsiSetDataCount(uint32_t count)\r
 {\r
        *SCSI_DATA_CNT_HI = count >> 8;\r
        *SCSI_DATA_CNT_LO = count & 0xff;\r
@@ -126,7 +126,7 @@ scsiReadByte(void)
                assertFail();\r
        }\r
 #endif\r
-       startScsiRx(1);\r
+       scsiSetDataCount(1);\r
 \r
        trace(trace_spinPhyRxFifo);\r
        while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
@@ -151,9 +151,10 @@ scsiReadByte(void)
 static void\r
 scsiReadPIO(uint8_t* data, uint32_t count)\r
 {\r
-       for (int i = 0; i < count; ++i)\r
+       uint16_t* fifoData = (uint16_t*)data;\r
+       for (int i = 0; i < (count + 1) / 2; ++i)\r
        {\r
-               data[i] = scsiPhyRx();\r
+               fifoData[i] = scsiPhyRx(); // TODO ASSUMES LITTLE ENDIAN\r
        }\r
        // TODO scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read();\r
 }\r
@@ -168,7 +169,11 @@ scsiReadDMA(uint8_t* data, uint32_t count)
        scsiTxDMAComplete = 1; // TODO not used much\r
        scsiRxDMAComplete = 0; // TODO not used much\r
 \r
-       HAL_DMA_Start(&fsmcToMem, (uint32_t) SCSI_FIFO_DATA, (uint32_t) data, count);\r
+       HAL_DMA_Start(\r
+               &fsmcToMem,\r
+               (uint32_t) SCSI_FIFO_DATA,\r
+               (uint32_t) data,\r
+               (count + 1) / 2);\r
 }\r
 \r
 int\r
@@ -209,7 +214,7 @@ scsiRead(uint8_t* data, uint32_t count)
                chunk = chunk & 0xFFFFFFF8;\r
        }\r
 #endif\r
-       startScsiRx(chunk);\r
+       scsiSetDataCount(chunk);\r
 \r
        while (i < count && likely(!scsiDev.resetFlag))\r
        {\r
@@ -226,7 +231,7 @@ scsiRead(uint8_t* data, uint32_t count)
 #endif\r
                if (nextChunk > 0)\r
                {\r
-                       startScsiRx(nextChunk);\r
+                       scsiSetDataCount(nextChunk);\r
                }\r
 \r
 #ifdef SCSI_FSMC_DMA\r
@@ -278,6 +283,8 @@ scsiWriteByte(uint8_t value)
        scsiPhyTx(value);\r
        scsiPhyFifoFlip();\r
 \r
+       scsiSetDataCount(1);\r
+\r
        trace(trace_spinTxComplete);\r
        while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {}\r
 \r
@@ -292,9 +299,10 @@ scsiWriteByte(uint8_t value)
 static void\r
 scsiWritePIO(const uint8_t* data, uint32_t count)\r
 {\r
-       for (int i = 0; i < count; ++i)\r
+       uint16_t* fifoData = (uint16_t*)data;\r
+       for (int i = 0; i < (count + 1) / 2; ++i)\r
        {\r
-               scsiPhyTx(data[i]);\r
+               scsiPhyTx(fifoData[i]);\r
        }\r
 }\r
 \r
@@ -383,6 +391,7 @@ scsiWrite(const uint8_t* data, uint32_t count)
 #endif\r
 \r
                scsiPhyFifoFlip();\r
+               scsiSetDataCount(chunk);\r
                i += chunk;\r
        }\r
        while (!scsiPhyComplete() && likely(!scsiDev.resetFlag))\r
@@ -486,7 +495,7 @@ void scsiPhyReset()
        *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING;\r
 \r
        // DMA Benchmark code\r
-       // Currently 6.6MB/s. Assume 13MB/s is achievable with 16 bits\r
+       // Currently 11MB/s.\r
        #ifdef DMA_BENCHMARK\r
        while(1)\r
        {\r
@@ -551,7 +560,7 @@ void scsiPhyReset()
                        &fsmcToMem,\r
                        (uint32_t) SCSI_FIFO_DATA,\r
                        (uint32_t) &scsiDev.data[0],\r
-                       SCSI_FIFO_DEPTH);\r
+                       SCSI_FIFO_DEPTH / 2);\r
 \r
                HAL_DMA_PollForTransfer(\r
                        &fsmcToMem,\r
@@ -598,11 +607,11 @@ static void scsiPhyInitDMA()
                memToFSMC.Init.PeriphInc = DMA_PINC_ENABLE;\r
                memToFSMC.Init.MemInc = DMA_MINC_DISABLE;\r
                memToFSMC.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;\r
-               memToFSMC.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;\r
+               memToFSMC.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;\r
                memToFSMC.Init.Mode = DMA_NORMAL;\r
                memToFSMC.Init.Priority = DMA_PRIORITY_LOW;\r
                // FIFO mode is needed to allow conversion from 32bit words to the\r
-               // 8bit FSMC interface.\r
+               // 16bit FSMC interface.\r
                memToFSMC.Init.FIFOMode = DMA_FIFOMODE_ENABLE;\r
 \r
                // We only use 1 word (4 bytes) in the fifo at a time. Normally it's\r
@@ -622,7 +631,7 @@ static void scsiPhyInitDMA()
                fsmcToMem.Init.Direction = DMA_MEMORY_TO_MEMORY;\r
                fsmcToMem.Init.PeriphInc = DMA_PINC_DISABLE;\r
                fsmcToMem.Init.MemInc = DMA_MINC_ENABLE;\r
-               fsmcToMem.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;\r
+               fsmcToMem.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;\r
                fsmcToMem.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;\r
                fsmcToMem.Init.Mode = DMA_NORMAL;\r
                fsmcToMem.Init.Priority = DMA_PRIORITY_LOW;\r
index fa7e168..718b25f 100755 (executable)
 #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;