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

nRF52840 DK QSPI flash needs Erase before Write?

I'm currently working with the MX25R6435F flash chip on board the nRF52840 DK and I'm running into issues with it. I don't know whether it's down to my lack of understanding of the flash programming procedure, or there's simply something I'm missing. As it stands, I cannot program a flash sector without first erasing it.

The code to write the flash is buried deep in a wider project, but the relevant extracts are as follows.

Flash Init

nrfx_qspi_config_t qspi_cfg = NRFX_QSPI_DEFAULT_CONFIG;
  qspi_cfg.pins.csn_pin = 17;
  qspi_cfg.pins.sck_pin = 19;
  qspi_cfg.pins.io0_pin = 20;
  qspi_cfg.pins.io1_pin = 21;
  qspi_cfg.pins.io2_pin = 22;
  qspi_cfg.pins.io3_pin = 23;
  nrfx_err_t err = nrfx_qspi_init(&qspi_cfg,(nrfx_qspi_handler_t)_static_qspi_callback,NULL);

  uint8_t temporary = 0x40;
  uint32_t err_code;
  nrf_qspi_cinstr_conf_t cinstr_cfg = {
      .opcode    = QSPI_STD_CMD_RSTEN,
      .length    = NRF_QSPI_CINSTR_LEN_1B,
      .io2_level = true,
      .io3_level = true,
      .wipwait   = true,
      .wren      = true
  };  

  // Send reset enable
  err_code = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
  APP_ERROR_CHECK(err_code);

  // Send reset command
  cinstr_cfg.opcode = QSPI_STD_CMD_RST;
  err_code = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
  APP_ERROR_CHECK(err_code);

  // Switch to qspi mode 
  cinstr_cfg.opcode = QSPI_STD_CMD_WRSR;
  cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_2B;
  err_code = nrfx_qspi_cinstr_xfer(&cinstr_cfg, &temporary, NULL);
  APP_ERROR_CHECK(err_code);

  // Enable writing
  cinstr_cfg.opcode = QSPI_STD_CMD_WREN;
  cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_1B;
  err_code = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
  APP_ERROR_CHECK(err_code);

Flash Write

nrfx_err_t err;
  //Enable writing

  nrf_qspi_cinstr_conf_t cinstr_cfg = {
      .opcode    = QSPI_STD_CMD_WREN,
      .length    = NRF_QSPI_CINSTR_LEN_1B,
      .io2_level = true,
      .io3_level = true,
      .wipwait   = true,
      .wren      = true
  };  

  err = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
  APP_ERROR_CHECK(err);

  /*Target address determination omitted*/

  //Set state to busy and log the last action for callback
  _lastAction = FLASH_ERASE_REQ;

  size_t size = sizeof(imuData_t) * length;
  
  /*_state = FLASH_BUSY;
  err = nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB,target_address);
  APP_ERROR_CHECK(err);
  
  while(_state != FLASH_BUSY){
    __WFE();
  }
  APP_ERROR_CHECK(err);*/
  
  //Check status register
  uint8_t status_value = 0;
  nrf_qspi_cinstr_conf_t const config =
        NRFX_QSPI_DEFAULT_CINSTR(0x05,
                                 NRF_QSPI_CINSTR_LEN_2B);
  err = nrfx_qspi_cinstr_xfer(&config, &status_value, &status_value);
  APP_ERROR_CHECK(err);
  printf("S: 0x%02x\n",status_value);


  _lastAction = FLASH_WRITE_REQ;
  printf("W: 0x%x\n",target_address);
  printf("Ex: %d\n",data[0].acc.x);
  err = nrfx_qspi_write(data,size,target_address);
  APP_ERROR_CHECK(err);

  return err;

When attempting the write, the status register is reading as 0x42 (Quad enabled and write enabled), and the QSPI write instruction returns sucessfuly, but the actual write request is ignored by the flash chip.

If I uncomment the erase request, however, and wait for it it complete before attempting the write, the write completes successfully. However, a sector erase time of 40ms is a huge overhead for regular sensor write, so I'd like to avoid it if possible.

Parents
  • Hi

    I'm not able to see where the issue is by looking at the snippets you uploaded I'm afraid.

    As long as you're not trying to write to an already full/used block/page on the flash chip I don't you shouldn't have to do an erase before writing. When you comment out the erase command, where do you call the program command and write address? It could be that the WEL bit is not set to 1 when you try writing without erasing, as that will cause any program/erase instructions to be ignored.

    Best regards,

    Simon

Reply
  • Hi

    I'm not able to see where the issue is by looking at the snippets you uploaded I'm afraid.

    As long as you're not trying to write to an already full/used block/page on the flash chip I don't you shouldn't have to do an erase before writing. When you comment out the erase command, where do you call the program command and write address? It could be that the WEL bit is not set to 1 when you try writing without erasing, as that will cause any program/erase instructions to be ignored.

    Best regards,

    Simon

Children
No Data
Related