cancel
Showing results for 
Search instead for 
Did you mean: 

Micro SD Card Application Problem using STM32F4 Discovery Board

Ogulcan Ariyurek
Associate II
Posted on November 07, 2017 at 10:09

Hi,

I'm using STM32F4 Discovery board with its base-board extension that has a micro-sd card slot. I'm using the STMCubeMX and its current latest F4 firmware which is 

STMCubeMX FW F4 

1.17.0.

There is no SD card example for STM32F4 Discovery board but I found an example code for another discovery board which is located at the following directory:

STM32Cube_FW_F4_V1.17.0\Projects\STM32469I-Discovery\Applications\FatFs\FatFs_uSD

I've tried many different combinations of possible solutions using the libraries offered in STM32CubeMX with the help of that example project, but I have been getting errors although it mounts succesfully as the error code suggests.

Here are the important parts of my code:

/* USER CODE BEGIN 0 */

FATFS SDFatFs; /* File system object for SD disk logical drive */

FIL MyFile; /* File object */

static uint8_t buffer[_MAX_SS]; /* a work buffer for the f_mkfs() */

FRESULT res; /* FatFs function common result code */

// uint32_t byteswritten, bytesread; /* File write/read counts */

// uint8_t wtext[] = 'This is STM32 working with FatFs\n'; /* File write buffer */

// uint8_t rtext[100];

int retlink = 0xFF, retmount = 0xFF, retmkfs = 0xFF, retopen = 0xFF, retwrite = 0xFF, retclose = 0xFF;

/* USER CODE END 0 */

//...........................................

//...........................................

  /* USER CODE BEGIN 2 */

char SDPath[4];

SDPath[0]='0';

SDPath[1]=':';

SDPath[2]='/';

SDPath[3]=0;

char fn[11];

fn[0]='0'; fn[1]=':'; fn[2]='s'; fn[3]='t'; fn[4]='m'; fn[5]='3'; fn[6]='2'; fn[7]='.'; fn[8]='t'; fn[9]='x'; fn[10]='t';// fn[11]='/'; fn[12]=0;

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);

HAL_Delay(100);

retmount = f_mount(&SDFatFs, '0:', 0); /* (0) Succeeded */

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);

HAL_Delay(1000);

retopen = f_open(&MyFile, '0:stm32.txt', FA_READ);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);

HAL_Delay(100);

retwrite = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);

HAL_Delay(100);

retclose = f_close(&MyFile);

HAL_Delay(100);

f_mount(0, '0:', 0);

Here is my SDIO init function:

/* SDIO init function */

static void MX_SDIO_SD_Init(void)

{

hsd.Instance = SDIO;

hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;

hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;

hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;

hsd.Init.BusWide = SDIO_BUS_WIDE_1B;

hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;

hsd.Init.ClockDiv = 118;

}

While I'm debugging the project, I get following error returns:

for f_open: (3) The physical drive cannot work

for f_write: (9) The file/directory object is invalid

for f_close:  (9) The file/directory object is invalid

I'll be glad to hear for any suggestions to solve this issue.

Cheers,

Ogulcan

#stm32cubemx #stm32f4-discovery #sdcard #fatfs #sdio #fatfs-sdio #stm32cube_fw_f4_v1.17.0 #microsd #stm32f4
12 REPLIES 12
alfbaz
Associate II
Posted on November 07, 2017 at 13:16

I, very recently had a crack at cubemx for the first time and specifically tried to create an sdcard application using what seems like the exact same hardware you are using.

The first thing I noticed on reviewing the code generated by cubemx was that MX_SDIO_SD_Init(void) function.

The function simply fills in the values of a structure. It doesn't seem to initialize any hardware registers anywhere.

I've looked no further into it at this stage but at first glance it doesn't look promising

Posted on November 07, 2017 at 16:08

Thanks for the reply.

What I first noticed was that it initializes the bus as if 1 bit instead of 4 bits as follows:

hsd.Init.BusWide = SDIO_BUS_WIDE_1B;

It should have been:

hsd.Init.BusWide = SDIO_BUS_WIDE_4B;

However, changing this did not solve it.

So how can I manually initialize hardware registers?

Cheers,

Ogulcan

Posted on November 07, 2017 at 17:11

The card must be initialized in 1-bit mode 400 KHz, and then walked to the desired settings once communications have been established and the type of card determined.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 07, 2017 at 17:13

hsd.Init.ClockDiv = 118;

ie 48,000,000 / 120 = 400,000

>>

So how can I manually initialize hardware registers?

If you want to do this you need to thoroughly read and understand the SDIO peripheral described in the Reference Manual, and also understand the SD/MMC card protocol/specifications.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Ogulcan Ariyurek
Associate II
Posted on November 08, 2017 at 08:24

I've just figured out that it successfully mounts although there is no sd card in the slot.

Ogulcan Ariyurek
Associate II
Posted on November 08, 2017 at 08:35

I checked the CLK pin (PC12) with an oscilloscope and there is no clock signal here.

Posted on November 08, 2017 at 07:54

Hi Clive,

I would not need the STM32CubeMX if I do such low level work. Is there a way of achiving this using STM32CubeMX?

My clock is 168MHz, so I need 168,000,000 / 400,000 = 420

Which means I guess I need to set 

hsd.Init.ClockDiv = 420;

What else I may be doing wrong?

Cheers,

Ogulcan

Posted on November 09, 2017 at 02:14

I still don't see how setting hsd structure members will set anything in the hardware.

hsd is a structure of typedef SD_HandleTypeDef

Submember hsd.Init is simply another structure of type SD_InitTypeDef witch is just another structure who's members are all uint32_t's

At no point in the code generated do the values you have assigned to your hsd structure get sent to a function that takes those values and uses them to poke actual hardware registers.

MX_SDIO_SD_Init() initializes members of the hsd structure but I believe you will have to send hsd to some form of SD init function that takes values from the hsd structure and acutally pokes them into hardware registers.

In sdio.c, immediately following MX_SDIO_SD_Init() you have HAL_SD_MspInit() but all it does is set gpio's to SDIO alternate functions.

I don't have a proper project setup at the moment so it's difficult to navigate all the files. You will either have to set the appropriate hardware regs yourself or look for a function somewhere that takes a SD_InitTypeDef structure that actually uses the values stored in the Init sub-member to actually configure the hardware registers

paulcatherall9
Associate II

Hi, I have been trying for 2 days none stop now to get the SD card to work , I have a custom board with STM32F407VG that I have thoroughly checked the hardware and I also have the STM32DIS-BB card for the STM32F407 Disco.

I have used SD cards on STM32F107 in the past with no issues.

I've been using Cubmx for the past 12 months and so far everything has been fine CAN, UART, SPI. USB etc so I thought it would be straightforward!

My board is configured for 4 bit mode but I have also tried 1bit and tried different SD cards to no avail.

The FATFS drive mounts ok but I always get not ready when trying to open a file.

I have tried many examples including downgrading Cubemx as people have suggested.

So for my own sanity can anyone supply a working .hex/.bin file of a SD FATFS working example for a STM32f407VG/ DISCO default SDIO pins e.g writing to SD card so I can test both my hardware platforms, I can drive the Card detect pin manually if I know what it is. A 1 bit or 4 bit example is fine.

Thanks

Paul