LittleFs file support for QSPI flash in Zephyr

Mark Zachmann
Apr 16, 2020 · 3 min read

The board I’m working on has 1MB of QSPI flash. That is serial flash that’s directly controlled by the Nordic nrf52840. See here ->

QspiFlash connections to chip

The chip can use any 6 high-speed pins it likes for the flash interface so I’ve chosen pins that make the layout simple. Nordic suggests certain pins for noise/speed reasons and these are mainly from that set.

I had a terrible time getting this working correctly. It’s not hard to get it working well, it’s hard to figure out exactly what to set. So,…

It’s simple in zephyr to read/write raw data to the chip, tougher to get integrated use of qspi functionality where the F_DataX pins produce a 4 pin data bus for speed and easy dma.

The Nordic-specific Qspi driver was added at the end of 2019. I haven’t checked, but compared with raw SPI this driver should be much quicker and more power efficient.

1. Add Qspi Definition to the .dts file

This chunk specifies the pin mappings and other flash chip internals like max clock frequency.

It is added to my board .dtsi file. For information about the entries see: zephyr\dts\bindings\mtd\nordic,qspi-nor.yaml or use the gui to see qspi-nor settings.

This entry says we have a device based off the predefined qspi-nor device. See the schematic above for pin-mapping. It must be specified as &qspi to inherit from the nrf52840 qspi definition.

&qspi { /* dedicated MX25L */
status = "okay";
sck-pin = <21>;
io-pins = <17>, <23>, <22>, <19>;
csn-pins = <20>;
mx25r08: mx25r0835f@0 {
compatible = "nordic,qspi-nor";
reg = <0>;
writeoc = "pp4io";
readoc = "read4io";
sck-frequency = <8000000>;
label = "MX25R0835F";
jedec-id = [c2 28 14];
size = <0x0800000>; /* flash capacity in bits */
t-enter-dpd = <10000>;
t-exit-dpd = <35000>;

Note that if you get the jedec-id wrong then no driver will be created and you’ll be left with null pointers to undefined drivers.

The writeoc and readoc values indicate that all 4 pins are used for data and the size here is deliberately small to guarantee some of the flash is left alone. The sck-frequency is also very conservative.

2. Specify a “storage” partition

Also added to the board .dtsi file is the following partition:

// using an mx25R0835
/delete-node/ &storage_partition;
&mx25r08 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@40000 {
label = "storage";
reg = <0x00040000 0x00020000>;

Here I don’t need much space so I’ve started the partition at 0x40000 to leave space at the beginning for a fat system or other stuff. The reg setting is <’offset’ ‘size in bytes’>.

The &mx25r08 links it to the qspi definition subobject and we thus have a single partition of size 0x20000 named ‘storage’. We delete-node the original board default soc flash storage_partition.

3. Add defines to prj.conf

Now we have to add enough to the prj.conf to support qspi.

# Need this when storage is on MX25R08
# the default page size is 64K but 4K is allowed so...
#--- any file system
#----little file system

3a. Debugging ->

It’s hard to see what’s going wrong during qspi definition because most of the driver initialization is done static — before main() gets called. It is possible, however, to put breakpoints on that initialization code in Segger and that’s how I tracked down the jedec-id requirement. Find the source module then place a breakpoint.

Debugging the flash init sequence

4. Use it in code

Here’s a code chunk with one test method and one raw read/write method.

Home Wireless

Home automation in the wireless IOT era

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store