cancel
Showing results for 
Search instead for 
Did you mean: 

CubeMX SD Card usage

Johanan1
Associate II
Posted on March 27, 2015 at 13:34

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-that
8 REPLIES 8
Posted on March 27, 2015 at 16:24

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..

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Johanan1
Associate II
Posted on March 29, 2015 at 07:30

The board is my design, using STM32F429. SD SPI with PD2, PC12,PC8 as SPI, and PH2 as SD CS. It may be my hardware, but I could not find a working code sample which I trust.

Looking at the ST sample code, It does not work, And the code seems to miss any initialization so I am not sure this sample code is really OK. That is why I am asking for a verified working example, so I can make sure my hardware is OK.

Thanks.

markb
Associate II
Posted on March 29, 2015 at 10:35

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 */
}
}

Johanan1
Associate II
Posted on March 30, 2015 at 08:02

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.

Regards

Johanan

florian239955_st
Associate II
Posted on August 17, 2015 at 18:28

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,

Flo

florian239955_st
Associate II
Posted on August 18, 2015 at 09:18

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,

Flo

robert-hartung
Associate II
Posted on August 18, 2015 at 20:13

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!

- Robert

florian239955_st
Associate II
Posted on August 19, 2015 at 09:48

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