0xFF | thinking is a momentary dismissal of irrelevancies
posted by Andreas Bernhard Wagner on Jul 15, 2016

SPI WinBond W25Q80BV 1MiB Discrete Flash

I wrote amforth-W25Qx a driver for the 1MiB Winbond SPI flash chip W25Q80BV. I expect it would work with their other sizes without many changes (W25Q16, W25Q32, W25Q64, W25Q128).

Before I was working to convert the apparently non-functional amforth SD/MMC card driver into a functional MicroSD (SDHC) driver. Even though I have 10 of these Waveshare MicroSD card sockets, I still switched to discrete SPI Flash chips because it was a better fit for my application (a cranberry bog remote sensing network):

  • The hardware is simpler.
  • The driver can be very simple.
  • I had very tight cost constraints.
  • Low power usage was another constraint that made SPI flash a better fit.
  • I didn’t have any need for speed.
  • I didn’t need the storage capacity of MicroSD cards.

pinout & setup

I wrote this for my Arduino Pro Minis (3.3v) running amforth.

W25Q80BV pin assignments

W25Q80BV         AVR
/CS      [1] --- CS   [10]
 DO      [2] --- MISO [12]
/WP      [3] --- VCC
 GND     [4] --- GND
 DI      [5] --- MOSI [11]
 CLK     [6] --- SCLK [13]
/HOLD    [7] --- VCC
 VCC     [8] --- VCC

the code

What did I learn by writing this simple driver? I learned that Forth words are not functions because they aren’t to be thought of as interfaces. We don’t need to juggle arguments into position at the start of a definition. Slices of code are pulled-out, factored (same meaning as in algebra) and substituted with names primarily as a form of documentation.

: write_page ( addr len -- ) write writing finished ;
: read_page  ( addr len -- ) read  reading finished ;

If you think there’s not much substance to this, I guess you are right.

Forth applications may be too simple, and so uninteresting. It takes a very strange fish to spend hours talking about light switches, broomsticks, and hammers. Indeed it seems that all good solutions disappear in to the background. It’s only when things don’t work that we have anything to talk about.

/u/dlyund

todo

All that said, this driver was written a long time ago. I’ve learned a lot since and there are some things remaining to be done.

  • Use BLOCK wordset.

ANS forthers have deprecated the BLOCK wordset, because we live in a Unix world they say. However, not even Unix has deprecated blocks for low level io. If I want to use files in Forth to play nice with Unix then I’ll most likely be doing it with blocks, right?

  • Implement all commands.

The driver is not complete.

  • Wear-leveling layer and Bad block management.

this is an interesting one. these winbond spi flash chips are indeed raw flash and thus need some kind of fault tolerance, FEC or bad-block management. A fault tolerant alternative to bad block management which is suitable for many applications are sparse distributed representations, but that’s for another post.

I’m in Boston right now, away from my gadgets. When I get back I can try new refinements with the hardware on my desk.