STM32L4R9I-Discovery BSP User Manual: stm32l4r9i_discovery_sd.c Source File

STM32L4R9I-Discovery BSP

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</center></h2>
00050   *
00051   * Redistribution and use in source and binary forms, with or without modification,
00052   * are permitted provided that the following conditions are met:
00053   *   1. Redistributions of source code must retain the above copyright notice,
00054   *      this list of conditions and the following disclaimer.
00055   *   2. Redistributions in binary form must reproduce the above copyright notice,
00056   *      this list of conditions and the following disclaimer in the documentation
00057   *      and/or other materials provided with the distribution.
00058   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00059   *      may be used to endorse or promote products derived from this software
00060   *      without specific prior written permission.
00061   *
00062   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00063   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00064   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00065   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00066   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00067   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00068   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00069   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00070   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00071   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00072   *
00073   ******************************************************************************
00074   */
00075 
00076 /* Includes ------------------------------------------------------------------*/
00077 #include "stm32l4r9i_discovery_io.h"
00078 #include "stm32l4r9i_discovery_sd.h"
00079 
00080 /** @addtogroup BSP
00081   * @{
00082   */
00083 
00084 /** @addtogroup STM32L4R9I_DISCOVERY
00085   * @{
00086   */
00087 
00088 /** @defgroup STM32L4R9I_DISCOVERY_SD STM32L4R9I_DISCOVERY SD
00089   * @{
00090   */
00091 
00092 /* Private variables ---------------------------------------------------------*/
00093 
00094 /** @defgroup STM32L4R9I_DISCOVERY_SD_Private_Variables Private Variables
00095   * @{
00096   */
00097 SD_HandleTypeDef hsd_discovery;
00098 static uint8_t UseExtiModeDetection = 0;
00099 /**
00100   * @}
00101   */
00102 
00103 /* Private function prototypes -----------------------------------------------*/
00104 
00105 /* Exported functions ---------------------------------------------------------*/
00106 
00107 /** @addtogroup STM32L4R9I_DISCOVERY_SD_Exported_Functions
00108   * @{
00109   */
00110 
00111 /**
00112   * @brief  Initializes the SD card device.
00113   * @retval SD status
00114   */
00115 uint8_t BSP_SD_Init(void)
00116 {
00117   uint8_t sd_state = MSD_OK;
00118 
00119   /* uSD device interface configuration */
00120   hsd_discovery.Instance = SDMMC1;
00121   hsd_discovery.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
00122   hsd_discovery.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
00123   hsd_discovery.Init.BusWide             = SDMMC_BUS_WIDE_4B;
00124   hsd_discovery.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
00125   hsd_discovery.Init.ClockDiv            = 1;
00126   hsd_discovery.Init.Transceiver         = SDMMC_TRANSCEIVER_DISABLE;
00127 
00128   /* Initialize IO functionalities (MFX) used by SD detect pin */
00129   BSP_IO_Init();
00130 
00131   /* Check if the SD card is plugged in the slot */
00132   BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_INPUT_PU);
00133 
00134   /* Check if the SD card is plugged in the slot */
00135   if(BSP_SD_IsDetected() != SD_PRESENT)
00136   {
00137     return MSD_ERROR_SD_NOT_PRESENT;
00138   }
00139 
00140   /* Msp SD initialization */
00141   BSP_SD_MspInit(&hsd_discovery, NULL);
00142 
00143   /* HAL SD initialization */
00144   if(HAL_SD_Init(&hsd_discovery) != HAL_OK)
00145   {
00146     sd_state = MSD_ERROR;
00147   }
00148 
00149   return  sd_state;
00150 }
00151 
00152 /**
00153   * @brief  DeInitializes the SD card device.
00154   * @retval SD status
00155   */
00156 uint8_t BSP_SD_DeInit(void)
00157 {
00158   uint8_t sd_state = MSD_OK;
00159 
00160   hsd_discovery.Instance = SDMMC1;
00161 
00162   /* Set back Mfx pin to INPUT mode in case it was in exti */
00163   UseExtiModeDetection = 0;
00164 
00165   /* HAL SD deinitialization */
00166   if(HAL_SD_DeInit(&hsd_discovery) != HAL_OK)
00167   {
00168     sd_state = MSD_ERROR;
00169   }
00170 
00171   /* Msp SD deinitialization */
00172   BSP_SD_MspDeInit(&hsd_discovery, NULL);
00173 
00174   return  sd_state;
00175 }
00176 
00177 /**
00178   * @brief  Configures Interrupt mode for SD detection pin.
00179   * @retval IO_OK: if all initializations are OK. Other value if error.
00180   */
00181 uint8_t BSP_SD_ITConfig(void)
00182 {
00183   /* Configure Interrupt mode for SD detection pin */
00184   /* Note: disabling exti mode can be done calling BSP_SD_DeInit() */
00185   UseExtiModeDetection = 1;
00186 
00187   /* Check SD card detect pin */
00188   if(BSP_IO_ReadPin(SD_DETECT_PIN) == IO_PIN_RESET)
00189   {
00190     /* Card present */
00191     return BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_RISING_EDGE_PU);
00192   }
00193   else
00194   {
00195     /* Card not present */
00196     return BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_FALLING_EDGE_PU);
00197   }
00198 }
00199 
00200 /**
00201  * @brief  Detects if SD card is correctly plugged in the memory slot or not.
00202  * @retval Returns if SD is detected or not
00203  */
00204 uint8_t BSP_SD_IsDetected(void)
00205 {
00206   __IO uint8_t status = SD_PRESENT;
00207 
00208   /* Check SD card detect pin */
00209   if (BSP_IO_ReadPin(SD_DETECT_PIN) == IO_PIN_RESET)
00210   {
00211     /* Card present */
00212     if (UseExtiModeDetection)
00213     {
00214       BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_RISING_EDGE_PU);
00215     }
00216   }
00217   else
00218   {
00219     /* Card not present */
00220     status = SD_NOT_PRESENT;
00221     if (UseExtiModeDetection)
00222     {
00223       BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_IT_FALLING_EDGE_PU);
00224     }
00225   }
00226 
00227   return status;
00228 }
00229 
00230 /**
00231   * @brief  Reads block(s) from a specified address in an SD card, in polling mode.
00232   * @param  pData: Pointer to the buffer that will contain the data to transmit
00233   * @param  ReadAddr: Address from where data is to be read
00234   * @param  NumOfBlocks: Number of SD blocks to read
00235   * @param  Timeout: Timeout for read operation
00236   * @retval SD status
00237   */
00238 uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00239 {
00240   HAL_StatusTypeDef  sd_state = HAL_OK;
00241 
00242   sd_state =  HAL_SD_ReadBlocks(&hsd_discovery, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout);
00243 
00244   if  (sd_state == HAL_OK)
00245   {
00246     return MSD_OK;
00247   }
00248   else
00249   {
00250     return MSD_ERROR;
00251   }
00252 }
00253 
00254 /**
00255   * @brief  Writes block(s) to a specified address in an SD card, in polling mode.
00256   * @param  pData: Pointer to the buffer that will contain the data to transmit
00257   * @param  WriteAddr: Address from where data is to be written
00258   * @param  NumOfBlocks: Number of SD blocks to write
00259   * @param  Timeout: Timeout for write operation
00260   * @retval SD status
00261   */
00262 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00263 {
00264   HAL_StatusTypeDef  sd_state = HAL_OK;
00265 
00266   sd_state = HAL_SD_WriteBlocks(&hsd_discovery, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout);
00267 
00268   if( sd_state == HAL_OK)
00269   {
00270     return MSD_OK;
00271   }
00272   else
00273   {
00274     return MSD_ERROR;
00275   }
00276 }
00277 
00278 /**
00279   * @brief  Reads block(s) from a specified address in an SD card, in DMA mode.
00280   * @param  pData: Pointer to the buffer that will contain the data to transmit
00281   * @param  ReadAddr: Address from where data is to be read
00282   * @param  NumOfBlocks: Number of SD blocks to read
00283   * @retval SD status
00284   */
00285 uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
00286 {
00287   HAL_StatusTypeDef  sd_state = HAL_OK;
00288 
00289   /* Read block(s) in DMA transfer mode */
00290   sd_state = HAL_SD_ReadBlocks_DMA(&hsd_discovery, (uint8_t *)pData, ReadAddr, NumOfBlocks);
00291 
00292   if( sd_state == HAL_OK)
00293   {
00294     return MSD_OK;
00295   }
00296   else
00297   {
00298     return MSD_ERROR;
00299   }
00300 }
00301 
00302 /**
00303   * @brief  Writes block(s) to a specified address in an SD card, in DMA mode.
00304   * @param  pData: Pointer to the buffer that will contain the data to transmit
00305   * @param  WriteAddr: Address from where data is to be written
00306   * @param  NumOfBlocks: Number of SD blocks to write
00307   * @retval SD status
00308   */
00309 uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
00310 {
00311   HAL_StatusTypeDef  sd_state = HAL_OK;
00312 
00313   /* Write block(s) in DMA transfer mode */
00314   sd_state = HAL_SD_WriteBlocks_DMA(&hsd_discovery, (uint8_t *)pData, WriteAddr, NumOfBlocks);
00315 
00316   if( sd_state == HAL_OK)
00317   {
00318     return MSD_OK;
00319   }
00320   else
00321   {
00322     return MSD_ERROR;
00323   }
00324 }
00325 
00326 /**
00327   * @brief  Erases the specified memory area of the given SD card.
00328   * @param  StartAddr: Start byte address
00329   * @param  EndAddr: End byte address
00330   * @retval SD status
00331   */
00332 uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr)
00333 {
00334   HAL_StatusTypeDef  sd_state = HAL_OK;
00335 
00336   sd_state = HAL_SD_Erase(&hsd_discovery, StartAddr, EndAddr);
00337 
00338   if( sd_state == HAL_OK)
00339   {
00340     return MSD_OK;
00341   }
00342   else
00343   {
00344     return MSD_ERROR;
00345   }
00346 }
00347 
00348 /**
00349   * @brief  Gets the current SD card data status.
00350   * @retval Data transfer state.
00351   *          This value can be one of the following values:
00352   *            @arg  SD_TRANSFER_OK: No data transfer is acting
00353   *            @arg  SD_TRANSFER_BUSY: Data transfer is acting
00354   */
00355 uint8_t BSP_SD_GetCardState(void)
00356 {
00357   return((HAL_SD_GetCardState(&hsd_discovery) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY);
00358 }
00359 
00360 /**
00361   * @brief  Get SD information about specific SD card.
00362   * @param  CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
00363   * @retval None
00364   */
00365 void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo)
00366 {
00367   /* Get SD card Information */
00368   HAL_SD_GetCardInfo(&hsd_discovery, CardInfo);
00369 }
00370 
00371 
00372 /**
00373   * @brief  Initializes the SD MSP.
00374   * @retval None
00375   */
00376 __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params)
00377 {
00378   GPIO_InitTypeDef gpioinitstruct = {0};
00379   RCC_OscInitTypeDef        RCC_OscInitStruct;
00380   RCC_PeriphCLKInitTypeDef  RCC_PeriphClkInit;
00381 
00382   /* Check whether HSI48 is enabled or not */
00383   HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
00384   if(RCC_OscInitStruct.HSI48State != RCC_HSI48_ON)
00385   {
00386     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
00387     RCC_OscInitStruct.HSI48State     = RCC_HSI48_ON;
00388     RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
00389     if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
00390     {
00391       while(1) {}
00392     }
00393   }
00394 
00395   /* Configure the SDMMC1 clock source. The clock is derived from the HSI48 */
00396   RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC1;
00397   RCC_PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_HSI48;
00398   if(HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK)
00399   {
00400     while(1) {}
00401   }
00402 
00403   /* Enable SDMMC1 clock */
00404   __HAL_RCC_SDMMC1_CLK_ENABLE();
00405 
00406   /* Enable GPIOs clock */
00407   __HAL_RCC_GPIOC_CLK_ENABLE();
00408   __HAL_RCC_GPIOD_CLK_ENABLE();
00409 
00410   /* Common GPIO configuration */
00411   gpioinitstruct.Mode      = GPIO_MODE_AF_PP;
00412   gpioinitstruct.Pull      = GPIO_PULLUP;
00413   gpioinitstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
00414   gpioinitstruct.Alternate = GPIO_AF12_SDMMC1;
00415 
00416   /* GPIOC configuration */
00417   gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
00418   HAL_GPIO_Init(GPIOC, &gpioinitstruct);
00419 
00420   /* GPIOD configuration */
00421   gpioinitstruct.Pin = GPIO_PIN_2;
00422   HAL_GPIO_Init(GPIOD, &gpioinitstruct);
00423 
00424   /* NVIC configuration for SDMMC1 interrupts */
00425   HAL_NVIC_SetPriority(SDMMCx_IRQn, 5, 0);
00426   HAL_NVIC_EnableIRQ(SDMMCx_IRQn);
00427 }
00428 
00429 /**
00430   * @brief  De-Initializes the SD MSP.
00431   * @retval None
00432   */
00433 __weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params)
00434 {
00435   GPIO_InitTypeDef gpioinitstruct = {0};
00436 
00437   /* NVIC configuration for SDMMC1 interrupts */
00438   HAL_NVIC_DisableIRQ(SDMMCx_IRQn);
00439 
00440   /* Disable SDMMC1 clock */
00441   __HAL_RCC_SDMMC1_CLK_DISABLE();
00442 
00443   /* Enable GPIOs clock */
00444   __HAL_RCC_GPIOC_CLK_ENABLE();
00445   __HAL_RCC_GPIOD_CLK_ENABLE();
00446 
00447   /* Common GPIO configuration */
00448   gpioinitstruct.Mode      = GPIO_MODE_ANALOG;
00449   gpioinitstruct.Pull      = GPIO_NOPULL;
00450   gpioinitstruct.Speed     = GPIO_SPEED_FREQ_LOW;
00451   gpioinitstruct.Alternate = 0;
00452 
00453   /* GPIOC configuration */
00454   gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
00455   HAL_GPIO_Init(GPIOC, &gpioinitstruct);
00456 
00457   /* GPIOD configuration */
00458   gpioinitstruct.Pin = GPIO_PIN_2;
00459   HAL_GPIO_Init(GPIOD, &gpioinitstruct);
00460 }
00461 
00462 /**
00463   * @brief BSP SD Abort callback
00464   * @retval None
00465   */
00466 __weak void BSP_SD_AbortCallback(void)
00467 {
00468 
00469 }
00470 
00471 /**
00472   * @brief BSP Tx Transfer completed callback
00473   * @retval None
00474   */
00475 __weak void BSP_SD_WriteCpltCallback(void)
00476 {
00477 
00478 }
00479 
00480 /**
00481   * @brief BSP Rx Transfer completed callback
00482   * @retval None
00483   */
00484 __weak void BSP_SD_ReadCpltCallback(void)
00485 {
00486 
00487 }
00488 
00489 /**
00490   * @brief SD Abort callbacks
00491   * @param hsd: SD handle
00492   * @retval None
00493   */
00494 void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
00495 {
00496   BSP_SD_AbortCallback();
00497 }
00498 
00499 /**
00500   * @brief Tx Transfer completed callback
00501   * @param hsd: SD handle
00502   * @retval None
00503   */
00504 void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
00505 {
00506   BSP_SD_WriteCpltCallback();
00507 }
00508 
00509 /**
00510   * @brief Rx Transfer completed callback
00511   * @param hsd: SD handle
00512   * @retval None
00513   */
00514 void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
00515 {
00516   BSP_SD_ReadCpltCallback();
00517 }
00518 
00519 /**
00520   * @}
00521   */
00522 
00523 /**
00524   * @}
00525   */
00526 
00527 /**
00528   * @}
00529   */
00530 
00531 /**
00532   * @}
00533   */
00534 
00535 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Oct 13 2017 02:37:42 for STM32L4R9I-Discovery BSP User Manual by   doxygen 1.7.6.1