AnsweredAssumed Answered

stm32f4discovery fatfs sdio (how i solved my issue report)

Question asked by mai.willian on Apr 23, 2015
Latest reply on Jan 30, 2016 by van_schelven.rob

THIS IS NOT A QUESTION, is a report of how I solved my problem, to help others with the same issue..

 

I've lost about one hour writing a text here of workarounds for my problem, unfortunately the forum login timeout had it destroyed, asking me to login again (please ST admin, disable this login timeout), now I will try to be patient and write it again.. but with less details and quicker..

 

I've tested the example from STM324xG_EVAL at the stm32f4discovery and it worked fine at my sd card:

\stm32cubef4\STM32Cube_FW_F4_V1.5.0\Projects\STM324xG_EVAL\Applications\FatFs\FatFs_uSD_RTOS\EWARM

 

but when generated with STM32CubeMX it didn't work, neither at 1-bit neither at 4-bit SDIO mode..

 

-- my main problem was with "BAD contact wiring or interference", because the wire is 10cm long (found this after full two days working on it), so pay attention to this issue. I exchanged the wires and got it working, at 1-bit SDIO mode. 4-bit still doesn't work but I feel is due to bad contact. I'll make a pcb for try it more carefully)

-- second problem is that it only work with one modification (found at the forums here) which i'll post here

 

all settings in STM32CubeMX for SDIO and FATFS are default

 

I've attached my CLOCK config

 

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
    PC12     ------> SDIO_CK
    PD2     ------> SDIO_CMD
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|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);
  
  /* USER CODE BEGIN SDIO_MspInit 1 */
  
  /* USER CODE END SDIO_MspInit 1 */
  }
  
}

this is my modified fatfs.c:

got from eval example..

/**
  ******************************************************************************
  * File Name          : fatfs.c
  * Date               : 22/04/2015 23:31:11
  * Description        : Code for fatfs applications
  ******************************************************************************
  *
  * COPYRIGHT(c) 2015 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
 
#include "fatfs.h"
 
uint8_t retSD;    /* Return value for SD */
char SD_Path[4];  /* SD logical drive path */
 
/* USER CODE BEGIN Variables */
#include "main.h"
 
    FATFS SDFatFs;  /* File system object for SD card logical drive */
    FIL MyFile;     /* File object */
     
//FATFS SDFatFs;  /* File system object for SD card logical drive */
//FIL MyFile;     /* File object */
//char SDPath[4]; /* SD card logical drive path */   
  FRESULT res;                                          /* FatFs function common result code */
  uint32_t byteswritten, bytesread;                     /* File write/read counts */
  uint8_t wtext[] = "This is STM32 working with FatFs oyeah"; /* File write buffer */
  uint8_t rtext[100];                                   /* File read buffer */
/* USER CODE END Variables */   
 
void MX_FATFS_Init(void)
{
  /*## FatFS: Link the SD driver ###########################*/
  retSD = FATFS_LinkDriver(&SD_Driver, SD_Path);
 
  /* USER CODE BEGIN Init */
  /* additional user code for init */    
   
//  /*##-1- Link the SD disk I/O driver ##*/
//  if(retSD==0){//resSD==0 means fine
//    printf("sd path is: %s\n",(TCHAR const*)SD_Path);
//    /*##-2- Register the file system object to the FatFs module ##*/
//    if(f_mount(&SDFatFs,(TCHAR const*)SD_Path,0)!=FR_OK){
//      /* FatFs Initialization Error */
//      printf("FatFs init error %d\n",(uint32_t)res);
//      Error_Handler();
//    }else{
//      /*##-3- Create a FAT file system (format) on the logical drive ##*/
//      if(f_mkfs((TCHAR const*)SD_Path,0,0)!=FR_OK){
//        /* FatFs format error */
//        printf("#FatFs format error %d\n",(uint32_t)res);
//        Error_Handler();       
//      }
//    }
//   
//  }
   
 
   
 
   
  /* USER CODE END Init */
}
 
/* USER CODE BEGIN Application */
void testSD(){
  /*##-1- Link the micro SD disk I/O driver ##################################*/
  if(retSD == 0)
  {
    /*##-2- Register the file system object to the FatFs module ##############*/
    if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)
    {
      /* FatFs Initialization Error */
      printf("FatFs Initialization Error");
      Error_Handler();
    }
    else
    {
      /*##-3- Create a FAT file system (format) on the logical drive #########*/
      /* WARNING: Formatting the uSD card will delete all content on the device */
      if(f_mkfs((TCHAR const*)SD_Path, 0, 0) != FR_OK)
      {
        /* FatFs Format Error */
        printf("FatFs Format Error");
        Error_Handler();
      }
//      if(0==1){
//        printf("0==1");
//      }
      else
      {
        /*##-4- Create and Open a new text file object with write access #####*/
        if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
        {
          /* 'STM32.TXT' file Open for write Error */
          printf("f_open error");
          Error_Handler();
        }
        else
        {
          /*##-5- Write data to the text file ################################*/
          res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);
           
          if((byteswritten == 0) || (res != FR_OK))
          {
            /* 'STM32.TXT' file Write or EOF Error */
            printf("'STM32.TXT' file Write or EOF Error");
            Error_Handler();
          }
          else
          {
            /*##-6- Close the open text file #################################*/
            f_close(&MyFile);
             
            /*##-7- Open the text file object with read access ###############*/
            if(f_open(&MyFile, "STM32.TXT", FA_READ) != FR_OK)
            {
              /* 'STM32.TXT' file Open for read Error */
              Error_Handler();
            }
            else
            {
              /*##-8- Read data from the text file ###########################*/
              res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread);
               
              if((bytesread == 0) || (res != FR_OK))
              {
                /* 'STM32.TXT' file Read or EOF Error */
                Error_Handler();
              }
              else
              {
                /*##-9- Close the open text file #############################*/
                f_close(&MyFile);
                 
                /*##-10- Compare read data with the expected data ############*/
                if((bytesread != byteswritten))
                {               
                  /* Read data is different from the expected data */
                  Error_Handler();
                }
                else
                {
                  /* Success of the demo: no error occurrence */
                  //BSP_LED_On(LED1);
                  printf("SUCCESS !!!!!!!!!!!!!!!!!!!!!");
                }
              }
            }
          }
        }
      }
    }
  }
  /*##-11- Unlink the RAM disk I/O driver ####################################*/
  FATFS_UnLinkDriver(SD_Path);      
}
/* USER CODE END Application */
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


 

also made this code for debugging, i've put mine in main.c and created a main.h header, but you might prefer putting it on sdio.c to ease the job..

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void Error_Handler(void)
{
    
  printf("Error_Handler exception\n");
        
/* Example how to turn pins via registers //onenote0x223342A */
 
         
/* must #include "system_stm32f4xx.h" */
 
         
////RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
 
         
//RCC->AHB1ENR |= (0x01<<3); //01000//shift 1 over 3 times to enable CLK for port D
 
    //GPIOD->MODER |= (0x01<<13*2);//enable PortD pin13 as output
         
//GPIOD->ODR     |= (1<<13);//turn GPIOD pin 13 on
 
         
HAL_GPIO_DeInit(GPIOD,GPIO_PIN_15);
 
         
//HAL_GPIO_DeInit(GPIOD,GPIO_PIN_5);
 
         
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;//enable the clock to GPIOD
 
    GPIOD->MODER |= (1<<15*2);//enable PortD pin15 (pin62 at mcu) as output
    GPIOD->ODR |= (1<<15);//turn GPIOD pin 15 on
         
  
 
         
HAL_GPIO_DeInit(GPIOA,GPIO_PIN_9);
 
         
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
 
    GPIOA->MODER |= (1<<9*2);
    GPIOA->ODR |= (1<<9); 
         
  
 
         
HAL_GPIO_DeInit(GPIOD,GPIO_PIN_5);
 
         
//RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
 
    GPIOD->MODER |= (1<<5*2);
    GPIOD->ODR |= (1<<5); 
  //BSP_LED_On(LED3);
  while(1){
    //GPIOD->BSRR |= (1 << 15);
    GPIOD->ODR |= (1<<15);
    GPIOD->ODR |= (1<<5);
    GPIOA->ODR |= (1<<9);
    osDelay(200);
    GPIOD->ODR &= ~(1<<15);//ld6
    GPIOD->ODR &= ~(1<<5);//ld8
    GPIOA->ODR &= ~(1<<9);//ld7
    osDelay(200);
  }
}
/* USER CODE END 4 */

 

 

NOW IS WORKING, but..

in 4-bit mode and (when it had bad contact also in 1-bit mode) it fails here:

if fails here: 

    (ff.c)

    …

    for (n = 1; n < n_fat; n++) {       /* This loop may take a time on FAT32 volume due to many single sector writes */

            

if (disk_write(pdrv, tbl, wsect++, 1))

                

return FR_DISK_ERR;

        

}

    …

    at line 4192 of ff.c

 

that's it, 

i personally am very satisfied with 1-bit sdio because read that 4-bit won't make a very bit difference for non high speed sd cards, and most of us won't need it right?

 

hope have saved someone's time. unfortunately I've lost 3 days working on it..

I've shared to help and stimulate others to help. Today you help, tomorrow you might be helped. 

 

 

From <[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Java/NewForm.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java&ContentTypeId=0x01200200770978C69A1141439FE559EB459D758000AEE4C5D5F6F7794783CEF933B9BACC13&Source=/public/STe2ecommunities/mcu/Lists/STM32Java/AllItems.aspx]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/NewForm.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java&ContentTypeId=0x01200200770978C69A1141439FE559EB459D758000AEE4C5D5F6F7794783CEF933B9BACC13&Source=/public/STe2ecommunities/mcu/Lists/STM32Java/AllItems.aspx

Outcomes