Skip to main content
Tommaso De Gennaro
Associate II
March 20, 2023
Question

Initialize SDRAM in SystemInit

  • March 20, 2023
  • 3 replies
  • 5079 views

Hello,

I am using a STM32H7A3 and a SDRAM MT48LC8M16A2P.

In a project using the emWin graphic library, I would want to store the relative buffer 'aMemory' in SDRAM.

By reading on community and seeing the examples I understood that I have to write a SystemInit_ExtMemCtl function and call it in SystemInit before to call the main function.

In this function I have to configure the GPIOs relative to FMC, configure FMC and send commands to SDRAM.

But after the send of the clock enable command, the CPU halts on the check of the busy bit of the FMC (instruction FMC_Bank5_6_R->SDSR & 0x00000020).

Please could you help me to understand ?

Thanks in advice

Tommaso

PS This is my code:

void SystemInit_ExtMemCtl(void)
 
{
 
 __IO uint32_t tmp = 0; 
 
 register uint32_t tmpreg = 0, timeout = 0xFFFF;
 
 register __IO uint32_t index;
 
 
 
 /* Enable GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface 
 
 clock */
 
 RCC->AHB4ENR |= 0x000001F8;
 
	
 
	/* Delay after an RCC peripheral clock enabling */
 
 tmp = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN);
 
 
 
 /* Connect PDx pins to FMC Alternate function */
 
 GPIOD->AFR[0] = 0xC0CC50CC;		//0x000000CC;
 
 GPIOD->AFR[1] = 0xCCCCCCCC;		//0xCC000CCC;
 
 /* Configure PDx pins in Alternate function mode */ 
 
 GPIOD->MODER = 0xAAAABABA;		//0xAFEAFFFA;
 
 /* Configure PDx pins speed to VERY High speed */ 
 
 GPIOD->OSPEEDR = 0xFFFFCF0F;		//0xF03F000F;
 
 /* Configure PDx pins Output type to push-pull */ 
 
 GPIOD->OTYPER = 0x00000000;
 
 /* Configure PDx pins in Pull-up */
 
 GPIOD->PUPDR = 0x00000000;		//0x50150005;
 
 
 
 /* Connect PEx pins to FMC Alternate function */
 
 GPIOE->AFR[0] = 0xCCCCC0CC;	//0xC00000CC;
 
 GPIOE->AFR[1] = 0xCCCCCCCC;
 
 /* Configure PEx pins in Alternate function mode */ 
 
 GPIOE->MODER = 0xAAAAAABA;
 
 /* Configure PEx pins speed to 100 MHz */ 
 
 GPIOE->OSPEEDR = 0xFFFFFFCF;
 
 /* Configure PEx pins Output type to push-pull */ 
 
 GPIOE->OTYPER = 0x00000000;
 
 /* Configure PEx pins in Pull-up */
 
 GPIOE->PUPDR = 0x00000000;	//0x55554005;
 
 
 
 /* Connect PFx pins to FMC Alternate function */
 
 GPIOF->AFR[0] = 0x00CCCCCC;	//0x0;		//0x00CCCCCC;
 
 GPIOF->AFR[1] = 0xCCCCC000;	//0x0;		//0xCCCCC000;
 
 /* Configure PFx pins in Alternate function mode */ 
 
 GPIOF->MODER = 0xAA8F7AAA;	//0xFFCF7FFF;	//0xAABFFAAA;
 
 /* Configure PFx pins speed to 100 MHz */ 
 
 GPIOF->OSPEEDR = 0xFFC00FFF;	//0x00;	//0xFFC00FFF;
 
 /* Configure PFx pins Output type to push-pull */ 
 
 GPIOF->OTYPER = 0x00000000;
 
 /* Configure PFx pins in Pull-up */
 
 GPIOF->PUPDR = 0x00;		//0x55400555;
 
 
 
 /* Connect PGx pins to FMC Alternate function */
 
 GPIOG->AFR[0] = 0x00CCCCCC;	//0x00CCCCCC;
 
 GPIOG->AFR[1] = 0xC700007C;	//0xC000000C;
 
 /* Configure PGx pins in Alternate function mode */ 
 
 GPIOG->MODER = 0xACFA3AAA;	//0xBFFEFAAA;
 
 /* Configure PGx pins speed to 100 MHz */ 
 
 GPIOG->OSPEEDR = 0xC0030FFF;
 
 /* Configure PGx pins Output type to push-pull */ 
 
 GPIOG->OTYPER = 0x00000000;
 
 /* Configure PGx pins in Pull-up */ 
 
 GPIOG->PUPDR = 0x00;	//0x40010555;
 
 
 
 /* Connect PHx pins to FMC Alternate function */
 
 GPIOH->AFR[0] = 0x02C00C00;	//0xCCC00000;
 
 GPIOH->AFR[1] = 0x00002200;	//0xCCCCCCCC;
 
 /* Configure PHx pins in Alternate function mode */ 
 
 GPIOH->MODER = 0xDCAFE8EF;	//0xAAAAABFF;
 
 /* Configure PHx pins speed to 100 MHz */ 
 
 GPIOH->OSPEEDR = 0x00300C30;	//0xFFFFFC00;
 
 /* Configure PHx pins Output type to push-pull */ 
 
 GPIOH->OTYPER = 0x00000000;
 
 /* Configure PHx pins in Pull-up */
 
 GPIOH->PUPDR = 0x00;	//0x55555400;
 
 
 
 /* Connect PIx pins to FMC Alternate function */
 
 GPIOI->AFR[0] = 0x00305500;	//0xCCCCCCCC;
 
 GPIOI->AFR[1] = 0x00;	//0x00000CC0;
 
 /* Configure PIx pins in Alternate function mode */ 
 
 GPIOI->MODER = 0x7C7C3BAF;	//0xFFEBAAAA;
 
 /* Configure PIx pins speed to 100 MHz */ 
 
 GPIOI->OSPEEDR = 0x00;	//0x003CFFFF;
 
 /* Configure PIx pins Output type to push-pull */ 
 
 GPIOI->OTYPER = 0x00000000;
 
 /* Configure PIx pins in Pull-up */
 
 GPIOI->PUPDR = 0x00;	//0x00145555;
 
 
 
/*-- FMC Configuration ------------------------------------------------------*/
 
 /* Enable the FMC interface clock */
 
 (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN));
 
	
 
	/* Delay after an RCC peripheral clock enabling */
 
 tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
 
	
 
 /*SDRAM Timing and access interface configuration*/
 
 /*LoadToActiveDelay = 2
 
 ExitSelfRefreshDelay = 6
 
 SelfRefreshTime = 4
 
 RowCycleDelay = 6
 
 WriteRecoveryTime = 2
 
 RPDelay = 2
 
 RCDDelay = 2
 
 SDBank = FMC_SDRAM_BANK2
 
 ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9 
 
 RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12
 
 MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32
 
 InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4
 
 CASLatency = FMC_SDRAM_CAS_LATENCY_2
 
 WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE
 
 SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2
 
 ReadBurst = FMC_SDRAM_RBURST_ENABLE
 
 ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0*/
 
 
 
 FMC_Bank5_6_R->SDCR[0] = 0x00005DD5;	//0x00001800;
 
 FMC_Bank5_6_R->SDTR[0] = 0x01105361;	//0x00105000;
 
	
 
 
 
 /* SDRAM initialization sequence */
 
 /* Clock enable command */ 
 
 FMC_Bank5_6_R->SDCMR = 0x11;	//0x00000009; 
 
 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; 
 
 while((tmpreg != 0) && (timeout-- > 0))
 
 {
 
 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; 
 
 }
 
 
 
 /* Delay */
 
 for (index = 0; index<1000; index++);
 
	
 
 /* PALL command */ 
 
 FMC_Bank5_6_R->SDCMR = 0x12;	//0x0000000A; 	
 
 timeout = 0xFFFF;
 
 while((tmpreg != 0) && (timeout-- > 0))
 
 {
 
 tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; 
 
 }
 
// other commands
 
}

This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
March 20, 2023

Does the SDRAM initialize and function properly if brought up by HAL code in your BSP / test application?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Tommaso De Gennaro
Associate II
March 20, 2023

Hi,

thank you for answer me. Yes, I tested the SDRAM with HAL and i​t works properly. The problem is initialize it at the start in systemInit.

Tesla DeLorean
Guru
March 20, 2023

Is this using Bank1 or Bank2 ? If Bank2, per the comment, then it's definitely wrong.

Please define the memory configuration in your design, pins, etc.

Ideally attach the equivalent BSP / MSP code fragment that works.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Pavel A.
Super User
March 21, 2023

Why do you think SDRAM must be initialized in SystemInit? Does the test app initalize it tis way?

Even if emWin has some statically initialized data in SDRAM, you can copy it "manually" in your main(), after normal initialization of FMC, MPU, SDRAM and before any emWin call.

Tesla DeLorean
Guru
March 21, 2023

That's where it's supposed to be initialized for the CMSIS model.

SystemInit() sets up memories, is called by the startup code, so the C runtime initialization can do it's job. And for C++ so that the constructors can do their thing properly.

Tools like Keil build initialization tables (scatter list), so the scatter loader can do the job without dozens of symbols.

The "do it in main()" method is rather sloppy, but does allow for all statics to be initialized, rather having things in a "pre-execution" state where more care needs to be taken. Much better for the generally oblivious..

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Pavel A.
Super User
March 21, 2023

This is IMHO one of good examples of how coding for small embedded systems differs from "normal". And why main() and main.c better should stay away from C++.

SystemInit for STM32F4 initializes external memory on FMC, but for H7 that has been removed. Too complicated.

Earlier in this forum you've advised to initialize this stuff in a bootloader, so the app won't need to deal with chicken/egg issues.