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)
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)
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);
}
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;
}
/* 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)
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) */
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 */
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 */
{
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);
}
}
/* 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)
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;
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 */
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
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();
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
{
Error_Handler();
- }
-
+ }*/
}
void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
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;
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. */
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;
}
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)
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)
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);
}
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;
}
-
/* 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)
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) */
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 */
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 */
{
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);
}
}
/* 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)
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;
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 */
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
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();
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
{
Error_Handler();
- }
-
+ }*/
}
void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
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;
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. */
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;
}
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);
}
}
* @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);
* @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);
{
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) &&
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);
}
/**
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);
}
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,
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)
{
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,
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 */
{
*/
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)
{
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;
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,
}
- 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;
}
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;