STM32769I_EVAL BSP User Manual: stm32f769i_eval_sd.c Source File

STM32769I EVAL BSP Drivers

stm32f769i_eval_sd.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f769i_eval_sd.c
00004   * @author  MCD Application Team
00005   * @version V2.0.0
00006   * @date    30-December-2016
00007   * @brief   This file includes the uSD card driver mounted on STM32F769I-EVAL 
00008   *          evaluation boards.
00009   @verbatim
00010   How To use this driver:
00011   -----------------------
00012    - This driver is used to drive the micro SD external cards mounted on STM32F769I-EVAL
00013      evaluation board.
00014    - This driver does not need a specific component driver for the micro SD device
00015      to be included with.
00016 
00017   Driver description:
00018   ------------------
00019   + Initialization steps:
00020      o Initialize the micro SD card using the BSP_SD_InitEx() function. This 
00021        function includes the MSP layer hardware resources initialization and the
00022        SDIO interface configuration to interface with the external micro SD. It 
00023        also includes the micro SD initialization sequence for SDCard1 or SDCard2.
00024        When BSP_SD_Init() is called, SDCard1 is by default initialized.
00025      o To check the SD card presence you can use the function BSP_SD_IsDetectedEx() which 
00026        returns the detection status for SDCard1 or SDCard2.
00027        the function BSP_SD_IsDetected() returns the detection status for SDCard1.
00028      o If SD presence detection interrupt mode is desired, you must configure the 
00029        SD detection interrupt mode by calling the functions BSP_SD_ITConfig() for
00030        SDCard1 or BSP_SD_ITConfigEx() for SDCard2 . The interrupt is generated as 
00031        an external interrupt whenever the micro SD card is plugged/unplugged
00032        in/from the evaluation board. The SD detection is managed by MFX, so the 
00033        SD detection interrupt has to be treated by MFX_IRQOUT gpio pin IRQ handler.
00034      o The function BSP_SD_GetCardInfo()/BSP_SD_GetCardInfoEx() are used to get 
00035        the micro SD card information which is stored in the structure 
00036        "HAL_SD_CardInfoTypedef".
00037 
00038   + Micro SD card operations
00039      o The micro SD card can be accessed with read/write block(s) operations once 
00040        it is ready for access. The access, by default to SDCard1, can be performed whether 
00041        using the polling mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(),  
00042        or by DMA transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA().
00043        The access can be performed to SDCard1 or SDCard2 by calling BSP_SD_ReadBlocksEx(),
00044        BSP_SD_WriteBlocksEx() or by calling BSP_SD_ReadBlocks_DMAEx()/BSP_SD_WriteBlocks_DMAEx().
00045      o The DMA transfer complete is used with interrupt mode. Once the SD transfer
00046        is complete, the SD interrupt is handled using the function BSP_SDMMC1_IRQHandler()
00047        when SDCard1 is used or BSP_SDMMC2_IRQHandler() when SDCard2 is used.
00048        The DMA Tx/Rx transfer complete are handled using the functions
00049        BSP_SDMMC1_DMA_Tx_IRQHandler(), BSP_SDMMC1_DMA_Rx_IRQHandler(), 
00050        BSP_SDMMC2_DMA_Tx_IRQHandler(), BSP_SDMMC2_DMA_Rx_IRQHandler(). The corresponding
00051        user callbacks are implemented by the user at application level. 
00052      o The SD erase block(s) is performed using the functions BSP_SD_Erase()/BSP_SD_EraseEx() 
00053        with specifying the number of blocks to erase.
00054      o The SD runtime status is returned when calling the function BSP_SD_GetCardState()
00055        BSP_SD_GetCardStateEx().
00056 
00057   @endverbatim
00058   ******************************************************************************
00059   * @attention
00060   *
00061   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00062   *
00063   * Redistribution and use in source and binary forms, with or without modification,
00064   * are permitted provided that the following conditions are met:
00065   *   1. Redistributions of source code must retain the above copyright notice,
00066   *      this list of conditions and the following disclaimer.
00067   *   2. Redistributions in binary form must reproduce the above copyright notice,
00068   *      this list of conditions and the following disclaimer in the documentation
00069   *      and/or other materials provided with the distribution.
00070   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00071   *      may be used to endorse or promote products derived from this software
00072   *      without specific prior written permission.
00073   *
00074   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00075   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00076   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00077   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00078   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00079   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00080   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00081   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00082   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00083   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00084   *
00085   ******************************************************************************
00086   */ 
00087 
00088 /* Includes ------------------------------------------------------------------*/
00089 #include "stm32f769i_eval_sd.h"
00090 
00091 /** @addtogroup BSP
00092   * @{
00093   */
00094 
00095 /** @addtogroup STM32F769I_EVAL
00096   * @{
00097   */ 
00098   
00099 /** @defgroup STM32F769I_EVAL_SD STM32F769I_EVAL SD
00100   * @{
00101   */ 
00102 
00103 
00104 /** @defgroup STM32F769I_EVAL_SD_Private_TypesDefinitions SD Private TypesDefinitions
00105   * @{
00106   */
00107 /**
00108   * @}
00109   */ 
00110 
00111 /** @defgroup STM32F769I_EVAL_SD_Private_Defines SD Private Defines
00112   * @{
00113   */
00114 /**
00115   * @}
00116   */ 
00117   
00118 /** @defgroup STM32F769I_EVAL_SD_Private_Macros SD Private Macros
00119   * @{
00120   */    
00121 /**
00122   * @}
00123   */  
00124 
00125 /** @defgroup STM32F769I_EVAL_SD_Private_Variables SD Private Variables
00126   * @{
00127   */
00128 SD_HandleTypeDef uSdHandle;
00129 SD_HandleTypeDef uSdHandle2;
00130 static uint8_t UseExtiModeDetection = 0;
00131 
00132 /**
00133   * @}
00134   */ 
00135   
00136 /** @defgroup STM32F769I_EVAL_SD_Private_Functions_Prototypes SD Private Functions Prototypes
00137   * @{
00138   */
00139 /**
00140   * @}
00141   */ 
00142   
00143 /** @defgroup STM32F769I_EVAL_SD_Private_Functions SD Private Functions
00144   * @{
00145   */
00146 
00147 /**
00148   * @brief  Initializes the SD card device.
00149   * @retval SD status
00150   */
00151 uint8_t BSP_SD_Init(void)
00152 { 
00153   /* By default, initialize SDMMC1 */
00154   return BSP_SD_InitEx(SD_CARD1);
00155 }
00156 
00157 /**
00158   * @brief  Initializes the SD card device.
00159   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2 
00160   * @retval SD status
00161   */
00162 uint8_t BSP_SD_InitEx(uint32_t SdCard)
00163 { 
00164   uint8_t sd_state = MSD_OK;
00165   
00166   /* uSD device interface configuration */
00167   if(SdCard == SD_CARD1)
00168   {  
00169     uSdHandle.Instance = SDMMC1;
00170     uSdHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
00171     uSdHandle.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
00172     uSdHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
00173     uSdHandle.Init.BusWide             = SDMMC_BUS_WIDE_1B;
00174     uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
00175     uSdHandle.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;
00176   }
00177   else
00178   {
00179     uSdHandle2.Instance = SDMMC2;
00180     uSdHandle2.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
00181     uSdHandle2.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
00182     uSdHandle2.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
00183     uSdHandle2.Init.BusWide             = SDMMC_BUS_WIDE_1B;
00184     uSdHandle2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
00185     uSdHandle2.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;   
00186   }
00187   /* Initialize IO functionalities (MFX) used by SD detect pin */
00188   BSP_IO_Init(); 
00189   
00190   /* Check if the SD card is plugged in the slot */
00191   if(SdCard == SD_CARD1)
00192   {
00193     BSP_IO_ConfigPin(SD1_DETECT_PIN, IO_MODE_INPUT_PU);
00194     
00195     if(BSP_SD_IsDetected() != SD_PRESENT)
00196     {
00197       return MSD_ERROR_SD_NOT_PRESENT;
00198     }
00199     
00200     /* Msp SD initialization */
00201     BSP_SD_MspInit(&uSdHandle, NULL);
00202     
00203     /* HAL SD initialization */
00204     if(HAL_SD_Init(&uSdHandle) != HAL_OK)
00205     {
00206       sd_state = MSD_ERROR;
00207     }  
00208   }
00209   else
00210   {
00211     BSP_IO_ConfigPin(SD2_DETECT_PIN, IO_MODE_INPUT_PU);
00212     
00213     if(BSP_SD_IsDetectedEx(SD_CARD2) != SD_PRESENT)
00214     {
00215       return MSD_ERROR_SD_NOT_PRESENT;
00216     }
00217     /* Msp SD initialization */
00218     BSP_SD_MspInit(&uSdHandle2, NULL);
00219     
00220     /* HAL SD initialization */
00221     if(HAL_SD_Init(&uSdHandle2) != HAL_OK)
00222     {
00223       sd_state = MSD_ERROR;
00224     }    
00225   }
00226   
00227   
00228   /* Configure SD Bus width */
00229   if(sd_state == MSD_OK)
00230   {
00231     if(SdCard == SD_CARD1)
00232     {    
00233       /* Enable wide operation */
00234       sd_state = HAL_SD_ConfigWideBusOperation(&uSdHandle, SDMMC_BUS_WIDE_4B); 
00235     }
00236     else
00237     {
00238       /* Enable wide operation */    
00239       sd_state = HAL_SD_ConfigWideBusOperation(&uSdHandle2, SDMMC_BUS_WIDE_4B);
00240     }
00241     if(sd_state != HAL_OK)
00242     {
00243       sd_state = MSD_ERROR;
00244     }
00245     else
00246     {
00247       sd_state = MSD_OK;
00248     }
00249   }
00250   
00251   return  sd_state;
00252 }
00253 
00254 
00255 /**
00256   * @brief  DeInitializes the SD card device.
00257   * @retval SD status
00258   */
00259 uint8_t BSP_SD_DeInit(void)
00260 {
00261   /* By default, DeInitialize SDMMC1 */
00262   return BSP_SD_DeInitEx(SD_CARD1);
00263 }
00264 
00265 /**
00266   * @brief  DeInitializes the SD card device.
00267   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2 
00268   * @retval SD status
00269   */
00270 uint8_t BSP_SD_DeInitEx(uint32_t SdCard)
00271 { 
00272   uint8_t sd_state = MSD_OK;
00273   
00274   /* Set back Mfx pin to INPUT mode in case it was in exti */
00275   UseExtiModeDetection = 0;
00276   if(SdCard == SD_CARD1)
00277   {
00278     uSdHandle.Instance = SDMMC1;    
00279     /* HAL SD deinitialization */
00280     if(HAL_SD_DeInit(&uSdHandle) != HAL_OK)
00281     {
00282       sd_state = MSD_ERROR;
00283     }
00284     
00285     /* Msp SD deinitialization */
00286     BSP_SD_MspDeInit(&uSdHandle, NULL);    
00287     BSP_IO_ConfigPin(SD1_DETECT_PIN, IO_MODE_INPUT_PU);
00288   }
00289   else
00290   {
00291     uSdHandle2.Instance = SDMMC2;    
00292     BSP_IO_ConfigPin(SD2_DETECT_PIN, IO_MODE_INPUT_PU); 
00293     
00294     /* HAL SD deinitialization */
00295     if(HAL_SD_DeInit(&uSdHandle2) != HAL_OK)
00296     {
00297       sd_state = MSD_ERROR;
00298     }
00299     
00300     /* Msp SD deinitialization */
00301     BSP_SD_MspDeInit(&uSdHandle2, NULL);
00302   }  
00303   return  sd_state;
00304 }
00305 
00306 /**
00307   * @brief  Configures Interrupt mode for SD1 detection pin.
00308   * @retval Returns 0
00309   */
00310 uint8_t BSP_SD_ITConfig(void)
00311 {  
00312   /* Configure Interrupt mode for SD1 detection pin */  
00313   /* Note: disabling exti mode can be done calling BSP_SD_DeInit() */
00314   UseExtiModeDetection = 1;  
00315   BSP_SD_IsDetected();
00316 
00317   return 0;
00318 }
00319 
00320 /**
00321   * @brief  Configures Interrupt mode for SD detection pin.
00322   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2
00323   * @retval Returns 0
00324   */
00325 uint8_t BSP_SD_ITConfigEx(uint32_t SdCard)
00326 {  
00327   /* Configure Interrupt mode for SD2 detection pin */  
00328   /* Note: disabling exti mode can be done calling BSP_SD_DeInitEx(SD_CARD2) */
00329   UseExtiModeDetection = 1;  
00330   BSP_SD_IsDetectedEx(SdCard);
00331 
00332   return 0;
00333 }
00334 
00335 /**
00336  * @brief  Detects if SD card is correctly plugged in the memory slot or not.
00337  * @retval Returns if SD is detected or not
00338  */
00339 uint8_t BSP_SD_IsDetected(void)
00340 {
00341   return BSP_SD_IsDetectedEx(SD_CARD1);
00342 }
00343 
00344 /**
00345  * @brief  Detects if SD card is correctly plugged in the memory slot or not.
00346  * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2 
00347  * @retval Returns if SD is detected or not
00348  */
00349 uint8_t BSP_SD_IsDetectedEx(uint32_t SdCard)
00350 {
00351   __IO uint8_t status = SD_PRESENT;
00352   
00353   if(SdCard == SD_CARD1)
00354   {
00355     /* Check SD card detect pin */
00356     if((BSP_IO_ReadPin(SD1_DETECT_PIN)&SD1_DETECT_PIN) != SD1_DETECT_PIN)
00357     {
00358       if (UseExtiModeDetection)
00359       {
00360         BSP_IO_ConfigPin(SD1_DETECT_PIN, IO_MODE_IT_RISING_EDGE_PU);
00361       }
00362     }
00363     else
00364     {
00365       status = SD_NOT_PRESENT;
00366       if (UseExtiModeDetection)
00367       {
00368         BSP_IO_ConfigPin(SD1_DETECT_PIN, IO_MODE_IT_FALLING_EDGE_PU);
00369       }
00370     }
00371   }
00372   else
00373   {
00374     /* Check SD card detect pin */
00375     if((BSP_IO_ReadPin(SD2_DETECT_PIN)&SD2_DETECT_PIN) != SD2_DETECT_PIN)
00376     {
00377       if (UseExtiModeDetection)
00378       {
00379         BSP_IO_ConfigPin(SD2_DETECT_PIN, IO_MODE_IT_RISING_EDGE_PU);
00380       }
00381     }
00382     else
00383     {
00384       status = SD_NOT_PRESENT;
00385       if (UseExtiModeDetection)
00386       {
00387         BSP_IO_ConfigPin(SD2_DETECT_PIN, IO_MODE_IT_FALLING_EDGE_PU);
00388       }
00389     }    
00390   }
00391   return status;
00392 }
00393 
00394 /**
00395   * @brief  Reads block(s) from a specified address in an SD card, in polling mode.
00396   * @param  pData: Pointer to the buffer that will contain the data to transmit
00397   * @param  ReadAddr: Address from where data is to be read
00398   * @param  NumOfBlocks: Number of SD blocks to read
00399   * @param  Timeout: Timeout for read operation
00400   * @retval SD status
00401   */
00402 uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00403 {
00404   return BSP_SD_ReadBlocksEx(SD_CARD1, pData, ReadAddr, NumOfBlocks, Timeout);
00405 }
00406 
00407 /**
00408   * @brief  Reads block(s) from a specified address in an SD card, in polling mode.
00409   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2 
00410   * @param  pData: Pointer to the buffer that will contain the data to transmit
00411   * @param  ReadAddr: Address from where data is to be read  
00412   * @param  NumOfBlocks: Number of SD blocks to read
00413   * @param  Timeout: Timeout for read operation
00414   * @retval SD status
00415   */
00416 uint8_t BSP_SD_ReadBlocksEx(uint32_t SdCard, uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00417 {
00418   HAL_StatusTypeDef  sd_state = HAL_OK;
00419   
00420   if(SdCard == SD_CARD1)
00421   {
00422     sd_state = HAL_SD_ReadBlocks(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout);
00423   }
00424   else
00425   {
00426     sd_state = HAL_SD_ReadBlocks(&uSdHandle2, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout);
00427   }
00428   
00429   if( sd_state == HAL_OK)
00430   {
00431     return MSD_OK;
00432   }
00433   else
00434   {
00435     return MSD_ERROR;
00436   }
00437 }
00438 
00439 /**
00440   * @brief  Writes block(s) to a specified address in an SD card, in polling mode. 
00441   * @param  pData: Pointer to the buffer that will contain the data to transmit
00442   * @param  WriteAddr: Address from where data is to be written
00443   * @param  NumOfBlocks: Number of SD blocks to write
00444   * @param  Timeout: Timeout for write operation
00445   * @retval SD status
00446   */
00447 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00448 {
00449     return BSP_SD_WriteBlocksEx(SD_CARD1, pData, WriteAddr, NumOfBlocks, Timeout);
00450 }
00451 
00452 /**
00453   * @brief  Writes block(s) to a specified address in an SD card, in polling mode.
00454   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2
00455   * @param  pData: Pointer to the buffer that will contain the data to transmit
00456   * @param  WriteAddr: Address from where data is to be written  
00457   * @param  NumOfBlocks: Number of SD blocks to write
00458   * @param  Timeout: Timeout for write operation
00459   * @retval SD status
00460   */
00461 uint8_t BSP_SD_WriteBlocksEx(uint32_t SdCard, uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
00462 {
00463   HAL_StatusTypeDef  sd_state = HAL_OK;
00464   
00465   if(SdCard == SD_CARD1)
00466   {
00467     sd_state = HAL_SD_WriteBlocks(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout);
00468   }
00469   else
00470   {
00471     sd_state = HAL_SD_WriteBlocks(&uSdHandle2, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout);
00472   }
00473   
00474   if( sd_state == HAL_OK)
00475   {
00476     return MSD_OK;
00477   }
00478   else
00479   {
00480     return MSD_ERROR;
00481   }  
00482 }
00483 
00484 /**
00485   * @brief  Reads block(s) from a specified address in an SD card, in DMA mode.
00486   * @param  pData: Pointer to the buffer that will contain the data to transmit
00487   * @param  ReadAddr: Address from where data is to be read
00488   * @param  NumOfBlocks: Number of SD blocks to read 
00489   * @retval SD status
00490   */
00491 uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
00492 {
00493   return BSP_SD_ReadBlocks_DMAEx(SD_CARD1, pData, ReadAddr, NumOfBlocks);
00494 }
00495 
00496 /**
00497   * @brief  Reads block(s) from a specified address in an SD card, in DMA mode.
00498   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2
00499   * @param  pData: Pointer to the buffer that will contain the data to transmit
00500   * @param  ReadAddr: Address from where data is to be read
00501   * @param  NumOfBlocks: Number of SD blocks to read 
00502   * @retval SD status
00503   */
00504 uint8_t BSP_SD_ReadBlocks_DMAEx(uint32_t SdCard, uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
00505 {
00506   HAL_StatusTypeDef  sd_state = HAL_OK;
00507   
00508   if(SdCard == SD_CARD1)
00509   {
00510     /* Read block(s) in DMA transfer mode */
00511     sd_state = HAL_SD_ReadBlocks_DMA(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks);
00512   }
00513   else
00514   {
00515     /* Read block(s) in DMA transfer mode */
00516     sd_state = HAL_SD_ReadBlocks_DMA(&uSdHandle2, (uint8_t *)pData, ReadAddr, NumOfBlocks);
00517   }
00518   
00519   if( sd_state == HAL_OK)
00520   {
00521     return MSD_OK;
00522   }
00523   else
00524   {
00525     return MSD_ERROR;
00526   }
00527 }
00528 
00529 /**
00530   * @brief  Writes block(s) to a specified address in an SD card, in DMA mode.
00531   * @param  pData: Pointer to the buffer that will contain the data to transmit
00532   * @param  WriteAddr: Address from where data is to be written
00533   * @param  NumOfBlocks: Number of SD blocks to write 
00534   * @retval SD status
00535   */
00536 uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
00537 {
00538   return BSP_SD_WriteBlocks_DMAEx(SD_CARD1, pData, WriteAddr, NumOfBlocks);
00539 }
00540 
00541 /**
00542   * @brief  Writes block(s) to a specified address in an SD card, in DMA mode.
00543   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2
00544   * @param  pData: Pointer to the buffer that will contain the data to transmit
00545   * @param  WriteAddr: Address from where data is to be written
00546   * @param  NumOfBlocks: Number of SD blocks to write 
00547   * @retval SD status
00548   */
00549 uint8_t BSP_SD_WriteBlocks_DMAEx(uint32_t SdCard, uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
00550 {
00551   HAL_StatusTypeDef  sd_state = HAL_OK;
00552   
00553   if(SdCard == SD_CARD1)
00554   {  
00555     /* Write block(s) in DMA transfer mode */
00556     sd_state = HAL_SD_WriteBlocks_DMA(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks);
00557   }
00558   else
00559   {
00560     /* Write block(s) in DMA transfer mode */ 
00561     sd_state = HAL_SD_WriteBlocks_DMA(&uSdHandle2, (uint8_t *)pData, WriteAddr, NumOfBlocks);
00562   }
00563   
00564   if( sd_state == HAL_OK)
00565   {
00566     return MSD_OK;
00567   }
00568   else
00569   {
00570     return MSD_ERROR;
00571   }
00572 }
00573 
00574 /**
00575   * @brief  Erases the specified memory area of the given SD card. 
00576   * @param  StartAddr: Start byte address
00577   * @param  EndAddr: End byte address
00578   * @retval SD status
00579   */
00580 uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr)
00581 {
00582   return BSP_SD_EraseEx(SD_CARD1, StartAddr, EndAddr);
00583 }
00584 
00585 /**
00586   * @brief  Erases the specified memory area of the given SD card. 
00587   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2
00588   * @param  StartAddr: Start byte address
00589   * @param  EndAddr: End byte address
00590   * @retval SD status
00591   */
00592 uint8_t BSP_SD_EraseEx(uint32_t SdCard, uint32_t StartAddr, uint32_t EndAddr)
00593 {
00594   HAL_StatusTypeDef  sd_state = HAL_OK;
00595   
00596   if(SdCard == SD_CARD1)
00597   {
00598     sd_state = HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr);
00599   }
00600   else
00601   {
00602     sd_state = HAL_SD_Erase(&uSdHandle2, StartAddr, EndAddr); 
00603   }
00604 
00605   if( sd_state == HAL_OK)
00606   {
00607     return MSD_OK;
00608   }
00609   else
00610   {
00611     return MSD_ERROR;
00612   } 
00613 }
00614 
00615 /**
00616   * @brief  Initializes the SD MSP.
00617   * @param  hsd: SD handle
00618   * @param  Params  
00619   * @retval None
00620   */
00621 __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params)
00622 {
00623   static DMA_HandleTypeDef dma_rx_handle;
00624   static DMA_HandleTypeDef dma_tx_handle;
00625   static DMA_HandleTypeDef dma_rx_handle2;
00626   static DMA_HandleTypeDef dma_tx_handle2;  
00627   GPIO_InitTypeDef gpio_init_structure;
00628   
00629   /* Camera has to be powered down as some signals use same GPIOs between 
00630   * SD card and camera bus. Camera drives its signals to low impedance 
00631   * when powered ON. So the camera is powered off to let its signals
00632   * in high impedance */
00633   
00634   /* Camera power down sequence */
00635   BSP_IO_ConfigPin(RSTI_PIN, IO_MODE_OUTPUT);
00636   BSP_IO_ConfigPin(XSDN_PIN, IO_MODE_OUTPUT);
00637   /* De-assert the camera STANDBY pin (active high) */
00638   BSP_IO_WritePin(XSDN_PIN, BSP_IO_PIN_RESET);
00639   /* Assert the camera RSTI pin (active low) */
00640   BSP_IO_WritePin(RSTI_PIN, BSP_IO_PIN_RESET);
00641   if(hsd->Instance == SDMMC1)
00642   {
00643     /* Enable SDIO clock */
00644     __HAL_RCC_SDMMC1_CLK_ENABLE();
00645     
00646     /* Enable DMA2 clocks */
00647     __DMAx_TxRx_CLK_ENABLE();
00648     
00649     /* Enable GPIOs clock */
00650     __HAL_RCC_GPIOC_CLK_ENABLE();
00651     __HAL_RCC_GPIOD_CLK_ENABLE();
00652     
00653     /* Common GPIO configuration */
00654     gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00655     gpio_init_structure.Pull      = GPIO_PULLUP;
00656     gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
00657     gpio_init_structure.Alternate = GPIO_AF12_SDMMC1;
00658     
00659     /* GPIOC configuration: SD1_D0, SD1_D1, SD1_D2, SD1_D3 and SD1_CLK pins */
00660     gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
00661     
00662     HAL_GPIO_Init(GPIOC, &gpio_init_structure);
00663     
00664     /* GPIOD configuration: SD1_CMD pin */
00665     gpio_init_structure.Pin = GPIO_PIN_2;
00666     HAL_GPIO_Init(GPIOD, &gpio_init_structure);
00667     
00668     /* NVIC configuration for SDIO interrupts */
00669     HAL_NVIC_SetPriority(SDMMC1_IRQn, 0x0E, 0);
00670     HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
00671   
00672     dma_rx_handle.Init.Channel             = SD1_DMAx_Rx_CHANNEL;
00673     dma_rx_handle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
00674     dma_rx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
00675     dma_rx_handle.Init.MemInc              = DMA_MINC_ENABLE;
00676     dma_rx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00677     dma_rx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00678     dma_rx_handle.Init.Mode                = DMA_PFCTRL;
00679     dma_rx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
00680     dma_rx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
00681     dma_rx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00682     dma_rx_handle.Init.MemBurst            = DMA_MBURST_INC4;
00683     dma_rx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;
00684     dma_rx_handle.Instance                 = SD1_DMAx_Rx_STREAM;
00685     
00686     /* Associate the DMA handle */
00687     __HAL_LINKDMA(hsd, hdmarx, dma_rx_handle);
00688     
00689     /* Deinitialize the stream for new transfer */
00690     HAL_DMA_DeInit(&dma_rx_handle);
00691     
00692     /* Configure the DMA stream */    
00693     HAL_DMA_Init(&dma_rx_handle);
00694          
00695     dma_tx_handle.Init.Channel             = SD1_DMAx_Tx_CHANNEL;
00696     dma_tx_handle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
00697     dma_tx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
00698     dma_tx_handle.Init.MemInc              = DMA_MINC_ENABLE;
00699     dma_tx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00700     dma_tx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00701     dma_tx_handle.Init.Mode                = DMA_PFCTRL;
00702     dma_tx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
00703     dma_tx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
00704     dma_tx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00705     dma_tx_handle.Init.MemBurst            = DMA_MBURST_INC4;
00706     dma_tx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;
00707     dma_tx_handle.Instance                 = SD1_DMAx_Tx_STREAM; 
00708     
00709     /* Associate the DMA handle */
00710     __HAL_LINKDMA(hsd, hdmatx, dma_tx_handle);
00711     
00712     /* Deinitialize the stream for new transfer */
00713     HAL_DMA_DeInit(&dma_tx_handle);
00714     
00715     /* Configure the DMA stream */
00716     HAL_DMA_Init(&dma_tx_handle);  
00717 
00718     /* NVIC configuration for DMA transfer complete interrupt */
00719     HAL_NVIC_SetPriority(SD1_DMAx_Rx_IRQn, 0x0F, 0);
00720     HAL_NVIC_EnableIRQ(SD1_DMAx_Rx_IRQn);
00721     
00722     /* NVIC configuration for DMA transfer complete interrupt */
00723     HAL_NVIC_SetPriority(SD1_DMAx_Tx_IRQn, 0x0F, 0);
00724     HAL_NVIC_EnableIRQ(SD1_DMAx_Tx_IRQn);  
00725   }
00726   else
00727   {
00728     /* Enable SDIO clock */
00729     __HAL_RCC_SDMMC2_CLK_ENABLE();
00730     
00731     /* Enable DMA2 clocks */
00732     __DMAx_TxRx_CLK_ENABLE();
00733     
00734     /* Enable GPIOs clock */
00735     __HAL_RCC_GPIOB_CLK_ENABLE();
00736     __HAL_RCC_GPIOD_CLK_ENABLE();
00737     __HAL_RCC_GPIOG_CLK_ENABLE();
00738     
00739     /* Common GPIO configuration */
00740     gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00741     gpio_init_structure.Pull      = GPIO_PULLUP;
00742     gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
00743     gpio_init_structure.Alternate = GPIO_AF10_SDMMC2;
00744     
00745     /* GPIOB configuration: SD2_D2 and SD2_D3 pins */
00746     gpio_init_structure.Pin = GPIO_PIN_3 | GPIO_PIN_4;
00747     
00748     HAL_GPIO_Init(GPIOB, &gpio_init_structure);
00749     
00750     /* GPIOD configuration: SD2_CLK and SD2_CMD pins */
00751     gpio_init_structure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
00752     gpio_init_structure.Alternate = GPIO_AF11_SDMMC2;
00753     HAL_GPIO_Init(GPIOD, &gpio_init_structure);
00754     
00755     /* GPIOG configuration: SD2_D0 and SD2_D1 pins */
00756     gpio_init_structure.Pin = GPIO_PIN_9 | GPIO_PIN_10;
00757     
00758     HAL_GPIO_Init(GPIOG, &gpio_init_structure);
00759     
00760     /* NVIC configuration for SDIO interrupts */
00761     HAL_NVIC_SetPriority(SDMMC2_IRQn, 0x0E, 0);
00762     HAL_NVIC_EnableIRQ(SDMMC2_IRQn);
00763     
00764    
00765     dma_rx_handle2.Init.Channel             = SD2_DMAx_Rx_CHANNEL;
00766     dma_rx_handle2.Init.Direction           = DMA_PERIPH_TO_MEMORY;
00767     dma_rx_handle2.Init.PeriphInc           = DMA_PINC_DISABLE;
00768     dma_rx_handle2.Init.MemInc              = DMA_MINC_ENABLE;
00769     dma_rx_handle2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00770     dma_rx_handle2.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
00771     dma_rx_handle2.Init.Mode                = DMA_PFCTRL;
00772     dma_rx_handle2.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
00773     dma_rx_handle2.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
00774     dma_rx_handle2.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00775     dma_rx_handle2.Init.MemBurst            = DMA_MBURST_INC16;
00776     dma_rx_handle2.Init.PeriphBurst         = DMA_PBURST_INC4;
00777     dma_rx_handle2.Instance                 = SD2_DMAx_Rx_STREAM;     
00778     
00779     /* Associate the DMA handle */
00780     __HAL_LINKDMA(hsd, hdmarx, dma_rx_handle2);
00781     
00782     /* Deinitialize the stream for new transfer */
00783     HAL_DMA_DeInit(&dma_rx_handle2);
00784     
00785     /* Configure the DMA stream */    
00786     HAL_DMA_Init(&dma_rx_handle2);
00787 
00788     dma_tx_handle2.Init.Channel             = SD2_DMAx_Tx_CHANNEL;
00789     dma_tx_handle2.Init.Direction           = DMA_MEMORY_TO_PERIPH;
00790     dma_tx_handle2.Init.PeriphInc           = DMA_PINC_DISABLE;
00791     dma_tx_handle2.Init.MemInc              = DMA_MINC_ENABLE;
00792     dma_tx_handle2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00793     dma_tx_handle2.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
00794     dma_tx_handle2.Init.Mode                = DMA_PFCTRL;
00795     dma_tx_handle2.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
00796     dma_tx_handle2.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
00797     dma_tx_handle2.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00798     dma_tx_handle2.Init.MemBurst            = DMA_MBURST_INC16;
00799     dma_tx_handle2.Init.PeriphBurst         = DMA_PBURST_INC4;
00800     dma_tx_handle2.Instance                 = SD2_DMAx_Tx_STREAM;    
00801     
00802     /* Associate the DMA handle */
00803     __HAL_LINKDMA(hsd, hdmatx, dma_tx_handle2);
00804     
00805     /* Deinitialize the stream for new transfer */
00806     HAL_DMA_DeInit(&dma_tx_handle2);
00807     
00808     /* Configure the DMA stream */
00809     HAL_DMA_Init(&dma_tx_handle2);  
00810  
00811     /* NVIC configuration for DMA transfer complete interrupt */
00812     HAL_NVIC_SetPriority(SD2_DMAx_Rx_IRQn, 0x0F, 0);
00813     HAL_NVIC_EnableIRQ(SD2_DMAx_Rx_IRQn);
00814     
00815     /* NVIC configuration for DMA transfer complete interrupt */
00816     HAL_NVIC_SetPriority(SD2_DMAx_Tx_IRQn, 0x0F, 0);
00817     HAL_NVIC_EnableIRQ(SD2_DMAx_Tx_IRQn);     
00818   }
00819 }
00820 
00821 /**
00822   * @brief  DeInitializes the SD MSP.
00823   * @param  hsd: SD handle
00824   * @param  Params  
00825   * @retval None
00826   */
00827 __weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params)
00828 {
00829   static DMA_HandleTypeDef dma_rx_handle;
00830   static DMA_HandleTypeDef dma_tx_handle;
00831   static DMA_HandleTypeDef dma_rx_handle2;
00832   static DMA_HandleTypeDef dma_tx_handle2;
00833   
00834   if(hsd->Instance == SDMMC1)
00835   {
00836     /* Disable NVIC for DMA transfer complete interrupts */
00837     HAL_NVIC_DisableIRQ(SD1_DMAx_Rx_IRQn);
00838     HAL_NVIC_DisableIRQ(SD1_DMAx_Tx_IRQn);
00839     
00840     /* Deinitialize the stream for new transfer */
00841     dma_rx_handle.Instance = SD1_DMAx_Rx_STREAM;
00842     HAL_DMA_DeInit(&dma_rx_handle);
00843     
00844     /* Deinitialize the stream for new transfer */
00845     dma_tx_handle.Instance = SD1_DMAx_Tx_STREAM;
00846     HAL_DMA_DeInit(&dma_tx_handle);
00847     
00848     /* Disable NVIC for SDIO interrupts */
00849     HAL_NVIC_DisableIRQ(SDMMC1_IRQn);
00850     
00851     /* DeInit GPIO pins can be done in the application 
00852     (by surcharging this __weak function) */
00853     
00854     /* Disable SDMMC1 clock */
00855     __HAL_RCC_SDMMC1_CLK_DISABLE();
00856   }
00857   else
00858   {    /* Disable NVIC for DMA transfer complete interrupts */
00859     HAL_NVIC_DisableIRQ(SD2_DMAx_Rx_IRQn);
00860     HAL_NVIC_DisableIRQ(SD2_DMAx_Tx_IRQn);
00861     
00862     /* Deinitialize the stream for new transfer */
00863     dma_rx_handle2.Instance = SD2_DMAx_Rx_STREAM;
00864     HAL_DMA_DeInit(&dma_rx_handle2);
00865     
00866     /* Deinitialize the stream for new transfer */
00867     dma_tx_handle2.Instance = SD2_DMAx_Tx_STREAM;
00868     HAL_DMA_DeInit(&dma_tx_handle2);
00869     
00870     /* Disable NVIC for SDIO interrupts */
00871     HAL_NVIC_DisableIRQ(SDMMC2_IRQn);
00872     
00873     /* DeInit GPIO pins can be done in the application 
00874     (by surcharging this __weak function) */
00875     
00876     /* Disable SDMMC2 clock */
00877     __HAL_RCC_SDMMC2_CLK_DISABLE();
00878   }
00879   /* GPIO pins clock and DMA clocks can be shut down in the application
00880   by surcharging this __weak function */ 
00881 }
00882 
00883 /**
00884   * @brief  Gets the current SD card data status.
00885   * @retval Data transfer state.
00886   *          This value can be one of the following values:
00887   *            @arg  SD_TRANSFER_OK: No data transfer is acting
00888   *            @arg  SD_TRANSFER_BUSY: Data transfer is acting
00889   */
00890 uint8_t BSP_SD_GetCardState(void)
00891 {
00892   return BSP_SD_GetCardStateEx(SD_CARD1);
00893 }
00894 
00895 /**
00896   * @brief  Gets the current SD card data status.
00897   * @param  SdCard: SD_CARD1 or SD_CARD2
00898   * @retval Data transfer state.
00899   *          This value can be one of the following values:
00900   *            @arg  SD_TRANSFER_OK: No data transfer is acting
00901   *            @arg  SD_TRANSFER_BUSY: Data transfer is acting
00902   */
00903 uint8_t BSP_SD_GetCardStateEx(uint32_t SdCard)
00904 {
00905   if(SdCard == SD_CARD1)
00906   {
00907     return((HAL_SD_GetCardState(&uSdHandle) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY);
00908   }
00909   else
00910   {
00911     return((HAL_SD_GetCardState(&uSdHandle2) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY);
00912   }
00913 }
00914 
00915 /**
00916   * @brief  Get SD information about specific SD card.
00917   * @param  CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
00918   * @retval None 
00919   */
00920 void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo)
00921 {
00922   BSP_SD_GetCardInfoEx(SD_CARD1, CardInfo);
00923 }
00924 
00925 /**
00926   * @brief  Get SD information about specific SD card.
00927   * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2  
00928   * @param  CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
00929   * @retval None 
00930   */
00931 void BSP_SD_GetCardInfoEx(uint32_t SdCard, BSP_SD_CardInfo *CardInfo)
00932 {
00933   /* Get SD card Information */
00934   if(SdCard == SD_CARD1)
00935   {
00936     HAL_SD_GetCardInfo(&uSdHandle, CardInfo);
00937   }
00938   else
00939   {
00940     HAL_SD_GetCardInfo(&uSdHandle2, CardInfo);
00941   }
00942 }
00943 
00944 /**
00945   * @brief SD Abort callbacks
00946   * @param hsd: SD handle
00947   * @retval None
00948   */
00949 void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
00950 {
00951   BSP_SD_AbortCallback((hsd == &uSdHandle) ? SD_CARD1 : SD_CARD2);
00952 }
00953 
00954 /**
00955   * @brief Tx Transfer completed callbacks
00956   * @param hsd: SD handle
00957   * @retval None
00958   */
00959 void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
00960 {
00961   BSP_SD_WriteCpltCallback((hsd == &uSdHandle) ? SD_CARD1 : SD_CARD2);
00962 }
00963 
00964 /**
00965   * @brief Rx Transfer completed callbacks
00966   * @param hsd: SD handle
00967   * @retval None
00968   */
00969 void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
00970 {
00971   BSP_SD_ReadCpltCallback((hsd == &uSdHandle) ? SD_CARD1 : SD_CARD2);
00972 }
00973 
00974 /**
00975   * @brief BSP SD Abort callbacks
00976   * @param SdCard: SD_CARD1 or SD_CARD2
00977   * @retval None
00978   */
00979 __weak void BSP_SD_AbortCallback(uint32_t SdCard)
00980 {
00981 
00982 }
00983 
00984 /**
00985   * @brief BSP Tx Transfer completed callbacks
00986   * @param SdCard: SD_CARD1 or SD_CARD2
00987   * @retval None
00988   */
00989 __weak void BSP_SD_WriteCpltCallback(uint32_t SdCard)
00990 {
00991 
00992 }
00993 
00994 /**
00995   * @brief BSP Rx Transfer completed callbacks
00996   * @param SdCard: SD_CARD1 or SD_CARD2
00997   * @retval None
00998   */
00999 __weak void BSP_SD_ReadCpltCallback(uint32_t SdCard)
01000 {
01001 
01002 }
01003 /**
01004   * @}
01005   */ 
01006 
01007 /**
01008   * @}
01009   */ 
01010 
01011 /**
01012   * @}
01013   */ 
01014 
01015 /**
01016   * @}
01017   */
01018  
01019 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Dec 30 2016 20:55:35 for STM32769I_EVAL BSP User Manual by   doxygen 1.7.6.1