[Andy] stuffed some more RAM onto an Arduino Mega and his three-part walk through on the design, construction, and software is a great read and one of the more ‘hard core’ Arduino builds we’ve seen.
The build is centered around a 512K × 8 SRAM module [PDF warning]. Because the RAM is divided up into about 512,000 chunks of 8 bits, the Arduino has to access the RAM through 16 ‘address lines’, then send the data through 8 ‘data lines’. [Andy] didn’t want to use up 24 pins on his Arduino, so he used a latch to multiplex the lowest 8 address lines and the data lines together. With the 512KB RAM expansion installed, the Mega is able to address a whopping 520 Kilobytes.
We’ve seen a few builds that have been limited by the amount of RAM available in the Arduino, like capturing video and some robot hacks, and adding some more RAM to those builds would be great. Multiplexing data and address lines using a latch can be expanded even further, but 520KB ought to be enough for anybody.
24 thoughts on “Upgrading RAM In An Arduino Mega”
you know, bill gates supposedly said once that 640k should be enough for everyone… so 520k? it will get eaten up very fast.
Haha, I was just going to post the same! Great minds think alike!
See here, he never actually said that
As an aside to those who aren’t familiar with these devices…
The article shows the use of “parallel” RAM, which is accessed one word at a time, using a large number of I/O pins.
An alternative is to use SPI RAM, which is accessed using the Serial Peripheral Interface bus. With SPI, an address is sent and the RAM replies with the corresponding data.
Given that the data is sent serially (one bit at a time), it’s a bit slower… But you’ll only be down four I/O lines, instead of 24 (or 16 if you’re clever like Andy.)
And SPI RAM isn’t available as much as parallel RAM; IIRC only Microchip has a 32K part iirc. Another alternative is DRAM; it usually has the address lines pre-multiplexed and in some cases you can also mux the data-lines to it by just connecting them together. Controlling it is a bit more difficult and you’ll need to refresh it every now and then, but it’s doable, take a look at my CP/M build as an example.
Microchip isn’t the only one OnSemi has some offerings, for example this 256K module in an easy to solder (as far as SMD goes) 8 pin SOIC package: http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=766-1041-ND
You’re right though, and it is a point worth making. Parallel RAM is certainly more widely available.
Oh hey, you’re *that* guy! I’ve enjoyed looking at the projects on your site. Great stuff!
we have SPI SRAM up to 64KByte which is double density than Microchip or ONSemi
I believe that this, and the Rugged Circuits “MegaRam” board, tie in to the AVR “external RAM” circuitry, which means that it shows up in the address space as ram, and can be used directly by the C compiler (well, 64K worth can; that’s the limit of the address space. After that you have to start doing bank switching, manually.)
And SPI RAM would have to be read and written manually, at great overhead (relatively speaking); it’d be an entirely different beast.
can anyone confirm or deny whether the atmega328p supports external ram? repeated reading of the datasheet hasn’t made me sure one way or the other, since the earlier megas seem to do it. i’ve been contemplating a project but unless my math is way off 2k ram is simply not enough, but i have a bucnh of old srams kicking around.
There is no “external memory interface” on the mega328, or it’s datasheet would have a chapter called “external memory interface” like the one in the m1280 datasheet. 28 pins just isn’t enough.
(You can still talk to SPI memories, manually, of course.)
But how many cycles to read and write to this external RAM?
How about the new Rugged Circuits MegaRAM which is fast-access and direct no-wait-state RAM?
dont some AVR support external memory with a built-in memory controller?
yeah, atleast the AT90CAN32, AT90CAN64 and AT90CAN128 chips support external memory with a built in controler
you can even put the stack on external memory
ah, after checking the article, he did use that feature :)
Not all 520.5 kilobytes are addressable. 8704 bytes (8.5 kilobytes) built in to the ATmega1280 are permanently mapped to 0000 through 21FF, which leaves 56,832 bytes (55.5 kilobytes) mapped to 2200 through FFFF. To get at the rest of the memory, three GPIO pins are used to select one-of-eight banks, and 55.5 times 8 is addressable 444 kilobytes, so 68 kilobytes (roughly 1.25 banks) are lost. It’s possible to reclaim the lost memory, but it requires significantly finer grained software control over addressing. It may also be possible to construct a memory mapper to piece together a ninth bank and a partial tenth bank from the scraps missed by the first eight, but it’ll take another GPIO pin and quite a bit more hardware. It’s definitely not worth it. If more memory is needed, just toss in another 512 kilobyte chip, and have the fourth GPIO pin pick which CE (chip enable) pin is asserted. It’ll cost less, and it’ll yield 444 additional addressable kilobytes, instead of a mere 68.
On second thought, if you’re really desperate to squeeze every last byte out of your 512 KB part, you can disconnect the ATmega1280’s A15 to get a bank size of 32 KB instead of 55.5 KB, then wire four GPIO pins to the SRAM’s A15 through A18. Now you have 16 banks * 32 KB per bank = 512 KB external addressable memory, and add 8.5 KB internal to get 520.5 KB total. This costs one additional GPIO pin and reduces the bank size by 42%, increasing the need for bank switching by an estimated 73%. But you’ll get 68 KB more memory without any significant hardware changes.
The internal memory is mapped to 0000 through 21FF, and the external to 2200 through A1FF. Addresses A1FF through FFFF alias addresses 2200 through 7FFF (8000h bytes lower).
Figure 9-7 in the ATmega1280 datasheet gives the right idea but has the wrong address ranges; the surrounding text is correct.
The 32 KB scheme I described above provides another possibility for expansion. Rather than leave the ATmega1280’s A15 pin disconnected, tie it to external memory mapping hardware. Instead of wrapping back to lower memory, addresses A1FF through FFFF can map to other external devices, for instance more memory ICs. ;^) That’s 23.5 KB worth of addresses, multiplied by sixteen to give 376 KB. You can tie that to a 256 KB chip, giving 32 KB more per bank, leaving only 7.5 KB of dead space per bank. Simply connect A15 to one memory chip’s CE and the complement of A15 to the other’s CE.
>>We’ve seen a few builds that have
>>been limited by the amount of RAM
>>available in the Arduino,
You could always not use an Arduino which is based on an Atmel chip that is meant for applications that need < 64K of RAM and use something sensible..
People use Arduino because they’re good intro boards, have a good set of libraries and are affordable.
Cost and accessibility are a major factor for a lot of hackers out there… I for one don’t have the budget for more advanced processor dev boards, and typically reuse my Arduino for multiple ideas I have.
Excelent implementation by Andy,but the Hack Award goes to the Atmel Guy that designed this interesting feature in the first place.
spi ram vs parallel ram ..
smart guys pay less and get more ..
sometimes, it’s not can vs cannot..but smart vs ..
… aaammm, nice job, interesting ideas and arguments but … if one needs so much rum, why not just get a bigger processor? Apart from MBytes of RAM one also would get a faster processor … you are aware, this is a toy-board, right? … doesn’t even expose all the i/o pins …
apologies for throwing the spanner in the clockwork …
… whooops! I swear, i’m not on rum! Cross my heart!! I meant RAM … :) where is my brain this morning??? It must be a subliminal processing … or something telling me something?
Please be kind and respectful to help make the comments section excellent. (Comment Policy)