AnsweredAssumed Answered

sample code for STM32F411 accessing uSD card?

Question asked by mao on Oct 19, 2015
Latest reply on Oct 23, 2015 by Clive One
Accessing file in a uSD card should be pretty easy.
STM32Cubemx can generate the code for you, however, I never succeed in accessing uSD with the code generated by cubemx.

In my own board I have a STM32F411RC chip. In order to study uSD, I have a F4 discovery board with BB board to test uSD. A testing code was utilized to test the hardware to ensure that the hardware has no problem. The code generated by cubemx for uSD is attached. Only a few sentences were added to the main() function. I couldn't find any problem in the code. At debuging, it stops at the line: if(f_open(&MyFile, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)  //note filename length should be <=8

Anyone, please help to check the code. All project files are attached.
Only main.c file is posted on page to view. Others files were generated by cubemx, not changed at all.

Or please generate a simple sample code for STM32F411RC to access uSD.
I have been struggling for a few days. 
Really appreciate for suggestions and help.


#include "stm32f4xx_hal.h"
#include "fatfs.h"
 
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;
HAL_SD_CardInfoTypedef SDCardInfo;
DMA_HandleTypeDef hdma_sdio_rx;
DMA_HandleTypeDef hdma_sdio_tx;
 
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
FATFS SDFatFs;  /* File system object for SD card logical drive */
FIL MyFile;     /* File object */
/* USER CODE END PV */
static void Error_Handler(void);
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SDIO_SD_Init(void);
 
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
int main(void)
{
 
  /* USER CODE BEGIN 1 */
  FRESULT res;                                          /* FatFs function common result code */
  uint32_t byteswritten, bytesread;                     /* File write/read counts */
  uint8_t wtext[] = "testing using own code. This is STM32 working with FatFs"; /* File write buffer */
  uint8_t rtext[100];
    char textbuf[200]; //string buffer
    char filename[]="testA01.txt"; //filename length should be <=8
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SDIO_SD_Init();
//  MX_FATFS_Init();
 
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
      if(FATFS_LinkDriver(&SD_Driver, SD_Path) == 0) //no need, it was initialized in MX_FATFS_Init();
  {
     
    /*##-2- Register the file system object to the FatFs module ##############*/
    if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)
    {
      /* FatFs Initialization Error */
      Error_Handler();
    }
    else
    {
   
        /*##-4- Create and Open a new text file object with write access #####*/
        if(f_open(&MyFile, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)  //note filename length should be <=8
        {
          /* 'STM32.TXT' file Open for write 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 */
            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, filename, 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);
                }
              }
            }
          }
        }
       
    }
  }
   
  /*##-11- Unlink the RAM disk I/O driver ####################################*/
  FATFS_UnLinkDriver(SD_Path);
  while (1)
  {
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
 
  }
  /* USER CODE END 3 */
 
}
static void Error_Handler(void)
{
  /* Turn LED3 on */
//  BSP_LED_On(LED3);
  while(1)
  {
  }
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
  __PWR_CLK_ENABLE();
 
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
  RCC_ClkInitStruct.ClockType = 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_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
 
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
 
/* SDIO init function */
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 = 0;
 
}
 
/**
  * Enable DMA controller clock
  */
void MX_DMA_Init(void)
{
  /* DMA controller clock enable */
  __DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
  HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 6, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
 
}
 
/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{
 
  /* GPIO Ports Clock Enable */
  __GPIOH_CLK_ENABLE();
  __GPIOC_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();
  __GPIOD_CLK_ENABLE();
 
}
 
/* USER CODE BEGIN 4 */
 
/* USER CODE END 4 */
 
#ifdef USE_FULL_ASSERT
 
/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
 
}
 
#endif
 
/**
  * @}
  */
 
/**
  * @}
*/
 

Attachments

Outcomes