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

nRF52840 DK - SDK16 - Not able to erase external FLASH memory blocks using QSPI

Hi everyone,

I am experimenting with the QSPI example provided with SDK 16. I am facing issues when I try to erase memory blocks or the entire chip.

1. First of all I try to erase the entire chip calling the functions below (either the first or the second one), however for both cases the system crashes end restarts.. 

err_code = nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_ALL, 0);

err_code = nrfx_qspi_chip_erase();

2. The second problem I am facing is when I try to erase a specific memory block. The snippet bellow:

  1. Erases a 64KB memory block starting from address 0
  2. Writes 8 bytes to the memory starting from address 0
  3. Erases a 4KB memory block starting from address 4000
  4. Read the first 8 bytes of the memory
  5. Compares Tx and Rx

m_finished = false;
  err_code = nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_64KB, 0); // NA - nrf_drv_qspi_erase,  Function for starting erasing of one memory block
  APP_ERROR_CHECK(err_code);
  WAIT_FOR_PERIPH();
  NRF_LOG_INFO("Process of erasing first block start");

  err_code = nrf_drv_qspi_write(m_buffer_tx, QSPI_TEST_DATA_SIZE, 0); // NA - nrf_drv_qspi_write,  Function for writing data to QSPI memory.
  APP_ERROR_CHECK(err_code);
  WAIT_FOR_PERIPH();
  NRF_LOG_INFO("Process of writing data start");

  m_finished = false;
  err_code = nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, 4000); // NA - nrf_drv_qspi_erase,  Function for starting erasing of one memory block
  APP_ERROR_CHECK(err_code);
  WAIT_FOR_PERIPH();
  NRF_LOG_INFO("Process of erasing first block start");

  err_code = nrf_drv_qspi_read(m_buffer_rx, QSPI_TEST_DATA_SIZE, 0); // NA - nrf_drv_qspi_read,   Function for reading data from QSPI memory.
  WAIT_FOR_PERIPH();
  NRF_LOG_INFO("Data read");
  for (i = 0; i < QSPI_TEST_DATA_SIZE; i++) {
    NRF_LOG_INFO("Data %d. %d", i, m_buffer_rx[i])
  }

  NRF_LOG_INFO("Compare...");
  if (memcmp(m_buffer_tx, m_buffer_rx, QSPI_TEST_DATA_SIZE) == 0) // memcpy() is used to copy a block of memory from a location to another
  {
    NRF_LOG_INFO("Data consistent");
  } else {
    NRF_LOG_INFO("Data inconsistent");
  }

The problem is that when I write the memory (step 2) and then erase a block (step 3), the written data erased when the starting address (of nrf_drv_qspi_write() function) is between 0-4092. When I read the first 8 bytes of memory, I read nothing (255) as shown below.. And also comparing the Tx with Rx the data are inconsistent.. I cannot understand what is going on.. Iam not able to erase any memory block between the address range 8-4092 without losing the written data..

However when I use as a starting address >= 4096 to erase the memory block then surprisingly I do not have any problem. I can read the written data and comparing Tx with Rx the data are consistent

err_code = nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, 4096);

  

Could you provide some help on these issues?

Thanks in advance

Nick

  • Hi Nick

    Do you get the unmodified QSPI example to work as intended? 

    Have you tried setting the DEBUG define in your preprocessor defines so you are able to see the debug messages as well, as I think you should get more information from the application that way. 

    1. Have you called the WREN command before doing the QSPI erase, as this is required by the MX25R6435F onboard flash chip to let you change data (doing write or erase). 

    2. 

    Iam not able to erase any memory block between the address range 8-4092 without losing the written data.

     I'm struggling to understand the question here. Do you say that you erase a block of data and is no longer seeing the data you've already written? If so, wouldn't that make sense, as you erase that block, effectively emptying it? 

    Please also note that all memory access by the QSPI peripheral to external memories have to be word-aligned to the external memory address space, and you can only read/write in full words (usually 32 bits).

    Best regards,

    Simon

  • Hi Simonr and thank you for your answer.

    Have you called the WREN command before doing the QSPI erase, as this is required by the MX25R6435F onboard flash chip to let you change data (doing write or erase).

    Why do I need to call the WREN command? I was thinking that this was performed in the background after calling either nrf_drv_qspi_erase or nrf_drv_qspi_write or nrf_drv_qspi_read

    Do you get the unmodified QSPI example to work as intended? 

    The unmodified example works fine. I can write and read the flash memory. Also I can erase and call the nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_64KB, 0). However, as I mentioned when I try to erase the entire chip bu calling either nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_ALL, 0) or nrfx_qspi_chip_erase() the system crashes.

    Can you replicate this?

    I'm struggling to understand the question here.

    What I mean is that if for example write the address range 0x00 - 0x07 (nrf_drv_qspi_write(m_buffer_tx, 8, 0x00)) and then I perform a sector erase starting from address 0x0C (nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, 0x0C)), the written data on address 0x00 - 0x07 will be erased as well, while I am expecting to erase the address range 0x0C - 0xFAB

    Please also note that all memory access by the QSPI peripheral to external memories have to be word-aligned to the external memory address space, and you can only read/write in full words (usually 32 bits).

    I noticed that thanks. All the write/read actions are 32bit aligned

    Please find atached the project ot replicate te issue.

    qspi.zip

  • Hi

    I'm restricted to home office for the moment, and I don't have an nRF52840 DK available at home I'm afraid, so I haven't been able to test your application. However, I took a look at your project, and I see that you have decreased the buffer size "QSPI_TEST_DATA_SIZE" by quite a lot from the default example (from 256 to 8). Is there a reason you have decreased the test data size by so much?

    In previous similar cases, it has been necessary to specifically word align the buffers to avoid data shifts. You can try doing that as well with these lines of code.

    __ALIGN(4) static uint8_t m_buffer_rx[QSPI_TEST_DATA_SIZE];
    __ALIGN(4) static uint8_t m_buffer_tx[QSPI_TEST_DATA_SIZE];

    Best regards,

    Simon

  • Hi Simon,

    Is there a reason you have decreased the test data size by so much?

    Just for testing purposes. Bus as fas as I know this couldn't be an issues since I am 4byte alligned. By the way, I tested the project by increasing the data size to 256bytes and also I word aligned the buffers but there was any effect..

    I think that I know what is going on.. Please correct me if I am wrong. The MX25R6435F flash memory is devided into 64k-byte blocks, 32k-byte blocks, 4k-byte sectors and 256bytes pages (see pg 13). Also according to page 9, the flash memory is sector or block erasable. This means that I cannot for example erase the 2nd half of sector 0 and the 1st half of sector 1 right? I have to erase either the entire sector 0 or sector 1 of both of them.

    The sector 0 has address range from 0x000 - 0xFFF. So by trying to perform a 4k-byte erasement starting from address 0x0C won't work and it will effectivelly delete the whole sector (that's why the data located at 0x00 - 0x0B are erased?)? This is how the nrf_drv_qspi_erase() function works?

    Thanks in advance 

    Nick

  • Nikosant03 said:
    This means that I cannot for example erase the 2nd half of sector 0 and the 1st half of sector 1 right? I have to erase either the entire sector 0 or sector 1 of both of them.

     Indeed, great detective work! I'm sorry I didn't catch this initially.

     

    Nikosant03 said:
    The sector 0 has address range from 0x000 - 0xFFF. So by trying to perform a 4k-byte erasement starting from address 0x0C won't work and it will effectivelly delete the whole sector (that's why the data located at 0x00 - 0x0B are erased?)

     Yes, that makes sense. When you call a sector erase from the 0x0C address, the whole sector where this address is located will be erased. 

    Best regards,

    Simon

Related