STM32L4R9I-Discovery BSP User Manual
|
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>© 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 1.7.6.1