STM32F429ZI Discovery board drivers

Dependents:   2a 2b 2c 2d1 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f429i_discovery_sdram.c Source File

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