en.radzio.dxp.pl

STM32F429I Discovery : SDRAM
STM32F429I-DISCO board is equipped with 8MB SDRAM chip (IS42S16400J from Integrated Silicon Solution, Inc.). This SDRAM memory chip is connected to SDRAM bank 2 of Flexible Memory Controller of STM32F429 MCU. SDRAM memory can be used as frame buffer for big LCDs (up to 800x600).

Initialization of SDRAM memory controller
Initialization of SDRAM controller is done by some writes to registers. Most important are SDCR (SDRAM Control Register) and SDTR (SDRAM Timing Register) registers. Each of two banks have own SDCR/SDTR register set, but when we want configure only BANK2 some values must be written to registers for BANK1 and for BANK2 are don't care (please refer to section 37.7.5 of RM0090 Reference Manual). On our discovery board SDRAM is connected to BANK2, so we must write configuration to both register sets. Initialization sequence is described in section 37.7.3 of RM0090 document.

Defines for SDRAM base address and size (in SDRAM.h file):

// SDRAM base address for Bank 2
#define SDRAM_BASE 0xD0000000
// SDRAM size is 8MB
#define SDRAM_SIZE 0x00800000

For easier specifying timig values I defined some macros for timing register values :

#define TMRD(x) (x << 0)  /* Load Mode Register to Active */
#define TXSR(x) (x << 4)  /* Exit Self-refresh delay */
#define TRAS(x) (x << 8)  /* Self refresh time */
#define TRC(x)  (x << 12) /* Row cycle delay */
#define TWR(x)  (x << 16) /* Recovery delay */
#define TRP(x)  (x << 20) /* Row precharge delay */
#define TRCD(x) (x << 24) /* Row to column delay */

GPIO configuration

Tables with GPIO configuration data.

static GPIO_TypeDef * const GPIOInitTable[] = {
  GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOG, GPIOG,
  GPIOD, GPIOD, GPIOD, GPIOD, GPIOE, GPIOE, GPIOE, GPIOE, GPIOE, GPIOE, GPIOE, GPIOE, GPIOE, GPIOD,   GPIOD, GPIOD,
  GPIOB, GPIOB, GPIOC, GPIOE, GPIOE, GPIOF, GPIOG, GPIOG, GPIOG, GPIOG,
  0};

static uint8_t const PINInitTable[] = {
  0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 0, 1,
  14, 15, 0, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 8,
  9, 10,
  5, 6, 0, 0, 1, 11, 4, 5, 8, 15,
  0};

Initialization function source code :

void SDRAM_Init(void)
{
  vu32 tmp;
  uint8_t i = 0;

  // Configure all pins used for SDRAM connections
  while(GPIOInitTable[i] != 0){
  gpio_conf(GPIOInitTable[i], PINInitTable[i], MODE_AF, TYPE_PUSHPULL, SPEED_100MHz, PULLUP_NONE,    12);
  i++;
  }
  // Enable clock for FMC
  RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN;
  // Initialization step 1
  FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE_1;
  FMC_Bank5_6->SDCR[1] = FMC_SDCR1_NR_0 | FMC_SDCR1_MWID_0 | FMC_SDCR1_NB | FMC_SDCR1_CAS;
  // Initialization step 2
  FMC_Bank5_6->SDTR[0] = TRC(7) | TRP(2);
  FMC_Bank5_6->SDTR[1] = TMRD(2) | TXSR(7) | TRAS(4) | TWR(2) | TRCD(2);
  // Initialization step 3
  while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
  FMC_Bank5_6->SDCMR = 1 | FMC_SDCMR_CTB2 | (1 << 5);
  // Initialization step 4
  for(tmp = 0; tmp < 1000000; tmp++);
  // Initialization step 5
  while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
  FMC_Bank5_6->SDCMR = 2 | FMC_SDCMR_CTB2 | (1 << 5);
  // Initialization step 6
  while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
  FMC_Bank5_6->SDCMR = 3 | FMC_SDCMR_CTB2 | (4 << 5);
  // Initialization step 7
  while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
  FMC_Bank5_6->SDCMR = 4 | FMC_SDCMR_CTB2 | (1 << 5) | (0x231 << 9);
  // Initialization step 8
  while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
  FMC_Bank5_6->SDRTR |= (683 << 1);
  while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
  // Clear SDRAM or fill with some pattern/color
  for(tmp = SDRAM_BASE; tmp < (SDRAM_BASE + SDRAM_SIZE); tmp += 4)
    *((uint32_t *)tmp) = 0x00000000;
}

After configuration of SDRAM controller memory can be used as any other memory connected to STM32 MCU, but please read section 2.8 FMC peripheral limitation in Errata Sheet for STM32F429/439 to avoid issues.

Download
  STM32F429/439 SDRAM configuration

Next : STM32F429 TFT LCD controller

 

 
(c) Radosław Kwiecień