cancel
Showing results for 
Search instead for 
Did you mean: 

Addressing 16-bit variables 512K SRAM

dbilancione
Associate II
Posted on September 04, 2013 at 13:05

Hi everyone. I can't get my head around this ... I was using a SRAM memory of 128K in a project, interfaced via the FSMC controller, but now I have to extend it to 512K. I have 16-bit words to store in the memory in two separate pages. The memory occupies Bank1_region3 FSMC address space (0x68000000). With 128K it was easy: I had the first page going from 0x68000000 up to 0x6800FFFF, whereas the second page from 0x68010000 up to 0x6801FFFF. Thus, I was still able to address each location with a 16-bit address added to the page base address (0x68000000 or 0x68010000). Now, each page is 3FFFF long hence the same trick wouldn't work and I can't get my head around this.

A little help will be really appreciate.

Thank you!

#fsmc #sram-fsmc #gcc-fsmc
15 REPLIES 15
Posted on September 05, 2013 at 19:20

Am I missing anything or doing anything wrong?

 

Well one of the things that's prone to cause problems is that the external bus must be initialized prior to the C startup code zeroing or copying static data on to it. You want to look carefully at what startup_stm32fxxx.s does, where it calls SystemInit() vs main(), and where you configure the FSMC.

What you really want to do is get your debugger to start by stepping through ResetHandler, till you get to main. Have a Hard Fault handler that provides diagnostic information about where/how the code is faulting.

If you can't get the debugger to do that, then your options are to flag progress through the code using GPIO pins, or via a USART you initialized early in the ResetHandler code.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dbilancione
Associate II
Posted on September 05, 2013 at 19:39

hey clive. I can initialize the FSMC just after the system clock configuration and before the execution jumps to main but I don't want to use the external SRAM for the head and stack.

I know exactly when the applications ends to HardFault_Handler, as soon as I do this

__attribute__ ((section(''.xram''))) int16_t DDL[2][XSRAM_SIZE/4];
__IO uint32_t i;
for (i = 0; i < 0x40000; i++)
{
DDL[0][i] = 0;
DDL[1][i] = 0; /*!< Jumps to the HardFault_Handler */
}

I have checked the address of the two columns &DDL[0][0] = 0x68000000 &DDL[1][0] = 0x68080000 The memory is 512K x 16bit, therefore 1024K (0x00100000). I thought the processor couldn't access the memory thus I have tried specifying a smaller size but it keeps on doing the same thing. I'm gonna try initializing the FSMC before the main and let you know what happens. thank you
dbilancione
Associate II
Posted on September 05, 2013 at 20:57

I have not initialized all 26 address lines but only the 19 which connect to the SRAM. Could that be causing the HardFault?

Posted on September 05, 2013 at 21:35

I think that would be perfectly adequate, I'm not sure why it would fault. If it were me, I'd be digging into the processor's state to better understand the source/nature of the fault.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 05, 2013 at 22:10

For what it's worth, this is the code used by the RedDragon407 to initialize the FSMC at 0x68000000 using an

http://www.issi.com/WW/pdf/61LV25616AL.pdf

, I haven't evaluated it yet.

FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
GPIO_InitTypeDef GPIO_InitStructure; 
FSMC_NORSRAMTimingInitTypeDef Timing_read,Timing_write;
/* Enable GPIOs clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF |
RCC_AHB1Periph_GPIOG, ENABLE);
/* Enable FSMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &Timing_read;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &Timing_write;
FSMC_NORSRAMStructInit(&FSMC_NORSRAMInitStructure);
/*--------------------- read timings configuration ---------------------*/
Timing_read.FSMC_AddressSetupTime = 3; /* [3:0] F2/F4 1~15 HCLK */
Timing_read.FSMC_AddressHoldTime = 0; /* [7:4] keep 0x00 in SRAM mode */
Timing_read.FSMC_DataSetupTime = 4; /* [15:8] F2/F4 0~255 HCLK */
/* [19:16] Time between NEx high to NEx low (BUSTURN HCLK) */
Timing_read.FSMC_BusTurnAroundDuration = 1;
Timing_read.FSMC_CLKDivision = 0; /* [24:20] keep 0x00 in SRAM mode */
Timing_read.FSMC_DataLatency = 0; /* [27:25] keep 0x00 in SRAM mode */
Timing_read.FSMC_AccessMode = FSMC_AccessMode_A;
/*--------------------- write timings configuration ---------------------*/
Timing_write.FSMC_AddressSetupTime =2; /* [3:0] F2/F4 1~15 HCLK */
Timing_write.FSMC_AddressHoldTime = 0; /* [7:4] keep 0x00 in SRAM mode */
Timing_write.FSMC_DataSetupTime =3; /* [15:8] F2/F4 0~255 HCLK */
/* [19:16] Time between NEx high to NEx low (BUSTURN HCLK) */
Timing_write.FSMC_BusTurnAroundDuration = 1;
Timing_write.FSMC_CLKDivision = 0; /* [24:20] keep 0x00 in SRAM mode */
Timing_write.FSMC_DataLatency = 0; /* [27:25] keep 0x00 in SRAM mode */
Timing_write.FSMC_AccessMode = FSMC_AccessMode_A;
/* GPIOD configuration */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |
GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* GPIOE configuration */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource3 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 |
GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* GPIOF configuration */
GPIO_PinAFConfig(GPIOF, GPIO_PinSource0 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource1 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource2 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource3 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource4 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource5 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource12 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource13 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource14 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource15 , GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5 |
GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOF, &GPIO_InitStructure);
/* GPIOG configuration */
GPIO_PinAFConfig(GPIOG, GPIO_PinSource0 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource1 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource2 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource3 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource4 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource5 , GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource10 , GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_10;
GPIO_Init(GPIOG, &GPIO_InitStructure);
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &Timing_read;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &Timing_write;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/*!< Enable FSMC Bank1_SRAM3 Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dbilancione
Associate II
Posted on September 06, 2013 at 03:01

THANK YOU BOTH! I've got it working and here's what I did ...

I modified the FSMC configuration in the system_stm32f4xx.c, generated by the clock config tool, as I am using a low power, thus slower memory compare to the high-speed one mounted on the STM3210E-EVAL board. Also the region was different.

I didn't know about the bus turnaround phase duration until I checked the code of RedDragon407 posted by Clive; did the calculation and ended up with 2 cycles (I had 0 initially).

Then I modified the load script as suggested by Jack, declared a 2-D array and that was it.

thanks again