STM324xG_EVAL BSP User Manual: stm324xg_eval_sd.c Source File

STM3240G / STM3241G EVAL BSP Drivers

stm324xg_eval_sd.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm324xg_eval_sd.c
00004   * @author  MCD Application Team
00005   * @version V2.2.1
00006   * @date    15-January-2016
00007   * @brief   This file includes the uSD card driver mounted on STM324xG-EVAL
00008   *          evaluation board.
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * <h2><center>&copy; COPYRIGHT(c) 2016 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 STM324xG-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 handeled 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 reay for access. The access cand 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 handeled using the function BSP_SD_IRQHandler(),
00073        the DMA Tx/Rx transfer complete are handeled 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 "stm324xg_eval_sd.h"
00084 
00085 /** @addtogroup BSP
00086   * @{
00087   */
00088 
00089 /** @addtogroup STM324xG_EVAL
00090   * @{
00091   */ 
00092   
00093 /** @defgroup STM324xG_EVAL_SD STM324xG EVAL SD
00094   * @{
00095   */ 
00096   
00097 /** @defgroup STM324xG_EVAL_SD_Private_Types_Definitions STM324xG EVAL SD Private Types Definitions
00098   * @{
00099   */ 
00100 /**
00101   * @}
00102   */ 
00103 
00104 /** @defgroup STM324xG_EVAL_SD_Private_Defines STM324xG EVAL SD Private Defines
00105   * @{
00106   */
00107 /**
00108   * @}
00109   */
00110    
00111 /** @defgroup STM324xG_EVAL_SD_Private_Macros STM324xG EVAL SD Private Macros
00112   * @{
00113   */  
00114 /**
00115   * @}
00116   */   
00117 
00118 /** @defgroup STM324xG_EVAL_SD_Private_Variables STM324xG EVAL SD Private Variables
00119   * @{
00120   */       
00121 static SD_HandleTypeDef uSdHandle;
00122 static SD_CardInfo uSdCardInfo;
00123 /**
00124   * @}
00125   */ 
00126 
00127 /** @defgroup STM324xG_EVAL_SD_Private_Function_Prototypes STM324xG EVAL SD Private Function Prototypes
00128   * @{
00129   */ 
00130 static void SD_MspInit(void);
00131 /**
00132   * @}
00133   */
00134 
00135 /** @defgroup STM324xG_EVAL_SD_Private_Functions STM324xG EVAL SD Private Functions
00136   * @{
00137   */
00138 
00139 /**
00140   * @brief  Initializes the SD card device.
00141   * @retval SD status.
00142   */
00143 uint8_t BSP_SD_Init(void)
00144 { 
00145   uint8_t SD_state = MSD_OK;
00146   
00147   /* uSD device interface configuration */
00148   uSdHandle.Instance = SDIO;
00149 
00150   uSdHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
00151   uSdHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
00152   uSdHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
00153   uSdHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
00154   uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
00155   uSdHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV;
00156   
00157   /* Check if the SD card is plugged in the slot */
00158   if(BSP_SD_IsDetected() != SD_PRESENT)
00159   {
00160     return MSD_ERROR;
00161   }
00162   
00163   /* HAL SD initialization */
00164   SD_MspInit();
00165   if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK)
00166   {
00167     SD_state = MSD_ERROR;
00168   }
00169   
00170   /* Configure SD Bus width */
00171   if(SD_state == MSD_OK)
00172   {
00173     /* Enable wide operation */
00174     if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK)
00175     {
00176       SD_state = MSD_ERROR;
00177     }
00178     else
00179     {
00180       SD_state = MSD_OK;
00181     }
00182   }
00183   
00184   return  SD_state;
00185 }
00186 
00187 /**
00188   * @brief  Configures Interrupt mode for SD detection pin.
00189   * @retval Returns 0
00190   */
00191 uint8_t BSP_SD_ITConfig(void)
00192 { 
00193   GPIO_InitTypeDef GPIO_Init_Structure;
00194   
00195   /* Configure Interrupt mode for SD detection pin */ 
00196   GPIO_Init_Structure.Mode      = GPIO_MODE_IT_RISING_FALLING;
00197   GPIO_Init_Structure.Pull      = GPIO_PULLUP;
00198   GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
00199   GPIO_Init_Structure.Pin       = SD_DETECT_PIN;
00200   HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_Init_Structure);
00201     
00202   /* NVIC configuration for SDIO interrupts */
00203   HAL_NVIC_SetPriority(SD_DETECT_IRQn, 5, 0);
00204   HAL_NVIC_EnableIRQ(SD_DETECT_IRQn);
00205   
00206   return 0;
00207 }
00208 
00209 /**
00210  * @brief  Detects if SD card is correctly plugged in the memory slot or not.
00211  * @retval Returns if SD is detected or not
00212  */
00213 uint8_t BSP_SD_IsDetected(void)
00214 {
00215   __IO uint8_t status = SD_PRESENT;
00216 
00217   /* Check SD card detect pin */
00218   if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_RESET) 
00219   {
00220     status = SD_NOT_PRESENT;
00221   }
00222   
00223   return status;
00224 }
00225 
00226 /** @brief  SD detect IT treatment
00227   */
00228 void BSP_SD_DetectIT(void)
00229 {
00230   /* SD detect IT callback */
00231   BSP_SD_DetectCallback();
00232   
00233 }
00234 
00235 
00236 /** @brief  SD detect IT detection callback
00237   */
00238 __weak void BSP_SD_DetectCallback(void)
00239 {
00240   /* NOTE: This function Should not be modified, when the callback is needed,
00241   the BSP_SD_DetectCallback could be implemented in the user file
00242   */ 
00243   
00244 }
00245 
00246 /**
00247   * @brief  Reads block(s) from a specified address in an SD card, in polling mode.
00248   * @param  pData: Pointer to the buffer that will contain the data to transmit
00249   * @param  ReadAddr: Address from where data is to be read  
00250   * @param  BlockSize: SD card data block size, that should be 512
00251   * @param  NumOfBlocks: Number of SD blocks to read 
00252   * @retval SD status
00253   */
00254 uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
00255 {
00256   if(HAL_SD_ReadBlocks(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK)
00257   {
00258     return MSD_ERROR;
00259   }
00260   else
00261   {
00262     return MSD_OK;
00263   }
00264 }
00265 
00266 /**
00267   * @brief  Writes block(s) to a specified address in an SD card, in polling mode. 
00268   * @param  pData: Pointer to the buffer that will contain the data to transmit
00269   * @param  WriteAddr: Address from where data is to be written  
00270   * @param  BlockSize: SD card data block size, that should be 512
00271   * @param  NumOfBlocks: Number of SD blocks to write
00272   * @retval SD status
00273   */
00274 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
00275 {
00276   if(HAL_SD_WriteBlocks(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK)
00277   {
00278     return MSD_ERROR;
00279   }
00280   else
00281   {
00282     return MSD_OK;
00283   }
00284 }
00285 
00286 /**
00287   * @brief  Reads block(s) from a specified address in an SD card, in DMA mode.
00288   * @param  pData: Pointer to the buffer that will contain the data to transmit
00289   * @param  ReadAddr: Address from where data is to be read  
00290   * @param  BlockSize: SD card data block size, that should be 512
00291   * @param  NumOfBlocks: Number of SD blocks to read 
00292   * @retval SD status
00293   */
00294 uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
00295 {
00296   uint8_t SD_state = MSD_OK;
00297   
00298   /* Read block(s) in DMA transfer mode */
00299   if(HAL_SD_ReadBlocks_DMA(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK)
00300   {
00301     SD_state = MSD_ERROR;
00302   }
00303   
00304   /* Wait until transfer is complete */
00305   if(SD_state == MSD_OK)
00306   {
00307     if(HAL_SD_CheckReadOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK)
00308     {
00309       SD_state = MSD_ERROR;
00310     }
00311     else
00312     {
00313       SD_state = MSD_OK;
00314     }
00315   }
00316   
00317   return SD_state; 
00318 }
00319 
00320 /**
00321   * @brief  Writes block(s) to a specified address in an SD card, in DMA mode.
00322   * @param  pData: Pointer to the buffer that will contain the data to transmit
00323   * @param  WriteAddr: Address from where data is to be written  
00324   * @param  BlockSize: SD card data block size, that should be 512
00325   * @param  NumOfBlocks: Number of SD blocks to write 
00326   * @retval SD status
00327   */
00328 uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
00329 {
00330   uint8_t SD_state = MSD_OK;
00331   
00332   /* Write block(s) in DMA transfer mode */
00333   if(HAL_SD_WriteBlocks_DMA(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK)
00334   {
00335     SD_state = MSD_ERROR;
00336   }
00337   
00338   /* Wait until transfer is complete */
00339   if(SD_state == MSD_OK)
00340   {
00341     if(HAL_SD_CheckWriteOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK)
00342     {
00343       SD_state = MSD_ERROR;
00344     }
00345     else
00346     {
00347       SD_state = MSD_OK;
00348     }
00349   }
00350   
00351   return SD_state;  
00352 }
00353 
00354 /**
00355   * @brief  Erases the specified memory area of the given SD card. 
00356   * @param  StartAddr: Start byte address
00357   * @param  EndAddr: End byte address
00358   * @retval SD status
00359   */
00360 uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr)
00361 {
00362   if(HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) != SD_OK)
00363   {
00364     return MSD_ERROR;
00365   }
00366   else
00367   {
00368     return MSD_OK;
00369   }
00370 }
00371 
00372 /**
00373   * @brief  Initializes the SD MSP.
00374   */
00375 static void SD_MspInit(void)
00376 {
00377   static DMA_HandleTypeDef dmaRxHandle;
00378   static DMA_HandleTypeDef dmaTxHandle;
00379   GPIO_InitTypeDef GPIO_Init_Structure;
00380   SD_HandleTypeDef *hsd = &uSdHandle;
00381   
00382   /* Enable SDIO clock */
00383   __SDIO_CLK_ENABLE();
00384   
00385   /* Enable DMA2 clocks */
00386   __DMAx_TxRx_CLK_ENABLE();
00387 
00388   /* Enable GPIOs clock */
00389   __GPIOC_CLK_ENABLE();
00390   __GPIOD_CLK_ENABLE();
00391   __SD_DETECT_GPIO_CLK_ENABLE();
00392   
00393   /* Common GPIO configuration */
00394   GPIO_Init_Structure.Mode      = GPIO_MODE_AF_PP;
00395   GPIO_Init_Structure.Pull      = GPIO_PULLUP;
00396   GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
00397   GPIO_Init_Structure.Alternate = GPIO_AF12_SDIO;
00398   
00399   /* GPIOC configuration */
00400   GPIO_Init_Structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
00401    
00402   HAL_GPIO_Init(GPIOC, &GPIO_Init_Structure);
00403 
00404   /* GPIOD configuration */
00405   GPIO_Init_Structure.Pin = GPIO_PIN_2;
00406   HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);
00407 
00408   /* SD Card detect pin configuration */
00409   GPIO_Init_Structure.Mode      = GPIO_MODE_INPUT;
00410   GPIO_Init_Structure.Pull      = GPIO_PULLUP;
00411   GPIO_Init_Structure.Speed     = GPIO_SPEED_HIGH;
00412   GPIO_Init_Structure.Pin       = SD_DETECT_PIN;
00413   HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_Init_Structure);
00414     
00415   /* NVIC configuration for SDIO interrupts */
00416   HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0);
00417   HAL_NVIC_EnableIRQ(SDIO_IRQn);
00418     
00419   /* Configure DMA Rx parameters */
00420   dmaRxHandle.Init.Channel             = SD_DMAx_Rx_CHANNEL;
00421   dmaRxHandle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
00422   dmaRxHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
00423   dmaRxHandle.Init.MemInc              = DMA_MINC_ENABLE;
00424   dmaRxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00425   dmaRxHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00426   dmaRxHandle.Init.Mode                = DMA_PFCTRL;
00427   dmaRxHandle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
00428   dmaRxHandle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
00429   dmaRxHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00430   dmaRxHandle.Init.MemBurst            = DMA_MBURST_INC4;
00431   dmaRxHandle.Init.PeriphBurst         = DMA_PBURST_INC4;
00432   
00433   dmaRxHandle.Instance = SD_DMAx_Rx_STREAM;
00434   
00435   /* Associate the DMA handle */
00436   __HAL_LINKDMA(hsd, hdmarx, dmaRxHandle);
00437   
00438   /* Deinitialize the stream for new transfer */
00439   HAL_DMA_DeInit(&dmaRxHandle);
00440   
00441   /* Configure the DMA stream */
00442   HAL_DMA_Init(&dmaRxHandle);
00443   
00444   /* Configure DMA Tx parameters */
00445   dmaTxHandle.Init.Channel             = SD_DMAx_Tx_CHANNEL;
00446   dmaTxHandle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
00447   dmaTxHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
00448   dmaTxHandle.Init.MemInc              = DMA_MINC_ENABLE;
00449   dmaTxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00450   dmaTxHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00451   dmaTxHandle.Init.Mode                = DMA_PFCTRL;
00452   dmaTxHandle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
00453   dmaTxHandle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
00454   dmaTxHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00455   dmaTxHandle.Init.MemBurst            = DMA_MBURST_INC4;
00456   dmaTxHandle.Init.PeriphBurst         = DMA_PBURST_INC4;
00457   
00458   dmaTxHandle.Instance = SD_DMAx_Tx_STREAM;
00459   
00460   /* Associate the DMA handle */
00461   __HAL_LINKDMA(hsd, hdmatx, dmaTxHandle);
00462   
00463   /* Deinitialize the stream for new transfer */
00464   HAL_DMA_DeInit(&dmaTxHandle);
00465   
00466   /* Configure the DMA stream */
00467   HAL_DMA_Init(&dmaTxHandle); 
00468   
00469   /* NVIC configuration for DMA transfer complete interrupt */
00470   HAL_NVIC_SetPriority(SD_DMAx_Rx_IRQn, 6, 0);
00471   HAL_NVIC_EnableIRQ(SD_DMAx_Rx_IRQn);
00472   
00473   /* NVIC configuration for DMA transfer complete interrupt */
00474   HAL_NVIC_SetPriority(SD_DMAx_Tx_IRQn, 6, 0);
00475   HAL_NVIC_EnableIRQ(SD_DMAx_Tx_IRQn);
00476 }
00477 
00478 /**
00479   * @brief  Handles SD card interrupt request.
00480   */
00481 void BSP_SD_IRQHandler(void)
00482 {
00483   HAL_SD_IRQHandler(&uSdHandle);
00484 }
00485 
00486 /**
00487   * @brief  Handles SD DMA Tx transfer interrupt request.
00488   */
00489 void BSP_SD_DMA_Tx_IRQHandler(void)
00490 {
00491   HAL_DMA_IRQHandler(uSdHandle.hdmatx); 
00492 }
00493 
00494 /**
00495   * @brief  Handles SD DMA Rx transfer interrupt request.
00496   */
00497 void BSP_SD_DMA_Rx_IRQHandler(void)
00498 {
00499   HAL_DMA_IRQHandler(uSdHandle.hdmarx);
00500 }
00501 
00502 /**
00503   * @brief  Gets the current SD card data status.
00504   * @retval Data transfer state.
00505   *          This value can be one of the following values:
00506   *            @arg  SD_TRANSFER_OK: No data transfer is acting
00507   *            @arg  SD_TRANSFER_BUSY: Data transfer is acting
00508   *            @arg  SD_TRANSFER_ERROR: Data transfer error 
00509   */
00510 HAL_SD_TransferStateTypedef BSP_SD_GetStatus(void)
00511 {
00512   return(HAL_SD_GetStatus(&uSdHandle));
00513 }
00514 
00515 /**
00516   * @brief  Get SD information about specific SD card.
00517   * @param  CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
00518   */
00519 void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo)
00520 {
00521   /* Get SD card Information */
00522   HAL_SD_Get_CardInfo(&uSdHandle, CardInfo);
00523 }
00524 
00525 /**
00526   * @}
00527   */  
00528 
00529 /**
00530   * @}
00531   */ 
00532 
00533 /**
00534   * @}
00535   */ 
00536 
00537 /**
00538   * @}
00539   */ 
00540 
00541 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Jan 15 2016 14:22:29 for STM324xG_EVAL BSP User Manual by   doxygen 1.7.6.1