Cannot initialize QSPI (nRF52840 and Micron NOR Flash)

I'm working on a custom board with a nRF52840 and a Micron NOR Flash MT25QU128ABA8E12-0SIT (https://www.micron.com/products/nor-flash/serial-nor-flash/part-catalog/mt25qu128aba8e12-0sit)

I copied code from the QSPI example in SDK17.1.0, after verifying that it worked on the PCA10056 board.

Here's a snippet of the relevant code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "boards.h"

#include "nrf_drv_qspi.h"
#include "nrf_delay.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#include "main_memory.h"

#define QSPI_STD_CMD_WRSR   0x01
#define QSPI_STD_CMD_RSTEN  0x66
#define QSPI_STD_CMD_RST    0x99

#define QSPI_TEST_DATA_SIZE 256

#define WAIT_FOR_PERIPH() do { \
        while (!m_finished) {} \
        m_finished = false;    \
    } while (0)

static volatile bool m_finished = false;
static uint8_t m_buffer_tx[QSPI_TEST_DATA_SIZE];
static uint8_t m_buffer_rx[QSPI_TEST_DATA_SIZE];

static void qspi_handler(nrf_drv_qspi_evt_t event, void * p_context);
static void configure_memory(void);

void main_memory_setup(void){ }
void main_memory_start(void){ }

void main_memory_tests(void)
{ 
    uint32_t i;
    uint32_t err_code;

    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_INFO(""
                 "QSPI write and read example using 24bit addressing mode");

    srand(0);
    for (i = 0; i < QSPI_TEST_DATA_SIZE; ++i)
    {
        m_buffer_tx[i] = (uint8_t)rand();
    }

    nrf_drv_qspi_config_t config = NRF_DRV_QSPI_DEFAULT_CONFIG;

    err_code = nrf_drv_qspi_init(&config, qspi_handler, NULL);
    APP_ERROR_CHECK(err_code);
    NRF_LOG_INFO("QSPI example started.");
}

I checked multiple times that all the GPIO pins are properly defined, as below

//QSPI
#define BSP_QSPI_CSN_PIN          P0_18
#define BSP_QSPI_SCK_PIN          P0_19
#define BSP_QSPI_IO0_PIN          P0_21
#define BSP_QSPI_IO1_PIN          P0_22
#define BSP_QSPI_IO2_PIN          P0_23
#define BSP_QSPI_IO3_PIN          P1_00

And I copied the relevant sections from the example's sdk_config.h

As soon as I call nrf_drv_qspi_init(&config, qspi_handler, NULL);, I get an APP_ERROR_CHECK of a timeout.

Everything I read, implies a physical connection problem on the board between the nRF52 and the QSPI NOR Flash. But following the traces, everything looks as it should be. I could assume a poor BGA soldering or other chip-specific problem, but it happens on 5 different boards, so I can rule that out.

I cannot use the logic analyzer, given it's a multilayer board and the QSPI chip is a BGA form factor (not saying i cannot be done, just that I don't have the tools/skills to do it).

I looked at everything I could think of (pin drive strength, etc) and tried different clock cycles and configs (i.e. QSPI_CONFIG_READOC 2), but nothing makes a difference

I'm obviously missing something, possibly in the timing of the Micron part we are using. I could understand if the code failed when trying to read or write to the NOR, but in the case fails at init, which seems to imply a pretty major problem

Any suggestions on what to try next? What am I missing?

EDIT: i just noticed that the board designer has used P0.18 as CS, and CS can be defined as nRESET. I managed to read the voltage on the QSPI_CSN (P0.18), and it's always stuck high. I found a ticket mentioning removing CONFIG_GPIO_AS_PINRESET, which I did, but doesn't seem to make any differenbce even after forcing a clean rebuild

Any idea why P0.18 is stuck high (assuming it's not a hardware problem, but the board layout seems ok, and it happens on multiple boards)

  • Answering my own question: it was indeed a problem with having originally defined CONFIG_GPIO_AS_PINRESET. Once that is done, the pin is always pulled up high and even if redefined as a GPIO or for QSPI, it won't work (with no error notification)

    What I didn't realize, is that the setting is persisted in UICR (which makes sense in hindsight, as most things do Slight smile). So once an image with CONFIG_GPIO_AS_PINRESET is flashed on the chip, pin P0.18 will not work for anything else anymore, until the UICR data is erased

    So, after removing CONFIG_GPIO_AS_PINRESET, I also needed to erase UICR, either with nrfjprog or the Erase All function in the GUI Nordic Prgrammer. 

    Problem solved, QSPI now initializes as expected

Related