STM32F429I-Discovery BSP User Manual: stm32f429i_discovery_sdram.c Source File

STM32F429I-Discovery BSP Driver

stm32f429i_discovery_sdram.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f429i_discovery_sdram.c
00004   * @author  MCD Application Team
00005   * @version V2.1.5
00006   * @date    27-January-2017
00007   * @brief   This file provides a set of functions needed to drive the
00008   *          IS42S16400J SDRAM memory mounted on STM32F429I-Discovery Kit.    
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00013   *
00014   * Redistribution and use in source and binary forms, with or without modification,
00015   * are permitted provided that the following conditions are met:
00016   *   1. Redistributions of source code must retain the above copyright notice,
00017   *      this list of conditions and the following disclaimer.
00018   *   2. Redistributions in binary form must reproduce the above copyright notice,
00019   *      this list of conditions and the following disclaimer in the documentation
00020   *      and/or other materials provided with the distribution.
00021   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022   *      may be used to endorse or promote products derived from this software
00023   *      without specific prior written permission.
00024   *
00025   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035   *
00036   ******************************************************************************
00037   */
00038 
00039 /* Includes ------------------------------------------------------------------*/
00040 #include "stm32f429i_discovery_sdram.h"
00041 
00042 /** @addtogroup BSP
00043   * @{
00044   */ 
00045 
00046 /** @addtogroup STM32F429I_DISCOVERY
00047   * @{
00048   */
00049   
00050 /** @defgroup STM32F429I_DISCOVERY_SDRAM STM32F429I DISCOVERY SDRAM
00051   * @{
00052 */ 
00053 
00054 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Types_Definitions STM32F429I DISCOVERY SDRAM Private Types Definitions
00055   * @{
00056   */
00057 /**
00058   * @}
00059   */ 
00060 
00061 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Defines STM32F429I DISCOVERY SDRAM Private Defines
00062   * @{
00063   */
00064 /**
00065   * @}
00066   */  
00067 
00068 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Macros STM32F429I DISCOVERY SDRAM Private Macros
00069   * @{
00070   */ 
00071 /**
00072   * @}
00073   */  
00074 
00075 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Variables STM32F429I DISCOVERY SDRAM Private Variables
00076   * @{
00077   */
00078 static SDRAM_HandleTypeDef SdramHandle;
00079 static FMC_SDRAM_TimingTypeDef Timing;
00080 static FMC_SDRAM_CommandTypeDef Command;
00081 /**
00082   * @}
00083   */ 
00084 
00085 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Function_Prototypes STM32F429I DISCOVERY SDRAM Private Function Prototypes
00086   * @{
00087   */ 
00088 /**
00089   * @}
00090   */
00091 
00092 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Functions STM32F429I DISCOVERY SDRAM Private Functions
00093   * @{
00094   */
00095 
00096 /**
00097   * @brief  Initializes the SDRAM device.
00098   */
00099 uint8_t BSP_SDRAM_Init(void)
00100 {
00101   static uint8_t sdramstatus = SDRAM_ERROR;
00102 
00103   /* SDRAM device configuration */
00104   SdramHandle.Instance = FMC_SDRAM_DEVICE;
00105 
00106   /* FMC Configuration -------------------------------------------------------*/
00107   /* FMC SDRAM Bank configuration */
00108   /* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */
00109   /* TMRD: 2 Clock cycles */
00110   Timing.LoadToActiveDelay    = 2;
00111   /* TXSR: min=70ns (7x11.11ns) */
00112   Timing.ExitSelfRefreshDelay = 7;
00113   /* TRAS: min=42ns (4x11.11ns) max=120k (ns) */
00114   Timing.SelfRefreshTime      = 4;
00115   /* TRC:  min=70 (7x11.11ns) */
00116   Timing.RowCycleDelay        = 7;
00117   /* TWR:  min=1+ 7ns (1+1x11.11ns) */
00118   Timing.WriteRecoveryTime    = 2;
00119   /* TRP:  20ns => 2x11.11ns*/
00120   Timing.RPDelay              = 2;
00121   /* TRCD: 20ns => 2x11.11ns */
00122   Timing.RCDDelay             = 2;
00123   
00124   /* FMC SDRAM control configuration */
00125   SdramHandle.Init.SDBank             = FMC_SDRAM_BANK2;
00126   /* Row addressing: [7:0] */
00127   SdramHandle.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;
00128   /* Column addressing: [11:0] */
00129   SdramHandle.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;
00130   SdramHandle.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;
00131   SdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
00132   SdramHandle.Init.CASLatency         = SDRAM_CAS_LATENCY;
00133   SdramHandle.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
00134   SdramHandle.Init.SDClockPeriod      = SDCLOCK_PERIOD;
00135   SdramHandle.Init.ReadBurst          = SDRAM_READBURST;
00136   SdramHandle.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_1;
00137                     
00138   /* SDRAM controller initialization */
00139   /* __weak function can be surcharged by the application code */
00140   BSP_SDRAM_MspInit(&SdramHandle, (void *)NULL);
00141   if(HAL_SDRAM_Init(&SdramHandle, &Timing) != HAL_OK)
00142   {
00143     sdramstatus = SDRAM_ERROR;
00144   }
00145   else
00146   {
00147     sdramstatus = SDRAM_OK;
00148   }
00149   
00150   /* SDRAM initialization sequence */
00151   BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);
00152   
00153   return sdramstatus;
00154 }
00155 
00156 /**
00157   * @brief  Programs the SDRAM device.
00158   * @param  RefreshCount: SDRAM refresh counter value 
00159   */
00160 void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)
00161 {
00162   __IO uint32_t tmpmrd =0;
00163   
00164   /* Step 1:  Configure a clock configuration enable command */
00165   Command.CommandMode             = FMC_SDRAM_CMD_CLK_ENABLE;
00166   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00167   Command.AutoRefreshNumber       = 1;
00168   Command.ModeRegisterDefinition  = 0;
00169 
00170   /* Send the command */
00171   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
00172 
00173   /* Step 2: Insert 100 us minimum delay */ 
00174   /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
00175   HAL_Delay(1);
00176 
00177   /* Step 3: Configure a PALL (precharge all) command */ 
00178   Command.CommandMode             = FMC_SDRAM_CMD_PALL;
00179   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00180   Command.AutoRefreshNumber       = 1;
00181   Command.ModeRegisterDefinition  = 0;
00182 
00183   /* Send the command */
00184   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);  
00185   
00186   /* Step 4: Configure an Auto Refresh command */ 
00187   Command.CommandMode             = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
00188   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00189   Command.AutoRefreshNumber       = 4;
00190   Command.ModeRegisterDefinition  = 0;
00191 
00192   /* Send the command */
00193   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
00194   
00195   /* Step 5: Program the external memory mode register */
00196   tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
00197                      SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
00198                      SDRAM_MODEREG_CAS_LATENCY_3           |
00199                      SDRAM_MODEREG_OPERATING_MODE_STANDARD |
00200                      SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
00201   
00202   Command.CommandMode             = FMC_SDRAM_CMD_LOAD_MODE;
00203   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00204   Command.AutoRefreshNumber       = 1;
00205   Command.ModeRegisterDefinition  = tmpmrd;
00206 
00207   /* Send the command */
00208   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
00209   
00210   /* Step 6: Set the refresh rate counter */
00211   /* Set the device refresh rate */
00212   HAL_SDRAM_ProgramRefreshRate(&SdramHandle, RefreshCount); 
00213 }
00214 
00215 /**
00216   * @brief  Reads an mount of data from the SDRAM memory in polling mode. 
00217   * @param  uwStartAddress : Read start address
00218   * @param  pData : Pointer to data to be read  
00219   * @param  uwDataSize: Size of read data from the memory
00220   */
00221 uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
00222 {
00223   if(HAL_SDRAM_Read_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00224   {
00225     return SDRAM_ERROR;
00226   }
00227   else
00228   {
00229     return SDRAM_OK;
00230   }  
00231 }
00232 
00233 /**
00234   * @brief  Reads an mount of data from the SDRAM memory in DMA mode. 
00235   * @param  uwStartAddress : Read start address
00236   * @param  pData : Pointer to data to be read  
00237   * @param  uwDataSize: Size of read data from the memory
00238   */
00239 uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00240 {
00241   if(HAL_SDRAM_Read_DMA(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00242   {
00243     return SDRAM_ERROR;
00244   }
00245   else
00246   {
00247     return SDRAM_OK;
00248   }        
00249 }
00250   
00251 /**
00252   * @brief  Writes an mount of data to the SDRAM memory in polling mode.
00253   * @param  uwStartAddress : Write start address
00254   * @param  pData : Pointer to data to be written  
00255   * @param  uwDataSize: Size of written data from the memory
00256   */
00257 uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00258 {
00259   /* Disable write protection */
00260   HAL_SDRAM_WriteProtection_Disable(&SdramHandle);
00261   
00262   /*Write 32-bit data buffer to SDRAM memory*/
00263   if(HAL_SDRAM_Write_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00264   {
00265     return SDRAM_ERROR;
00266   }
00267   else
00268   {
00269     return SDRAM_OK;
00270   }  
00271 }
00272 
00273 /**
00274   * @brief  Writes an mount of data to the SDRAM memory in DMA mode.
00275   * @param  uwStartAddress : Write start address
00276   * @param  pData : Pointer to data to be written  
00277   * @param  uwDataSize: Size of written data from the memory
00278   */
00279 uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00280 {
00281   if(HAL_SDRAM_Write_DMA(&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  Sends command to the SDRAM bank.
00293   * @param  SdramCmd: Pointer to SDRAM command structure 
00294   * @retval HAL status
00295   */  
00296 uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)
00297 {
00298   if(HAL_SDRAM_SendCommand(&SdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)
00299   {
00300     return SDRAM_ERROR;
00301   }
00302   else
00303   {
00304     return SDRAM_OK;
00305   }
00306 }
00307 
00308 /**
00309   * @brief  Handles SDRAM DMA transfer interrupt request.
00310   */
00311 void BSP_SDRAM_DMA_IRQHandler(void)
00312 {
00313   HAL_DMA_IRQHandler(SdramHandle.hdma); 
00314 }
00315 
00316 /**
00317   * @brief  Initializes SDRAM MSP.
00318   * @note   This function can be surcharged by application code.
00319   * @param  hsdram: pointer on SDRAM handle
00320   * @param  Params: pointer on additional configuration parameters, can be NULL.
00321   */
00322 __weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00323 {
00324   static DMA_HandleTypeDef dmaHandle;
00325   GPIO_InitTypeDef GPIO_InitStructure;
00326 
00327   if(hsdram != (SDRAM_HandleTypeDef  *)NULL)
00328   {
00329   /* Enable FMC clock */
00330   __HAL_RCC_FMC_CLK_ENABLE();
00331 
00332   /* Enable chosen DMAx clock */
00333   __DMAx_CLK_ENABLE();
00334 
00335   /* Enable GPIOs clock */
00336   __HAL_RCC_GPIOB_CLK_ENABLE();
00337   __HAL_RCC_GPIOC_CLK_ENABLE();
00338   __HAL_RCC_GPIOD_CLK_ENABLE();
00339   __HAL_RCC_GPIOE_CLK_ENABLE();
00340   __HAL_RCC_GPIOF_CLK_ENABLE();
00341   __HAL_RCC_GPIOG_CLK_ENABLE();
00342                             
00343 /*-- GPIOs Configuration -----------------------------------------------------*/
00344 /*
00345  +-------------------+--------------------+--------------------+--------------------+
00346  +                       SDRAM pins assignment                                      +
00347  +-------------------+--------------------+--------------------+--------------------+
00348  | PD0  <-> FMC_D2   | PE0  <-> FMC_NBL0  | PF0  <-> FMC_A0    | PG0  <-> FMC_A10   |
00349  | PD1  <-> FMC_D3   | PE1  <-> FMC_NBL1  | PF1  <-> FMC_A1    | PG1  <-> FMC_A11   |
00350  | PD8  <-> FMC_D13  | PE7  <-> FMC_D4    | PF2  <-> FMC_A2    | PG8  <-> FMC_SDCLK |
00351  | PD9  <-> FMC_D14  | PE8  <-> FMC_D5    | PF3  <-> FMC_A3    | PG15 <-> FMC_NCAS  |
00352  | PD10 <-> FMC_D15  | PE9  <-> FMC_D6    | PF4  <-> FMC_A4    |--------------------+ 
00353  | PD14 <-> FMC_D0   | PE10 <-> FMC_D7    | PF5  <-> FMC_A5    |   
00354  | PD15 <-> FMC_D1   | PE11 <-> FMC_D8    | PF11 <-> FMC_NRAS  | 
00355  +-------------------| PE12 <-> FMC_D9    | PF12 <-> FMC_A6    | 
00356                      | PE13 <-> FMC_D10   | PF13 <-> FMC_A7    |    
00357                      | PE14 <-> FMC_D11   | PF14 <-> FMC_A8    |
00358                      | PE15 <-> FMC_D12   | PF15 <-> FMC_A9    |
00359  +-------------------+--------------------+--------------------+
00360  | PB5 <-> FMC_SDCKE1| 
00361  | PB6 <-> FMC_SDNE1 | 
00362  | PC0 <-> FMC_SDNWE |
00363  +-------------------+  
00364   
00365 */
00366   
00367   /* Common GPIO configuration */
00368   GPIO_InitStructure.Mode  = GPIO_MODE_AF_PP;
00369   GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
00370   GPIO_InitStructure.Pull  = GPIO_NOPULL;
00371   GPIO_InitStructure.Alternate = GPIO_AF12_FMC;
00372 
00373   /* GPIOB configuration */
00374   GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_6;
00375   HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);  
00376 
00377   /* GPIOC configuration */
00378   GPIO_InitStructure.Pin = GPIO_PIN_0;      
00379   HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);  
00380   
00381   /* GPIOD configuration */
00382   GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1  | GPIO_PIN_8 |
00383                            GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |
00384                            GPIO_PIN_15;
00385   HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
00386 
00387   /* GPIOE configuration */
00388   GPIO_InitStructure.Pin = GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_7 |
00389                            GPIO_PIN_8  | GPIO_PIN_9  | GPIO_PIN_10 |
00390                            GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
00391                            GPIO_PIN_14 | GPIO_PIN_15;
00392   HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
00393 
00394   /* GPIOF configuration */
00395   GPIO_InitStructure.Pin = GPIO_PIN_0  | GPIO_PIN_1 | GPIO_PIN_2 | 
00396                            GPIO_PIN_3  | GPIO_PIN_4 | GPIO_PIN_5 |
00397                            GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
00398                            GPIO_PIN_14 | GPIO_PIN_15;
00399   HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
00400 
00401   /* GPIOG configuration */
00402   GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 |
00403                            GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
00404   HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
00405 
00406   /* Configure common DMA parameters */
00407   dmaHandle.Init.Channel             = SDRAM_DMAx_CHANNEL;
00408   dmaHandle.Init.Direction           = DMA_MEMORY_TO_MEMORY;
00409   dmaHandle.Init.PeriphInc           = DMA_PINC_ENABLE;
00410   dmaHandle.Init.MemInc              = DMA_MINC_ENABLE;
00411   dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00412   dmaHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00413   dmaHandle.Init.Mode                = DMA_NORMAL;
00414   dmaHandle.Init.Priority            = DMA_PRIORITY_HIGH;
00415   dmaHandle.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
00416   dmaHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00417   dmaHandle.Init.MemBurst            = DMA_MBURST_SINGLE;
00418   dmaHandle.Init.PeriphBurst         = DMA_PBURST_SINGLE; 
00419   
00420   dmaHandle.Instance = SDRAM_DMAx_STREAM;
00421   
00422   /* Associate the DMA handle */
00423   __HAL_LINKDMA(hsdram, hdma, dmaHandle);
00424   
00425   /* Deinitialize the stream for new transfer */
00426   HAL_DMA_DeInit(&dmaHandle);
00427   
00428   /* Configure the DMA stream */
00429   HAL_DMA_Init(&dmaHandle); 
00430   
00431   /* NVIC configuration for DMA transfer complete interrupt */
00432   HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 0x0F, 0);
00433   HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
00434   } /* of if(hsdram != (SDRAM_HandleTypeDef  *)NULL) */
00435 }
00436 
00437 /**
00438   * @brief  DeInitializes SDRAM MSP.
00439   * @note   This function can be surcharged by application code.
00440   * @param  hsdram: pointer on SDRAM handle
00441   * @param  Params: pointer on additional configuration parameters, can be NULL.
00442   */
00443 __weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00444 {
00445     static DMA_HandleTypeDef dma_handle;
00446 
00447     if(hsdram != (SDRAM_HandleTypeDef  *)NULL)
00448     {
00449       /* Disable NVIC configuration for DMA interrupt */
00450       HAL_NVIC_DisableIRQ(SDRAM_DMAx_IRQn);
00451 
00452       /* Deinitialize the stream for new transfer */
00453       dma_handle.Instance = SDRAM_DMAx_STREAM;
00454       HAL_DMA_DeInit(&dma_handle);
00455 
00456       /* DeInit GPIO pins can be done in the application
00457        (by surcharging this __weak function) */
00458 
00459       /* GPIO pins clock, FMC clock and DMA clock can be shut down in the application
00460        by surcharging this __weak function */
00461 
00462     } /* of if(hsdram != (SDRAM_HandleTypeDef  *)NULL) */
00463 }
00464 
00465 /**
00466   * @}
00467   */
00468 
00469 /**
00470   * @}
00471   */
00472 
00473 /**
00474   * @}
00475   */
00476 
00477 /**
00478   * @}
00479   */
00480 
00481 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Feb 17 2017 12:10:38 for STM32F429I-Discovery BSP User Manual by   doxygen 1.7.6.1