I slightly modified the qspi example code to try something that I'd eventually like to implement as part of my application. But when I try to interleave reads and writes then I get inconsistent data.
I made sure that my read write addresses are 4byte aligned, so that should not be a problem. Also another thing I noticed is that if I write the whole array m1 in one nrf_drv_qspi_write() call, and then read it into m2 in one nrf_drv_qspi_read() call - then the data is consistent. Only when I interleave read and write calls of smaller chunks, I see an issue.
Here is the code to illustrate what I'm doing.
typedef struct {
uint8_t buffer[6];
uint32_t value;
} my_struct;
my_struct m1[19], m2[19];
int main(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 32bit addressing mode");
srand(0);
for (i = 0; i < QSPI_TEST_DATA_SIZE; ++i)
{
m_buffer_tx[i] = (uint8_t)rand();
}
nrfx_qspi_config_t config = {
.xip_offset = NRFX_QSPI_CONFIG_XIP_OFFSET,
.pins = {
.sck_pin = QSPI_PIN_SCK,
.csn_pin = QSPI_PIN_CSN,
.io0_pin = QSPI_PIN_IO0,
.io1_pin = QSPI_PIN_IO1,
.io2_pin = QSPI_PIN_IO2,
.io3_pin = QSPI_PIN_IO3,
},
.irq_priority = 6,
.prot_if = {
.readoc = NRF_QSPI_READOC_FASTREAD,
.writeoc = NRF_QSPI_WRITEOC_PP,
.addrmode = NRF_QSPI_ADDRMODE_32BIT,
.dpmconfig = false,
},
.phy_if = {
.sck_freq = NRF_QSPI_FREQ_32MDIV2,
.sck_delay = 1,
.spi_mode = NRF_QSPI_MODE_0,
.dpmen = false
},
};
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(QSPI_ERASE_LEN_LEN_All, 0);
APP_ERROR_CHECK(err_code);
WAIT_FOR_PERIPH();
NRF_LOG_INFO("Process of erasing first block start");
int count = 0;
for(int i = 0; i <19; i++) {
m1[i].buffer[0] = count+1;
m1[i].buffer[1] = count+2;
m1[i].buffer[2] = count+3;
m1[i].buffer[3] = count+4;
m1[i].buffer[4] = count+3;
m1[i].buffer[5] = count+4;
m1[i].value = count+1234;
count++;
}
err_code = nrf_drv_qspi_write(&m1, 10*sizeof(my_struct), 0);
APP_ERROR_CHECK(err_code);
WAIT_FOR_PERIPH();
err_code = nrf_drv_qspi_write(&m1[10], 9*sizeof(my_struct), 20*sizeof(my_struct));
APP_ERROR_CHECK(err_code);
WAIT_FOR_PERIPH();
err_code = nrf_drv_qspi_read(&m2, 10*sizeof(my_struct), 0);
APP_ERROR_CHECK(err_code);
WAIT_FOR_PERIPH();
err_code = nrf_drv_qspi_read(&m2[10], 9*sizeof(my_struct), 20*sizeof(my_struct));
APP_ERROR_CHECK(err_code);
WAIT_FOR_PERIPH();
NRF_LOG_INFO("Compare...");
NRF_LOG_INFO("Struct size %u", sizeof(my_struct));
for(int i = 0; i < 19; i++) {
if (memcmp(&m1[i], &m2[i], sizeof(my_struct)) == 0)
{
NRF_LOG_INFO("Data consistent at index %u", i);
}
else
{
NRF_LOG_INFO("Data inconsistent at index %u", i);
NRF_LOG_INFO("WRITE -> %u %u %u %u %u %u", m1[i].buffer[0], m1[i].buffer[1], m1[i].buffer[2], m1[i].buffer[3], m1[i].buffer[4], m1[i].value);
NRF_LOG_INFO("READ -> %u %u %u %u %u %u", m2[i].buffer[0], m2[i].buffer[1], m2[i].buffer[2], m2[i].buffer[3], m2[i].buffer[4], m2[i].value);
}
}
nrf_drv_qspi_uninit();
for (;;)
{
}
}
And when this is the output for the code:
<info> app: QSPI write and read example using 32bit addressing mode <info> app: QSPI example started. <info> app: Process of erasing first block start <info> app: Compare... <info> app: Struct size 12 <info> app: Data inconsistent at index 0 <info> app: WRITE -> 1 2 3 4 3 1234 <info> app: READ -> 0 0 1 0 0 1024 <info> app: Data inconsistent at index 1 <info> app: WRITE -> 2 3 4 5 4 1235 <info> app: READ -> 0 1 0 0 0 1024 <info> app: Data inconsistent at index 2 <info> app: WRITE -> 3 4 5 6 5 1236 <info> app: READ -> 1 0 1 0 0 1024 <info> app: Data inconsistent at index 3 <info> app: WRITE -> 4 5 6 7 6 1237 <info> app: READ -> 0 1 2 0 0 0 <info> app: Data inconsistent at index 4 <info> app: WRITE -> 5 6 7 8 7 1238 <info> app: READ -> 1 2 3 0 0 0 <info> app: Data inconsistent at index 5 <info> app: WRITE -> 6 7 8 9 8 1239 <info> app: READ -> 4 3 0 0 0 0 <info> app: Data inconsistent at index 6 <info> app: WRITE -> 7 8 9 10 9 1240 <info> app: READ -> 5 0 1 0 0 0 <info> app: Data inconsistent at index 7 <info> app: WRITE -> 8 9 10 11 10 1241 <info> app: READ -> 0 1 2 0 0 1024 <info> app: Data consistent at index 8 <info> app: Data consistent at index 9 <info> app: Data inconsistent at index 10 <info> app: WRITE -> 11 12 13 14 13 1244 <info> app: READ -> 0 0 1 0 0 1024 <info> app: Data inconsistent at index 11 <info> app: WRITE -> 12 13 14 15 14 1245 <info> app: READ -> 0 1 0 0 0 1024 <info> app: Data inconsistent at index 12 <info> app: WRITE -> 13 14 15 16 15 1246 <info> app: READ -> 1 0 1 0 0 1024 <info> app: Data inconsistent at index 13 <info> app: WRITE -> 14 15 16 17 16 1247 <info> app: READ -> 0 1 2 0 0 0 <info> app: Data inconsistent at index 14 <info> app: WRITE -> 15 16 17 18 17 1248 <info> app: READ -> 1 2 3 0 0 0 <info> app: Data inconsistent at index 15 <info> app: WRITE -> 16 17 18 19 18 1249 <info> app: READ -> 4 3 0 0 0 0 <info> app: Data inconsistent at index 16 <info> app: WRITE -> 17 18 19 20 19 1250 <info> app: READ -> 5 0 1 0 0 0 <info> app: Data inconsistent at index 17 <info> app: WRITE -> 18 19 20 21 20 1251 <info> app: READ -> 0 1 2 0 0 1024 <info> app: Data inconsistent at index 18 <info> app: WRITE -> 19 20 21 22 21 1252 <info> app: READ -> 9 10 11 12 11 1242
Please let me know if I'm doing something horribly wrong or if this is a known issue with a workaround.