This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Look like a hard coded bug in API generated in build\zephyr\include\generated\syscalls\flash.h

Look like a hard coded bug in API generated in build\zephyr\include\generated\syscalls\flash.h  ? 

-- Found BOARD.dts:  zephyr/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts.


When the QSPI interface of nRF52840 is set to quad mode, there is a quad enable(QE) bit of the status register of the external QSPI flash is also needed to be set.   The QSPI flash used in the nRF52840_DK is MX25R64 from Macroni and the QE bit is bit 6 of the status registeras indicated in page 26, table 3 of the MX25R64


https://www.mxic.com.tw/Lists/Datasheet/Attachments/7873/MX25U25645G,%201.8V,%20256Mb,%20v1.4.pdf

0x40 is seemed to be hard coded in the API generated in build\zephyr\include\generated\syscalls\flash.h when the QSPI is in Quad mode.  It works fine if you are using the nRF52840_DK, but it may break when you have a custom board with a different flash chip.  I am using GD25LQ80C and the QE bit is bit 9 instead of bit 6 and bit 6 is for block protection, so using the API generated will fail in write operation if QSPI is in quad mode because the chip is block protected.

Page 11 of the following data sheet from gigadevice.  bit 9 is the QE bit and bit 6 is for block protection. 

www.gigadevice.com/.../

There is nothing in the zephyr.dts generated can mislead to a MX25R64 being used
-- Generated zephyr.dts:       build/zephyr/zephyr.dts
qspi: qspi@40029000 {
                        compatible = "nordic,nrf-qspi";
                        #address-cells = < 0x1 >;
                        #size-cells = < 0x0 >;
                        reg = < 0x40029000 0x1000 >;
                        interrupts = < 0x29 0x1 >;
                        status = "okay";
                        label = "QSPI";
                        sck-pin = < 0x13 >;
                        io-pins = < 0x15 >, < 0x17 >, < 0x20 >, < 0x16 >;
                        csn-pins = < 0x21 >;
                        gd25lq80c: gd25lq80ceigr@0 {
                                compatible = "nordic,qspi-nor";
                                reg = < 0x0 >;
                                writeoc = "pp4o";
                                readoc = "read4io";
                                sck-frequency = < 0x1e8480 >;
                                label = "GD25LQ80C";
                                jedec-id = [ C8 60 14 ];
                                sfdp-bfp;
                                size = < 0x800000 >;
                                has-dpd;
                                t-enter-dpd = < 0x64 >;
                                t-exit-dpd = < 0x64 >;
                        };
                };

The following is the waveform captured from the logic analyzer indicating bit 6 of the external flash is being set by the API generated.0x05 is the Read Status Register command(RDRS) and the result is 0x43.   bits 0 and 1 are WEL and WIP.  However, bit 6 is Block protection bit for GD25LQ80C and QE bit for MX25R64.  <---  See the problem!!!

0x05 is the RDSR Read Status command and the 0x43 is the result indicating the bit6(BP for GD25LQ80C but QE for MX25R64).  bits 0 and 1 are WEL and WIP for write enable latched and write in progress.  Repeating 0x05 Read Status commands pulling 0x43 until it became 0x40 when both WIP and WEL were cleared to 0 indicating the write operation was done.  However, 0x40 indicating bit 6 was set.  It is a problem for GD25LQ80C when block protection is set in a write operation, but it is the QE bit for the MX25R64.

Since block protection bit 6 of the status register was set(0x40).  The write enable command(0x06) and program page command(0x32) failed to write data into the GD25LQ80C flash device.  

0x40(bit 6) is cleared when the QSPI interface is set to standard mode.

My set up

-- Zephyr version: 2.4.99

NCS Toolchain 1.6.1 for building.

-- The C compiler identification is GNU 9.2.1

-- The CXX compiler identification is GNU 9.2.1

-- The ASM compiler identification is GNU

I am using a MAC

MAC OS.  Big Sur. ver 11.5.2

Model Name: MacBook Pro

  Model Identifier: MacBookPro14,1

  Processor Name: Dual-Core Intel Core i5

  Processor Speed: 2.3 GHz

  Number of Processors: 1

  Total Number of Cores: 2

  L2 Cache (per Core): 256 KB

  L3 Cache: 4 MB

  Hyper-Threading Technology: Enabled

  Memory: 8 GB

  System Firmware Version: 429.140.8.0.0

Parents
  • Hi

    QE bit handling is specified by the quad-enable-requirements property of the nordic, qspi-nor binding. The default value of this property is "S1B6", and hence the driver sets bit 6 of the first status register byte to enable the Quad mode (that's what is required for the MX25R64). Apart from the "S1B6" value, the QSPI NOR Flash driver also supports the "NONE" value, which prevents the driver from setting any bit in the status register to enable the Quad mode. It seems that for both GD25LQ80C and W25Q32FV this setting should be used, as the QE bit is non-volatile in both flash chips. Thus, the QE bit should be set once to 1 and the driver should be prevented from writing the status register, hence the following line should be added in the "nordic, qspi-nor" compatible mode:

    quad-enable-requirements = "NONE";
    

    For reference, there is a commit that introduced the current way of handling the QE bit (previously, the QSPI NOR Flash driver used a Kconfig option for specifying this bit). The commit message explains why this is done how it is.

    Best regards,

    Simon

  • Hello Simonr,

    quad-enable-requirements = "S2B1";   <---  It not supported.  This should be an action
    item for Zephyr to support QE bit located in any bit position in the status register.

    Only (['NONE', 'S2B1v1', 'S1B6', 'S2B7', 'S2B1v4', 'S2B1v5', 'S2B1v6']). are support now

    As indicated in the following error message.

    devicetree error: value of property 'quad-enable-requirements' on /soc/qspi@40029000/gd25lq80ceigr@0 in nrf52840dk_nrf52840.dts.pre.tmp ('S2B1') is not in 'enum' list in ........./zephyr/dts/bindings/mtd/nordic,qspi-nor.yaml (['NONE', 'S2B1v1', 'S1B6', 'S2B7', 'S2B1v4', 'S2B1v5', 'S2B1v6'])

     
    quad-enable-requirements = "S1B6";   <---- It is the default setting for nRF52840DK, but
    it hidden. It need to be put in the BOARD.dts file explicitly, because many custom board using
    nRF52840DK as the base for hw and sw reference and Nordic will get a lot of question like getting
    88888... or 0000... in reading SPI flash if the quad-enable-requirements is not set correctly.

    Just my 2cents for future improvement on quad-enable-requirements
Reply
  • Hello Simonr,

    quad-enable-requirements = "S2B1";   <---  It not supported.  This should be an action
    item for Zephyr to support QE bit located in any bit position in the status register.

    Only (['NONE', 'S2B1v1', 'S1B6', 'S2B7', 'S2B1v4', 'S2B1v5', 'S2B1v6']). are support now

    As indicated in the following error message.

    devicetree error: value of property 'quad-enable-requirements' on /soc/qspi@40029000/gd25lq80ceigr@0 in nrf52840dk_nrf52840.dts.pre.tmp ('S2B1') is not in 'enum' list in ........./zephyr/dts/bindings/mtd/nordic,qspi-nor.yaml (['NONE', 'S2B1v1', 'S1B6', 'S2B7', 'S2B1v4', 'S2B1v5', 'S2B1v6'])

     
    quad-enable-requirements = "S1B6";   <---- It is the default setting for nRF52840DK, but
    it hidden. It need to be put in the BOARD.dts file explicitly, because many custom board using
    nRF52840DK as the base for hw and sw reference and Nordic will get a lot of question like getting
    88888... or 0000... in reading SPI flash if the quad-enable-requirements is not set correctly.

    Just my 2cents for future improvement on quad-enable-requirements
Children
Related