1

I noticed there are quite some libraries for the 23LC1024 SRAM 1 Mbit memory:

  1. SpiRam Extended library
  2. SpiRam library
  3. Direct SPI ?

I tried 1 and 3 so far. What I noticed was that to read 1 byte took around 18 us for the 3th solution and around 25 us for the first library. However, the first has possibilities to read multiple bytes and that considerably speeds up the time.

Also there are other libraries like MQTT and possibly I missed some.

However, in all cases I would expect speeds around just a few us. Since I maybe need to read 100 of different small groups of bytes preferably within 10 us (and process them), it might get problematic in worst case scenarios.

Does anybody know where the speed differences come from or if there are ways to increase the speed or which library is fast?

  • 1
    since they both use the SPI lib, SPI.setClockDivider matters. a lot on RAM. digitalWrite is slower than the PORTB stuff. there's overhead in sending, so shipping many bytes at once saves "handshake" time. put the tricks together for max speed. might update the code to use arduino.cc/en/Reference/SPISettings – dandavis Apr 6 '17 at 9:49
  • @dandavis Thanks for that information ... I hope I can get it to work since I also want to connect an SD card via SPI so have to change the settings probably when switching between SD and SRAM (this will only be needed in the first second after startup and only to transfer 128 KB in 512 byte blocks (so 256 times), afterwards I don't need the SD anymore. – Michel Keijzers Apr 6 '17 at 10:13
1

SPI RAM has two modes of operation: single byte and "page mode".

In single-byte mode you first send the read or write command followed by the (typically 3-byte) address and then read a byte. That's 5 bytes per transaction, or 40 SPI clock cycles. At the maximum of 8MHz (SPI_CLOCK_DIV2 on a 16MHz MCU) that would be at absolute best (1/8000000*40) 5µS per byte read or written. That's not including the time taken to toggle the CS pin and perform the other software-level parts of controlling the SPI peripheral.

In page mode it is possible to send one start address and then read or write sequential data from that address upwards. Ideal if you need to read a larger number of bytes that are sequentially in memory. For instance, to read 100 bytes sequentially it would take 104 SPI bytes - one for the read/write command, three for the start address, and 100 for the data. That is 832 SPI clocks, or at 8MHz, 104µS.

As you can see, reading 100 bytes within 10µS is not possible on an Arduino with SPI SRAM. There just isn't enough speed. Even 100 sequential bytes. 100 "small groups of bytes" just ain't gonna happen.

There are other technologies that are faster which may be more suited to your use, but they require different peripherals in the chip (namely SQI), and the chips with that in tend to be more powerful and have more RAM anyway, so your 1Mb of external SRAM would be redundant.

  • Thank you for the very detailed answer ... I don't think I will go for SQI for now, since I'm a beginner, however I will check into the byte versus page modes. I guess I will find in the libraries what is used. So maybe I have to adapt the manual if I want to use both ways. My idea is to use quite some lookup tables so a smart layout of the memory map in the SRAM might be useful. – Michel Keijzers Apr 6 '17 at 10:40
  • Hello! I use Arduino Due and i require external ram to be read/written fast for real time audio. What is SQI? – user1584421 Jul 12 '17 at 19:54
  • @user1584421 Serial quad interface. Like SPI but uses 4 data bits instead of 1 for transfers. – Majenko Jul 12 '17 at 19:56
  • Thanks! Are there chipsets like the 23LC1024 that provide external RAM that can be used with arduino DUE for quick r/w? Are you aware of any? – user1584421 Jul 12 '17 at 19:58
  • Or do you think 23LC1024 would be suitable for realtime audio? (using the ADCs and DACs). – user1584421 Jul 12 '17 at 19:59
1

This was an excellent challenge for an SPI bus manager and device driver support library I have been working on. Below are some performance results for the SRAM (23LC1024) device driver (Arduino Uno @ 16 MHz, SPI @ 8 MHz) read/write us per byte, kbytes/s, in benchmark.

write: 9.875 + N*1.4275 us, max. 700 kbyte/s
read: 9.875 + N*1.5 us, max. 670 kbyte/s
where N is the number of bytes transfered

The protocol overhead (9.875 us) is 1) slave select pin handling, and 2) command byte and 24-bit address (four bytes header in total).

Cheers!

Update [2017-09-25]

@MichelKeijzers I recently had time to work on an abstraction of external storage and refactor a number of device drivers to support the new interface. The abstraction includes memory block allocation, caching, handling of large vectors, and streams on external storage. Please see https://github.com/mikaelpatel/Arduino-Storage for more details; benchmarks, example sketches, etc.

  • I got with my test for 1 byte: 23,49 us/byte, for 8 bytes: 6,70 us/byte, for 100 bytes: 4,06 us/byte, for 1000: 3,86 us/byte. So yours are really faster. However, I decided to not use the 23LC1024 since I want to store some more complicated structures and 'real' RAM (being able to use real variables/pointers etc) is more comfortable. Therefore I ordered a 192 KB STM32 (which causes me a lot steeper learning curve which I'm still busy with). – Michel Keijzers Sep 17 '17 at 19:40
  • 1
    Actually there is more speed to be gained by interleaving (pipelining) the SPI transfer with data collect. All the SPI wait cycles can be used. The SPI library does some pipelining of the data fetch/store to the buffer. The data access (read/write) and the pointer increments are done while waiting for the SPI transfer. My next challenge is to add a file system/heap on the SRAM and then a Stream binding so that it can work as a ultra fast intermediate Serial for trace etc. – Mikael Patel Sep 17 '17 at 20:48
  • To be honest, I never checked much inside the library itself. Sounds like an interesting project you are doing. It seems like external SRAM is good for continuous regions (and reading less or more bytes from it). Like in your case a file system. To use it as 'real' SRAM is complicated or impossible (meaning to have any kind of variables) to be either using internal SRAM or external SRAM (and even not be aware of the difference as the user of SRAM). – Michel Keijzers Sep 17 '17 at 21:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.