Working with the HOLD pin is not necessary for any of the tutorials, it is only included on the breakout board for completeness. In the sketch it will always be set as an output in a high state, and on the I2C and SPI Education Shield, the pin is tied directly to the 3V3 rail on the PCB.
Reading AT25SF081 Memory Pages
Knowing how to pull a single byte of data is great, but since this thing can hold about a million bytes, chances are you’ll want to be able to work with larger quantities of data.
There is no great mystery on how to accomplish this. The AT25SF081 will send you one byte of data at a time, and do so sequentially as long as you keep sending it clock cycles. So if you’re reading the data back from byte 0x000003, you’ll get byte 4, then 5, then 6, etc. in turn as long as you keep sending junk data out on MOSI.
To accomplish this, we’ll need to make three structural changes to our code.
We’ll need an array of bytes to hold the large chunk of bytes being returned from Flash.
In order to keep things clean, we’d like to take all the commands necessary to read the data back and place them in their own function. This will also make reusing code much easier for later modules.
Some method of displaying the returned values will be necessary too, so we’ll need a function to perform that as well.
Building a Buffer
Since we program the memory array in “pages” comprised of 256 bytes each, that seems like a reasonable size to make our buffer, and creating it is simple enough,
bytepageData;. We now have an array of 256 bytes, ready to receive a full page of data.
You don’t pass the values of arrays back and forth between functions like you do with regular variables, you pass pointers to the array back and forth. That means our the functions that will receive the data and cram it into pageData and the one that will then spit that data out to the serial monitor will have to be coded specifically to accommodate that.
The functions that we need to make I’m going to call readPage and outputData. Nothing too inventive there.
For the readPage function, we’ll need to send it the starting memory array address to read from, and the pointer to the array we want it to load the data into. The address is called some24bitLocation and the array we declared above, pageData. When the function gets hold of it, the function will reference those as readAddress and memoryData.
When looking at how we create the function, pay attention to the fact that we’re saying it’s not going to return anything, that’s what the “void” means at the start. We’re passing the pointer to the pageData array and inside the function, we’ll be directly manipulating the values in that array, so there’s nothing to return.
We will still need a junk data byte to use, and the way we send the memory address is exactly the same as in the previous module.
What we need to change is very simple, instead of just reading back the single byte into a variable as we did before, we’re doing to read back single bytes, but do it 256 times in a row, relying on the fact that sending that junk byte over and over again to the AT25SF081 will cause it to read back the next byte, and then the next byte, and then the next byte, etc.
And, of course, all of that has to get wrapped with bringing chip select low and high. The final form of this function then looks like this.
SPI.transfer((readAddress&0xFF0000)>>16);// Byte address - MSB Sig Byte
SPI.transfer((readAddress&0x00FF00)>>8);// Byte address - MID Sig Byte
SPI.transfer((readAddress&0x0000FF)>>0);// Byte address - LSB Sig Byte
memoryData[i]=SPI.transfer(JUNK);// Read byte from address
Our output function is really just a bunch of formatted serial commands. We’ll pass it the pointer to the array just like we did for the readPage function.
The if statements at the top just say that if we’re reading back the first 100 bytes of data, add some extra whitespace to the output to the columns nice and clean. When you look at the code and see the output at the same time, it’ll make total sense.
Here’s the sketch in full…
A sketch to control the 8-Mbit AT25SF081 Flash Memory IC. This sketch will read
back a full 256 byte page from the memory address specified in the
some24bitLocation variable within Setup.
The code supposes the use of the Education Shield, but if you're using a breakout
board, connect the CS pin to Digital 10, HOLD to Digital 9, and the SPI pins in