STM324x9I_EVAL BSP User Manual: stm324x9i_eval_sd.c Source File

STM32429I/STM32439I/STM32469I/STM32479I EVAL BSP Drivers

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>&copy; 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 1.7.6.1