0

I'm new Arduino user and I'm trying out a SPI protocol to interface a SRAM, specifically, the 23LCV512.

I have found the instructables steps to interface a SRAM using the SPI bus on an Arduino UNO very helpful (http://www.instructables.com/id/Interface-an-SRAM-bus-to-your-arduino/), but there is one point that i would like some explanation for:

In the mem_demo.ino and other various SPI.h code, I have seen variations of the following, however I do not understand why you would have to do this? I think here that we are communicating the right shifting of an input address 16 places along with 8 bits of '1'.

SPI.transfer((uint8_t)(address >> 16) & 0xff);   
SPI.transfer((uint8_t)(address >> 8) & 0xff);   
SPI.transfer((uint8_t)address);

Commenting these lines out for the write did not effect the writing to the SRAM, but reading caused it to return mostly 0's.

I really appreciate any help iIget, I do not have a lot of experience with memory addresses and electronics, thank you.

0

It is actually slightly confusing owing to the (actually redundant) & 0xff in there.

What is happening is first the address is right-shifted so as to place the byte of interest at that moment in the lowest 8-bits (address >> 16 for instance to get bits 16-23 moved to bits 0-7) and then the lowest 8 bits are masked off by ANDing them with 0b11111111 (0xFF). This removes any bits that are above the 8 bits we are interested in - however the fact that it's cast to uint8_t and also passed to a function that expects uint8_t makes that masking redundant. Any bits above the first 8 are discarded anyway.

So to take an example address of, say, 100,000 (which is 0x186A0 in hex) and run those three commands on it, we end up with:

SPI.transfer((uint8_t)(address >> 16) & 0xff);

0x186A0 >> 16 = 0x00001
0x00001 & 0xFF = 0x01

SPI.transfer((uint8_t)(address >> 8) & 0xff);

0x186A0 >> 8 = 0x00186
0x00186 & 0xFF = 0x86

SPI.transfer((uint8_t)address);

(uint8_t)0x186A0 = 0xA0

The end result as you can see is three SPI transfers each sending a single byte:

0x01, 0x86, 0xA0

And that corresponds to the protocol for that chip, which is basically:

<Command>, <Address H>, <Address M>, <Address L>, <Data>...

For instance:

0x02, 0x01, 0x86, 0xA0, 0x69

You send the "WRITE" command, send the three bytes of the address you want to write to, then follow that with the data to write. Or you send the READ command, send the three bytes of the address you want to read from, then the data is returned to you a byte at a time.

  • It's kinda weird, that he's using 3B address, as it's 64kB memory and 16bits should be enough. So: 1B read command, 2B adddress, 1B dummy (or more) to shift out data from the device. – KIIV Oct 25 '16 at 11:57
  • @KIIV The 24-bit address is a standard protocol. It's the same as for flash chips, and they come in megabyte sizes. You can't arbitrarily choose your protocol, it is dictated by the chip, and all the chips use the same standard. – Majenko Oct 25 '16 at 12:03
  • For Flash yes, but this is the SRAM and according to the datasheet, it uses only 2Byte Address for direct access and 1B Address for page read/write – KIIV Oct 25 '16 at 12:06
  • 2
    You're right, that one does only use a 16-bit address. So the OP should read the datasheet and modify their code accordingly. Also they should never trust anything they read on Instructables since it's completely filled with complete ****. – Majenko Oct 25 '16 at 12:08
  • @Majenko Thank you for your thorough explanation, i have a lot more insight into what is happening on the memory level. I have been looking at SPI and SpiRAM code on github and have seen that they do not include the & 0xFF because it is redundant. – Turing101 Oct 25 '16 at 13:53

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.