w25q128 SPI memory

Moderator: Benj

Post Reply
mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

w25q128 SPI memory

Post by mnf »

So not a component yet - but a request for comments..

I recently started playing with a w25q128 memory chip which packs a lot of memory 128Mbits into a 8 pin package... Data read/write is via SPI so should be quicker than i2c.
Initial experiments failed - so I thought to write my own component. Here, however, is a FC component / program hybrid.

So - the problem - the FC component doesn't check for the chip being available - so writing multiple bytes failed for some - also the user needs to track page numbers and addresses and also enable write before every write command... (So I tried WriteDataByte(0,0,123), WriteDataByte(0,1,124)... - and only the first byte was written :-( )

Working from my i2c eeprom code - I went for a different interface - user sets a write (and/or read) address then writes (or reads) as required - the program (component) handles the page and address details.

I added a read/write block, int, long int, float and string (actually ReadString isn't here - but see below)
The test program simply writes 0..9999 as long ints (32 bit) to address 0 onwards then reads and displays to UART (Successfully!)

So - anyone thoughts on interface etc (I cheat slightly - in that I get the address of a variable using C and use this as the argument to a write / read block macro - lots of compiler warnings - and so everything is handled by one write/read macro (note I didn't actually do a Write/ReadByte - but they are on the list.)

Strings - Reading or Writing - I'm inclined to include the terminating 0 (write does here) - but what do people think (this means ReadString doesn't need to know the length of the string - but maybe needs a maximum length?) An alternative is to store a length at the start of the string (8 or 16bit,?) - which makes for quicker reads

Important - the chip is 3v so use a level shifter or 3.3v MCU. It also supports dual/quad SPI - but I don't think FC does on any platform??
w25.fcfx
(40.19 KiB) Downloaded 199 times
Martin

mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

Re: w25q128 SPI memory

Post by mnf »

So for anyone playing along (2 downloadees?)

This version now works with any size data blocks (tested with 64 * 1000 byte writes and reads) & has read / write byte, string and data (array + length) (strings use a 16 bit length - so up to 65535 chars)

Note that the FC component macros (for example erase) still need to be used with care - see the (currently disabled) block at the end where WriteByte is tested. Unless WaitAvail is called before the erase then strange things happen... (Write/Read Byte actually caused me most grief - I'd just called erase before them and they didn't work :-( ) WaitAvail before the Erase fixed this (- next job is to change erase etc to do this automatically to reduce the chance of user errors)

The routines I've added (all the Read/Write in the 'main' program) are written to be robust - so Writes call WriteEnable(1) before attempting to write (so the user doesn't need to!) and also wait for the memory chip to be ready for commands.
So - both Read and Write (String or Data) can work with any size data block!
w25.fcfx
(42.25 KiB) Downloaded 183 times
Martin

stefan.erni
Valued Contributor
Valued Contributor
Posts: 654
Joined: Fri Aug 19, 2016 2:09 pm
Location: switzerland
Has thanked: 182 times
Been thanked: 179 times
Contact:

Re: w25q128 SPI memory

Post by stefan.erni »

Hi Martin

Thank you for sharing.

I thought about using this memory instead of the Sd card. With the SD card, FAT takes over the management of the related data and free space. But with this memory I have no idea where to read or write data. Is there a way to manage the memory like in FAT?

regards

Stefan

mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

Re: w25q128 SPI memory

Post by mnf »

Hi Stefan,

It doesn't have a file system like SD..

There are ways around this - for example have each 'file' (or record might be a better term) take a fixed amount of memory (say 100 bytes for demonstration purposes)..

Then to access record 5 - SetReadAddress(5 x 100).. If you wanted each record could have a string as a field (So name = ReadString() here) - which is similar to what would happen with SD cards (4k blocks or larger depending on the FAT type)

It would also be possible to create a linked list of 'files' by using a 'pointer' to the next 'file'

So - a record would consist of
Pointer to next 'file (or length of current 'file')
'name'
data
...
...

Next pointer
'name'

Which would be quite straight forward to set - with the program needing to set the next-pointer after finishing writing the data.. (However - this can get tricky if you allow files to be 'deleted' and want memory to be recycled - although one way to achieve this is to 'compact' the data on deletions...)

I'm willing to try if you have any ideas / use cases you'd like to see.

In the first instance - adding a 'Seek' command is a easy hit.

Martin

stefan.erni
Valued Contributor
Valued Contributor
Posts: 654
Joined: Fri Aug 19, 2016 2:09 pm
Location: switzerland
Has thanked: 182 times
Been thanked: 179 times
Contact:

Re: w25q128 SPI memory

Post by stefan.erni »

Hi Martin

I only need a "single file". I have to add data for 7 days. Then I have to read all the data and clear the memory.
Only sometimes does the battery run out or I switch off the device. So I would have to save in the W25 where I have to continue writing data.

regards

Stefan

mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

Re: w25q128 SPI memory

Post by mnf »

That sounds possible..

Last night I added a Get Read/Write Address - removed the FC component and all seemed to work well.. Sadly when I made into a component it didn't :roll: so something slightly amiss? - fixed, forgot to delete the test code in the component, so running out of RAM in test program.

Still - need to save current address either in w25 or much eeprom.

So:
Start-up
Load current write address

Repeat
Write data (at intervals)
Save write address

Note that if power is lost before saving the address the last record will be lost. Saving the address before writing the record (for a fixed size record) means the last record might be corrupt (power out mid write). It's possible to work around this - possibly with a capacitor and brown-out detection. The same problems apply to SD card as well - and the solution depends on how critical the data is..

Another solution is to have a 'marker' for a valid record (are they a constant size?)...

Martin

mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

Re: w25q128 SPI memory

Post by mnf »

Okay for anyone who would like a try:
w25 eeprom.fcpx
(4.86 KiB) Downloaded 195 times
w25 test.fcfx
(15.13 KiB) Downloaded 196 times
This gives access to a w25q128 (I believe other capacity varieties are available - and here there are no checks. (Should there be?))
Component in Data-Storage as w25 EEPROM

Advantages:
Data writes and read can be from/to blocks of any size (component handles the paging issues) Obviously this requires RAM support on the MCU - but test program here uses 1000 byte arrays (on an Arduino)
Support routines for bytes, ints, longs, strings, arrays (of byte) and floats. (Anything else needed - could be easily added)
Component handles waits / enabling writes so the user doesn't need to worry about them.

Drawbacks:
No simulation.
Gives a lot of compiler warnings!
?

Do I need to export any extra setup details (alt pins etc for PIC / ARM users)?
I'll test with ARM (I don't have PIC access)

Note - one catch with the chip is that you MUST erase sectors before writing to them (or EraseChip) - rewriting sectors doesn't seem to work without an erase (I hit this when I erased a 4k block and then wrote 10k to the eeprom)

Erase chip is slow! (20-100s according to the datasheet) - so don't be alarmed by a long wait if you use this..

Martin

mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

Re: w25q128 SPI memory

Post by mnf »

Stefan,

Here's a simple 'data' logger (okay it's not real data just some random strings...) as a proof of concept.

It 'checks' for a marker at the start of the eeprom (chip initialised) and erases some (in this case) or all (change EraseBlock to EraseChip) if not found - then writes an 'id' at the start of the chip.
OR
If the 'id' is found then it displays all the currently logged strings.

Then it starts saving strings (randomly generated) at 2s intervals. Pulling the plug or resetting the MCU - should then output all the current data and then restart logging.

Note that the real data would probably be more complicated - but I use -1 (value stored on 'unwritten' (erased) addresses in the eeprom) as an end of data marker. (I use the length of the string - but any value != -1 is okay - followed by a data 'log' of known or in this case stored length)

Problems - it seems to work well :-) But it will stop working when it runs out of erased memory (I erase a block rather than the full chip for speed) - the question is, what should it do when it runs out of space:
a) Stop logging (set a alarm or other user indicator) (easiest option)
b) Erase some data and continue logging (probably erase the oldest data) - note that the minimum that can be erased is a 4kb block - and keep erasing old data as needed?
T
It probably needs a 'clear data' or 'upload data' mechanism (rather than just the dump to UART I have here)

The majority of the code here is concerned with outputting the data to UART - but the 'out of space' issue will complicate things...
data logger.fcfx
(15.35 KiB) Downloaded 175 times
Martin

mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

Re: w25q128 SPI memory

Post by mnf »

And a slightly more realistic example:

I added a DHT22 to the breadboard with d3 - VCC d4 - data d5 and d6 GND

Now logs temp and humidity every 10s.

Note in a real example - you wouldn't save the 'Temp = ' and 'Humidity = ' but just the data and probably the time as well (I didn't have a RTC to hand)
I still save the data as a single string - but this is just laziness rather than a requirement..

Note - I also changed UART speed to 115200 to make playback faster.
dht22 logger.fcfx
(17.44 KiB) Downloaded 185 times
Note you'll need the w25 eeprom component above for this to work..

This ran happily for 2 days - recording over 12000 samples (with multiple power cycles (swapping from adapter to PC to check progress...)) It would also be possible to record a power-lost message at each restart.

Martin

Post Reply