No changes made

Fork of BSP_DISCO_F746NG by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32746g_discovery_sdram.c Source File

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 void wait_ms(int ms); // MBED to replace HAL_Delay function
00082 
00083 /** @addtogroup BSP
00084   * @{
00085   */
00086 
00087 /** @addtogroup STM32746G_DISCOVERY
00088   * @{
00089   */ 
00090   
00091 /** @defgroup STM32746G_DISCOVERY_SDRAM STM32746G_DISCOVERY_SDRAM
00092   * @{
00093   */ 
00094 
00095 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Types_Definitions STM32746G_DISCOVERY_SDRAM Private Types Definitions
00096   * @{
00097   */ 
00098 /**
00099   * @}
00100   */
00101 
00102 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Defines STM32746G_DISCOVERY_SDRAM Private Defines
00103   * @{
00104   */
00105 /**
00106   * @}
00107   */
00108 
00109 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Macros STM32746G_DISCOVERY_SDRAM Private Macros
00110   * @{
00111   */  
00112 /**
00113   * @}
00114   */
00115 
00116 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Variables STM32746G_DISCOVERY_SDRAM Private Variables
00117   * @{
00118   */       
00119 SDRAM_HandleTypeDef sdramHandle;
00120 static FMC_SDRAM_TimingTypeDef Timing;
00121 static FMC_SDRAM_CommandTypeDef Command;
00122 /**
00123   * @}
00124   */ 
00125 
00126 /** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Function_Prototypes STM32746G_DISCOVERY_SDRAM Private Function Prototypes
00127   * @{
00128   */ 
00129 /**
00130   * @}
00131   */
00132     
00133 /** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Functions STM32746G_DISCOVERY_SDRAM Exported Functions
00134   * @{
00135   */ 
00136 
00137 /**
00138   * @brief  Initializes the SDRAM device.
00139   * @retval SDRAM status
00140   */
00141 uint8_t BSP_SDRAM_Init(void)
00142 { 
00143   static uint8_t sdramstatus = SDRAM_ERROR;
00144   /* SDRAM device configuration */
00145   sdramHandle.Instance = FMC_SDRAM_DEVICE;
00146     
00147   /* Timing configuration for 100Mhz as SD clock frequency (System clock is up to 200Mhz) */
00148   Timing.LoadToActiveDelay    = 2;
00149   Timing.ExitSelfRefreshDelay = 7;
00150   Timing.SelfRefreshTime      = 4;
00151   Timing.RowCycleDelay        = 7;
00152   Timing.WriteRecoveryTime    = 2;
00153   Timing.RPDelay              = 2;
00154   Timing.RCDDelay             = 2;
00155   
00156   sdramHandle.Init.SDBank             = FMC_SDRAM_BANK1;
00157   sdramHandle.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;
00158   sdramHandle.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;
00159   sdramHandle.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;
00160   sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
00161   sdramHandle.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_2;
00162   sdramHandle.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
00163   sdramHandle.Init.SDClockPeriod      = SDCLOCK_PERIOD;
00164   sdramHandle.Init.ReadBurst          = FMC_SDRAM_RBURST_ENABLE;
00165   sdramHandle.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_0;
00166   
00167   /* SDRAM controller initialization */
00168 
00169   BSP_SDRAM_MspInit(&sdramHandle, NULL); /* __weak function can be rewritten by the application */
00170 
00171   if(HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK)
00172   {
00173     sdramstatus = SDRAM_ERROR;
00174   }
00175   else
00176   {
00177     sdramstatus = SDRAM_OK;
00178   }
00179   
00180   /* SDRAM initialization sequence */
00181   BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);
00182   
00183   return sdramstatus;
00184 }
00185 
00186 /**
00187   * @brief  DeInitializes the SDRAM device.
00188   * @retval SDRAM status
00189   */
00190 uint8_t BSP_SDRAM_DeInit(void)
00191 { 
00192   static uint8_t sdramstatus = SDRAM_ERROR;
00193   /* SDRAM device de-initialization */
00194   sdramHandle.Instance = FMC_SDRAM_DEVICE;
00195 
00196   if(HAL_SDRAM_DeInit(&sdramHandle) != HAL_OK)
00197   {
00198     sdramstatus = SDRAM_ERROR;
00199   }
00200   else
00201   {
00202     sdramstatus = SDRAM_OK;
00203   }
00204   
00205   /* SDRAM controller de-initialization */
00206   BSP_SDRAM_MspDeInit(&sdramHandle, NULL);
00207   
00208   return sdramstatus;
00209 }
00210 
00211 /**
00212   * @brief  Programs the SDRAM device.
00213   * @param  RefreshCount: SDRAM refresh counter value 
00214   * @retval None
00215   */
00216 void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)
00217 {
00218   __IO uint32_t tmpmrd = 0;
00219   
00220   /* Step 1: Configure a clock configuration enable command */
00221   Command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;
00222   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00223   Command.AutoRefreshNumber      = 1;
00224   Command.ModeRegisterDefinition = 0;
00225 
00226   /* Send the command */
00227   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
00228 
00229   /* Step 2: Insert 100 us minimum delay */ 
00230   /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
00231   //HAL_Delay(1); // MBED
00232   wait_ms(1); // MBED
00233     
00234   /* Step 3: Configure a PALL (precharge all) command */ 
00235   Command.CommandMode            = FMC_SDRAM_CMD_PALL;
00236   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00237   Command.AutoRefreshNumber      = 1;
00238   Command.ModeRegisterDefinition = 0;
00239 
00240   /* Send the command */
00241   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);  
00242   
00243   /* Step 4: Configure an Auto Refresh command */ 
00244   Command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
00245   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00246   Command.AutoRefreshNumber      = 8;
00247   Command.ModeRegisterDefinition = 0;
00248 
00249   /* Send the command */
00250   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
00251   
00252   /* Step 5: Program the external memory mode register */
00253   tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |\
00254                      SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |\
00255                      SDRAM_MODEREG_CAS_LATENCY_2           |\
00256                      SDRAM_MODEREG_OPERATING_MODE_STANDARD |\
00257                      SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
00258   
00259   Command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;
00260   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
00261   Command.AutoRefreshNumber      = 1;
00262   Command.ModeRegisterDefinition = tmpmrd;
00263 
00264   /* Send the command */
00265   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
00266   
00267   /* Step 6: Set the refresh rate counter */
00268   /* Set the device refresh rate */
00269   HAL_SDRAM_ProgramRefreshRate(&sdramHandle, RefreshCount); 
00270 }
00271 
00272 /**
00273   * @brief  Reads an amount of data from the SDRAM memory in polling mode.
00274   * @param  uwStartAddress: Read start address
00275   * @param  pData: Pointer to data to be read  
00276   * @param  uwDataSize: Size of read data from the memory
00277   * @retval SDRAM status
00278   */
00279 uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
00280 {
00281   if(HAL_SDRAM_Read_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00282   {
00283     return SDRAM_ERROR;
00284   }
00285   else
00286   {
00287     return SDRAM_OK;
00288   } 
00289 }
00290 
00291 /**
00292   * @brief  Reads an amount of data from the SDRAM memory in DMA mode.
00293   * @param  uwStartAddress: Read start address
00294   * @param  pData: Pointer to data to be read  
00295   * @param  uwDataSize: Size of read data from the memory
00296   * @retval SDRAM status
00297   */
00298 uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
00299 {
00300   if(HAL_SDRAM_Read_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00301   {
00302     return SDRAM_ERROR;
00303   }
00304   else
00305   {
00306     return SDRAM_OK;
00307   }     
00308 }
00309 
00310 /**
00311   * @brief  Writes an amount of data to the SDRAM memory in polling mode.
00312   * @param  uwStartAddress: Write start address
00313   * @param  pData: Pointer to data to be written  
00314   * @param  uwDataSize: Size of written data from the memory
00315   * @retval SDRAM status
00316   */
00317 uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00318 {
00319   if(HAL_SDRAM_Write_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00320   {
00321     return SDRAM_ERROR;
00322   }
00323   else
00324   {
00325     return SDRAM_OK;
00326   }
00327 }
00328 
00329 /**
00330   * @brief  Writes an amount of data to the SDRAM memory in DMA mode.
00331   * @param  uwStartAddress: Write start address
00332   * @param  pData: Pointer to data to be written  
00333   * @param  uwDataSize: Size of written data from the memory
00334   * @retval SDRAM status
00335   */
00336 uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00337 {
00338   if(HAL_SDRAM_Write_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00339   {
00340     return SDRAM_ERROR;
00341   }
00342   else
00343   {
00344     return SDRAM_OK;
00345   } 
00346 }
00347 
00348 /**
00349   * @brief  Sends command to the SDRAM bank.
00350   * @param  SdramCmd: Pointer to SDRAM command structure 
00351   * @retval SDRAM status
00352   */  
00353 uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)
00354 {
00355   if(HAL_SDRAM_SendCommand(&sdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)
00356   {
00357     return SDRAM_ERROR;
00358   }
00359   else
00360   {
00361     return SDRAM_OK;
00362   }
00363 }
00364 
00365 /**
00366   * @brief  Initializes SDRAM MSP.
00367   * @param  hsdram: SDRAM handle
00368   * @param  Params
00369   * @retval None
00370   */
00371 __weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00372 {  
00373   static DMA_HandleTypeDef dma_handle;
00374   GPIO_InitTypeDef gpio_init_structure;
00375   
00376   /* Enable FMC clock */
00377   __HAL_RCC_FMC_CLK_ENABLE();
00378   
00379   /* Enable chosen DMAx clock */
00380   __DMAx_CLK_ENABLE();
00381 
00382   /* Enable GPIOs clock */
00383   __HAL_RCC_GPIOC_CLK_ENABLE();
00384   __HAL_RCC_GPIOD_CLK_ENABLE();
00385   __HAL_RCC_GPIOE_CLK_ENABLE();
00386   __HAL_RCC_GPIOF_CLK_ENABLE();
00387   __HAL_RCC_GPIOG_CLK_ENABLE();
00388   __HAL_RCC_GPIOH_CLK_ENABLE();
00389   
00390   /* Common GPIO configuration */
00391   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00392   gpio_init_structure.Pull      = GPIO_PULLUP;
00393   gpio_init_structure.Speed     = GPIO_SPEED_FAST;
00394   gpio_init_structure.Alternate = GPIO_AF12_FMC;
00395   
00396   /* GPIOC configuration */
00397   gpio_init_structure.Pin   = GPIO_PIN_3;
00398   HAL_GPIO_Init(GPIOC, &gpio_init_structure);
00399 
00400   /* GPIOD configuration */
00401   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 |
00402                               GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
00403   HAL_GPIO_Init(GPIOD, &gpio_init_structure);
00404 
00405   /* GPIOE configuration */  
00406   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\
00407                               GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
00408                               GPIO_PIN_15;
00409   HAL_GPIO_Init(GPIOE, &gpio_init_structure);
00410   
00411   /* GPIOF configuration */  
00412   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\
00413                               GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
00414                               GPIO_PIN_15;
00415   HAL_GPIO_Init(GPIOF, &gpio_init_structure);
00416   
00417   /* GPIOG configuration */  
00418   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_8 |\
00419                               GPIO_PIN_15;
00420   HAL_GPIO_Init(GPIOG, &gpio_init_structure);
00421 
00422   /* GPIOH configuration */  
00423   gpio_init_structure.Pin   = GPIO_PIN_3 | GPIO_PIN_5;
00424   HAL_GPIO_Init(GPIOH, &gpio_init_structure); 
00425   
00426   /* Configure common DMA parameters */
00427   dma_handle.Init.Channel             = SDRAM_DMAx_CHANNEL;
00428   dma_handle.Init.Direction           = DMA_MEMORY_TO_MEMORY;
00429   dma_handle.Init.PeriphInc           = DMA_PINC_ENABLE;
00430   dma_handle.Init.MemInc              = DMA_MINC_ENABLE;
00431   dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00432   dma_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00433   dma_handle.Init.Mode                = DMA_NORMAL;
00434   dma_handle.Init.Priority            = DMA_PRIORITY_HIGH;
00435   dma_handle.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;         
00436   dma_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00437   dma_handle.Init.MemBurst            = DMA_MBURST_SINGLE;
00438   dma_handle.Init.PeriphBurst         = DMA_PBURST_SINGLE; 
00439   
00440   dma_handle.Instance = SDRAM_DMAx_STREAM;
00441   
00442    /* Associate the DMA handle */
00443   __HAL_LINKDMA(hsdram, hdma, dma_handle);
00444   
00445   /* Deinitialize the stream for new transfer */
00446   HAL_DMA_DeInit(&dma_handle);
00447   
00448   /* Configure the DMA stream */
00449   HAL_DMA_Init(&dma_handle); 
00450   
00451   /* NVIC configuration for DMA transfer complete interrupt */
00452   HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 0x0F, 0);
00453   HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
00454 }
00455 
00456 /**
00457   * @brief  DeInitializes SDRAM MSP.
00458   * @param  hsdram: SDRAM handle
00459   * @param  Params
00460   * @retval None
00461   */
00462 __weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00463 {  
00464     static DMA_HandleTypeDef dma_handle;
00465   
00466     /* Disable NVIC configuration for DMA interrupt */
00467     HAL_NVIC_DisableIRQ(SDRAM_DMAx_IRQn);
00468 
00469     /* Deinitialize the stream for new transfer */
00470     dma_handle.Instance = SDRAM_DMAx_STREAM;
00471     HAL_DMA_DeInit(&dma_handle);
00472 
00473     /* GPIO pins clock, FMC clock and DMA clock can be shut down in the applications
00474        by surcharging this __weak function */ 
00475 }
00476 
00477 /**
00478   * @}
00479   */  
00480   
00481 /**
00482   * @}
00483   */ 
00484   
00485 /**
00486   * @}
00487   */ 
00488   
00489 /**
00490   * @}
00491   */ 
00492 
00493 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/