STM3210E_EVAL 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 V6.0.2 00006 * @date 29-April-2016 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) 2016 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_EVAL_SD_Private_Variables STM3210E EVAL SD Private Variables 00095 * @{ 00096 */ 00097 SD_HandleTypeDef uSdHandle; 00098 static SD_CardInfo uSdCardInfo; 00099 /** 00100 * @} 00101 */ 00102 00103 /** @defgroup STM3210E_EVAL_SD_Private_Functions STM3210E EVAL SD 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_EVAL_SD_Exported_Functions STM3210E EVAL SD 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_FREQ_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, 0xE, 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 */ 00207 void BSP_SD_DetectIT(void) 00208 { 00209 /* SD detect IT callback */ 00210 BSP_SD_DetectCallback(); 00211 00212 } 00213 00214 00215 /** @brief SD detect IT detection callback 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 */ 00361 void BSP_SD_DMA_Tx_IRQHandler(void) 00362 { 00363 HAL_DMA_IRQHandler(uSdHandle.hdmatx); 00364 } 00365 00366 /** 00367 * @brief Handles SD DMA Rx transfer interrupt request. 00368 */ 00369 void BSP_SD_DMA_Rx_IRQHandler(void) 00370 { 00371 HAL_DMA_IRQHandler(uSdHandle.hdmarx); 00372 } 00373 00374 /** 00375 * @brief Gets the current SD card data status. 00376 * @retval Data transfer state. 00377 * This value can be one of the following values: 00378 * @arg SD_TRANSFER_OK: No data transfer is acting 00379 * @arg SD_TRANSFER_BUSY: Data transfer is acting 00380 * @arg SD_TRANSFER_ERROR: Data transfer error 00381 */ 00382 HAL_SD_TransferStateTypedef BSP_SD_GetStatus(void) 00383 { 00384 return(HAL_SD_GetStatus(&uSdHandle)); 00385 } 00386 00387 /** 00388 * @brief Get SD information about specific SD card. 00389 * @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure 00390 */ 00391 void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo) 00392 { 00393 /* Get SD card Information */ 00394 HAL_SD_Get_CardInfo(&uSdHandle, CardInfo); 00395 } 00396 00397 /** 00398 * @} 00399 */ 00400 00401 00402 /** @addtogroup STM3210E_EVAL_SD_Private_Functions 00403 * @{ 00404 */ 00405 00406 /** 00407 * @brief Initializes the SD MSP. 00408 * @retval None 00409 */ 00410 static void SD_MspInit(void) 00411 { 00412 GPIO_InitTypeDef gpioinitstruct = {0}; 00413 00414 /* Enable SDIO clock */ 00415 __HAL_RCC_SDIO_CLK_ENABLE(); 00416 00417 /* Enable DMA2 clocks */ 00418 __DMAx_TxRx_CLK_ENABLE(); 00419 00420 /* Enable GPIOs clock */ 00421 __HAL_RCC_GPIOC_CLK_ENABLE(); 00422 __HAL_RCC_GPIOD_CLK_ENABLE(); 00423 __SD_DETECT_GPIO_CLK_ENABLE(); 00424 00425 /* Common GPIO configuration */ 00426 gpioinitstruct.Mode = GPIO_MODE_AF_PP; 00427 gpioinitstruct.Pull = GPIO_PULLUP; 00428 gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH; 00429 00430 /* GPIOC configuration */ 00431 gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; 00432 00433 HAL_GPIO_Init(GPIOC, &gpioinitstruct); 00434 00435 /* GPIOD configuration */ 00436 gpioinitstruct.Pin = GPIO_PIN_2; 00437 HAL_GPIO_Init(GPIOD, &gpioinitstruct); 00438 00439 /* SD Card detect pin configuration */ 00440 gpioinitstruct.Mode = GPIO_MODE_INPUT; 00441 gpioinitstruct.Pull = GPIO_PULLUP; 00442 gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH; 00443 gpioinitstruct.Pin = SD_DETECT_PIN; 00444 HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpioinitstruct); 00445 00446 /* NVIC configuration for SDIO interrupts */ 00447 HAL_NVIC_SetPriority(SDIO_IRQn, 0xC, 0); 00448 HAL_NVIC_EnableIRQ(SDIO_IRQn); 00449 00450 /* 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*/ 00451 } 00452 00453 /** 00454 * @brief SD_DMAConfigRx 00455 * @par Function Description 00456 * This function configure the DMA to receive data from the SD card 00457 * @retval 00458 * SD_ERROR or SD_OK 00459 */ 00460 HAL_SD_ErrorTypedef SD_DMAConfigRx(SD_HandleTypeDef *hsd) 00461 { 00462 static DMA_HandleTypeDef hdma_rx; 00463 HAL_StatusTypeDef status = HAL_ERROR; 00464 00465 if(hsd->hdmarx == NULL) 00466 { 00467 /* Configure DMA Rx parameters */ 00468 hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; 00469 hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; 00470 hdma_rx.Init.MemInc = DMA_MINC_ENABLE; 00471 hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; 00472 hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; 00473 hdma_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; 00474 00475 hdma_rx.Instance = SD_DMAx_Rx_INSTANCE; 00476 00477 /* Associate the DMA handle */ 00478 __HAL_LINKDMA(hsd, hdmarx, hdma_rx); 00479 00480 /* Stop any ongoing transfer and reset the state*/ 00481 HAL_DMA_Abort(&hdma_rx); 00482 00483 /* Deinitialize the Channel for new transfer */ 00484 HAL_DMA_DeInit(&hdma_rx); 00485 00486 /* Configure the DMA Channel */ 00487 status = HAL_DMA_Init(&hdma_rx); 00488 00489 /* NVIC configuration for DMA transfer complete interrupt */ 00490 HAL_NVIC_SetPriority(SD_DMAx_Rx_IRQn, 0xD, 0); 00491 HAL_NVIC_EnableIRQ(SD_DMAx_Rx_IRQn); 00492 } 00493 else 00494 { 00495 status = HAL_OK; 00496 } 00497 00498 return (status != HAL_OK? SD_ERROR : SD_OK); 00499 } 00500 00501 /** 00502 * @brief SD_DMAConfigTx 00503 * @par Function Description 00504 * This function configure the DMA to transmit data to the SD card 00505 * @retval 00506 * SD_ERROR or SD_OK 00507 */ 00508 HAL_SD_ErrorTypedef SD_DMAConfigTx(SD_HandleTypeDef *hsd) 00509 { 00510 static DMA_HandleTypeDef hdma_tx; 00511 HAL_StatusTypeDef status; 00512 00513 if(hsd->hdmatx == NULL) 00514 { 00515 /* Configure DMA Tx parameters */ 00516 hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; 00517 hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; 00518 hdma_tx.Init.MemInc = DMA_MINC_ENABLE; 00519 hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; 00520 hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; 00521 hdma_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH; 00522 00523 hdma_tx.Instance = SD_DMAx_Tx_INSTANCE; 00524 00525 /* Associate the DMA handle */ 00526 __HAL_LINKDMA(hsd, hdmatx, hdma_tx); 00527 00528 /* Stop any ongoing transfer and reset the state*/ 00529 HAL_DMA_Abort(&hdma_tx); 00530 00531 /* Deinitialize the Channel for new transfer */ 00532 HAL_DMA_DeInit(&hdma_tx); 00533 00534 /* Configure the DMA Channel */ 00535 status = HAL_DMA_Init(&hdma_tx); 00536 00537 /* NVIC configuration for DMA transfer complete interrupt */ 00538 HAL_NVIC_SetPriority(SD_DMAx_Tx_IRQn, 0xD, 0); 00539 HAL_NVIC_EnableIRQ(SD_DMAx_Tx_IRQn); 00540 } 00541 else 00542 { 00543 status = HAL_OK; 00544 } 00545 00546 return (status != HAL_OK? SD_ERROR : SD_OK); 00547 } 00548 00549 /** 00550 * @} 00551 */ 00552 00553 /** 00554 * @} 00555 */ 00556 00557 /** 00558 * @} 00559 */ 00560 00561 /** 00562 * @} 00563 */ 00564 00565 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Feb 24 2017 17:15:11 for STM3210E_EVAL BSP User Manual by 1.7.6.1