]> localhost Git - SCSI2SD-V6.git/commitdiff
Reapply STMCubeMX patches and FIX USB sense codes and workaround for USB<->SDIO dma...
authorMichael McMaster <michael@codesrc.com>
Tue, 23 Feb 2021 10:36:56 +0000 (20:36 +1000)
committerMichael McMaster <michael@codesrc.com>
Tue, 23 Feb 2021 10:36:56 +0000 (20:36 +1000)
16 files changed:
STM32CubeMX/2020c.diff
STM32CubeMX/2020c/Drivers/STM32F2xx_HAL_Driver/Src/stm32f2xx_hal_sd.c
STM32CubeMX/2020c/Src/fsmc.c
STM32CubeMX/2020c/Src/sdio.c
STM32CubeMX/2020c/Src/spi.c
STM32CubeMX/2020c/Src/usbd_conf.c
STM32CubeMX/2021.diff
STM32CubeMX/2021/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c
STM32CubeMX/2021/Src/fmc.c
STM32CubeMX/2021/Src/sdio.c
STM32CubeMX/2021/Src/spi.c
STM32CubeMX/2021/Src/usbd_conf.c
src/firmware/usb_device/usbd_composite.c
src/firmware/usb_device/usbd_msc_bot.c
src/firmware/usb_device/usbd_msc_bot.h
src/firmware/usb_device/usbd_msc_scsi.c

index cc21a39e7e24ad3b9d4021491eb51498e8ade899..5a582b176536f6225619e17b6bad64a43e01b708 100644 (file)
@@ -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;
  }
index 569c8b1c033f243f21158b3348375a79d66f08f8..cd27bd7418747c8ab303408de7c480e7430d624f 100644 (file)
@@ -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;
index 03a1b12ba77de7b705e076b5aa84a71a546d690a..1b01446fc190bca91946f7a6ecd5170f9d0c89dc 100644 (file)
@@ -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 
index f2a0b7cea656aacaff8ba3ef7a84289b011298b1..a00c6a8eca765cc9adff9e5fe054538271bd6019 100644 (file)
@@ -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)
index 902bdb2d84856420aa8b6afd616a73c8265f36a0..4935bf00a455e915fe9bcbf1eb667ba94735368c 100644 (file)
@@ -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;
index eee1fd89fbe611af2c9d69d0c1732b25441f7e73..9567a9572e0082d351beec9565c0593e0504246e 100644 (file)
@@ -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;
 }
index b67f732ecc3acdf1b0da8c536af6e31a416728f7..d77cad7aff2a4e44c1201241caf1a90e191a4c1c 100644 (file)
@@ -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;
  }
-
index d2a88d750e79aae12bae73a77d6dd63813afd0b8..6fffb51416f983d368167efeb95f052f0b364f22 100644 (file)
@@ -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;
index dae179a854648b26d9eea9fd02ae832728dfaf24..995fd15dcb35c9137bac64df83981544733cb3f4 100644 (file)
@@ -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 
index 01e38956cedf03b598b010c876c6b6b72b6b4676..33fbae16b897f581b65ddfbeec26d1145f56cf6d 100644 (file)
@@ -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)
index 2f9fbfbcbf5d54f8ad1d374470883b5d82a5e578..aa786dd29b158f294e4771a8adcd1147411b6967 100644 (file)
@@ -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;
index 5b1012660d1ada227b9323e82101a6c4337616ce..a2c404724e8a5133a90462333dc2e78ada9d2b0e 100644 (file)
@@ -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;
 }
index aea505da3c5023dece4e75ea386c62e3f63e9fb1..32d98304c739b54c3b762d8edf6673ea505e3b59 100755 (executable)
@@ -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);
        }
 }
 
index 98ac924e3bd86d9c02ac54686733a6b065e32d0d..85164a8589266c51d27a82149b492e71ec09060c 100755 (executable)
@@ -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);
 }
 
 /**
index 61b4f6cdbbc4770d2726dcd2c12058db6c04f622..d453d4f25a63f484aeb45a759252caf37bf314b9 100755 (executable)
@@ -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);
index 63ddca6dd35d86a89850e6d4e01be06b4bb57b1e..aa0880c20a8c72d77dbf51cb0886517e48c52773 100755 (executable)
@@ -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;