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
jpeacock2399
Associate II
Posted on September 04, 2013 at 15:54

Assuming you have enough address lines from the FSMC going to the external RAM then it's a linear address, 0x68000000 to 0x6807FFFF for 512KB.  16 bit external RAM access shifts the address lines so your A0 address is really the two byte lane signals, which is why a physical address of 3FFFF becomes 7FFFF.  FSMC takes care of the details, just use it as a linear 512KB RAm memory space.

It isn't like a PIC or 8051 with banked memory; with a 32-bit address space you don't need to look at memory in terms of pages.

  Jack Peacock
dbilancione
Associate II
Posted on September 04, 2013 at 17:35

Hi Jack. thank you for your reply. It is not a pic I am working with but an STM32F4 I am working on an audio processing application; the idea to have the memory split in two pages is because each page is dedicated to one channel (LEFT and RIGHT). I have 19 address lines (A0:A18) and 16 data lines. The memory I am using is similar to the one mountedon theSTM3210E-EVAL board (IS62WV51216BLL-55TLL), 5 times slower by it is a low power memory.

I understand that the FSMC takes care of the details, but when I try reading from a memory location it crashes. The functions I am using to read and write from/to the memory are the followings

/**
* @brief Writes data to SRAM.
* @param wAddr: the SRAM internal address to write to
* @param data: value to store in SRAM
* @retval None
*/
static void BufferWrite(uint32_t wAddr, uint16_t data)
{
(wAddr & 1) ? wAddr++ : wAddr;
/* write to memory */
*(uint16_t *)wAddr = data;
}
/**
* @brief Reads data from SRAM.
* @param rAddr: the SRAM internal address to read from
* @retval Data retrieved from SRAM
*/
static uint16_t BufferRead(uint32_t rAddr)
{
(rAddr & 1) ? rAddr++ : rAddr;
/* read from memory */
return *(__IO uint16_t *)rAddr;
}

Now shouldn't the instruction

return *(__IO uint16_t *)rAddr;

return the 16-bit value stored at the 32-bit address ''rAddr''? thanks
jpeacock2399
Associate II
Posted on September 05, 2013 at 00:26

Nothing obviously wrong with your routines other than not checking for a valid pointer address.  You can vastly simplify your logic by  assigning a 2 dimensional (left and right) array of shorts to span the external memory, then you wouldn't have to bother with dereferenced pointers.

When your program crashes what are the contents of the pointers?  If valid then check the FSMC setup.  If not valid you got a program bug.

  Jack Peacock
dbilancione
Associate II
Posted on September 05, 2013 at 01:11

The FSMC address and data setup time are correct: the memories are identical, apart the size. I had to increase of one cycle the address setup time using the 512K. I have watched the pointer's address while debugging the code and it is within the range I want it to be. But as soon as the code attempt to read from the buffer, the process ends up in the HardFault_Handler for some reason. So you are telling me that I can simply declare a 2-dimensional array in the FSMC address space and don't bother with pointers (which would be awesome!)?

thank you

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

I have read that you could specify to the linker the address and length of the external SRAM modifying the arm-gcc-link.ld, i.e. adding a section to it. I have seen the FSMC data memory peripheral example but not quite sure how to proceed. Is that what you meant?

thanks

jpeacock2399
Associate II
Posted on September 05, 2013 at 15:53

Here's an excerpt where I declare a global array in GCC and then the linker section where I assign the address:

unsigned char __attribute__ ((section(''.xram''))) BackText[LCD_MAX_COLUMN/8][LCD_MAX_ROW/8]; 
In the loader script: 
XRAM (w): ORIGIN = 0x64000000, LENGTH = 2048K 
/* the XRAM section is used for slow external SRAM */ 
.xram (NOLOAD) : 
{ 
_sxram = .; 
*(.xram*) /* uninitialized data */ 
. = ALIGN(2); /* halfword align, 16-bit memory */ 
_exram = .; 
} > XRAM 
} 

Hope that helps. Jack Peacock
dbilancione
Associate II
Posted on September 05, 2013 at 16:23

that's what I was talking about! I'll give it a go and let you know. last couple of questions though:

can I declare the 2-D array where I need it? (as I 've seen a similar declaration for the stack memory is system_stm32f4xx.c)

the length to specify is in bytes? the memory I'm using is a 512K x 16-bit, thus 1024Kbyte.

thanks jack!

dbilancione
Associate II
Posted on September 05, 2013 at 16:38

let's make 3 questions...

in the loader script you have specified a XRAM (w); I suppose that means you will be only writing to that memory (after all, it has been dedicated to an LCD display). Therefore, in my application I should specify XRAM (rwx) to read/write and x might be erase, not sure.

thanks

dbilancione
Associate II
Posted on September 05, 2013 at 19:07

hey Jack. I have tried your suggestion but I can't explain why is working in a simple SRAM test application and not working when I use the same code in the application. I have declared the 2-D array

#define XSRAM_SIZE ((uint32_t)0x00100000) /*!< External SRAM size in bytes */
__attribute__ ((section(''.xram''))) int16_t DDL[2][XSRAM_SIZE/4];

and in the loader script I have included

/* Internal Memory Map*/
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x00100000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
ram1 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000
xram (rwx) : ORIGIN = 0x68000000, LENGTH = 0x00100000
}
_eram = 0x20000000 + 0x00020000;
/* Section Definitions */ 
SECTIONS 
{ 
...
...
...
/* the XRAM section which is used for slow external SRAM */
.xram (NOLOAD) :
{
_sxram = . ;
*(.xram .xram*) /* uninitialized data */
. = ALIGN(2); /* halfword alignment, 16-bit memory */
_exram = . ;
} > xram
. = ALIGN(4); 
_end = . ; 
}

but as soon as I access the array to initialize its values to 0, the application ends in theHardFault_Handler. Am I missing anything or doing anything wrong? thanks