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