STM32L152D_EVAL BSP User Manual: stm32l152d_eval_sd.c Source File

STM32L152D_EVAL BSP

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