It turned out to be much harder to use the QSPI flash chip with the Nordic SDK than I expected. Mainly this is because their documentation is nonexistent. So, a simple tutorial is useful.
I’ve written sample code that implements the FatFs using QSPI for the nrf52840 here: Sample Code. The stuff below talks about raw QSPI flash support.
Take a look at the example QSPI application in the Nordic SDK Peripherals/Qspi.
- Convert nrf_drv to nrfx to use the new interface.
- The NRFX_QSPI settings in sdk_config.h are what you need for config settings. Do not include the QSPI_ settings (which are legacy). Just defining QSPI_ENABLE cascades a host of legacy stuff.
- Define values for the qspi pins. I used variant.h and the existing QSPI entries. So the lines in sdk_config should look like this:
#ifndef NRFX_QSPI_PIN_SCK #define NRFX_QSPI_PIN_SCK PIN_QSPI_SCK #endif
Retry the sample application with the new settings to ensure things are working ok. I found that removing the interrupt handler and doing things synchronously helped.
Using the QSPI Flash
Erase it first
You must erase an area Flash before using it. The QSPI_Erase method can erase a 64KB or 4KB block. This initializes the flash to all 0xff values.
Flash is write-once
You can write to a location in flash as much as you want but flash only turns bits from 1 to 0. So there’s the strange result of writing three times and seeing:
write 11 -> read 11 (11=8|2|1) write 7 -> read 3 (11&7 == 3) write 4 -> read 0 (11&7&4 == 0)
You can set things to zero to turn them off but otherwise it’s pretty much write-once.
Flash is word-aligned
They don’t say this in the doc, but everything is word (32 bit) aligned and they truncate. So, make sure your addresses are word aligned and read/write additional data if necessary to round up transfer sizes to multiples of 4 bytes.