2015-03-27 05:34 AM
Has anybody used the CubeMx SD Card generated code?
I tried but could not use it, I assume my init code is not correct (or that cube code is useless).On the same board, I have USB host with FATFS working, I need to be able to use SD card as well.If you got this working, please help.Thanks #i-can''t-help-you-with-that2015-03-27 08:24 AM
All I've heard is lots of problems...
Not sure which STM32 or board is being discussed here, but would strongly suggest proving out the SPI/SDIO interface to the card with known working code, and proceed from there..2015-03-28 10:30 PM
2015-03-29 01:35 AM
Hi,
Sorry about the poor formatting, I don't understand how to use these forum editors!
I am using the following setup code and also doing HAL_SD_WideBusOperation_Config(&hsd, SDIO_BUS_WIDE_4B) and SD card IO appears to work very well with FATFS and DMA. You must use DMA otherwise you will get SD FIFO underruns. The hardware is my own board using a stm32f
To use DMA you need to alter sd_diskio like this:
DRESULT SD_read(BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_OK;
if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,
(uint64_t)sector * BLOCK_SIZE,
BLOCK_SIZE,
count) != MSD_OK)
{
res = RES_ERROR;
}
return res;
}
and
DRESULT SD_write(const BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_OK;
if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
(uint64_t)sector * BLOCK_SIZE,
BLOCK_SIZE, count) != MSD_OK)
{
res = RES_ERROR;
}
return res;
}
-----------
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hsd->Instance==SDIO)
{
/* USER CODE BEGIN SDIO_MspInit 0 */
/* USER CODE END SDIO_MspInit 0 */
/* Peripheral clock enable */
__SDIO_CLK_ENABLE();
/**SDIO GPIO Configuration
PC8 ------> SDIO_D0
PC9 ------> SDIO_D1
PC10 ------> SDIO_D2
PC11 ------> SDIO_D3
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_sdio_rx.Instance = DMA2_Stream3;
hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&hdma_sdio_rx);
__HAL_LINKDMA(hsd,hdmarx,hdma_sdio_rx);
hdma_sdio_tx.Instance = DMA2_Stream6;
hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_sdio_tx.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&hdma_sdio_tx);
__HAL_LINKDMA(hsd,hdmatx,hdma_sdio_tx);
/* System interrupt init*/
HAL_NVIC_SetPriority(SDIO_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SDIO_IRQn);
/* USER CODE BEGIN SDIO_MspInit 1 */
/* USER CODE END SDIO_MspInit 1 */
}
}
2015-03-29 11:02 PM
Thanks for this help.
My first attempt was to use SPI, but I assume wide access is much faster. My PCB needs some changes, so I will go for the 4 bit interface.RegardsJohanan2015-08-17 09:28 AM
Hi Guys,
has anybody used the FatFS + SDIO (1 Bit Mode) + DMA with a STM32F103 device? These devices have one dma/interrupt channel for the tx and rx, so I have to switch the direction of the dma controller. I don't get this working... /* Peripheral DMA init*/ hdma_sdio.Instance = DMA2_Channel4; hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio.Init.Mode = DMA_NORMAL; hdma_sdio.Init.Priority = DMA_PRIORITY_VERY_HIGH; HAL_DMA_Init(&hdma_sdio); /* Several peripheral DMA handle pointers point to the same DMA handle. Be aware that there is only one channel to perform all the requested DMAs. */ /* Be sure to change transfer direction before calling HAL_SD_ReadBlocks_DMA or HAL_SD_WriteBlocks_DMA. */ __HAL_LINKDMA(hsd,hdmarx,hdma_sdio); __HAL_LINKDMA(hsd,hdmatx,hdma_sdio); I also use the FreeRTOS. The FatFs and SD drivers work in polling mode without FreeRTOS. If I add the FreeRTOS, this doesn't work anymore... Does anybody have an idea? So I tried it with DMA, but also no success... Best regards, Flo2015-08-18 12:18 AM
Good Morning,
I found the bug in the polling mode with FreeRtos. In the function SD_PowerOn is an 1ms delay done by the function HAL_Delay, that ends in an endless loop... so this function has to be replaced... static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd) { SDIO_CmdInitTypeDef sdio_cmdinitstructure = {0}; __IO HAL_SD_ErrorTypedef errorstate = SD_OK; uint32_t response = 0, count = 0, validvoltage = 0; uint32_t sdtype = SD_STD_CAPACITY; /* Power ON Sequence -------------------------------------------------------*/ /* Disable SDIO Clock */ __HAL_SD_SDIO_DISABLE(hsd); /* Set Power State to ON */ SDIO_PowerState_ON(hsd->Instance); /* 1ms: required power up waiting time before starting the SD initialization sequence */ // HAL_Delay(1); Regards, Flo2015-08-18 11:13 AM
This sounds like you didn't active the Systick Handler (+ interrupt) that is used by HAL_Delay() that is used at various places.
The only problem I had was the Clock Divider from CubeMX init. It is overwritten internally, no matter what!- Robert2015-08-19 12:48 AM
Hi Robert,
the problem is, that I used the SDIO and also HAL_Delay before starting FreeRTOS... If FreeRTOS is running, it works... Regards, Flo