cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f429 and sdram

alireza_roozitalab
Associate III
Posted on July 11, 2014 at 17:58

hello every one

i use stm32f429 disco and keil compiler

i need to load a .bmp file to sdram

the .bmp file is about 230400 bytes

so i define DATA_IN_ExtSDRAM

 and i config the options like attached file

but it makes hard fault from beginning in void SystemInit_ExtMemCtl(void) function.if i dont chose default. keil makes error that hasn't space in ram.

9 REPLIES 9
Posted on July 11, 2014 at 18:55

The code in system_stm32f4xx.c for SystemInit_ExtMemCtl() you are using probably isn't for the STM32F429I-DISCO (whatever the comment suggests)

Does it initialize pins on GPIOB?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
alireza_roozitalab
Associate III
Posted on July 11, 2014 at 20:27

thanks for your replay

its true .

i should change the config pins

i try it and replay it result

alireza.roozitalab

Posted on July 11, 2014 at 21:44

#ifdef DATA_IN_ExtSDRAM
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f429_439xx.s before jump to main.
* This function configures the external SDRAM mounted on STM32F429I-DISCO board
* This SDRAM will be used as program data memory (including heap and stack).
* Ported by CLIVE - SOURCER32@GMAIL.COM
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
register uint32_t tmpreg = 0, timeout = 0xFFFF;
register uint32_t index;
/*-- GPIOs Configuration -----------------------------------------------------*/
/*
+-------------------+--------------------+--------------------+--------------------+
+ SDRAM pins assignment +
+-------------------+--------------------+--------------------+--------------------+
| PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 |
| PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 |
| PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG4 <-> FMC_BA0 |
| PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG5 <-> FMC_BA1 |
| PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 | PG8 <-> FMC_SDCLK |
| PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 | PG15 <-> FMC_NCAS |
| PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | PF11 <-> FMC_NRAS |--------------------+
+-------------------| PE12 <-> FMC_D9 | PF12 <-> FMC_A6 |
| PE13 <-> FMC_D10 | PF13 <-> FMC_A7 |
| PE14 <-> FMC_D11 | PF14 <-> FMC_A8 |
| PE15 <-> FMC_D12 | PF15 <-> FMC_A9 |
+-------------------+--------------------+--------------------+
| PB5 <-> FMC_SDCKE1|
| PB6 <-> FMC_SDNE1 |
| PC0 <-> FMC_SDNWE |
+-------------------+
*/
/* Enable GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, and GPIOG interface
clock */
RCC->AHB1ENR |= 0x0000007E;
/* Connect PBx pins to FMC Alternate function */
GPIOB->AFR[0] = 0x0CC00000;
GPIOB->AFR[1] = 0x00000000;
/* Configure PBx pins in Alternate function mode */
GPIOB->MODER = 0x00002A80;
/* Configure PBx pins speed to 50 MHz */
GPIOB->OSPEEDR = 0x000028C0;
/* Configure PBx pins Output type to push-pull */
GPIOB->OTYPER = 0x00000000;
/* No pull-up, pull-down for PBx pins */
GPIOB->PUPDR = 0x00000100;
/* Connect PCx pins to FMC Alternate function */
GPIOC->AFR[0] = 0x0000000C;
GPIOC->AFR[1] = 0x00000000;
/* Configure PCx pins in Alternate function mode */
GPIOC->MODER = 0x00000002;
/* Configure PCx pins speed to 50 MHz */
GPIOC->OSPEEDR = 0x00000002;
/* Configure PCx pins Output type to push-pull */
GPIOC->OTYPER = 0x00000000;
/* No pull-up, pull-down for PCx pins */
GPIOC->PUPDR = 0x00000000;
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x000000CC;
GPIOD->AFR[1] = 0xCC000CCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xA02A000A;
/* Configure PDx pins speed to 50 MHz */
GPIOD->OSPEEDR = 0xA02A000A;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00000CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA800A;
/* Configure PEx pins speed to 50 MHz */
GPIOE->OSPEEDR = 0xAAAA800A;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0x00CCCCCC;
GPIOF->AFR[1] = 0xCCCCC000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0x00CC00CC;
GPIOG->AFR[1] = 0xC000000C;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x80020A0A;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0x80020A0A;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FMC Configuration ------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Configure and enable SDRAM bank2 */
FMC_Bank5_6->SDCR[0] = 0x00002800;
FMC_Bank5_6->SDCR[1] = 0x000001D4;
FMC_Bank5_6->SDTR[0] = 0x00106000;
FMC_Bank5_6->SDTR[1] = 0x00010361;
/* SDRAM initialization sequence */
/* Clock enable command - BANK2 0x08, BANK1 0x10 */
FMC_Bank5_6->SDCMR = 0x08 | 0x01;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index<
1000
; index++);
/* PALL command */
FMC_Bank5_6->SDCMR = 0x08 | 0x02;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
FMC_Bank5_6->SDCMR = 0x08 | 0x03 | 0x60;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
FMC_Bank5_6->SDCMR = 0x08 | 0x04 | 0x00046200;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR; // 64 ms / 8192 rows = 7.81us
FMC_Bank5_6->SDRTR = (tmpreg | (683 << 
1
)); // (7.81us * 90 MHz) - 
20
= 
682
.9
/* Disable write protection */
tmpreg
= 
FMC_Bank5_6
->SDCR[1];
FMC_Bank5_6->SDCR[1] = (tmpreg & 0xFFFFFDFF);
/*
Bank2_SDRAM is configured as follow:
FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;
FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7;
FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;
FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7;
FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;
FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;
FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;
FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank2_SDRAM;
FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_12b;
FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b;
FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3;
FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable;
FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2;
FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_Disable;
FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1;
FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
*/
}
#endif /* DATA_IN_ExtSDRAM */

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
awahba
Associate II
Posted on October 21, 2014 at 16:29

Hello,

This is my first post to this forum, but it was always a great resource for me for over a year now.

I am having difficulties getting to run the stm32f429-discovery using its SDRAM as data and program memory.

I went through the init procedure (copying from the eval board example, and changing the pins as you mention in this post). But whenever I change the RAM address, I get a hard fault during init. I am using IAR.

Do you mind sharing the SDRAM start address, or your linker (icf) parameters? The ones that I use (and fail) are start 0xD0000000 to 0xD07FFFFF

Thanks,

Ashraf

Posted on October 21, 2014 at 16:51

Yes, you can't execute code at 0xD0000000, you have to do a memory swap, but understand that SDRAM is VERY SLOW for code execution, as it intrinsically has high latency and is not cached.

Code would end up residing at 0x90000000, I'll have to go dig up the example

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
stm322399
Senior
Posted on October 21, 2014 at 17:07

It is also possible to run from segment 0xC0000000-0xDFFFFFFF by configuring MPU to turn this region into normal executable.

SDRAM is very slow for code execution (my JPEG compression takes x12 compare to flash execution), I only use it for debug sessions, hence my .gdbinit script:

# Turn 1st MB of DRAM into RO code region

set *(unsigned int*)0xE000ED94=7

set *(unsigned int*)0xE000ED98=0

set *(unsigned int*)0xE000ED9C=0xc0000000

set *(unsigned int*)0xE000EDA0=0x07020027

awahba
Associate II
Posted on October 22, 2014 at 16:41

Thanks for the replies.

I do not necessarily want to run my code from SDRAM, but I need the memory to store large amounts of data (~1MB from an image I want to process).  

In my discovery board project I modified the addresses and this is my icf file. 

I am going to review the pinout again, but I am sure I am setting the gpios and FMC correctly, as I compared the registers with a working SDRAM program for the discovery board that works, but just doesn't use the SDRAM for data & program. I am also interested in understanding how I can still have the program run form flash and have teh SDRAM store the data only.

Thanks,

Ashraf

/*###ICF### Section handled by ICF editor, don't touch! ****/

/*-Editor annotation file-*/

/* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */

/*-Specials-*/

define symbol __ICFEDIT_intvec_start__ = 0x08000000;

/*-Memory Regions-*/

define symbol __ICFEDIT_region_ROM_start__    = 0x08000000;

define symbol __ICFEDIT_region_ROM_end__      = 0x081FFFFF;

define symbol __ICFEDIT_region_RAM_start__    = 0xD0000000;

define symbol __ICFEDIT_region_RAM_end__      = 0xD07FFFFF;

define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;

define symbol __ICFEDIT_region_CCMRAM_end__   = 0x1000FFFF;

/*-Sizes-*/

define symbol __ICFEDIT_size_cstack__ = 0x400;

define symbol __ICFEDIT_size_heap__   = 0x200;

/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;

define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];

define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define region CCMRAM_region   = mem:[from __ICFEDIT_region_CCMRAM_start__   to __ICFEDIT_region_CCMRAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };

define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };

do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region   { readonly };

place in RAM_region   { readwrite,

                        block CSTACK, block HEAP };

Posted on October 22, 2014 at 17:22

There are a couple of specific issues to be aware of, you don't want SDRAM as your primary RAM, you want the STACK to reside in SRAM because it's functional at reset, whereas the external pins/busing of SDRAM is not. You also need to be carefully about initializing variables (statics) in SDRAM because again it needs to be configured prior to the C run time start up code attempting to zero it, or copy initial data. Consider marking SDRAM memory as ''noinit'' or ''noload''.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 22, 2014 at 17:28

I'm not an IAR user, but something like this should be viable

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF;
define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;
define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF;
define symbol __ICFEDIT_region_SDRAM_start__ = 0xD0000000;
define symbol __ICFEDIT_region_SDRAM_end__ = 0xD07FFFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x400000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__];
define region SDRAM_region = mem:[from __ICFEDIT_region_SDRAM_start__ to __ICFEDIT_region_SDRAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK };
place in SDRAM_region { block HEAP };

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..