cancel
Showing results for 
Search instead for 
Did you mean: 

what is wrong with the file system on stm32f411?

rwmao
Senior
Posted on January 16, 2017 at 00:45

I have two boards designed for stm32f405 and stm32f411 to test uSD card.

The problem of using uSD on STM32F405 was fixed as discussed earlier:

https://community.st.com/thread/35991-microsd-card-problem-bug-in-the-filestm32f4xxhalsdc

Reading file/writing file are totally fine withut any problem on the STM32F405.

Then I study the another board with a chip stm32f411ret6. These two boards are very similar because these two chips has very close pin configration.

Here is what is going on on the board with the chip stm32f4

I generated the code with cubemx, copy the testing code, and fixed the bug in the file mentioned above.

Low level io writing/reading has been tested. Pass!

Can I say that hardware problem (such as connection)is out of question?

But when I try to use file system to read/write file, there is an error in the line:

fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT boot sector as SFD */

returns FR_DISK_ERR.

Tried two sd card, 1g and 32g. Both works on the board with chip stm32f

What is wrong? Any instructions please.

The code for reading/writing testing is as followings

void SD_Test_LowLevel(void) {   uint8_t SD_state = MSD_OK;  static uint8_t prev_status = 0;   char usbbuffer[200]; SD_state = BSP_SD_Init();    if(SD_state != MSD_OK)  {  sprintf(usbbuffer,'\n---initialize failed ---\n');//export it to char buffer first.   SendTextMsgToUSB(usbbuffer); //send the txt back   Error_Handler();  } //initialization is done. Now go ahead for SD operation in low level      SD_state = BSP_SD_Erase(BLOCK_START_ADDR, (BLOCKSIZE * NUM_OF_BLOCKS));    if(SD_state != MSD_OK)  {  sprintf(usbbuffer,'\n---erase failed ---\n');//export it to char buffer first.   SendTextMsgToUSB(usbbuffer); //send the txt back   Error_Handler();  }    /* Fill the buffer to write */  Fill_Buffer(aTxBuffer, BUFFER_WORDS_SIZE, 0x22FF);  SD_state = BSP_SD_WriteBlocks(aTxBuffer, BLOCK_START_ADDR, BLOCKSIZE, NUM_OF_BLOCKS);    if(SD_state != MSD_OK)  {  Error_Handler();  } SD_state = BSP_SD_ReadBlocks(aRxBuffer, BLOCK_START_ADDR, BLOCKSIZE, NUM_OF_BLOCKS);  if(SD_state != MSD_OK)  {  sprintf(usbbuffer,'\n---reading failed ---\n');//export it to char buffer first.   SendTextMsgToUSB(usbbuffer); //send the txt back   }  else  {  sprintf(usbbuffer,'\n---Reading OK ---\n');//export it to char buffer first.   SendTextMsgToUSB(usbbuffer); //send the txt back   if(Buffercmp(aTxBuffer, aRxBuffer, BUFFER_WORDS_SIZE) > 0)  {  sprintf(usbbuffer,'\n---reading/writing compare failed ---\n');//export it to char buffer first.   SendTextMsgToUSB(usbbuffer); //send the txt back   }  else  {  sprintf(usbbuffer,'\n---Testing is done, OK ---\n');//export it to char buffer first.   SendTextMsgToUSB(usbbuffer); //send the txt back   }  }  GREEN_LED_ON;//Good while (1)  { } }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

#stm32f411 #sdio #stm32f405

Note: this post was migrated and contained many threaded conversations, some content may be missing.
25 REPLIES 25
Amel NASRI
ST Employee
Posted on January 16, 2017 at 13:12

Hi mao‌,

1- I confirm that there is a bug in the implementation of

SD_PowerON. As already said in

https://community.st.com/0D50X00009XkeRpSAJ

, this will be fixed in all packages.

2- Referring to datasheets of both products (

http://www.st.com/content/ccc/resource/technical/document/datasheet/b3/a5/46/3b/b4/e5/4c/85/DM00115pdf/files/DM00115pdf/jcr:content/translations/en.DM00115pdf

&

http://www.st.com/content/ccc/resource/technical/document/datasheet/ef/92/76/6d/bb/c2/4f/f7/DM00037pdf/files/DM00037pdf/jcr:content/translations/en.DM00037pdf

), we see that SDIO doesn't have the same characteristics (table 'Dynamic characteristics: SD / MMC characteristics'). So you have to pay attention to clock configuration mainly.

3- If you try to use same PCB for both products, make sure that you select same pins using CubeMX. In fact, there are other possible pins for STM32F411 chips compared to STM32F405 ones.

Please keep us updated about your finding.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on January 16, 2017 at 14:42

And which low level read is failing with an error? View what DISKIO.C layer is returning. Make sure DMA is 32-bit aligned.

I've used SDIO/FATFS on an STM32F411E-DISCO. Make sure you are clocking the Q PLL at an appropriate speed, supposing it is as USB is working. Check other bus clocks, and response of DMA/SDIO IRQs

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 16, 2017 at 21:52

My fault. It still have problem to for low level block reading. I tested again with low level reading. Error occurs inHal_SD_readblocks().

USB(CDC) is working well. I can see the debug string sent to the com port via USB. I guess clock should be fine. Can you help check the clock setting?

For block reading/writing, I tested in above code. Erasing/writing is fine. But stops at reading.

1. I find the problem is in the

BSP_SD_ReadBlocks

uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
{
 if(HAL_SD_ReadBlocks(&hsd, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) 
 {
 return MSD_ERROR;
 }
 else
 {
 return MSD_OK;
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

2. further trace into the Hal_SD_readblocks(), it comes to:

 else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))
 {
 __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
 errorstate = SD_START_BIT_ERR;
 return errorstate;
 } �?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Clock setting:0690X000006063uQAA.png

void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
 RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = 16;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 RCC_OscInitStruct.PLL.PLLM = 16;
 RCC_OscInitStruct.PLL.PLLN = 192;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 4;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
 {
 Error_Handler();
 }
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Posted on January 17, 2017 at 17:29

Hello Amel

Thanks for your reply.

I am using the same PCB board. By default, STM32F405 and F411 uses different pin in cubemx. Therefore I put a jump for those pins they are different in two chips. The jump is using solder iron to fix it permanently, very solid.

But I will try to alternate the pin configuration to use same pcb layout. and try what is going on.

Posted on January 17, 2017 at 17:49

>>

Can you help check the clock setting?

Clock settings look to be OK.

What Pin are you using for the Card Detect pin of the socket?

If you have details of pins, USARTs and LEDs, I could build a demo using the SPL

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
diabolo38
Associate II
Posted on January 19, 2017 at 21:06

What is the SDIO clk  divider set too ? try to slow down clk see if it help.

Are all pin assigned to sdio set to fast ? enabling internal  pull-up may help if onboard pull up are to weak.

With  flying wired SD  connection and unadapted pull up i remenber to get of errors if going too fast

specialy In PIO mode too fast SDIO clock lead to random  fail and issue soon or late

Last time  i used CubeMX for SDIO + FaftFS or MSC/SD usb it was only generating 'PIO' code and defautl pin setutp was not best possible (i did look at some working F4 example to copy the init )

Use of DMA was key to get reliable and fast access .

That where the few things i had play on a diocveryf4 wired to an uSd adapter with weak pullup on lines for prototyping purpose .

The final  board design with SD socket on board good pull up value  did run smoothly and reliably at  almost full SDIO speed (using DMA).

Posted on January 19, 2017 at 22:13

We've used external pull-ups place close to the socket, I've used a couple of GHI boards using the internal pull-ups

The BYPASS mode of the SDIO doesn't work properly (timing errata), so usually the SDIO CLK is DIV2 (ie 24 MHz from a 48 MHz clock). As I recall all SD cards are rated as 25 MHz, and all the MicroSD as 50 MHz. Probably don't need 100 MHz slew-rate, 25 or 50 would suffice if there is a lot of overshoot.

If you don't use USB the SDIO peripheral can clock at 75 MHz, yielding a 37.5 MHz pin clock.

Using DMA here also.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 20, 2017 at 02:28

Hello Sanches,

I tested with very low speed 400kHz. doesn't work. Initialization is OK, erasing/writing is fine. Error at reading.

further trace into the Hal_SD_readblocks(), it comes to:

 else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR))
 {
 __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR);
 errorstate = SD_START_BIT_ERR;
 return errorstate;
 } 

I have a pull up resistor 47k connected for eachpin except the clock.

Actually I use the same board tested for F405 chip. everything is OK for that chip.

As I mentioned earlier, these two chips are so close. So I just use jump to alternate the routing to accomodise both chips.

In the application level, I use same code except the pin configuration.

I don't know what is difference in the low level.

Posted on January 20, 2017 at 02:39

Clive,

I am using USB to output data. I tested the speed of 400kHz. stuck in reading block.

DMA is used

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 */
 __HAL_RCC_SDIO_CLK_ENABLE();
 
 /**SDIO GPIO Configuration 
 PA6 ------> SDIO_CMD
 PB15 ------> SDIO_CK
 PC8 ------> SDIO_D0
 PC9 ------> SDIO_D1
 PA9 ------> SDIO_D2
 PC11 ------> SDIO_D3 
 */
 GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_9;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_15;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_11;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
 HAL_GPIO_Init(GPIOC, &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_LOW;
 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;
 if (HAL_DMA_Init(&hdma_sdio_rx) != HAL_OK)
 {
 Error_Handler();
 }
__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_WORD;
 hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
 hdma_sdio_tx.Init.Priority = DMA_PRIORITY_LOW;
 hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
 hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
 hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
 if (HAL_DMA_Init(&hdma_sdio_tx) != HAL_OK)
 {
 Error_Handler();
 }
__HAL_LINKDMA(hsd,hdmatx,hdma_sdio_tx);
/* Peripheral interrupt init */
 HAL_NVIC_SetPriority(SDIO_IRQn, 1, 0);
 HAL_NVIC_EnableIRQ(SDIO_IRQn);
 /* USER CODE BEGIN SDIO_MspInit 1 */
/* USER CODE END SDIO_MspInit 1 */
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?