Selaa lähdekoodia

Reapply STMCubeMX patches and FIX USB sense codes and workaround for USB<->SDIO dma consistency problem

Michael McMaster 4 vuotta sitten
vanhempi
sitoutus
b9a61e0e26

+ 12 - 6
lib/SCSI2SD/STM32CubeMX/2020c.diff

@@ -174,7 +174,7 @@ index 03a1b12..1b01446 100644
    GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 
                            |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 
 diff --git a/STM32CubeMX/2020c/Src/sdio.c b/STM32CubeMX/2020c/Src/sdio.c
-index aeec4fa..01f716a 100644
+index f2a0b7c..a00c6a8 100644
 --- a/STM32CubeMX/2020c/Src/sdio.c
 +++ b/STM32CubeMX/2020c/Src/sdio.c
 @@ -40,6 +40,8 @@ void MX_SDIO_SD_Init(void)
@@ -210,7 +210,7 @@ index 902bdb2..4935bf0 100644
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
 diff --git a/STM32CubeMX/2020c/Src/usbd_conf.c b/STM32CubeMX/2020c/Src/usbd_conf.c
-index adb664f..9b9b800 100644
+index eee1fd8..9567a95 100644
 --- a/STM32CubeMX/2020c/Src/usbd_conf.c
 +++ b/STM32CubeMX/2020c/Src/usbd_conf.c
 @@ -458,9 +458,12 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
@@ -218,7 +218,7 @@ index adb664f..9b9b800 100644
    HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOINIncompleteCallback);
  #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 +
-+  // Sum of all FIFOs must be <= 320.
++  // Combined RX + TX fifo of 0x140 4-byte words (1280 bytes)
    HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
    HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
 -  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
@@ -227,15 +227,21 @@ index adb664f..9b9b800 100644
    }
    if (pdev->id == DEVICE_HS) {
    /* Link the driver to the stack. */
-@@ -498,8 +501,9 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
+@@ -497,9 +500,15 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
+   HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOOUTIncompleteCallback);
    HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOINIncompleteCallback);
  #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
++  // Combined RX + TX fifo of 0x400 4-byte words (4096 bytes)
    HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
 -  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
 -  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);
 +  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x40);
-+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x40);
-+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 2, 0x174);
++
++//  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x100);
++// HOst requests 7 sectors, which is an odd number and doesn't fill the
++// fifo, looks like it doesn't complete in this case !!!!
++  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x80); // 512 bytes
++  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 2, 0x40);
    }
    return USBD_OK;
  }

+ 48 - 22
lib/SCSI2SD/STM32CubeMX/2020c/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c

@@ -430,6 +430,10 @@ HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
   /* Enable SDIO Clock */
   __HAL_SD_ENABLE(hsd);
 
+  /* 1ms: required power up waiting time before starting the SD initialization 
+     sequence */
+  HAL_Delay(1);
+
   /* Identify card operating voltage */
   errorstate = SD_PowerON(hsd);
   if(errorstate != HAL_SD_ERROR_NONE)
@@ -1227,22 +1231,22 @@ HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, u
     else
     {
       /* Enable SD DMA transfer */
-      __HAL_SD_DMA_ENABLE(hsd);
+      // MM disabled, as this fails on fast cards. __HAL_SD_DMA_ENABLE(hsd);
 
       if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
       {
         add *= 512U;
-      }
 
-      /* Set Block Size for Card */
-      errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
-      if(errorstate != HAL_SD_ERROR_NONE)
-      {
-        /* Clear all the static flags */
-        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-        hsd->ErrorCode |= errorstate;
-        hsd->State = HAL_SD_STATE_READY;
-        return HAL_ERROR;
+        /* Set Block Size for Card */
+        errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+        if(errorstate != HAL_SD_ERROR_NONE)
+        {
+          /* Clear all the static flags */
+          __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+          hsd->ErrorCode |= errorstate;
+          hsd->State = HAL_SD_STATE_READY;
+          return HAL_ERROR;
+        }
       }
 
       /* Configure the SD DPSM (Data Path State Machine) */
@@ -1252,6 +1256,11 @@ HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, u
       config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
       config.DPSM          = SDIO_DPSM_ENABLE;
+
+      // We cannot enable DMA too early on UHS-I class 3 SD cards, or else the
+      // data is just discarded before the dpsm is started.
+      __HAL_SD_DMA_ENABLE(hsd);
+
       (void)SDIO_ConfigData(hsd->Instance, &config);
 
       /* Read Blocks in DMA mode */
@@ -1343,17 +1352,17 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
     {
       add *= 512U;
-    }
 
-    /* Set Block Size for Card */
-    errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
-    if(errorstate != HAL_SD_ERROR_NONE)
-    {
-      /* Clear all the static flags */
-      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-      hsd->ErrorCode |= errorstate;
-      hsd->State = HAL_SD_STATE_READY;
-      return HAL_ERROR;
+      /* Set Block Size for Card */
+      errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+      if(errorstate != HAL_SD_ERROR_NONE)
+      {
+        /* Clear all the static flags */
+        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+        hsd->ErrorCode |= errorstate;
+        hsd->State = HAL_SD_STATE_READY;
+        return HAL_ERROR;
+      }
     }
 
     /* Write Blocks in Polling mode */
@@ -1361,6 +1370,18 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
     {
       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);
     }
@@ -1382,7 +1403,7 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
     }
 
     /* Enable SDIO DMA transfer */
-    __HAL_SD_DMA_ENABLE(hsd);
+    // MM disabled, as this fails on fast cards. __HAL_SD_DMA_ENABLE(hsd);
 
     /* Enable the DMA Channel */
     if(HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK)
@@ -1403,6 +1424,11 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
       config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
       config.DPSM          = SDIO_DPSM_ENABLE;
+
+      // We cannot enable DMA too early on UHS-I class 3 SD cards, or else the
+      // data is just discarded before the dpsm is started.
+      __HAL_SD_DMA_ENABLE();
+
       (void)SDIO_ConfigData(hsd->Instance, &config);
 
       return HAL_OK;

+ 22 - 2
lib/SCSI2SD/STM32CubeMX/2020c/Src/fsmc.c

@@ -50,12 +50,28 @@ void MX_FSMC_Init(void)
   hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
   hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
   /* Timing */
+
+  // 1 clock to read the address, + 1 for synchroniser skew
   Timing.AddressSetupTime = 2;
   Timing.AddressHoldTime = 1;
+
+  // Writes to device:
+  //   1 for synchroniser skew (dbx also delayed)
+  //   1 to skip hold time
+  //   1 to write data.
+
+  // Reads from device:
+  //   3 for syncroniser
+  //   1 to write back to fsmc bus.
   Timing.DataSetupTime = 4;
+
+  // Allow a clock for us to release signals
+  // Need to avoid both devices acting as outputs
+  // on the multiplexed lines at the same time.
   Timing.BusTurnAroundDuration = 1;
-  Timing.CLKDivision = 16;
-  Timing.DataLatency = 17;
+
+  Timing.CLKDivision = 16; // Ignored for async
+  Timing.DataLatency = 17; // Ignored for async
   Timing.AccessMode = FSMC_ACCESS_MODE_A;
   /* ExtTiming */
 
@@ -105,6 +121,10 @@ 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_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 
                           |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 

+ 3 - 2
lib/SCSI2SD/STM32CubeMX/2020c/Src/sdio.c

@@ -40,6 +40,8 @@ void MX_SDIO_SD_Init(void)
   hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
   hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
   hsd.Init.ClockDiv = 0;
+
+  /*
   if (HAL_SD_Init(&hsd) != HAL_OK)
   {
     Error_Handler();
@@ -47,8 +49,7 @@ void MX_SDIO_SD_Init(void)
   if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
   {
     Error_Handler();
-  }
-
+  }*/
 }
 
 void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)

+ 2 - 0
lib/SCSI2SD/STM32CubeMX/2020c/Src/spi.c

@@ -37,6 +37,8 @@ void MX_SPI1_Init(void)
   hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
   hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
   hspi1.Init.NSS = SPI_NSS_SOFT;
+
+  // 13.5Mbaud FPGA device allows up to 25MHz write
   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

+ 12 - 3
lib/SCSI2SD/STM32CubeMX/2020c/Src/usbd_conf.c

@@ -458,9 +458,12 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
   HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOOUTIncompleteCallback);
   HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOINIncompleteCallback);
 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
+  // Combined RX + TX fifo of 0x140 4-byte words (1280 bytes)
   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
-  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, 0x40);
   }
   if (pdev->id == DEVICE_HS) {
   /* Link the driver to the stack. */
@@ -497,9 +500,15 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
   HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOOUTIncompleteCallback);
   HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOINIncompleteCallback);
 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+  // Combined RX + TX fifo of 0x400 4-byte words (4096 bytes)
   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
-  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
-  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x40);
+
+//  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x100);
+// HOst requests 7 sectors, which is an odd number and doesn't fill the
+// fifo, looks like it doesn't complete in this case !!!!
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x80); // 512 bytes
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 2, 0x40);
   }
   return USBD_OK;
 }

+ 16 - 8
lib/SCSI2SD/STM32CubeMX/2021.diff

@@ -174,7 +174,7 @@ index dae179a..995fd15 100644
    GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 
                            |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 
 diff --git a/STM32CubeMX/2021/Src/sdio.c b/STM32CubeMX/2021/Src/sdio.c
-index 3c8aff3..f187a45 100644
+index 01e3895..33fbae1 100644
 --- a/STM32CubeMX/2021/Src/sdio.c
 +++ b/STM32CubeMX/2021/Src/sdio.c
 @@ -40,6 +40,8 @@ void MX_SDIO_SD_Init(void)
@@ -197,7 +197,7 @@ index 3c8aff3..f187a45 100644
  
  void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
 diff --git a/STM32CubeMX/2021/Src/spi.c b/STM32CubeMX/2021/Src/spi.c
-index 902bdb2..1d8d45e 100644
+index 2f9fbfb..aa786dd 100644
 --- a/STM32CubeMX/2021/Src/spi.c
 +++ b/STM32CubeMX/2021/Src/spi.c
 @@ -37,6 +37,8 @@ void MX_SPI1_Init(void)
@@ -210,11 +210,14 @@ index 902bdb2..1d8d45e 100644
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
 diff --git a/STM32CubeMX/2021/Src/usbd_conf.c b/STM32CubeMX/2021/Src/usbd_conf.c
-index 1e08ba4..110da2f 100644
+index 5b10126..a2c4047 100644
 --- a/STM32CubeMX/2021/Src/usbd_conf.c
 +++ b/STM32CubeMX/2021/Src/usbd_conf.c
-@@ -468,7 +468,8 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
+@@ -466,9 +466,11 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
+   HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOOUTIncompleteCallback);
+   HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOINIncompleteCallback);
  #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
++  // Combined RX + TX fifo of 0x140 4-byte words (1280 bytes)
    HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
    HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
 -  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
@@ -223,16 +226,21 @@ index 1e08ba4..110da2f 100644
    }
    if (pdev->id == DEVICE_HS) {
    /* Link the driver to the stack. */
-@@ -507,8 +508,9 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
+@@ -506,9 +508,15 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
+   HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOOUTIncompleteCallback);
    HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOINIncompleteCallback);
  #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
++  // Combined RX + TX fifo of 0x400 4-byte words (4096 bytes)
    HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
 -  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
 -  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);
 +  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x40);
-+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x40);
-+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 2, 0x174);
++
++//  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x100);
++// HOst requests 7 sectors, which is an odd number and doesn't fill the
++// fifo, looks like it doesn't complete in this case !!!!
++  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x80); // 512 bytes
++  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 2, 0x40);
    }
    return USBD_OK;
  }
-

+ 48 - 22
lib/SCSI2SD/STM32CubeMX/2021/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c

@@ -430,6 +430,10 @@ HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
   /* Enable SDIO Clock */
   __HAL_SD_ENABLE(hsd);
 
+  /* 1ms: required power up waiting time before starting the SD initialization 
+     sequence */
+  HAL_Delay(1);
+
   /* Identify card operating voltage */
   errorstate = SD_PowerON(hsd);
   if(errorstate != HAL_SD_ERROR_NONE)
@@ -1247,22 +1251,22 @@ HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, u
     else
     {
       /* Enable SD DMA transfer */
-      __HAL_SD_DMA_ENABLE(hsd);
+      // MM disabled, as this fails on fast cards. __HAL_SD_DMA_ENABLE(hsd);
 
       if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
       {
         add *= 512U;
-      }
 
-      /* Set Block Size for Card */
-      errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
-      if(errorstate != HAL_SD_ERROR_NONE)
-      {
-        /* Clear all the static flags */
-        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-        hsd->ErrorCode |= errorstate;
-        hsd->State = HAL_SD_STATE_READY;
-        return HAL_ERROR;
+        /* Set Block Size for Card */
+        errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+        if(errorstate != HAL_SD_ERROR_NONE)
+        {
+          /* Clear all the static flags */
+          __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+          hsd->ErrorCode |= errorstate;
+          hsd->State = HAL_SD_STATE_READY;
+          return HAL_ERROR;
+        }
       }
 
       /* Configure the SD DPSM (Data Path State Machine) */
@@ -1272,6 +1276,11 @@ HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, u
       config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
       config.DPSM          = SDIO_DPSM_ENABLE;
+
+      // We cannot enable DMA too early on UHS-I class 3 SD cards, or else the
+      // data is just discarded before the dpsm is started.
+      __HAL_SD_DMA_ENABLE();
+
       (void)SDIO_ConfigData(hsd->Instance, &config);
 
       /* Read Blocks in DMA mode */
@@ -1367,17 +1376,17 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
     {
       add *= 512U;
-    }
 
-    /* Set Block Size for Card */
-    errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
-    if(errorstate != HAL_SD_ERROR_NONE)
-    {
-      /* Clear all the static flags */
-      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-      hsd->ErrorCode |= errorstate;
-      hsd->State = HAL_SD_STATE_READY;
-      return HAL_ERROR;
+      /* Set Block Size for Card */
+      errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+      if(errorstate != HAL_SD_ERROR_NONE)
+      {
+        /* Clear all the static flags */
+        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+        hsd->ErrorCode |= errorstate;
+        hsd->State = HAL_SD_STATE_READY;
+        return HAL_ERROR;
+      }
     }
 
     /* Write Blocks in Polling mode */
@@ -1385,6 +1394,18 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
     {
       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);
     }
@@ -1406,7 +1427,7 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
     }
 
     /* Enable SDIO DMA transfer */
-    __HAL_SD_DMA_ENABLE(hsd);
+    // MM disabled, as this fails on fast cards. __HAL_SD_DMA_ENABLE(hsd);
 
     /* Enable the DMA Channel */
     if(HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK)
@@ -1431,6 +1452,11 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData,
       config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
       config.DPSM          = SDIO_DPSM_ENABLE;
+
+      // We cannot enable DMA too early on UHS-I class 3 SD cards, or else the
+      // data is just discarded before the dpsm is started.
+      __HAL_SD_DMA_ENABLE();
+
       (void)SDIO_ConfigData(hsd->Instance, &config);
 
       return HAL_OK;

+ 22 - 2
lib/SCSI2SD/STM32CubeMX/2021/Src/fmc.c

@@ -52,12 +52,28 @@ void MX_FMC_Init(void)
   hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
   hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
   /* Timing */
+
+  // 1 clock to read the address, + 1 for synchroniser skew
   Timing.AddressSetupTime = 2;
   Timing.AddressHoldTime = 1;
+
+  // Writes to device:
+  //   1 for synchroniser skew (dbx also delayed)
+  //   1 to skip hold time
+  //   1 to write data.
+
+  // Reads from device:
+  //   3 for syncroniser
+  //   1 to write back to fsmc bus.
   Timing.DataSetupTime = 4;
+
+  // Allow a clock for us to release signals
+  // Need to avoid both devices acting as outputs
+  // on the multiplexed lines at the same time.
   Timing.BusTurnAroundDuration = 1;
-  Timing.CLKDivision = 16;
-  Timing.DataLatency = 17;
+
+  Timing.CLKDivision = 16; // Ignored for async
+  Timing.DataLatency = 17; // Ignored for async
   Timing.AccessMode = FMC_ACCESS_MODE_A;
   /* ExtTiming */
 
@@ -107,6 +123,10 @@ static void HAL_FMC_MspInit(void){
   PE0   ------> FMC_NBL0
   PE1   ------> FMC_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_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 
                           |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 

+ 3 - 2
lib/SCSI2SD/STM32CubeMX/2021/Src/sdio.c

@@ -40,6 +40,8 @@ void MX_SDIO_SD_Init(void)
   hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
   hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;
   hsd.Init.ClockDiv = 0;
+
+  /*
   if (HAL_SD_Init(&hsd) != HAL_OK)
   {
     Error_Handler();
@@ -47,8 +49,7 @@ void MX_SDIO_SD_Init(void)
   if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
   {
     Error_Handler();
-  }
-
+  }*/
 }
 
 void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)

+ 2 - 0
lib/SCSI2SD/STM32CubeMX/2021/Src/spi.c

@@ -37,6 +37,8 @@ void MX_SPI1_Init(void)
   hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
   hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
   hspi1.Init.NSS = SPI_NSS_SOFT;
+
+  // 22.5Mbaud. FPGA device allows up to 25MHz write
   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

+ 11 - 3
lib/SCSI2SD/STM32CubeMX/2021/Src/usbd_conf.c

@@ -466,9 +466,11 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
   HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOOUTIncompleteCallback);
   HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOINIncompleteCallback);
 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+  // Combined RX + TX fifo of 0x140 4-byte words (1280 bytes)
   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
   HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
-  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, 0x40);
   }
   if (pdev->id == DEVICE_HS) {
   /* Link the driver to the stack. */
@@ -506,9 +508,15 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
   HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOOUTIncompleteCallback);
   HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOINIncompleteCallback);
 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+  // Combined RX + TX fifo of 0x400 4-byte words (4096 bytes)
   HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
-  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
-  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x40);
+
+//  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x100);
+// HOst requests 7 sectors, which is an odd number and doesn't fill the
+// fifo, looks like it doesn't complete in this case !!!!
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x80); // 512 bytes
+  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 2, 0x40);
   }
   return USBD_OK;
 }

+ 4 - 5
lib/SCSI2SD/src/firmware/usb_device/usbd_composite.c

@@ -511,15 +511,14 @@ void s2s_usbDevicePoll(USBD_HandleTypeDef  *pdev) {
 
 	if (classData->DataInReady)
 	{
-		int tmp = classData->DataInReady;
 		classData->DataInReady = 0;
-		MSC_BOT_DataIn(pdev, tmp);
+		MSC_BOT_DataIn(pdev);
 	}
 
-	if (classData->DataOutReady) {
-		int tmp = classData->DataOutReady;
+	if (classData->DataOutReady)
+    {
 		classData->DataOutReady = 0;
-		MSC_BOT_DataOut(pdev, tmp);
+		MSC_BOT_DataOut(pdev);
 	}
 }
 

+ 12 - 12
lib/SCSI2SD/src/firmware/usb_device/usbd_msc_bot.c

@@ -167,7 +167,7 @@ void MSC_BOT_DeInit (USBD_HandleTypeDef  *pdev)
 * @param  epnum: endpoint index
 * @retval None
 */
-void MSC_BOT_DataIn (USBD_HandleTypeDef  *pdev, uint8_t epnum)
+void MSC_BOT_DataIn (USBD_HandleTypeDef  *pdev)
 {
 	USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
 	USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
@@ -194,10 +194,9 @@ void MSC_BOT_DataIn (USBD_HandleTypeDef  *pdev, uint8_t epnum)
 * @brief  MSC_BOT_DataOut
 *         Process MSC OUT data
 * @param  pdev: device instance
-* @param  epnum: endpoint index
 * @retval None
 */
-void MSC_BOT_DataOut (USBD_HandleTypeDef  *pdev, uint8_t epnum)
+void MSC_BOT_DataOut (USBD_HandleTypeDef  *pdev)
 {
 	USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
 	USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
@@ -252,14 +251,14 @@ static void  MSC_BOT_CBW_Decode (USBD_HandleTypeDef  *pdev)
 	{
 		if(SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0)
 		{
-			if(hmsc->bot_state == USBD_BOT_NO_DATA)
-			{
+		//	if(hmsc->bot_state == USBD_BOT_NO_DATA)
+		//	{
 				MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED);
-			}
-			else
-			{
-				MSC_BOT_Abort(pdev);
-			}
+		//	}
+		//	else
+		//	{
+		//		MSC_BOT_Abort(pdev);
+		//	}
 		}
 		/*Burst xfer handled internally*/
 		else if ((hmsc->bot_state != USBD_BOT_DATA_IN) &&
@@ -293,12 +292,13 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev,
 	USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
 	USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
 
-	len = MIN (hmsc->cbw.dDataLength, len);
+    uint16_t length = (uint16_t)MIN(hmsc->cbw.dDataLength, len);
+
 	hmsc->csw.dDataResidue -= len;
 	hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
 	hmsc->bot_state = USBD_BOT_SEND_DATA;
 
-	USBD_LL_Transmit (pdev, MSC_EPIN_ADDR, buf, len);
+	USBD_LL_Transmit (pdev, MSC_EPIN_ADDR, buf, length);
 }
 
 /**

+ 2 - 5
lib/SCSI2SD/src/firmware/usb_device/usbd_msc_bot.h

@@ -127,11 +127,8 @@ USBD_MSC_BOT_CSWTypeDef;
 void MSC_BOT_Init (USBD_HandleTypeDef  *pdev);
 void MSC_BOT_Reset (USBD_HandleTypeDef  *pdev);
 void MSC_BOT_DeInit (USBD_HandleTypeDef  *pdev);
-void MSC_BOT_DataIn (USBD_HandleTypeDef  *pdev, 
-                     uint8_t epnum);
-
-void MSC_BOT_DataOut (USBD_HandleTypeDef  *pdev, 
-                      uint8_t epnum);
+void MSC_BOT_DataIn (USBD_HandleTypeDef  *pdev);
+void MSC_BOT_DataOut (USBD_HandleTypeDef  *pdev);
 
 void MSC_BOT_SendCSW (USBD_HandleTypeDef  *pdev,
                              uint8_t CSW_Status);

+ 32 - 32
lib/SCSI2SD/src/firmware/usb_device/usbd_msc_scsi.c

@@ -507,11 +507,9 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *para
     }
     
     hmsc->bot_state = USBD_BOT_DATA_IN;
-    hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
-    hmsc->scsi_blk_len  *= hmsc->scsi_blk_size;
     
     /* cases 4,5 : Hi <> Dn */
-    if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
+    if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size))
     {
       SCSI_SenseCode(pdev,
                      hmsc->cbw.bLUN, 
@@ -535,12 +533,12 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *para
 
 static int8_t SCSI_Write10 (USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *params)
 {
-	USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
-	USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
+  USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
+  USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
+  uint32_t len;
   
   if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
   {
-    
     /* case 8 : Hi <> Do */
     
     if ((hmsc->cbw.bmFlags & 0x80) == 0x80)
@@ -588,12 +586,11 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *pa
     {
       return -1; /* error */      
     }
-    
-    hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
-    hmsc->scsi_blk_len  *= hmsc->scsi_blk_size;
+
+    len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
     
     /* cases 3,11,13 : Hn,Ho <> D0 */
-    if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
+    if (hmsc->cbw.dDataLength != len)
     {
       SCSI_SenseCode(pdev,
                      hmsc->cbw.bLUN, 
@@ -601,13 +598,15 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *pa
                      INVALID_CDB);
       return -1;
     }
+
+    len = MIN(len, S2S_MSC_MEDIA_PACKET);
     
     /* Prepare EP to receive first data packet */
     hmsc->bot_state = USBD_BOT_DATA_OUT;  
     USBD_LL_PrepareReceive (pdev,
                       MSC_EPOUT_ADDR,
                       hmsc->bot_data, 
-                      MIN (hmsc->scsi_blk_len, S2S_MSC_MEDIA_PACKET));  
+                      len);  
   }
   else /* Write Process ongoing */
   {
@@ -698,16 +697,19 @@ static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef  *pdev, uint8_t lun , u
 */
 static int8_t SCSI_ProcessRead (USBD_HandleTypeDef  *pdev, uint8_t lun)
 {
-	USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
-	USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
+  USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
+  USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
 
-  uint32_t len;
-  
-  len = MIN(hmsc->scsi_blk_len , S2S_MSC_MEDIA_PACKET); 
-  
+  uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+  len = MIN(len, S2S_MSC_MEDIA_PACKET);
+
+  // TODO there is a dcache issue here.
+  // work out how, and when, to flush cashes between sdio dma and usb dma
+  memset (hmsc->bot_data, 0xAA, len);
   if( ((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun ,
                               hmsc->bot_data, 
-                              hmsc->scsi_blk_addr / hmsc->scsi_blk_size, 
+                              hmsc->scsi_blk_addr, 
                               len / hmsc->scsi_blk_size) < 0)
   {
     
@@ -724,9 +726,8 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef  *pdev, uint8_t lun)
              hmsc->bot_data,
              len);
   
-  
-  hmsc->scsi_blk_addr   += len; 
-  hmsc->scsi_blk_len    -= len;  
+  hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
+  hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
   
   /* case 6 : Hi = Di */
   hmsc->csw.dDataResidue -= len;
@@ -747,15 +748,16 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef  *pdev, uint8_t lun)
 
 static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef  *pdev, uint8_t lun)
 {
-  uint32_t len;
-	USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
-	USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
+  USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData;
+  USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc);
 
-  len = MIN(hmsc->scsi_blk_len , S2S_MSC_MEDIA_PACKET); 
+  uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+  len = MIN(len, S2S_MSC_MEDIA_PACKET);
   
   if(((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun ,
                               hmsc->bot_data, 
-                              hmsc->scsi_blk_addr / hmsc->scsi_blk_size, 
+                              hmsc->scsi_blk_addr, 
                               len / hmsc->scsi_blk_size) < 0)
   {
     SCSI_SenseCode(pdev,
@@ -766,8 +768,8 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef  *pdev, uint8_t lun)
   }
   
   
-  hmsc->scsi_blk_addr  += len; 
-  hmsc->scsi_blk_len   -= len; 
+  hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
+  hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
   
   /* case 12 : Ho = Do */
   hmsc->csw.dDataResidue -= len;
@@ -778,11 +780,9 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef  *pdev, uint8_t lun)
   }
   else
   {
+    len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), S2S_MSC_MEDIA_PACKET);
     /* Prepare EP to Receive next packet */
-    USBD_LL_PrepareReceive (pdev,
-                            MSC_EPOUT_ADDR,
-                            hmsc->bot_data, 
-                            MIN (hmsc->scsi_blk_len, S2S_MSC_MEDIA_PACKET)); 
+    USBD_LL_PrepareReceive (pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
   }
   
   return 0;