STM32L152D_EVAL BSP User Manual
|
stm32l152d_eval_sd.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l152d_eval_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 STM32L152D-EVAL 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 and the 00019 SDIO 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 function BSP_SD_ITConfig(). The interrupt 00025 is generated as an external interrupt whenever the micro SD card is 00026 plugged/unplugged in/from the evaluation board. The SD detection interrupt 00027 is handeled by calling the function BSP_SD_DetectIT() which is called in the IRQ 00028 handler file, the user callback is implemented in the function BSP_SD_DetectCallback(). 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 cand be performed whether using the polling 00035 mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), or by DMA 00036 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 SD interrupt is handeled using the function BSP_SD_IRQHandler(), 00039 the DMA Tx/Rx transfer complete are handeled using the functions 00040 BSP_SD_DMA_Tx_IRQHandler()/BSP_SD_DMA_Rx_IRQHandler(). The corresponding user callbacks 00041 are implemented by the user at application level. 00042 (++) The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying 00043 the number of blocks to erase. 00044 (++) The SD runtime status is returned when calling the function BSP_SD_GetStatus(). 00045 [..] 00046 @endverbatim 00047 ****************************************************************************** 00048 * @attention 00049 * 00050 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00051 * 00052 * Redistribution and use in source and binary forms, with or without modification, 00053 * are permitted provided that the following conditions are met: 00054 * 1. Redistributions of source code must retain the above copyright notice, 00055 * this list of conditions and the following disclaimer. 00056 * 2. Redistributions in binary form must reproduce the above copyright notice, 00057 * this list of conditions and the following disclaimer in the documentation 00058 * and/or other materials provided with the distribution. 00059 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00060 * may be used to endorse or promote products derived from this software 00061 * without specific prior written permission. 00062 * 00063 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00064 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00065 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00066 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00067 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00068 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00069 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00070 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00071 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00072 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00073 * 00074 ****************************************************************************** 00075 */ 00076 00077 /* Includes ------------------------------------------------------------------*/ 00078 #include "stm32l152d_eval_sd.h" 00079 00080 /** @addtogroup BSP 00081 * @{ 00082 */ 00083 00084 /** @addtogroup STM32L152D_EVAL 00085 * @{ 00086 */ 00087 00088 /** @defgroup STM32L152D_EVAL_SD STM32L152D-EVAL SD 00089 * @{ 00090 */ 00091 00092 /** @defgroup STM32L152D_SD_Private_Variables Private Variables 00093 * @{ 00094 */ 00095 SD_HandleTypeDef uSdHandle; 00096 static SD_CardInfo uSdCardInfo; 00097 /** 00098 * @} 00099 */ 00100 00101 /** @defgroup STM32L152D_SD_Private_Functions Private Functions 00102 * @{ 00103 */ 00104 static void SD_MspInit(void); 00105 HAL_SD_ErrorTypedef SD_DMAConfigRx(SD_HandleTypeDef *hsd); 00106 HAL_SD_ErrorTypedef SD_DMAConfigTx(SD_HandleTypeDef *hsd); 00107 00108 /** 00109 * @} 00110 */ 00111 00112 /** @defgroup STM32L152D_EVAL_SD_Exported_Functions Exported Functions 00113 * @{ 00114 */ 00115 00116 /** 00117 * @brief Initializes the SD card device. 00118 * @retval SD status. 00119 */ 00120 uint8_t BSP_SD_Init(void) 00121 { 00122 uint8_t state = MSD_OK; 00123 00124 /* uSD device interface configuration */ 00125 uSdHandle.Instance = SDIO; 00126 00127 uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; 00128 uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; 00129 uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; 00130 uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B; 00131 uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; 00132 uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; 00133 00134 /* Check if the SD card is plugged in the slot */ 00135 if(BSP_SD_IsDetected() != SD_PRESENT) 00136 { 00137 return MSD_ERROR; 00138 } 00139 00140 /* HAL SD initialization */ 00141 SD_MspInit(); 00142 if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK) 00143 { 00144 state = MSD_ERROR; 00145 } 00146 00147 /* Configure SD Bus width */ 00148 if(state == MSD_OK) 00149 { 00150 /* Enable wide operation */ 00151 if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK) 00152 { 00153 state = MSD_ERROR; 00154 } 00155 else 00156 { 00157 state = MSD_OK; 00158 } 00159 } 00160 00161 return state; 00162 } 00163 00164 /** 00165 * @brief Configures Interrupt mode for SD detection pin. 00166 * @retval Returns 0 00167 */ 00168 uint8_t BSP_SD_ITConfig(void) 00169 { 00170 GPIO_InitTypeDef gpioinitstruct = {0}; 00171 00172 /* Configure Interrupt mode for SD detection pin */ 00173 gpioinitstruct.Mode = GPIO_MODE_IT_RISING_FALLING; 00174 gpioinitstruct.Pull = GPIO_PULLUP; 00175 gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; 00176 gpioinitstruct.Pin = SD_DETECT_PIN; 00177 HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpioinitstruct); 00178 00179 /* NVIC configuration for SDIO interrupts */ 00180 HAL_NVIC_SetPriority(SD_DETECT_IRQn, 5, 0); 00181 HAL_NVIC_EnableIRQ(SD_DETECT_IRQn); 00182 00183 return 0; 00184 } 00185 00186 /** 00187 * @brief Detects if SD card is correctly plugged in the memory slot or not. 00188 * @retval Returns if SD is detected or not 00189 */ 00190 uint8_t BSP_SD_IsDetected(void) 00191 { 00192 __IO uint8_t status = SD_PRESENT; 00193 00194 /* Check SD card detect pin */ 00195 if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_RESET) 00196 { 00197 status = SD_NOT_PRESENT; 00198 } 00199 00200 return status; 00201 } 00202 00203 /** @brief SD detect IT treatment 00204 * @retval None 00205 */ 00206 void BSP_SD_DetectIT(void) 00207 { 00208 /* SD detect IT callback */ 00209 BSP_SD_DetectCallback(); 00210 00211 } 00212 00213 00214 /** @brief SD detect IT detection callback 00215 * @retval None 00216 */ 00217 __weak void BSP_SD_DetectCallback(void) 00218 { 00219 /* NOTE: This function Should not be modified, when the callback is needed, 00220 the BSP_SD_DetectCallback could be implemented in the user file 00221 */ 00222 00223 } 00224 00225 /** 00226 * @brief Reads block(s) from a specified address in an SD card, in polling mode. 00227 * @param pData: Pointer to the buffer that will contain the data to transmit 00228 * @param ReadAddr: Address from where data is to be read 00229 * @param BlockSize: SD card data block size, that should be 512 00230 * @param NumOfBlocks: Number of SD blocks to read 00231 * @retval SD status 00232 */ 00233 uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) 00234 { 00235 if(HAL_SD_ReadBlocks(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) 00236 { 00237 return MSD_ERROR; 00238 } 00239 else 00240 { 00241 return MSD_OK; 00242 } 00243 } 00244 00245 /** 00246 * @brief Writes block(s) to a specified address in an SD card, in polling mode. 00247 * @param pData: Pointer to the buffer that will contain the data to transmit 00248 * @param WriteAddr: Address from where data is to be written 00249 * @param BlockSize: SD card data block size, that should be 512 00250 * @param NumOfBlocks: Number of SD blocks to write 00251 * @retval SD status 00252 */ 00253 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) 00254 { 00255 if(HAL_SD_WriteBlocks(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) 00256 { 00257 return MSD_ERROR; 00258 } 00259 else 00260 { 00261 return MSD_OK; 00262 } 00263 } 00264 00265 /** 00266 * @brief Reads block(s) from a specified address in an SD card, in DMA mode. 00267 * @param pData: Pointer to the buffer that will contain the data to transmit 00268 * @param ReadAddr: Address from where data is to be read 00269 * @param BlockSize: SD card data block size, that should be 512 00270 * @param NumOfBlocks: Number of SD blocks to read 00271 * @retval SD status 00272 */ 00273 uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) 00274 { 00275 uint8_t state = MSD_OK; 00276 00277 /* Invalidate the dma tx handle*/ 00278 uSdHandle.hdmatx = NULL; 00279 00280 /* Prepare the dma channel for a read operation */ 00281 state = ((SD_DMAConfigRx(&uSdHandle) == SD_OK) ? MSD_OK : MSD_ERROR); 00282 00283 if(state == MSD_OK) 00284 { 00285 /* Read block(s) in DMA transfer mode */ 00286 state = ((HAL_SD_ReadBlocks_DMA(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) == SD_OK) ? MSD_OK : MSD_ERROR); 00287 00288 /* Wait until transfer is complete */ 00289 if(state == MSD_OK) 00290 { 00291 state = ((HAL_SD_CheckReadOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) == SD_OK) ? MSD_OK : MSD_ERROR); 00292 } 00293 } 00294 00295 return state; 00296 } 00297 00298 /** 00299 * @brief Writes block(s) to a specified address in an SD card, in DMA mode. 00300 * @param pData: Pointer to the buffer that will contain the data to transmit 00301 * @param WriteAddr: Address from where data is to be written 00302 * @param BlockSize: SD card data block size, that should be 512 00303 * @param NumOfBlocks: Number of SD blocks to write 00304 * @retval SD status 00305 */ 00306 uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) 00307 { 00308 uint8_t state = MSD_OK; 00309 00310 /* Invalidate the dma rx handle*/ 00311 uSdHandle.hdmarx = NULL; 00312 00313 /* Prepare the dma channel for a read operation */ 00314 state = ((SD_DMAConfigTx(&uSdHandle) == SD_OK) ? MSD_OK : MSD_ERROR); 00315 00316 if(state == MSD_OK) 00317 { 00318 /* Write block(s) in DMA transfer mode */ 00319 state = ((HAL_SD_WriteBlocks_DMA(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) == SD_OK) ? MSD_OK : MSD_ERROR); 00320 00321 /* Wait until transfer is complete */ 00322 if(state == MSD_OK) 00323 { 00324 state = ((HAL_SD_CheckWriteOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) == SD_OK) ? MSD_OK : MSD_ERROR); 00325 } 00326 } 00327 00328 return state; 00329 } 00330 00331 /** 00332 * @brief Erases the specified memory area of the given SD card. 00333 * @param StartAddr: Start byte address 00334 * @param EndAddr: End byte address 00335 * @retval SD status 00336 */ 00337 uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr) 00338 { 00339 if(HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) != SD_OK) 00340 { 00341 return MSD_ERROR; 00342 } 00343 else 00344 { 00345 return MSD_OK; 00346 } 00347 } 00348 00349 /** 00350 * @brief Handles SD card interrupt request. 00351 * @retval None 00352 */ 00353 void BSP_SD_IRQHandler(void) 00354 { 00355 HAL_SD_IRQHandler(&uSdHandle); 00356 } 00357 00358 /** 00359 * @brief Handles SD DMA Tx transfer interrupt request. 00360 * @retval None 00361 */ 00362 void BSP_SD_DMA_Tx_IRQHandler(void) 00363 { 00364 HAL_DMA_IRQHandler(uSdHandle.hdmatx); 00365 } 00366 00367 /** 00368 * @brief Handles SD DMA Rx transfer interrupt request. 00369 * @retval None 00370 */ 00371 void BSP_SD_DMA_Rx_IRQHandler(void) 00372 { 00373 HAL_DMA_IRQHandler(uSdHandle.hdmarx); 00374 } 00375 00376 /** 00377 * @brief Gets the current SD card data status. 00378 * @retval Data transfer state. 00379 * This value can be one of the following values: 00380 * @arg SD_TRANSFER_OK: No data transfer is acting 00381 * @arg SD_TRANSFER_BUSY: Data transfer is acting 00382 * @arg SD_TRANSFER_ERROR: Data transfer error 00383 */ 00384 HAL_SD_TransferStateTypedef BSP_SD_GetStatus(void) 00385 { 00386 return(HAL_SD_GetStatus(&uSdHandle)); 00387 } 00388 00389 /** 00390 * @brief Get SD information about specific SD card. 00391 * @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure 00392 * @retval None 00393 */ 00394 void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo) 00395 { 00396 /* Get SD card Information */ 00397 HAL_SD_Get_CardInfo(&uSdHandle, CardInfo); 00398 } 00399 00400 /** 00401 * @} 00402 */ 00403 00404 00405 /** @addtogroup STM32L152D_SD_Private_Functions 00406 * @{ 00407 */ 00408 00409 /** 00410 * @brief Initializes the SD MSP. 00411 * @retval None 00412 */ 00413 static void SD_MspInit(void) 00414 { 00415 GPIO_InitTypeDef gpioinitstruct = {0}; 00416 00417 /* Enable SDIO clock */ 00418 __HAL_RCC_SDIO_CLK_ENABLE(); 00419 00420 /* Enable DMA2 clocks */ 00421 __DMAx_TxRx_CLK_ENABLE(); 00422 00423 /* Enable GPIOs clock */ 00424 __HAL_RCC_GPIOC_CLK_ENABLE(); 00425 __HAL_RCC_GPIOD_CLK_ENABLE(); 00426 __SD_DETECT_GPIO_CLK_ENABLE(); 00427 00428 /* Common GPIO configuration */ 00429 gpioinitstruct.Mode = GPIO_MODE_AF_PP; 00430 gpioinitstruct.Pull = GPIO_PULLUP; 00431 gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; 00432 gpioinitstruct.Alternate = GPIO_AF12_SDIO; 00433 00434 /* GPIOC configuration */ 00435 gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; 00436 00437 HAL_GPIO_Init(GPIOC, &gpioinitstruct); 00438 00439 /* GPIOD configuration */ 00440 gpioinitstruct.Pin = GPIO_PIN_2; 00441 HAL_GPIO_Init(GPIOD, &gpioinitstruct); 00442 00443 /* SD Card detect pin configuration */ 00444 gpioinitstruct.Mode = GPIO_MODE_INPUT; 00445 gpioinitstruct.Pull = GPIO_PULLUP; 00446 gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; 00447 gpioinitstruct.Pin = SD_DETECT_PIN; 00448 HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpioinitstruct); 00449 00450 /* NVIC configuration for SDIO interrupts */ 00451 HAL_NVIC_SetPriority(SDIO_IRQn, 0, 0); 00452 HAL_NVIC_EnableIRQ(SDIO_IRQn); 00453 00454 /* DMA initialization should be done here but , as there is only one channel for RX and TX it is configured and done directly when required*/ 00455 } 00456 00457 /** 00458 * @brief SD_DMAConfigRx 00459 * @par Function Description 00460 * This function configure the DMA to receive data from the SD card 00461 * @retval 00462 * SD_ERROR or SD_OK 00463 */ 00464 HAL_SD_ErrorTypedef SD_DMAConfigRx(SD_HandleTypeDef *hsd) 00465 { 00466 static DMA_HandleTypeDef hdma_rx; 00467 HAL_StatusTypeDef status = HAL_ERROR; 00468 00469 /* Configure DMA Rx parameters */ 00470 hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; 00471 hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; 00472 hdma_rx.Init.MemInc = DMA_MINC_ENABLE; 00473 hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; 00474 hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; 00475 hdma_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; 00476 00477 hdma_rx.Instance = DMA2_Channel4; 00478 00479 /* Associate the DMA handle */ 00480 __HAL_LINKDMA(hsd, hdmarx, hdma_rx); 00481 00482 /* Stop any ongoing transfer and reset the state*/ 00483 HAL_DMA_Abort(&hdma_rx); 00484 00485 /* Deinitialize the Channel for new transfer */ 00486 HAL_DMA_DeInit(&hdma_rx); 00487 00488 /* Configure the DMA Channel */ 00489 status = HAL_DMA_Init(&hdma_rx); 00490 00491 /* NVIC configuration for DMA transfer complete interrupt */ 00492 HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 1, 0); 00493 HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn); 00494 00495 return (status != HAL_OK? SD_ERROR : SD_OK); 00496 } 00497 00498 /** 00499 * @brief SD_DMAConfigTx 00500 * @par Function Description 00501 * This function configure the DMA to transmit data to the SD card 00502 * @retval 00503 * SD_ERROR or SD_OK 00504 */ 00505 HAL_SD_ErrorTypedef SD_DMAConfigTx(SD_HandleTypeDef *hsd) 00506 { 00507 static DMA_HandleTypeDef hdma_tx; 00508 HAL_StatusTypeDef status; 00509 00510 /* Configure DMA Tx parameters */ 00511 hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; 00512 hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; 00513 hdma_tx.Init.MemInc = DMA_MINC_ENABLE; 00514 hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; 00515 hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; 00516 hdma_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH; 00517 00518 hdma_tx.Instance = DMA2_Channel4; 00519 00520 /* Associate the DMA handle */ 00521 __HAL_LINKDMA(hsd, hdmatx, hdma_tx); 00522 00523 /* Stop any ongoing transfer and reset the state*/ 00524 HAL_DMA_Abort(&hdma_tx); 00525 00526 /* Deinitialize the Channel for new transfer */ 00527 HAL_DMA_DeInit(&hdma_tx); 00528 00529 /* Configure the DMA Channel */ 00530 status = HAL_DMA_Init(&hdma_tx); 00531 00532 /* NVIC configuration for DMA transfer complete interrupt */ 00533 HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 1, 0); 00534 HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn); 00535 00536 return (status != HAL_OK? SD_ERROR : SD_OK); 00537 } 00538 00539 /** 00540 * @} 00541 */ 00542 00543 /** 00544 * @} 00545 */ 00546 00547 /** 00548 * @} 00549 */ 00550 00551 /** 00552 * @} 00553 */ 00554 00555 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 00556
Generated on Thu Aug 24 2017 17:57:47 for STM32L152D_EVAL BSP User Manual by
