QSPI Flash memory configuration

Hello,

I have a nrf52840 project that uses an external flash over QSPI. My code works as expected with the PCA10056 devkit and the memory MX25R6435F (64 Mbit).
When I port the code to my custom PCB, which uses the memory MX25L25645G (256 Mbit), the same code works for addresses that are < 3 bytes length, but it fails to access bigger addresses. I.e. if I try to write to address 0x1000000, it will write to address 0, instead.

The MX25L25645G datasheet mentions that 4 bytes address mode needs to be enabled to access the higher addresses, so I suspect the flash driver (#include <zephyr/drivers/flash.h>) is not doing that.

My next step would be to check the driver implementation, but before I do that, I'd like to know what is the right way of solving this with Zephyr. This is my 1st Zephyr project and I'm not sure if I configured the memory correctly or I missed something.

In case I do need to change the driver, what's the best way of doing that? Just change the current code or create a new one? Guidance is appreciated.

This is the DTS configuration I'm using for the memory (I used the MX25R6435F as a base and changed the values accordingly).

qspi: qspi@40029000 
{
    compatible = "nordic,nrf-qspi";
    #address-cells = < 0x1 >;
    #size-cells = < 0x0 >;
    reg = < 0x40029000 0x1000 >, < 0x12000000 0x8000000 >;
    reg-names = "qspi", "qspi_mm";
    interrupts = < 0x29 0x1 >;
    status = "okay";
    pinctrl-0 = < &qspi_default >;
    pinctrl-1 = < &qspi_sleep >;
    pinctrl-names = "default", "sleep";
    mx25l25: mx25l25645g@0 
    {
        compatible = "nordic,qspi-nor";
        reg = < 0x0 >;
        writeoc = "pp4io";
        readoc = "read4io";
        sck-frequency = < 0x7a1200 >;
        jedec-id = [ C2 20 19 ];
        sfdp-bfp = [ E5 20 ... ];
        size = < 0x10000000 >;
        has-dpd;
        t-enter-dpd = < 0x2710 >;
        t-exit-dpd = < 0x88b8 >;
    };
};

Thank you!

  • Hi

    The nrfx_qspi library uses the NRF_QSPI_ADDRMODE_ to set the address mode to 24 bit by default, but in nrf_qspi.h there is also a NRF_QSPI_ADDRMODE_32BIT that can be used to set 32-bit addressing I think. Alternatively you can send this op code to the QSPI flash using a custom instruction which our QSPI peripheral supports. Here is an example snippet of how you can send an OP code to the flash device.

    nrfx_err_t CINSTR_function(size_t OPCODE)
    {
    	
    	nrf_qspi_cinstr_conf_t cinstr_cfg = {
    		.opcode 	= OPCODE,
    		.length 	= NRF_QSPI_CINSTR_LEN_1B,
    		.io2_level	= false,
    		.io3_level 	= false,
    		.wipwait 	= true,
    		.wren 		= true
    	};
    
        int err = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        if (err != NRFX_SUCCESS) {
    	    }
    
    
    return NRFX_SUCCESS;
    }

    Best regards,

    Simon

  • Thank you  , but the snippet you mentioned was not included in the message :)

    I used the info here as a start point and tried this (no luck, even trying with different parameters)

    nrf_qspi_cinstr_conf_t command;    
    command.opcode  = 0xB7;
    command.length 	= NRF_QSPI_CINSTR_LEN_1B;
    command.io2_level	= false;
    command.io3_level 	= false;
    command.wipwait 	= true;
    command.wren 		= true;
    nrf_qspi_cinstr_transfer_start(NRF_QSPI, &command);

    and then tried this (again, no luck):

    nrf_qspi_addrconfig_conf_t cfg;
    cfg.opcode = 0xB7;
    cfg.byte0 = 0;
    cfg.byte1 = 0;
    cfg.mode = NRF_QSPI_ADDRCONF_MODE_OPCODE;
    cfg.wipwait = true;
    cfg.wren = true;
    
    nrf_qspi_addrconfig_set(NRF_QSPI, &cfg);

    I sent these commands before doing the write/erase/read flash operations...

  • Hi

    Not sure what happened there. I have updated the previous reply to include the snippet I was referring to. Sorry about that.

    Best regards,

    Simon

  • I tried all the suggestions and none worked. The nrfx_qspi_cinstr_xfer function always returns BUSY error. I don't know why, but I think Zephyr is using the driver somehow and making it busy.

    Anyways, found a better solution using the DTS file. Just need to add:

    enter-4byte-addr = <0x87>;
    address-size-32;

    The whole overlay node I used:

    &qspi
    {    
        mx25l25: mx25l25645g@0
        {
            compatible = "nordic,qspi-nor";
            reg = < 0x0 >;
            writeoc = "pp4io";
            readoc = "read4io";
            sck-frequency = < 0x7a1200 >;
            jedec-id = [ C2 20 19 ];
            sfdp-bfp = [ e5 20 fb ff ff ff ff 0f 44 eb 08 6b 08 3b 04 bb fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52 10 d8 00 ff d6 59 dd 00 82 9f 03 db 44 03 67 38 30 b0 30 b0 f7 bd d5 5c 4a 9e 29 ff f0 50 f9 85 ];
            size = < 0x10000000 >;
            has-dpd;
            t-enter-dpd = < 0x2710 >;
            t-exit-dpd = < 0x88b8 >;
            enter-4byte-addr = <0x87>;
    		address-size-32;
        };
    };

Related