Pages: [1] 2   Go Down
Author Topic: extra RAM on Arduino Due  (Read 3905 times)
0 Members and 1 Guest are viewing this topic.
France
Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I want to store short wave files in RAM after having read them on an SD card, because I think SD card is slowing me down in my sketch.
For now, I have an arduino Due and an SD card wired on the SPI bus.
I want to add at least 1 MByte of RAM, and the best would 8 MByte.

I know that it's nearly impossible to add external RAM to arduino Due, due to the wiring of the pins. So I think there are only 2 solutions left :
Series RAM on SPI, and I²C RAM.
According to your experience, what is the best, with better speed? Is there no problem if I put several SPI peripherals (SD card + SRAM)?
The biggest module I found was 1 Mbit for SPI, and 512kb for I²C. It's not enough for me. Do you know if there are module with more memory and usable by arduino?
SPI : http://fr.farnell.com/microchip/23lc1024-i-p/sram-serie-1mbit-2-5v-8pdip/dp/2212152

If it doesn't exist, I thought about flash memory. There are modules with 8 Mbits.
http://fr.farnell.com/micron/m25p80-vmw6g/flash-serie-8mb-25p80-tube90/dp/1661753

Is the flash memory very slower than RAM?
Would it be faster than my SD card? (if no, I would have no interest to use one)

Thanks,

Gaétan
Logged

Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33419
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well you can have several of those chips on the SPI bus to make up the total.
The problem with SD card on the same bus is that I don't think you can have a file open and do any other SPI transaction, but I could be wrong on this.

The other option is to use paged RAM, that is where you read and write on a ports worth of I/O pins and use another bunch of I/O pins or a binary counter as the address lines. Then you can use parallel SRAM.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
because I think SD card is slowing me down in my sketch.
Showing that sketch, and explaining WHY you think that the SD access is the culprit might be entertaining. Perhaps even useful.

What are you doing with the wav file data?
Logged

France
Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

@Grumpy_mike

Thanks for the idea.

What you are telling about using parallel SRAM, is (for exemple) to link 20 pins from the arduino to the SRAM chip to use 1 M adresses, and connect 8 other pins to get 8 bit data?
So it would do 1 MByte data?

Did you already did that? I found someone who did this with a ttiny chip, but all was written in assembly code...

Is this this kind of chip ?
http://fr.farnell.com/renesas/r1lv0816asb-5si/sram-8mbit-3v-55ns-44tsop/dp/2068162


@ PaulS

Here is a piece of code from my blog, for a monophonic sampler with explainations :
http://groovuino.blogspot.com/2013/04/lets-code-simple-sampler.html

For polyphonic samples read, I'm doing something like this (just an extract) :

Code:
#include <samplerl.h>

const int samplernumber = 4;
Samplerl samp[samplernumber];
const char* samplefile[]= {"kick1.wav", "hithat1.wav", "snare1.wav", "snare2.wav"};


void setup() {
  for(int i=0; i<samplernumber; i++)
  {
    samp[i].init();
    samp[i].load(samplefile[i]);
  }

void loop() {
  for(int i=0; i<samplernumber; i++)
  {
    if(samp[i].buffill()) i= 100;
  }
}


void loop44kHz() {
  int32_t ulOutput=2048;
  for(int i=0; i<samplernumber; i++)
  {   
    samp[i].next();
    ulOutput += samp[i].output();
  }
  if(ulOutput>4095) ulOutput=4095;
  if(ulOutput<0) ulOutput=0;
  dacc_write_conversion_data(DACC_INTERFACE, ulOutput);
}



The library I've written is here, my problem is in the the sample.h file :
https://github.com/Gaetino/Groovuino

you can see this post too :
http://forum.arduino.cc/index.php?topic=167778.0



Here is the concept :

 . I have a buffer. There are 2 occurences : One that is being played, and one that is loaded from the SD card.
The best performances I obtained was with a 512 Bytes buffer.

 . I have a timer running at 44 kHz. Here I play the wave buffer.

 . In the main loop, I load the occurence of the buffer that has been played

So when I play 4 samples at a time, my code is doing something like this :

loop() :
occurence 1 : load buffer1 sample 1
occurence 2 : load buffer1 sample 2
occurence 3 : load buffer1 sample 3
occurence 4 : load buffer1 sample 4
occurence 5 : load buffer2 sample 1
occurence 6 : load buffer2 sample 2
occurence 7 : load buffer2 sample 3
occurence 8 : load buffer2 sample 4

The time to read 512 bytes in SD card is around 1 ms.
So time elapse between the loading of buffer1 and 2 of sample 1 is around 4 ms.

With 44kHz 16 bits (2 bytes) audio, it takes 512/2/44000 seconds = 5,8 ms to read one buffer

So as soon as I add a fifth sample, I can't read enough fast the SD card to fill the buffers.
I use SdFatLib, and maybe there are problems with reading several files at a time.


So if I can find a memory faster than SPI SD card, I think I can read more samples at a time.
« Last Edit: May 28, 2013, 07:29:53 am by gaith » Logged

Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33419
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Did you already did that?
Not on an arduino but I have done it on other processors.
You don't need all 20 address lines either for audio work. You want to access a lot of consecutive memory locations so your least significant n  bits ( say 8 or 10 ) can be replaced with a counter, so that you set the most significant bits and simply clock the counter between accesses. If you wire up the clock and reset for a counter that reduces the number of bits you need for the address.

Quote
but all was written in assembly code
There is no need for that using C is fine.
Logged

France
Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok thanks.
So if I'm considering the renesas chip which has 19 adress pins and 16 word pins (512k * 16 bits), let's call them Ad0-Ad18 and W0-W15 :
I connect Ad0-Ad10 to D0-D10 of my arduino. I will read or write at least 512 Bytes each time (size of my buffer), corresponding to 256*16 bits, so I can keep Ad11-Ad18 for the timer.
I connect W0-W15 to D11-D27 of the arduino.
I connect D28 to the clock of sram.
I connect D29 to send write/read instruction to sram.

Then I can send an 11 bits  adress with the arduino, and send or receive informations composed of 8 successive words of 16 bits.


But what I don't understand is where and how do I connect Ad11-Ad18. Do I have to add an hardware timer ? Or does the arduino can do that ? (If connect to the arduino, I won't save pins, so it's not usefull)

Other question : do you know a library which can deal with this, or will I have to make one ?

Thanks again

Gaétan
Logged

Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33419
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you got a specific chip in mind? If so can you provide a link?
Quote
I connect D28 to the clock of sram.
Most SDRAM does not have a clock but it does have a chip enable that you don't mention.

Quote
so I can keep Ad11-Ad18 for the timer.
What timer, do you mean the counter I talked about, they are not the same thing.

Logged

France
Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, sorry. The chip I had in mind is this one :
http://fr.farnell.com/renesas/r1lv0816asb-5si/sram-8mbit-3v-55ns-44tsop/dp/2068162

You're right. According to the specs, there is no clock. Only this :
CS# Chip select 
WE# Write enable
OE# Output enable
LB# Lower byte enable
UB# Upper byte enable

I think I will have to use WE (when writing) and OE (when reading).

Indeed, I wanted to talk about the counter, and not timer.
How can I generate this counter to send it to the sram chip ?
Logged

Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33419
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is what I was thinking.


* extra sram.png (7.86 KB, 355x290 - viewed 82 times.)
Logged

France
Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, nothing is better than a schematic to understand  smiley-grin

If I only count 8 bits, do you think that this binary counter is ok :
http://fr.farnell.com/texas-instruments/sn74hc590an/ic-counter-binary/dp/1470786

If yes, I will order ram and counter and keep you informed if it works. I might have some questions when I'll write the library to use it...
Logged

Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33419
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes that looks ok although I was thinking more like a 74LS93 or maybe a synchronous counter, you can cascade two of them for extra bits and have any size "page" you like.
Good luck
Logged

0
Offline Offline
Edison Member
*
Karma: 63
Posts: 1604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You might try the modern SdFat library http://code.google.com/p/sdfatlib/downloads/list.  The official Arduino SD library is based on a very old version of SdFat and is very slow on Due.

SdFat uses fast DMA on Due and large reads that are a multiple of 512 bytes are not copied.  Try allocating eight 8,192 byte buffers, two for each file.  Open all four files before starting your reads.

Here is an example benchmark for Due write/read with 8,192 byte buffers:
Quote
Free RAM: 87327
Type is FAT32
File size 10MB
Buffer size 8192 bytes
Starting write test.  Please wait up to a minute
Write 2688.79 KB/sec
Maximum latency: 92689 usec, Minimum Latency: 2302 usec, Avg Latency: 3042 usec

Starting read test.  Please wait up to a minute
Read 3852.83 KB/sec
Maximum latency: 4656 usec, Minimum Latency: 2087 usec, Avg Latency: 2124 usec

SD cards perform much better with large multi-block reads.
Logged

Ottawa,Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

thoughput oon SPI is great but the latency is killing me...
I'm generating ~30-40megBytes / min  & having the occasional long latency really mucks up my data

I've purchaced a fpga+ram board(ebay) to make a 32Megabyte spi buffer
-- but my verilog/VHDL coding skills are 10years rusty ...   

Also looking at the same fpga SPI buffer to exchange data between the DUE & Raspberry-PI (two masters...) with no droped datas
 
Logged

France
Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

@ fat16lib
I use the last version of SdFatLib (it was 1 month ago maybe, I don't know if it changed since then).
I open the wave files in the beginning of my sketch, then only read them to fill buffers, and use seek(0) to go back to the beginning.

I tried several sizes of buffer, and the more efficient I found was 512 samples (so 1024 bytes, because the wave is 16 bits).

8192 Bytes is really too much. For now I can play 4 samples at a time, but if I want to play 5 or more, it will be too big.
And when I'm doing a groovebox, I have to store waveform tables (4 kB), waveshaping effect tables (8 kB), etc...
With the 96 kB RAM of Due, it's not enough.

But I will experiment again with bigger buffers around 5-6 kBytes, and try to understand why it's not working better than 1k buffer.
Like you say, it should be faster. Maybe I have an other problem than just the reading time. 

Thanks for the reply.

@ralphnev
Yes, I'm afraid of the latency too. With real-time audio, I can't have any latency with the RAM.
So the Grumpy_Mike solution seems good, even if it's harder to do.
I'll receive components in a few days, and I'll post here my experiments. Because if you're interested, I think you can put a large amount of RAM with parallel SRAM, and all the pins of the Due.
« Last Edit: May 30, 2013, 04:30:31 am by gaith » Logged

Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

0
Offline Offline
Edison Member
*
Karma: 63
Posts: 1604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buffers sizes that are a power of two likely will work best.  The cluster size for files is a power of two and reading across a cluster boundary will defeat the larger buffer size.  Try 4 KB buffers.

Quote
Free RAM: 91423
Type is FAT32
File size 10MB
Buffer size 4096 bytes

Starting read test.  Please wait up to a minute
Read 2848.53 KB/sec
Maximum latency: 3510 usec, Minimum Latency: 1339 usec, Avg Latency: 1436 usec

Make sure you SD is formatted correctly with 32 KB clusters.  SD formatter https://www.sdcard.org/downloads/formatter_4/  places file system structures for best performance.
Logged

Pages: [1] 2   Go Up
Jump to:  

Powered by SMF 1.1.19 | SMF © 2013, Simple Machines