Setting up external SRAM in a project

Go To Last Post
31 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been beating my head on this wall over the last couple of days. So, to help other people and to clarify my remaining questions.

What I have: I have succeeded in making a PCB with an xmega128A1U onboard with 128K of external SRAM. Also been able to set up the EBI driver for this. The SRAM is set up with base address at zero like this.

void SRAM_Init(void)
{	// Setup hardware ports

	// Set signals which are active-low to high value
	// We do not have to set port J, it is overridden by SRAM controller
	PORTH.OUT = 0xFF;
	// Configure bus pins as outputs(except for data lines). */
	PORTH.DIR = 0xFF;		// !SRAM_WE, !SRAM_RE, SRAM_ALE, SRAM_A16(on !CS0)
	PORTJ.DIR = 0x00;		// Data port
	PORTK.DIR = 0xFF;		// A0-A7 direct, A8-A15 via 74AHC573 Latch

	// Port Q controls the SRAM chip enable
	// This has been done at startup - re-do to ensure it was not overridden
	PORTQ.DIRSET = (1<<PQ2_SRAM_CE);
	PORTQ.OUTCLR = (1<<PQ2_SRAM_CE);			// Enable CE for external SRAM

	// init EBI 3PORT/AL1/CS3 (A16-19)
	EBI.CTRL = EBI_SDDATAW_8BIT_gc | EBI_LPCMODE_ALE1_gc | EBI_SRMODE_ALE1_gc | EBI_IFMODE_3PORT_gc;

	//EBI.CS2.CTRLB = EBI_CS_SRWS_2CLK_gc;		// EBI time delays
	EBI.CS2.CTRLB = EBI_CS_SRWS_0CLK_gc;		// EBI time delays
	EBI.CS2.BASEADDR = 0x00;
	EBI.CS2.CTRLA = EBI_CS_MODE_SRAM_gc | EBI_CS_ASPACE_128KB_gc;
}

Then used a pointer approach to check that I can see SRAM between 0x4000 and 0xFFFE, like this: I am only peeking at a small block of it, as I am running a whole software system with watchdog enabled.

int8u SRAM_MemTest(void)
{	// Write and read a pattern to SRAM to test it.
	// Return True / False for SRAM test pass or fail.
	int16u i;
	int16u *ptr;
	int8u sram_err;
	
	sram_err = FALSE;
	ptr = (int16u *) 0x8000;
	// Just do a low ram check for now - between 16K and 64K
	//---- Fill SRAM with data - write 24K words
	//for (i = 0x4000; i < 0x5FFE; i++) {
	for (i = 0; i < 128; i++) {
		*ptr = SRAM_TESTWORD;
		ptr++;
	}
	ptr = (int16u *) 0x8000;
	//---- Check data in SRAM - read 24K words
	//for (i = 0; i < 0x5FFE; i++) {
	for (i = 0; i < 128; i++) {
		if (*ptr != SRAM_TESTWORD){
			sram_err++;
		}
		ptr++;
	}
	printf_P(PSTR("SRAM:Test:sram_err=d\r\n"), sram_err);	
	return sram_err;
}

So the above seems to be working fine.

What I would like to do now is define a named section in the block of memory between 0x4000 and 0xFFFE and then work with variables in this named section. Toi achieve this I belief I should add the following to the linker settings: I see that there is AVR/GNU Linker>>Memory settings and a block for SRAM segment. But if I try to add this
-Wl,--section-start="ExtRam"=0x804000
there, I get errors on compiling.
If I add the above under AVR/GNU Linker>>Miscellaneous, I do not get compiling errors. My problem with the above is that it does not seem to define the block length of the named section.

Then I add the following code:

static int8u varX[32767] __attribute__ ((section ("ExtRam")));

And the compiler and linker seems to be happy.

I understand that I am not accessing a large chunk of my SRAM in this way yet. But I would like to access the above specific block of SRAM as efficiently a possible (using normal 16bit pointers). I intend to access the rest of the SRAM using the EBI_xx functions for block access.

What I would like to do now is be able to see this memory section in the debugger. But it is not defined for the debugger - therefore there is no external ram selection for it in the debugger.

I have found a post here where it is described how to change the .XML file definition for the xmega128A1U. I have not tried this as I have various projects using this chip currently, and would therefore prefer to set this up in the project somehow, and not in the global definition file.

So, my question is. What am I missing so far and how do I set up a proper debug environment in Studio for this setup. Any comments appreciated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Xmega Xplained board has got 8MB of onboard SDRAM.

It is fairly painless to use.
128kB of SRAM should be much the same.

In practical terms, you have a similar number of pins / pcb bus traces. You have a single initialisation function. Away you go!

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

David, That does not answers OP question...
He wanted to know if it is possible and how to configure the debugger to show the variables defined and stored in the external SRAM.

Johan, does adding a smartwatch for any of the "outside" variables work ?

Have a nice day,
Kraal

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But it is not defined for the debugger

But it's section/label must be in the ELF? I guess this may be a limit of AS6 that it does not parse flash labels in anything other than .text from the DWARF2 info?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Kraal, I am not sure I understand what you mean with 'smartwatch'.

Putting a Watch on any of the "outside" variables results in the value shown as 'Unknown Location'.

If I open a Memory view, select memory drop down for 'data INTERNAL_SRAM' and then type in '0x008000,data' for the address - memory window shows everything as 0x00. On putting a break point after filling the block at 0x8000 with data and reading it back correctly using a pointer, I would expect some data there. I also did push the refresh icon.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ Clawson, we are trying to address RAM not Flash here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AFIK, the external SRAM will look exactly the same to the debugger. Much the same as when you use external SRAM on a mega128 or any other chip with a memory bus.

In practice you will probably use the external memory for malloc() or for big arrays and keep the stack and important variables in the faster internal memory.

You don't have to. You could put anything wherever you want. Just make sure that you have configured the bus before you actually use it.

Oh, I might have a go with the AS6 debugger and variables in the 4MB SDRAM.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ Cliff, If I search for the text 'ExtRam' in the .elf and .lss and the .map files. I only find it in the .map file as:
'Address of section ExtRam set to 0x804000'
not in the other two.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By smartwatch I meant watch, I couldn't remember the exact name. Thanks for the info on the "Unknown location" result with the watch on any variables in the ext RAM. What optimization do you use when you compile ? I mean are you sure that those variables are not optimized away ?

Have a nice day,
Kraal

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johan Hartman wrote:
I see that there is AVR/GNU Linker>>Memory settings and a block for SRAM segment. But if I try to add this
-Wl,--section-start="ExtRam"=0x804000
there, I get errors on compiling.
There you have to add only the name and address:
ExtRam=0x804000

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using external SDRAM is really pretty easy. You simply set RAMPX to the relevant page and read/write it.

However AS6 does not seem to know how to access it.
You can specify data INTERNAL_SRAM but anything outside 0x1000-0x2fff just shows 0x00.

The Xmega has no problem. It seems like AS6.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah-ha. It looks as if Dean is online !

How can you view the external memory in AS6 memory windows?

I have tried "extram", "extmem", ... but it all gets parsed as "data" (internal SRAM)

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should be able to just change the "Memory" drop-down in a Memory window to "data XRAM" to view external memory. Don't type into the address field (although that will work also with the appropriate external memory start address) just use the memory space selector on the left.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does AS use GDB?
If so, you have to tell it to:

mem 0x804000 0x823FFF rw nocache

or disable memory layout (not convenient):

set mem inaccessible-by-default off

Quote:
Putting a Watch on any of the "outside" variables

For ATMegas the "watch" works the same for all addresses, does not matter if it is inside or outside of the epoxy:
watch is for w, rwatch is for r and awatch is for rw.

No RSTDISBL, no fun!

Last Edited: Thu. Nov 21, 2013 - 08:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, AS6 uses its own Atmel backend.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Dean, the selection you suggest is sadly not available. See attached capture.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oops - I misread and tested the ATMEGA128. Looking in the XMEGA128A1U device XML there isn't a definition for the external EBI memory space; I'll see if there's a bug for it internally.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dean, is it OK then to manually edit the .XML file for the XMEGA128A1U. I have a link somewhere that describes how. My only concern is that this not negatively affect my other projects using the same device but with no external RAM. For instance, what will happen with the ram used calculation at the end of compiles?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

using the same device but with no external RAM

Yes but all A1's have an EBI whether you use it or not.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It shouldn't affect anything - there's a XML attribute in the node that indicates it is external memory so that studio will ignore it when appropriate.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried adding a "MAPPED XRAM" section with type "xram" to the ATxmega128A1.xml file.

This was not recognised by AS6.

So I deleted the new section and tried changing the type of the "MAPPED EEPROM" to "ram"

AS6 seems to still use the original "MAPPED EEPROM" section.

As I see it, the AS6 debug engine should have no problem accessing the EBI. However, we need to know how to configure it.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And so the plot thickens:

I found and applied the change suggested below. Sorry I do not have a link, just a saved copy of the text.:

----------------------------------
Have a solution for the missing EXTERNAL_SRAM display in Studio 6.
The device XML file located in the directory Atmel/Atmel Studio 6.0/devices needs to be modified to show the
 extra memory on the extended memory bus, if the device supports extended memory (or the EBI bus). So for example, I'm using the ATXmega128A1U device, so locate the ATxmega128A1U.xml file and open it up
 with notepad. Locate the line:  name="INTERNAL_SRAM"/> and make a copy of it, then past it right under the above line. Now modify the start="0x2000" to be 0x4000. Change size ="0x002000" to be what ever your physical SRAM
 size is in hex bytes. Mine happens to be 0x00C000 (24Kbytes). Then finally, change the
 name="INTERNAL_SRAM" to name="EXTERNAL_SRAM". Now save the file and restart Studio 6 so it will rescan the XML file. Go into the debugger and you should now
 see the new EXTERNAL_SRAM entry in the memory display window, and when selected, you should be able to
 examine your extended memory. Jerry Mulchin JWM Engineering Group, Inc.

-----------------------

I restarted Studio and started a debug session. I can now select and see a memory dump of the area 0x4000 to 0xFFFF in RAM. Jay!!! With correct values for areas that I filled using a pointer as described right at the beginning of the post.

However, constructing a module scope global variable like such:
static int8u varX[32767] __attribute__ ((section ("ExtRam")));

A variable watch on varX still shows its value as 'Unknown Location'

Any further new ideas.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, I was not accessing the varX variable above, so gcc dutyfully optimized it away. I used a loop to fill the first bunch of entries of the array with data. Now I can add a watch to varX and see it and its values correctly in the watch window.

Happyness Is!

I am as always chasing the next project deadline. Dean, will you file an internal bug report for the xmega128A1U.xml file.

Thanks for everybodies comments and suggestions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I followed the above plan exactly. Both with the true SDRAM size and with a trivial 24kB size (like yours)

I could not see the "data EXTERNAL SRAM" in the drop-down.

So I deleted the "EXTERNAL SRAM" section in the XML.
Then simply enlarged the size of "INTERNAL SRAM"

This also had no effect. i.e. the Memory windows only used the original sections and sizes.

Just in case I am using the 'wrong' XML, the ATxmega128A1.xml file is in the "C:\Program Files\Atmel\Atmel Studio 6.1\devices" directory.
This laptop is running VISTA-32

I am getting fed up with this AS6.1 + Dragon
It spends most of its time saying "Timed out waiting for device to reset" or "failed Launch"

I suppose that I could try the same thing on a Win7-64 desktop PC + JTAGICE-mkII

Somehow, something must be wrong with this "Visual Studio" setup.
After all, Rowley or Keil can work just fine with ARM JTAG debugging. Most ARM devices have more memory and more registers to transfer / display to debugging screen.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I feel your frustration David. Should you perhaps have modified the ATxmega128A1U.xml instead of ATxmega128A1.xml. You are in the correct directory. Did you remember to restart Studio after changing the .xml file.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. I am using the non-U Xmega. Both for the project and for editing XML.

Yes. I have looked at the XML nodes in both the A1.xml and the A1U.xml files. They are similar.

Yes. I restarted Studio each time. Pretty painful on this laptop.

When you consider that AVRs and even Xmega are fairly simple devices, you wonder why AS6 seems to make such a meal of them.

Unfortunately Rowley is crap for Xmega compilation. It does not do C++ and it uses non-standard header files for C. Otherwise I would just forget about AS6 as an unfortunate diversion.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I am getting fed up with this AS6.1 + Dragon
It spends most of its time saying "Timed out waiting for device to reset" or "failed Launch"

David did you pick up the most recent USB drivers that Morten posted?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No. I thought that the new USB driver was for JTAGICE-3.

Anyway, I have just edited ATxmega128A1.xml on my Win7-64 desktop.

Then run an Xmega EBI project with the JTAGICE-mkII.

Whoopee !!! It works. I can see EBI window !

Of course the debug session loads faster on the desktop. The world seems a better place. I will celebrate with a nice cup of tea.

While I am drinking my tea, I will re-start Vista-32 on the laptop.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah-ha. It seems to be a feature of Vista-32.

Re-started Vista-32.

I edited the XML yet again. (like on the working Win7 PC)

Started AS6. Attempted a debug session. No sign of EBI Window.

This is very odd. I can't see why Visual Studio should work differently between Vista-32 and Win7-64.

I will swap Dragon and JTAGICE-mkII but I can't see this making any difference.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Most ARM devices have more memory and more registers to transfer / display to debugging screen.

The memory size does not matter because a debugger (at least gdb) does not need to know whole memory. Typically only small part of the stack is being sniffed (for call stack). BTW, I do not remember if AS displays a call stack - if not then only the current PC is needed.
Quote:
and more registers to transfer

The ARMv7M (CM3) I use has only 13 gp registers.
I think the performance and price differences come mainly from the fact that one implementation is proprietary and the other one is freely available.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

BTW, I do not remember if AS displays a call stack - if not then only the current PC is needed.

It doesn't. But each time it stops at a breakpoint/(singlestep = same thing) it refreshes any memory displays, watch windows, the IO and processor views.