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.