[nRF52840dk] nrfjprog always reading external flash least significant bit as 0

I'm trying to use nrfjprog to read and write the mx25r6435f external flash on the nRF52840dk board (I have version 3.0.0). However, what I am noticing is that nrfjprog always reads the least significant bit of every byte as 0. For example:

$ nrfjprog --erasepage 0x12000000-0x12000004
WARNING: An address for the --erasepage operation is not aligned to the start
WARNING: of page.
Initializing the QSPI peripheral.
Erasing range [0x00000000 - 0x00000FFF] in the external memory device.
Uninitializing the QSPI peripheral.

and then immediately after:

nrfjprog --memrd 0x12000000 --log
[ #####                ]   0.000s | Reading external memory, 0x0004 bytes @ 0x00000000 - 0x00
[                      ]   0.000s | Reading external memory, 0x0004 bytes @ 0x00000000 - 0x00
[ #################### ]   0.000s | Reading external memory, 0x0004 bytes @ 0x00000000 - Done
0x12000000: EEEEEEEE

The read always returns with each byte having a 0 as the least significant bit. This also happens when I try to program the external flash. The erase works successfully, the write works successfully, but the verify (read) "fails" because nrfjprog thinks the LSB is 0.

I've run code on the nrf that reads the flash and it reads correctly (after erase it is all 0xff and after programming with nrfjprog I get the expected values.

My programming:

cat a.bin
hello from tock flash

arm-none-eabi-objcopy -v -I binary -O ihex --change-addresses 0x12000000  a.bin a.hex
nrfjprog --qspichiperase --program a.hex

Is this a known issue? What can I do?

Debugging

I've tried every version of nrfjprog back to 10.12.1. Through 10.13 I see the same issue. At 10.12.1 it seems I can no longer read the flash, probably because I have a newer version of the nRF52840-dk.

My Setup

I'm on MacOS Ventura (13.3.1a).

Parents
  • Ok, I've tracked this down. I'm using the same QSPI lines as normal SPI to read and write the mx25r6435f flash chip from the nrf52840 itself. It seems like somehow configuring the MOSI pin (P0.21 on the nRF52840) with the spim0 peripheral causes that pin to be held low, resulting in the LSB of each nibble reading 0. When I remove the code that setups the SPI interface to read the external flash in our software, reading the flash through nrfjprog works as expected.

    How should I make these two use cases co-exist? Is the correct approach to make sure the SPIM0 peripheral is disabled when not in active use, because when it is enabled it seems to hold MOSI low?

Reply
  • Ok, I've tracked this down. I'm using the same QSPI lines as normal SPI to read and write the mx25r6435f flash chip from the nrf52840 itself. It seems like somehow configuring the MOSI pin (P0.21 on the nRF52840) with the spim0 peripheral causes that pin to be held low, resulting in the LSB of each nibble reading 0. When I remove the code that setups the SPI interface to read the external flash in our software, reading the flash through nrfjprog works as expected.

    How should I make these two use cases co-exist? Is the correct approach to make sure the SPIM0 peripheral is disabled when not in active use, because when it is enabled it seems to hold MOSI low?

Children
  • Hi,

    nrfjprog is as little intrusive as possible, so there is normally no reset when trying to read/write QSPI flash, so the SPIM0 peripheral is not reset in this case, which seems to cause problems as it was configured to use one if the QSPI pins. So you need to somehow ensure that SPIM0 does not use the pin. That could be by reconfiguring your firmware, erasing the firmware or something else. Or you could simply perform a reset.

    The following script python script using pynrfjprog demonstrate how to to reset the device halt it an read QSPI memory. I did not get a chance to test with a device that has the pin configured with SPM0 today, but hopefully it would work (for a device that does not it dumps the first 0x100 bytes from QSPI memory successfully):

    from pynrfjprog import LowLevel
    
    segger_serial_number = 683741650
    with LowLevel.API('NRF52') as api:
        api.connect_to_emu_with_snr(segger_serial_number)
        api.sys_reset()
        api.halt()
        api.qspi_configure()
        api.qspi_init()
        data = api.qspi_read(0, 0x100) # Reading
        print(data)

Related