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