ST / BSP_DISCO_L4R9I

Dependents:   DISCO_L4R9I-LCD-demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4r9i_discovery_sd.c Source File

stm32l4r9i_discovery_sd.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4r9i_discovery_sd.c
00004   * @author  MCD Application Team
00005   * @brief   This file includes the uSD card driver.
00006   @verbatim
00007   ==============================================================================
00008                      ##### How to use this driver #####
00009   ==============================================================================
00010   (#) This driver is used to drive the micro SD external card mounted on STM32L4R9I_DISCOVERY
00011      evaluation board.
00012 
00013   (#) This driver does not need a specific component driver for the micro SD device
00014      to be included with.
00015 
00016   (#) Initialization steps:
00017        (++) Initialize the micro SD card using the BSP_SD_Init() function. This
00018             function includes the MSP layer hardware resources initialization (BSP_SD_MspInit())
00019             and the SDMMC1 interface configuration to interface with the external micro SD. It
00020             also includes the micro SD initialization sequence.
00021        (++) To check the SD card presence you can use the function BSP_SD_IsDetected() which
00022             returns the detection status.
00023        (++) If SD presence detection interrupt mode is desired, you must configure the
00024             SD detection interrupt mode by calling the functions BSP_SD_ITConfig().
00025             The interrupt is generated as an external interrupt whenever the
00026             micro SD card is plugged/unplugged in/from the evaluation board. The SD detection
00027             is managed by MFX, so the SD detection interrupt has to be treated by MFX_IRQOUT
00028             gpio pin IRQ handler.
00029        (++) The function BSP_SD_GetCardInfo() is used to get the micro SD card information
00030             which is stored in the structure "HAL_SD_CardInfoTypedef".
00031 
00032   (#) Micro SD card operations
00033        (++) The micro SD card can be accessed with read/write block(s) operations once
00034             it is reay for access. The access can be performed whether using the polling
00035             mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(),
00036             or by DMA transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA().
00037        (++) The DMA transfer complete is used with interrupt mode. Once the SD transfer
00038             is complete, the DMA Tx/Rx transfer complete are handled using the
00039             BSP_SD_WriteCpltCallback()/BSP_SD_ReadCpltCallback() user callback functions implemented
00040             by the user at application level.
00041        (++) The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying
00042             the number of blocks to erase.
00043        (++) The SD runtime status is returned when calling the function BSP_SD_GetStatus().
00044    [..]
00045   @endverbatim
00046   ******************************************************************************
00047   * @attention
00048   *
00049   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
00050   * All rights reserved.</center></h2>
00051   *
00052   * This software component is licensed by ST under BSD 3-Clause license,
00053   * the "License"; You may not use this file except in compliance with the
00054   * License. You may obtain a copy of the License at:
00055   *                        opensource.org/licenses/BSD-3-Clause
00056   *
00057   ******************************************************************************
00058   */
00059 
00060 /* Includes ------------------------------------------------------------------*/
00061 #include "stm32l4r9i_discovery_io.h"
00062 #include "stm32l4r9i_discovery_sd.h"
00063 
00064 /** @addtogroup BSP
00065   * @{
00066   */
00067 
00068 /** @addtogroup STM32L4R9I_DISCOVERY
00069   * @{
00070   */
00071 
00072 /** @defgroup STM32L4R9I_DISCOVERY_SD STM32L4R9I_DISCOVERY SD
00073   * @{
00074   */
00075 
00076 /* Private variables ---------------------------------------------------------*/
00077 
00078 /** @defgroup STM32L4R9I_DISCOVERY_SD_Private_Variables Private Variables
00079   * @{
00080   */
00081 SD_HandleTypeDef hsd_discovery;
00082 static uint8_t UseExtiModeDetection = 0;
00083 /**
00084   * @}
00085   */
00086 
00087 /* Private function prototypes -----------------------------------------------*/
00088 
00089 /* Exported functions ---------------------------------------------------------*/
00090 
00091 /** @addtogroup STM32L4R9I_DISCOVERY_SD_Exported_Functions
00092   * @{
00093   */
00094 
00095 /**
00096   * @brief  Initializes the SD card device.
00097   * @retval SD status
00098   */
00099 uint8_t BSP_SD_Init(void)
00100 {
00101   uint8_t sd_state = MSD_OK;
00102 
00103   /* uSD device interface configuration */
00104   hsd_discovery.Instance = SDMMC1;
00105   hsd_discovery.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
00106   hsd_discovery.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
00107   hsd_discovery.Init.BusWide             = SDMMC_BUS_WIDE_4B;
00108   hsd_discovery.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
00109   hsd_discovery.Init.ClockDiv            = 1;
00110   hsd_discovery.Init.Transceiver         = SDMMC_TRANSCEIVER_DISABLE;
00111 
00112   /* Initialize IO functionalities (MFX) used by SD detect pin */
00113   BSP_IO_Init();
00114 
00115   /* Check if the SD card is plugged in the slot */
00116   BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_INPUT_PU);
00117 
00118   /* Check if the SD card is plugged in the slot */
00119   if(BSP_SD_IsDetected() != SD_PRESENT)
00120   {
00121     return MSD_ERROR_SD_NOT_PRESENT;
00122   }
00123 
00124   /* Msp SD initialization */
00125   BSP_SD_MspInit(&hsd_discovery, NULL);
00126 
00127   /* HAL SD initialization */
00128   if(HAL_SD_Init(&hsd_discovery) != HAL_OK)
00129   {
00130     sd_state = MSD_ERROR;
00131   }
00132 
00133   return  sd_state;
00134 }
00135 
00136 /**
00137   * @brief  DeInitializes the SD card device.
00138   * @retval SD status
00139   */
00140 uint8_t BSP_SD_DeInit(void)
00141 {
00142   uint8_t sd_state = MSD_OK;
00143 
00144   hsd_discovery.Instance = SDMMC1;
00145 
00146   /* Set back Mfx pin to INPUT mode in case it was in exti */
00147   UseExtiModeDetection = 0;
00148 
00149   /* HAL SD deinitialization */
00150   if(HAL_SD_DeInit(&hsd_discovery) != HAL_OK)
00151   {
00152     sd_state = MSD_ERROR;
00153   }
00154 
00155   /* Msp SD deinitialization */
00156   BSP_SD_MspDeInit(&hsd_discovery, NULL);
00157 
00158   return  sd_state;
00159 }
00160 
00161 /**
00162   * @brief  Configures Interrupt mode for SD detection pin.
00163   * @retval IO_OK: if all initializations are OK. Other value if error.
00164   */
00165 uint8_t BSP_SD_ITConfig(void)
00166 {
00167   /* Configure Interrupt mode for SD detection pin */
00168   /* Note: disabling exti mode can be done calling BSP_SD_DeInit() */
00169   UseExtiModeDetection = 1;
00170 
00171   /* Check SD card detect pin */
00172   if(BSP_IO_ReadPin(SD_DETECT_PIN) == IO_PIN_RESET)
00173   {
00174     /* Card present */
00175     return BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_RISING_EDGE_PU);
00176   }
00177   else
00178   {
00179     /* Card not present */
00180     return BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_FALLING_EDGE_PU);
00181   }
00182 }
00183 
00184 /**
00185  * @brief  Detects if SD card is correctly plugged in the memory slot or not.
00186  * @retval Returns if SD is detected or not
00187  */
00188 uint8_t BSP_SD_IsDetected(void)
00189 {
00190   __IO uint8_t status = SD_PRESENT;
00191 
00192   /* Check SD card detect pin */
00193   if (BSP_IO_ReadPin(SD_DETECT_PIN) == IO_PIN_RESET)
00194   {
00195     /* Card present */
00196     if (UseExtiModeDetection)
00197     {
00198       BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_RISING_EDGE_PU);
00199     }
00200   }
00201   else
00202   {
00203     /* Card not present */
00204     status = SD_NOT_PRESENT;
00205     if (UseExtiModeDetection)
00206     {
00207       BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_FALLING_EDGE_PU);
00208     }
00209   }
00210 
00211   return status;
00212 }
00213 
00214 /**
00215   * @brief  Reads block(s) from a specified address in an SD card, in polling mode.
00216   * @param  pData: Pointer to the buffer that will contain the data to transmit
00217   * @param  ReadAddr: Address from where data is to be read
00218   * @param  NumOfBlocks: Number of SD blocks to read
00219   * @param  Timeout: Timeout for read operation
00220   * @retval SD status
00221   */
00222 uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00223 {
00224   HAL_StatusTypeDef  sd_state = HAL_OK;
00225 
00226   sd_state =  HAL_SD_ReadBlocks(&hsd_discovery, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout);
00227 
00228   if  (sd_state == HAL_OK)
00229   {
00230     return MSD_OK;
00231   }
00232   else
00233   {
00234     return MSD_ERROR;
00235   }
00236 }
00237 
00238 /**
00239   * @brief  Writes block(s) to a specified address in an SD card, in polling mode.
00240   * @param  pData: Pointer to the buffer that will contain the data to transmit
00241   * @param  WriteAddr: Address from where data is to be written
00242   * @param  NumOfBlocks: Number of SD blocks to write
00243   * @param  Timeout: Timeout for write operation
00244   * @retval SD status
00245   */
00246 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00247 {
00248   HAL_StatusTypeDef  sd_state = HAL_OK;
00249 
00250   sd_state = HAL_SD_WriteBlocks(&hsd_discovery, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout);
00251 
00252   if( sd_state == HAL_OK)
00253   {
00254     return MSD_OK;
00255   }
00256   else
00257   {
00258     return MSD_ERROR;
00259   }
00260 }
00261 
00262 /**
00263   * @brief  Reads block(s) from a specified address in an SD card, in DMA mode.
00264   * @param  pData: Pointer to the buffer that will contain the data to transmit
00265   * @param  ReadAddr: Address from where data is to be read
00266   * @param  NumOfBlocks: Number of SD blocks to read
00267   * @retval SD status
00268   */
00269 uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
00270 {
00271   HAL_StatusTypeDef  sd_state = HAL_OK;
00272 
00273   /* Read block(s) in DMA transfer mode */
00274   sd_state = HAL_SD_ReadBlocks_DMA(&hsd_discovery, (uint8_t *)pData, ReadAddr, NumOfBlocks);
00275 
00276   if( sd_state == HAL_OK)
00277   {
00278     return MSD_OK;
00279   }
00280   else
00281   {
00282     return MSD_ERROR;
00283   }
00284 }
00285 
00286 /**
00287   * @brief  Writes block(s) to a specified address in an SD card, in DMA mode.
00288   * @param  pData: Pointer to the buffer that will contain the data to transmit
00289   * @param  WriteAddr: Address from where data is to be written
00290   * @param  NumOfBlocks: Number of SD blocks to write
00291   * @retval SD status
00292   */
00293 uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
00294 {
00295   HAL_StatusTypeDef  sd_state = HAL_OK;
00296 
00297   /* Write block(s) in DMA transfer mode */
00298   sd_state = HAL_SD_WriteBlocks_DMA(&hsd_discovery, (uint8_t *)pData, WriteAddr, NumOfBlocks);
00299 
00300   if( sd_state == HAL_OK)
00301   {
00302     return MSD_OK;
00303   }
00304   else
00305   {
00306     return MSD_ERROR;
00307   }
00308 }
00309 
00310 /**
00311   * @brief  Erases the specified memory area of the given SD card.
00312   * @param  StartAddr: Start byte address
00313   * @param  EndAddr: End byte address
00314   * @retval SD status
00315   */
00316 uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr)
00317 {
00318   HAL_StatusTypeDef  sd_state = HAL_OK;
00319 
00320   sd_state = HAL_SD_Erase(&hsd_discovery, StartAddr, EndAddr);
00321 
00322   if( sd_state == HAL_OK)
00323   {
00324     return MSD_OK;
00325   }
00326   else
00327   {
00328     return MSD_ERROR;
00329   }
00330 }
00331 
00332 /**
00333   * @brief  Gets the current SD card data status.
00334   * @retval Data transfer state.
00335   *          This value can be one of the following values:
00336   *            @arg  SD_TRANSFER_OK: No data transfer is acting
00337   *            @arg  SD_TRANSFER_BUSY: Data transfer is acting
00338   */
00339 uint8_t BSP_SD_GetCardState(void)
00340 {
00341   return((HAL_SD_GetCardState(&hsd_discovery) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY);
00342 }
00343 
00344 /**
00345   * @brief  Get SD information about specific SD card.
00346   * @param  CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
00347   * @retval None
00348   */
00349 void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo)
00350 {
00351   /* Get SD card Information */
00352   HAL_SD_GetCardInfo(&hsd_discovery, CardInfo);
00353 }
00354 
00355 
00356 /**
00357   * @brief  Initializes the SD MSP.
00358   * @retval None
00359   */
00360 __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params)
00361 {
00362   GPIO_InitTypeDef gpioinitstruct = {0};
00363   RCC_OscInitTypeDef        RCC_OscInitStruct;
00364   RCC_PeriphCLKInitTypeDef  RCC_PeriphClkInit;
00365 
00366   /* Check whether HSI48 is enabled or not */
00367   HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
00368   if(RCC_OscInitStruct.HSI48State != RCC_HSI48_ON)
00369   {
00370     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
00371     RCC_OscInitStruct.HSI48State     = RCC_HSI48_ON;
00372     RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
00373     if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
00374     {
00375       while(1) {}
00376     }
00377   }
00378 
00379   /* Configure the SDMMC1 clock source. The clock is derived from the HSI48 */
00380   RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC1;
00381   RCC_PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_HSI48;
00382   if(HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK)
00383   {
00384     while(1) {}
00385   }
00386 
00387   /* Enable SDMMC1 clock */
00388   __HAL_RCC_SDMMC1_CLK_ENABLE();
00389 
00390   /* Enable GPIOs clock */
00391   __HAL_RCC_GPIOC_CLK_ENABLE();
00392   __HAL_RCC_GPIOD_CLK_ENABLE();
00393 
00394   /* Common GPIO configuration */
00395   gpioinitstruct.Mode      = GPIO_MODE_AF_PP;
00396   gpioinitstruct.Pull      = GPIO_PULLUP;
00397   gpioinitstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
00398   gpioinitstruct.Alternate = GPIO_AF12_SDMMC1;
00399 
00400   /* GPIOC configuration */
00401   gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
00402   HAL_GPIO_Init(GPIOC, &gpioinitstruct);
00403 
00404   /* GPIOD configuration */
00405   gpioinitstruct.Pin = GPIO_PIN_2;
00406   HAL_GPIO_Init(GPIOD, &gpioinitstruct);
00407 
00408   /* NVIC configuration for SDMMC1 interrupts */
00409   HAL_NVIC_SetPriority(SDMMCx_IRQn, 5, 0);
00410   HAL_NVIC_EnableIRQ(SDMMCx_IRQn);
00411 }
00412 
00413 /**
00414   * @brief  De-Initializes the SD MSP.
00415   * @retval None
00416   */
00417 __weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params)
00418 {
00419   GPIO_InitTypeDef gpioinitstruct = {0};
00420 
00421   /* NVIC configuration for SDMMC1 interrupts */
00422   HAL_NVIC_DisableIRQ(SDMMCx_IRQn);
00423 
00424   /* Disable SDMMC1 clock */
00425   __HAL_RCC_SDMMC1_CLK_DISABLE();
00426 
00427   /* Enable GPIOs clock */
00428   __HAL_RCC_GPIOC_CLK_ENABLE();
00429   __HAL_RCC_GPIOD_CLK_ENABLE();
00430 
00431   /* Common GPIO configuration */
00432   gpioinitstruct.Mode      = GPIO_MODE_ANALOG;
00433   gpioinitstruct.Pull      = GPIO_NOPULL;
00434   gpioinitstruct.Speed     = GPIO_SPEED_FREQ_LOW;
00435   gpioinitstruct.Alternate = 0;
00436 
00437   /* GPIOC configuration */
00438   gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
00439   HAL_GPIO_Init(GPIOC, &gpioinitstruct);
00440 
00441   /* GPIOD configuration */
00442   gpioinitstruct.Pin = GPIO_PIN_2;
00443   HAL_GPIO_Init(GPIOD, &gpioinitstruct);
00444 }
00445 
00446 /**
00447   * @brief BSP SD Abort callback
00448   * @retval None
00449   */
00450 __weak void BSP_SD_AbortCallback(void)
00451 {
00452 
00453 }
00454 
00455 /**
00456   * @brief BSP Tx Transfer completed callback
00457   * @retval None
00458   */
00459 __weak void BSP_SD_WriteCpltCallback(void)
00460 {
00461 
00462 }
00463 
00464 /**
00465   * @brief BSP Rx Transfer completed callback
00466   * @retval None
00467   */
00468 __weak void BSP_SD_ReadCpltCallback(void)
00469 {
00470 
00471 }
00472 
00473 /**
00474   * @brief SD Abort callbacks
00475   * @param hsd: SD handle
00476   * @retval None
00477   */
00478 void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
00479 {
00480   BSP_SD_AbortCallback();
00481 }
00482 
00483 /**
00484   * @brief Tx Transfer completed callback
00485   * @param hsd: SD handle
00486   * @retval None
00487   */
00488 void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
00489 {
00490   BSP_SD_WriteCpltCallback();
00491 }
00492 
00493 /**
00494   * @brief Rx Transfer completed callback
00495   * @param hsd: SD handle
00496   * @retval None
00497   */
00498 void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
00499 {
00500   BSP_SD_ReadCpltCallback();
00501 }
00502 
00503 /**
00504   * @}
00505   */
00506 
00507 /**
00508   * @}
00509   */
00510 
00511 /**
00512   * @}
00513   */
00514 
00515 /**
00516   * @}
00517   */
00518 
00519 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/