Initialize SDRAM in SystemInit
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
}