STM32746G-Discovery BSP User Manual: stm32746g_discovery_sdram.c Source File

STM32746G-Discovery BSP Drivers

stm32746g_discovery_sdram.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32746g_discovery_sdram.c
00004   * @author  MCD Application Team
00005   * @version V2.0.0
00006   * @date    30-December-2016
00007   * @brief   This file includes the SDRAM driver for the MT48LC4M32B2B5-7 memory 
00008   *          device mounted on STM32746G-Discovery board.
00009   @verbatim
00010    1. How To use this driver:
00011    --------------------------
00012       - This driver is used to drive the MT48LC4M32B2B5-7 SDRAM external memory mounted
00013         on STM32746G-Discovery board.
00014       - This driver does not need a specific component driver for the SDRAM device
00015         to be included with.
00016    
00017    2. Driver description:
00018    ---------------------
00019      + Initialization steps:
00020         o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This 
00021           function includes the MSP layer hardware resources initialization and the
00022           FMC controller configuration to interface with the external SDRAM memory.
00023         o It contains the SDRAM initialization sequence to program the SDRAM external 
00024           device using the function BSP_SDRAM_Initialization_sequence(). Note that this 
00025           sequence is standard for all SDRAM devices, but can include some differences
00026           from a device to another. If it is the case, the right sequence should be 
00027           implemented separately.
00028      
00029      + SDRAM read/write operations
00030         o SDRAM external memory can be accessed with read/write operations once it is
00031           initialized.
00032           Read/write operation can be performed with AHB access using the functions
00033           BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by DMA transfer using the functions
00034           BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().
00035         o The AHB access is performed with 32-bit width transaction, the DMA transfer
00036           configuration is fixed at single (no burst) word transfer (see the 
00037           SDRAM_MspInit() static function).
00038         o User can implement his own functions for read/write access with his desired 
00039           configurations.
00040         o If interrupt mode is used for DMA transfer, the function BSP_SDRAM_DMA_IRQHandler()
00041           is called in IRQ handler file, to serve the generated interrupt once the DMA 
00042           transfer is complete.
00043         o You can send a command to the SDRAM device in runtime using the function 
00044           BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between 
00045           the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure. 
00046  
00047   @endverbatim
00048   ******************************************************************************
00049   * @attention
00050   *
00051   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00052   *
00053   * Redistribution and use in source and binary forms, with or without modification,
00054   * are permitted provided that the following conditions are met:
00055   *   1. Redistributions of source code must retain the above copyright notice,
00056   *      this list of conditions and the following disclaimer.
00057   *   2. Redistributions in binary form must reproduce the above copyright notice,
00058   *      this list of conditions and the following disclaimer in the documentation
00059   *      and/or other materials provided with the distribution.
00060   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00061   *      may be used to endorse or promote products derived from this software
00062   *      without specific prior written permission.
00063   *
00064   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00065   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00066   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00067   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00068   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00069   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00070   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00071   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00072   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00073   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00074   *
00075   ******************************************************************************
00076   */
00077 
00078 /* Includes ------------------------------------------------------------------*/
00079 #include "stm32746g_discovery_sdram.h"
00080 
00081 /** @addtogroup BSP
00082   * @{
00083   */
00084 
00085 /** @addtogroup STM32746G_DISCOVERY
00086   * @{
00087   */ 
00088   
00089 /** @defgroup STM32746G_DISCOVERY_SDRAM STM32746G_DISCOVERY_SDRAM
00090   * @{
00091   */ 
00092 
00093 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Types_Definitions STM32746G_DISCOVERY_SDRAM Private Types Definitions
00094   * @{
00095   */ 
00096 /**
00097   * @}
00098   */
00099 
00100 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Defines STM32746G_DISCOVERY_SDRAM Private Defines
00101   * @{
00102   */
00103 /**
00104   * @}
00105   */
00106 
00107 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Macros STM32746G_DISCOVERY_SDRAM Private Macros
00108   * @{
00109   */  
00110 /**
00111   * @}
00112   */
00113 
00114 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Variables STM32746G_DISCOVERY_SDRAM Private Variables
00115   * @{
00116   */       
00117 SDRAM_HandleTypeDef sdramHandle;
00118 static FMC_SDRAM_TimingTypeDef Timing;
00119 static FMC_SDRAM_CommandTypeDef Command;
00120 /**
00121   * @}
00122   */ 
00123 
00124 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Function_Prototypes STM32746G_DISCOVERY_SDRAM Private Function Prototypes
00125   * @{
00126   */ 
00127 /**
00128   * @}
00129   */
00130     
00131 /** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Functions STM32746G_DISCOVERY_SDRAM Exported Functions
00132   * @{
00133   */ 
00134 
00135 /**
00136   * @brief  Initializes the SDRAM device.
00137   * @retval SDRAM status
00138   */
00139 uint8_t BSP_SDRAM_Init(void)
00140 { 
00141   static uint8_t sdramstatus = SDRAM_ERROR;
00142   /* SDRAM device configuration */
00143   sdramHandle.Instance = FMC_SDRAM_DEVICE;
00144     
00145   /* Timing configuration for 100Mhz as SD clock frequency (System clock is up to 200Mhz) */
00146   Timing.LoadToActiveDelay    = 2;
00147   Timing.ExitSelfRefreshDelay = 7;
00148   Timing.SelfRefreshTime      = 4;
00149   Timing.RowCycleDelay        = 7;
00150   Timing.WriteRecoveryTime    = 2;
00151   Timing.RPDelay              = 2;
00152   Timing.RCDDelay             = 2;
00153   
00154   sdramHandle.Init.SDBank             = FMC_SDRAM_BANK1;
00155   sdramHandle.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;
00156   sdramHandle.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;
00157   sdramHandle.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;
00158   sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
00159   sdramHandle.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_2;
00160   sdramHandle.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
00161   sdramHandle.Init.SDClockPeriod      = SDCLOCK_PERIOD;
00162   sdramHandle.Init.ReadBurst          = FMC_SDRAM_RBURST_ENABLE;
00163   sdramHandle.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_0;
00164   
00165   /* SDRAM controller initialization */
00166 
00167   BSP_SDRAM_MspInit(&sdramHandle, NULL); /* __weak function can be rewritten by the application */
00168 
00169   if(HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK)
00170   {
00171     sdramstatus = SDRAM_ERROR;
00172   }
00173   else
00174   {
00175     sdramstatus = SDRAM_OK;
00176   }
00177   
00178   /* SDRAM initialization sequence */
00179   BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);
00180   
00181   return sdramstatus;
00182 }
00183 
00184 /**
00185   * @brief  DeInitializes the SDRAM device.
00186   * @retval SDRAM status
00187   */
00188 uint8_t BSP_SDRAM_DeInit(void)
00189 { 
00190   static uint8_t sdramstatus = SDRAM_ERROR;
00191   /* SDRAM device de-initialization */
00192   sdramHandle.Instance = FMC_SDRAM_DEVICE;
00193 
00194   if(HAL_SDRAM_DeInit(&sdramHandle) != HAL_OK)
00195   {
00196     sdramstatus = SDRAM_ERROR;
00197   }
00198   else
00199   {
00200     sdramstatus = SDRAM_OK;
00201   }
00202   
00203   /* SDRAM controller de-initialization */
00204   BSP_SDRAM_MspDeInit(&sdramHandle, NULL);
00205   
00206   return sdramstatus;
00207 }
00208 
00209 /**
00210   * @brief  Programs the SDRAM device.
00211   * @param  RefreshCount: SDRAM refresh counter value 
00212   * @retval None
00213   */
00214 void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)
00215 {
00216   __IO uint32_t tmpmrd = 0;
00217   
00218   /* Step 1: Configure a clock configuration enable command */
00219   Command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;
00220   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00221   Command.AutoRefreshNumber      = 1;
00222   Command.ModeRegisterDefinition = 0;
00223 
00224   /* Send the command */
00225   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
00226 
00227   /* Step 2: Insert 100 us minimum delay */ 
00228   /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
00229   HAL_Delay(1);
00230     
00231   /* Step 3: Configure a PALL (precharge all) command */ 
00232   Command.CommandMode            = FMC_SDRAM_CMD_PALL;
00233   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00234   Command.AutoRefreshNumber      = 1;
00235   Command.ModeRegisterDefinition = 0;
00236 
00237   /* Send the command */
00238   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);  
00239   
00240   /* Step 4: Configure an Auto Refresh command */ 
00241   Command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
00242   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00243   Command.AutoRefreshNumber      = 8;
00244   Command.ModeRegisterDefinition = 0;
00245 
00246   /* Send the command */
00247   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
00248   
00249   /* Step 5: Program the external memory mode register */
00250   tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |\
00251                      SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |\
00252                      SDRAM_MODEREG_CAS_LATENCY_2           |\
00253                      SDRAM_MODEREG_OPERATING_MODE_STANDARD |\
00254                      SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
00255   
00256   Command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;
00257   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00258   Command.AutoRefreshNumber      = 1;
00259   Command.ModeRegisterDefinition = tmpmrd;
00260 
00261   /* Send the command */
00262   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
00263   
00264   /* Step 6: Set the refresh rate counter */
00265   /* Set the device refresh rate */
00266   HAL_SDRAM_ProgramRefreshRate(&sdramHandle, RefreshCount); 
00267 }
00268 
00269 /**
00270   * @brief  Reads an amount of data from the SDRAM memory in polling mode.
00271   * @param  uwStartAddress: Read start address
00272   * @param  pData: Pointer to data to be read  
00273   * @param  uwDataSize: Size of read data from the memory
00274   * @retval SDRAM status
00275   */
00276 uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
00277 {
00278   if(HAL_SDRAM_Read_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00279   {
00280     return SDRAM_ERROR;
00281   }
00282   else
00283   {
00284     return SDRAM_OK;
00285   } 
00286 }
00287 
00288 /**
00289   * @brief  Reads an amount of data from the SDRAM memory in DMA mode.
00290   * @param  uwStartAddress: Read start address
00291   * @param  pData: Pointer to data to be read  
00292   * @param  uwDataSize: Size of read data from the memory
00293   * @retval SDRAM status
00294   */
00295 uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
00296 {
00297   if(HAL_SDRAM_Read_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00298   {
00299     return SDRAM_ERROR;
00300   }
00301   else
00302   {
00303     return SDRAM_OK;
00304   }     
00305 }
00306 
00307 /**
00308   * @brief  Writes an amount of data to the SDRAM memory in polling mode.
00309   * @param  uwStartAddress: Write start address
00310   * @param  pData: Pointer to data to be written  
00311   * @param  uwDataSize: Size of written data from the memory
00312   * @retval SDRAM status
00313   */
00314 uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00315 {
00316   if(HAL_SDRAM_Write_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00317   {
00318     return SDRAM_ERROR;
00319   }
00320   else
00321   {
00322     return SDRAM_OK;
00323   }
00324 }
00325 
00326 /**
00327   * @brief  Writes an amount of data to the SDRAM memory in DMA mode.
00328   * @param  uwStartAddress: Write start address
00329   * @param  pData: Pointer to data to be written  
00330   * @param  uwDataSize: Size of written data from the memory
00331   * @retval SDRAM status
00332   */
00333 uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00334 {
00335   if(HAL_SDRAM_Write_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00336   {
00337     return SDRAM_ERROR;
00338   }
00339   else
00340   {
00341     return SDRAM_OK;
00342   } 
00343 }
00344 
00345 /**
00346   * @brief  Sends command to the SDRAM bank.
00347   * @param  SdramCmd: Pointer to SDRAM command structure 
00348   * @retval SDRAM status
00349   */  
00350 uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)
00351 {
00352   if(HAL_SDRAM_SendCommand(&sdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)
00353   {
00354     return SDRAM_ERROR;
00355   }
00356   else
00357   {
00358     return SDRAM_OK;
00359   }
00360 }
00361 
00362 /**
00363   * @brief  Initializes SDRAM MSP.
00364   * @param  hsdram: SDRAM handle
00365   * @param  Params
00366   * @retval None
00367   */
00368 __weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00369 {  
00370   static DMA_HandleTypeDef dma_handle;
00371   GPIO_InitTypeDef gpio_init_structure;
00372   
00373   /* Enable FMC clock */
00374   __HAL_RCC_FMC_CLK_ENABLE();
00375   
00376   /* Enable chosen DMAx clock */
00377   __DMAx_CLK_ENABLE();
00378 
00379   /* Enable GPIOs clock */
00380   __HAL_RCC_GPIOC_CLK_ENABLE();
00381   __HAL_RCC_GPIOD_CLK_ENABLE();
00382   __HAL_RCC_GPIOE_CLK_ENABLE();
00383   __HAL_RCC_GPIOF_CLK_ENABLE();
00384   __HAL_RCC_GPIOG_CLK_ENABLE();
00385   __HAL_RCC_GPIOH_CLK_ENABLE();
00386   
00387   /* Common GPIO configuration */
00388   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00389   gpio_init_structure.Pull      = GPIO_PULLUP;
00390   gpio_init_structure.Speed     = GPIO_SPEED_FAST;
00391   gpio_init_structure.Alternate = GPIO_AF12_FMC;
00392   
00393   /* GPIOC configuration */
00394   gpio_init_structure.Pin   = GPIO_PIN_3;
00395   HAL_GPIO_Init(GPIOC, &gpio_init_structure);
00396 
00397   /* GPIOD configuration */
00398   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
00399                               GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
00400   HAL_GPIO_Init(GPIOD, &gpio_init_structure);
00401 
00402   /* GPIOE configuration */  
00403   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\
00404                               GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
00405                               GPIO_PIN_15;
00406   HAL_GPIO_Init(GPIOE, &gpio_init_structure);
00407   
00408   /* GPIOF configuration */  
00409   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\
00410                               GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
00411                               GPIO_PIN_15;
00412   HAL_GPIO_Init(GPIOF, &gpio_init_structure);
00413   
00414   /* GPIOG configuration */  
00415   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_8 |\
00416                               GPIO_PIN_15;
00417   HAL_GPIO_Init(GPIOG, &gpio_init_structure);
00418 
00419   /* GPIOH configuration */  
00420   gpio_init_structure.Pin   = GPIO_PIN_3 | GPIO_PIN_5;
00421   HAL_GPIO_Init(GPIOH, &gpio_init_structure); 
00422   
00423   /* Configure common DMA parameters */
00424   dma_handle.Init.Channel             = SDRAM_DMAx_CHANNEL;
00425   dma_handle.Init.Direction           = DMA_MEMORY_TO_MEMORY;
00426   dma_handle.Init.PeriphInc           = DMA_PINC_ENABLE;
00427   dma_handle.Init.MemInc              = DMA_MINC_ENABLE;
00428   dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00429   dma_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00430   dma_handle.Init.Mode                = DMA_NORMAL;
00431   dma_handle.Init.Priority            = DMA_PRIORITY_HIGH;
00432   dma_handle.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;         
00433   dma_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00434   dma_handle.Init.MemBurst            = DMA_MBURST_SINGLE;
00435   dma_handle.Init.PeriphBurst         = DMA_PBURST_SINGLE; 
00436   
00437   dma_handle.Instance = SDRAM_DMAx_STREAM;
00438   
00439    /* Associate the DMA handle */
00440   __HAL_LINKDMA(hsdram, hdma, dma_handle);
00441   
00442   /* Deinitialize the stream for new transfer */
00443   HAL_DMA_DeInit(&dma_handle);
00444   
00445   /* Configure the DMA stream */
00446   HAL_DMA_Init(&dma_handle); 
00447   
00448   /* NVIC configuration for DMA transfer complete interrupt */
00449   HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 0x0F, 0);
00450   HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
00451 }
00452 
00453 /**
00454   * @brief  DeInitializes SDRAM MSP.
00455   * @param  hsdram: SDRAM handle
00456   * @param  Params
00457   * @retval None
00458   */
00459 __weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00460 {  
00461     static DMA_HandleTypeDef dma_handle;
00462   
00463     /* Disable NVIC configuration for DMA interrupt */
00464     HAL_NVIC_DisableIRQ(SDRAM_DMAx_IRQn);
00465 
00466     /* Deinitialize the stream for new transfer */
00467     dma_handle.Instance = SDRAM_DMAx_STREAM;
00468     HAL_DMA_DeInit(&dma_handle);
00469 
00470     /* GPIO pins clock, FMC clock and DMA clock can be shut down in the applications
00471        by surcharging this __weak function */ 
00472 }
00473 
00474 /**
00475   * @}
00476   */  
00477   
00478 /**
00479   * @}
00480   */ 
00481   
00482 /**
00483   * @}
00484   */ 
00485   
00486 /**
00487   * @}
00488   */ 
00489 
00490 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Dec 30 2016 16:31:33 for STM32746G-Discovery BSP User Manual by   doxygen 1.7.6.1