regarding the QSPI example merging with my application with other interruptions

Hi Nordic,

I am using your QSPI example code and make it into functions for my application. The code could run if I block the rest part of my code and only run the QSPI part. But when I add the rest of the application code, the QSPI function is not working. Could you please help to suggest how to fix this issue?

I am using the SDK 17.0.2

1. here is my main function part of the code , when I disable  the line 41-45, then the QSPI read and write works fine.

Else(when I enable) it reports errors below 

<error> app: ERROR 16 [NRF_ERROR_INVALID_ADDR] at D:\nRF5_SDK_17.0.2_d674dde\examples\nrf52840_222\ble_app_uart_peripheral\test\data_storage.c:301
PC at: 0x0002B261, It reports errors when calling "nrf_drv_qspi_write", my guessing is nrf_drv_qspi_init is not properly initialized wither.  

//@brief Application main function.

int main(void)
   {
	   
	  
    //gpio_output_voltage_setup_3v3();    //
	//NRF_LOG_INFO("\nTT\n");nrf_delay_ms(10);
    #ifdef  WATCHDOG_ENABLE
        start_watchdog();
    #endif
    
    gpio_output_voltage_setup(); 
    //gpio_output_voltage_setup_1_8();
    bool erase_bonds;
    uint8_t find_flag=0;
    AxesRaw_t data;

    log_init();
    
    store_data(); //Here is the QSPI function calling 

   
    //NRF_LOG_DEFAULT_BACKENDS_INIT();
    nrf_gpio_cfg_output(BLUE_LED);
	
	NRF_LOG_INFO("\nTT\n");nrf_delay_ms(10);

    //store_data(); //flash memory chipset test 
    //store_data(); //flash memory chipset test 
   
   #ifdef DEBUG_UART_INFO_RTT
	NRF_LOG_INFO("\nstart.\n");nrf_delay_ms(10);
	#endif
	
    nrf_gpio_cfg_output(BSP_BOARD_LED_0);

    nrf_gpio_cfg_output(IMU_POWER_PIN);
    nrf_gpio_pin_set(IMU_POWER_PIN); 
   
    // the code below added which cause the QSPI not running
    LIS3DH_Init(); 
    power_management_init();
    interrupt_pin_init();
    saadc_init();
}

2. the code for the function of QSPI is attached. 

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

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "sdk_config.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)
{
    UNUSED_PARAMETER(event);
    UNUSED_PARAMETER(p_context);
    m_finished = true;
}

static void configure_memory()
{
    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 = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    // Send reset command
    cinstr_cfg.opcode = QSPI_STD_CMD_RST;
    err_code = nrf_drv_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 = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &temporary, NULL);
    APP_ERROR_CHECK(err_code);
}


int store_data(void)
{
    uint32_t i;
    uint32_t err_code;

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

    //NRF_LOG_DEFAULT_BACKENDS_INIT();

    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_LOG_RAW_INFO("%2X ",m_buffer_tx[i]);
    }

    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.");

    configure_memory();

    m_finished = false;
    //err_code = nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_64KB, 0);
    err_code = nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, 0);
    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);
    APP_ERROR_CHECK(err_code);
    WAIT_FOR_PERIPH();
    NRF_LOG_INFO("Process of writing data start");
    for (i = 0; i < QSPI_TEST_DATA_SIZE; ++i)
    {
        NRF_LOG_RAW_INFO("%2X ",m_buffer_rx[i]);
    }

    err_code = nrf_drv_qspi_read(m_buffer_rx, QSPI_TEST_DATA_SIZE, 0);
    WAIT_FOR_PERIPH();
    NRF_LOG_INFO("Data read");

    for (i = 0; i < QSPI_TEST_DATA_SIZE; ++i)
    {
        NRF_LOG_RAW_INFO("%2X ",m_buffer_rx[i]);
    }



    NRF_LOG_INFO("Compare...");
    if (memcmp(m_buffer_tx, m_buffer_rx, QSPI_TEST_DATA_SIZE) == 0)
    {
        NRF_LOG_INFO("Data consistent");
    }
    else
    {
        NRF_LOG_INFO("Data inconsistent");
    }

    nrf_drv_qspi_uninit();


}

3. Here some interruption level I have setup. I wondering is it the interruption level cause the issues?

#ifndef GPIOTE_CONFIG_IRQ_PRIORITY
#define GPIOTE_CONFIG_IRQ_PRIORITY 7 
#endif

#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY
#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif

#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY
#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif

#ifndef NRFX_QSPI_CONFIG_IRQ_PRIORITY
#define NRFX_QSPI_CONFIG_IRQ_PRIORITY 6

// </e>

// <e> NRFX_QSPI_ENABLED - nrfx_qspi - QSPI peripheral driver
//==========================================================
#ifndef NRFX_QSPI_ENABLED
#define NRFX_QSPI_ENABLED 1//
#endif
// <o> NRFX_QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 


#ifndef NRFX_QSPI_CONFIG_SCK_DELAY
#define NRFX_QSPI_CONFIG_SCK_DELAY 1
#endif

// <o> NRFX_QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. 
#ifndef NRFX_QSPI_CONFIG_XIP_OFFSET
#define NRFX_QSPI_CONFIG_XIP_OFFSET 0
#endif

// <o> NRFX_QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
 
// <0=> FastRead 
// <1=> Read2O 
// <2=> Read2IO 
// <3=> Read4O 
// <4=> Read4IO 

#ifndef NRFX_QSPI_CONFIG_READOC
#define NRFX_QSPI_CONFIG_READOC 0
#endif

// <o> NRFX_QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
 
// <0=> PP 
// <1=> PP2O 
// <2=> PP4O 
// <3=> PP4IO 

#ifndef NRFX_QSPI_CONFIG_WRITEOC
#define NRFX_QSPI_CONFIG_WRITEOC 0
#endif

// <o> NRFX_QSPI_CONFIG_ADDRMODE  - Addressing mode.
 
// <0=> 24bit 
// <1=> 32bit 

#ifndef NRFX_QSPI_CONFIG_ADDRMODE
#define NRFX_QSPI_CONFIG_ADDRMODE 0
#endif

// <o> NRFX_QSPI_CONFIG_MODE  - SPI mode.
 
// <0=> Mode 0 
// <1=> Mode 1 

#ifndef NRFX_QSPI_CONFIG_MODE
#define NRFX_QSPI_CONFIG_MODE 0
#endif

// <o> NRFX_QSPI_CONFIG_FREQUENCY  - Frequency divider.
 
// <0=> 32MHz/1 
// <1=> 32MHz/2 
// <2=> 32MHz/3 
// <3=> 32MHz/4 
// <4=> 32MHz/5 
// <5=> 32MHz/6 
// <6=> 32MHz/7 
// <7=> 32MHz/8 
// <8=> 32MHz/9 
// <9=> 32MHz/10 
// <10=> 32MHz/11 
// <11=> 32MHz/12 
// <12=> 32MHz/13 
// <13=> 32MHz/14 
// <14=> 32MHz/15 
// <15=> 32MHz/16 

#ifndef NRFX_QSPI_CONFIG_FREQUENCY
#define NRFX_QSPI_CONFIG_FREQUENCY 15
#endif

// <s> NRFX_QSPI_PIN_SCK - SCK pin value.
#ifndef NRFX_QSPI_PIN_SCK
#define NRFX_QSPI_PIN_SCK 19// NRF_QSPI_PIN_NOT_CONNECTED
#endif

// <s> NRFX_QSPI_PIN_CSN - CSN pin value.
#ifndef NRFX_QSPI_PIN_CSN
#define NRFX_QSPI_PIN_CSN 17//NRF_QSPI_PIN_NOT_CONNECTED
#endif

// <s> NRFX_QSPI_PIN_IO0 - IO0 pin value.
#ifndef NRFX_QSPI_PIN_IO0
#define NRFX_QSPI_PIN_IO0 20// NRF_QSPI_PIN_NOT_CONNECTED
#endif

// <s> NRFX_QSPI_PIN_IO1 - IO1 pin value.
#ifndef NRFX_QSPI_PIN_IO1
#define NRFX_QSPI_PIN_IO1 21// NRF_QSPI_PIN_NOT_CONNECTED
#endif

// <s> NRFX_QSPI_PIN_IO2 - IO2 pin value.
#ifndef NRFX_QSPI_PIN_IO2
#define NRFX_QSPI_PIN_IO2 22// NRF_QSPI_PIN_NOT_CONNECTED
#endif

// <s> NRFX_QSPI_PIN_IO3 - IO3 pin value.
#ifndef NRFX_QSPI_PIN_IO3
#define NRFX_QSPI_PIN_IO3 23//NRF_QSPI_PIN_NOT_CONNECTED
#endif

// <o> NRFX_QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
 
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef NRFX_QSPI_CONFIG_IRQ_PRIORITY
#define NRFX_QSPI_CONFIG_IRQ_PRIORITY  6 
#endif

// </e>

// <e> NRFX_RNG_ENABLED - nrfx_rng - RNG peripheral driver

Parents
  • Hello,

    Please use '__ALIGN(4)' when defining the your tx buffer array to ensure it always starts at a word-aligned address as required by the QSPI peripheral. The write call will return with NRF_ERROR_INVALID_ADDR if the source address is not aligned to a word boundary.

    Register description stating that source pointer must be word aligned

    Defining the buffers with the ALIGN keyword

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

    Best regards,

    Vidar

Reply
  • Hello,

    Please use '__ALIGN(4)' when defining the your tx buffer array to ensure it always starts at a word-aligned address as required by the QSPI peripheral. The write call will return with NRF_ERROR_INVALID_ADDR if the source address is not aligned to a word boundary.

    Register description stating that source pointer must be word aligned

    Defining the buffers with the ALIGN keyword

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

    Best regards,

    Vidar

Children
Related