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

Compatibility between qspi driver and Winbond W25M02GW flash memory

The qspi driver seems to make a number of assumptions about the protocol that don't fit the Winbond W25M02GW (and certain other) SPI flash chips.

Two major issues I've run into:

  • The QSPI driver always seems to send 32 bits of payload with the Fast Read (0x0b) opcode, even with ADDRMODE_24BIT. The Winbond chip expects 24 bits of payload. This causes the peripheral to ignore the first byte read back.
  • Status register reads sent by the QSPI peripheral consist of a single 0x05 opcode with no arguments. The Winbond chip expects an argument indicating one of three types of status registers being read. I suspect this means that the QSPI peripheral will not block correctly as it can't get the BUSY signal from the device.

There are other issues too that are less critical:

  • The QSPI peripheral appears to assume that the Fast Read and related instructions address all of memory. The W25M02GW has a separate instruction to load a page from memory into buffer, and Fast Read and friends only read from the buffer. Not that big a deal, as it's possible to issue the separate instruction using a custom command.
  • Some of the driver documentation doesn't match what actually happens. For example, NRF_QSPI_ERASE_LEN_64KB corresponds to opcode 0xd8, which on W25M02GW erases a 128KB block (64 pages x 2048 bytes per page).

All of the above was verified by looking at the behavior of the QSPI peripheral using a logic analyser connected to the SPI bus.

Are there plans to support these types of QSPI devices in a future update?

Parents
    1. 24-bit address mode. 
      I'll investigate this when I get back from a business trip on Wednesday. D
      Do you need to use 24-bit addressing?

    2. Can you use a custom instruction for your register reads?

    3. The QSPI peripheral does not support all features that flash vendors have :/

    4. Different flash have different instruction set. The one we've used is that one on our DK. You should double check the instruction set and change it appropriately when using any other flash device. I agree that the documentation is lacking in this regard. I'll notify the developers :)
  • 1. I don't think either "32 bit" or "24 bit" addressing is really appropriate for this device. It uses a split addressing model where pages are addressed separately from columns in a page (each page is 2048 bytes). I just tried it in the hopes it would at least generate the right command sequence for a read.

    2. I can use custom instructions to block, as well as to set up a page before it's read (or similarly write a page to persistent memory). But I can't fix the peripheral's assumptions about read (and presumably write) command structure with custom instructions.

    4. What do you mean by "change it appropriately"? As far as I know, the driver does not allow this level of customization. Maybe the peripheral has hidden settings that the driver doesn't expose - if so it'd be great to get docs on those indeed.

  • I've got some comments from the driver developer:

    Few comments from my side. I assume that customer uses Buffer Read mode (not continous one).

     

     

    The QSPI driver always seems to send 32 bits of payload with the Fast Read (0x0b) opcode, even with ADDRMODE_24BIT. The Winbond chip expects 24 bits of payload. This causes the peripheral to ignore the first byte read back.
    

    This one is weird, because we are using 24bit mode on the pca10056 DKs and as I remember everythig worked well. There is example in SDK that uses 24bit addressing mode.

     

     

    --------------------------------------------------------------

     

    Status register reads sent by the QSPI peripheral consist of a single 0x05 opcode with no arguments. The Winbond chip expects an argument indicating one of three types of status registers being read. I suspect this means that the QSPI peripheral will not block correctly as it can't get the BUSY signal from the device.
    

    Sure, but there are two ways of checking status register. One way is nrfx_qspi_mem_busy_check() function that sends opcode and receive data, but also peripheral checks this register automatically when you for example trigger WRITE or ERASE task. READ task is not 'affected' by this.

    So this function (I mean status byte check) has to be implemented outside nrfx_qspi driver. Customer can use custom instruction method from nrfx_qspi driver to do it. I recommend to check status bytes before WRITE and ERASE procedures.

     

    ------------------------------------------------------------------

     

     

    The QSPI peripheral appears to assume that the Fast Read and related instructions address all of memory. The W25M02GW has a separate instruction to load a page from memory into buffer, and Fast Read and friends only read from the buffer. Not that big a deal, as it's possible to issue the separate instruction using a custom command.
    

    Sure, custom command to setup particular die (Software Die Select - 0xC2 ), execute command to load page (Page Data Read - 0x13) and fast read to start reading data in 24bit (remember that first 16bit data is column address and the last one - 8bit is just dummy block of data).

     

    Similar situation in write mechanism: setup particular die (Software Die Select - 0xC2 ), write data to internal buffer in memory using normal write mechanism in 24bit, execute program command (Program Execute - 0x10).

     

    ------------------------------------------------------------------

     

     

    Some of the driver documentation doesn't match what actually happens. For example, NRF_QSPI_ERASE_LEN_64KB corresponds to opcode 0xd8, which on W25M02GW erases a 128KB block (64 pages x 2048 bytes per page).
    

    nrfx_qspi driver code is based on our documentation and it says:

     

    http://projecttools.nordicsemi.no/nightly/index.jsp?topic=%2Fgraviton%2Fqspi.html&cp=2_7_0_6_18_9_17&anchor=register.ERASE.LEN

    I hope it helps a little bit. Please let me know if you need more!

Reply
  • I've got some comments from the driver developer:

    Few comments from my side. I assume that customer uses Buffer Read mode (not continous one).

     

     

    The QSPI driver always seems to send 32 bits of payload with the Fast Read (0x0b) opcode, even with ADDRMODE_24BIT. The Winbond chip expects 24 bits of payload. This causes the peripheral to ignore the first byte read back.
    

    This one is weird, because we are using 24bit mode on the pca10056 DKs and as I remember everythig worked well. There is example in SDK that uses 24bit addressing mode.

     

     

    --------------------------------------------------------------

     

    Status register reads sent by the QSPI peripheral consist of a single 0x05 opcode with no arguments. The Winbond chip expects an argument indicating one of three types of status registers being read. I suspect this means that the QSPI peripheral will not block correctly as it can't get the BUSY signal from the device.
    

    Sure, but there are two ways of checking status register. One way is nrfx_qspi_mem_busy_check() function that sends opcode and receive data, but also peripheral checks this register automatically when you for example trigger WRITE or ERASE task. READ task is not 'affected' by this.

    So this function (I mean status byte check) has to be implemented outside nrfx_qspi driver. Customer can use custom instruction method from nrfx_qspi driver to do it. I recommend to check status bytes before WRITE and ERASE procedures.

     

    ------------------------------------------------------------------

     

     

    The QSPI peripheral appears to assume that the Fast Read and related instructions address all of memory. The W25M02GW has a separate instruction to load a page from memory into buffer, and Fast Read and friends only read from the buffer. Not that big a deal, as it's possible to issue the separate instruction using a custom command.
    

    Sure, custom command to setup particular die (Software Die Select - 0xC2 ), execute command to load page (Page Data Read - 0x13) and fast read to start reading data in 24bit (remember that first 16bit data is column address and the last one - 8bit is just dummy block of data).

     

    Similar situation in write mechanism: setup particular die (Software Die Select - 0xC2 ), write data to internal buffer in memory using normal write mechanism in 24bit, execute program command (Program Execute - 0x10).

     

    ------------------------------------------------------------------

     

     

    Some of the driver documentation doesn't match what actually happens. For example, NRF_QSPI_ERASE_LEN_64KB corresponds to opcode 0xd8, which on W25M02GW erases a 128KB block (64 pages x 2048 bytes per page).
    

    nrfx_qspi driver code is based on our documentation and it says:

     

    http://projecttools.nordicsemi.no/nightly/index.jsp?topic=%2Fgraviton%2Fqspi.html&cp=2_7_0_6_18_9_17&anchor=register.ERASE.LEN

    I hope it helps a little bit. Please let me know if you need more!

Children
No Data
Related