During an execution of a winbond w25q64jv command (any command) during a BLE_GATTS_EVT_WRITE event the SPI bus goes inactive after the command is sent:

There is apparently no issue if I do any NVM operation outside a BLE_GATTS_EVT_WRITE event.
During an execution of a winbond w25q64jv command (any command) during a BLE_GATTS_EVT_WRITE event the SPI bus goes inactive after the command is sent:

There is apparently no issue if I do any NVM operation outside a BLE_GATTS_EVT_WRITE event.
Hello Edvin,
I am rewriting my code because of this strange issue. But, the 0xE6 byte after the 0x66 was not intended to be sent to NVM, The code for the NVM command is only intended to send the 0x66 (Enable Reset) on the SPI bus and nothing else for that command. I think that's why there is NVM issue, because that 2nd byte is probably putting the NVM in a bad state. I am not waiting for a callback. Snippet below (ENABLE_RESET_CMND_LEN = 1, W25_ENABLE_RESET_REG = 0x66, and W25_RESET_DEVICE_REG = 0x99):
void w25_reset(void)
{
ret_code_t err_code;
uint8_t spi_command[ENABLE_RESET_CMND_LEN] = {0};
uint8_t spi_response[ENABLE_RESET_CMND_LEN] = {0};
//Enable Reset Test
spi_command[CMND_BYTE_0] = W25_ENABLE_RESET_REG; //Write enable register address
err_code = spi_transfer(spi_command, spi_response, ENABLE_RESET_CMND_LEN, 0, MEM_CS); //Enable writing to NVM
APP_ERROR_CHECK(err_code);
//Send SW Reset
spi_command[CMND_BYTE_0] = W25_RESET_DEVICE_REG; //Write enable register address
err_code = spi_transfer(spi_command, spi_response, RESET_CMND_LEN, 0, MEM_CS); //Enable writing to NVM
APP_ERROR_CHECK(err_code);
}
Here is a snippet of working code and SPI bus capture:
bool Test_write_and_read_of_NVM()
{
uint8_t mydata[18] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x55, 0x00, 0x10}; //test data
ret_code_t err_code;
uint8_t spi_command[TEST_WR_RD_CMND_LEN] = {0};
uint8_t spi_response[TEST_WR_RD_CMND_LEN] = {0};
uint8_t buffer[18] = {0};
int WR_RD_check = 0;
uint8_t SectorAddr[TRIPLE_BYTES];
spi_command[CMND_BYTE_0] = W25_PAGE_PROGRAM_REG; //Page Program Command
spi_command[CMND_BYTE_1] = NVM_MEM_START_BYTE2; //Address to write MSByte 1st
spi_command[CMND_BYTE_2] = NVM_MEM_START_BYTE1; //Address to write
spi_command[CMND_BYTE_3] = NVM_MEM_START_BYTE0; //Address to write
//
SectorAddr[CMND_BYTE_0] = NVM_MEM_START_BYTE2; //Address to read MSByte 1st
SectorAddr[CMND_BYTE_1] = NVM_MEM_START_BYTE1; //Address to read
SectorAddr[CMND_BYTE_2] = NVM_MEM_START_BYTE0; //Address to read
//Load up SPI command rest of data
for (uint8_t ii = 0; ii < 18; ii++)
{
spi_command[ii + 4] = mydata[ii];
}
w25_write_enable();
//Write test data to NVM
err_code = spi_transfer(spi_command, spi_response, TEST_WR_RD_CMND_LEN, TEST_WR_RD_CMND_LEN, MEM_CS);
APP_ERROR_CHECK(err_code);
//Now Read Data back to compare to expected values. First check if NVM is busy
//while(Check_NVM_Busy() != false) {}
//Read data
// Check_NVM_Busy();
err_code = w25_read_data(SectorAddr, buffer, 18);
NRF_LOG_INFO("Read Test Data from NVM %u, %u, %u\n\r",buffer[0], buffer[1], buffer[2], buffer[3]);
//Compare data with test data with what was read in
WR_RD_check = memcmp(mydata, buffer, sizeof(buffer));
if(WR_RD_check != 0)
{
return (false);
}
else
{
return (true);
}
}

The code writes to NVM and reads the data back and compares it to original data to check it. Outside the BLE_GATTS_EVT_WRITE event it works, but not inside it.
Hello Edvin,
I am rewriting my code because of this strange issue. But, the 0xE6 byte after the 0x66 was not intended to be sent to NVM, The code for the NVM command is only intended to send the 0x66 (Enable Reset) on the SPI bus and nothing else for that command. I think that's why there is NVM issue, because that 2nd byte is probably putting the NVM in a bad state. I am not waiting for a callback. Snippet below (ENABLE_RESET_CMND_LEN = 1, W25_ENABLE_RESET_REG = 0x66, and W25_RESET_DEVICE_REG = 0x99):
void w25_reset(void)
{
ret_code_t err_code;
uint8_t spi_command[ENABLE_RESET_CMND_LEN] = {0};
uint8_t spi_response[ENABLE_RESET_CMND_LEN] = {0};
//Enable Reset Test
spi_command[CMND_BYTE_0] = W25_ENABLE_RESET_REG; //Write enable register address
err_code = spi_transfer(spi_command, spi_response, ENABLE_RESET_CMND_LEN, 0, MEM_CS); //Enable writing to NVM
APP_ERROR_CHECK(err_code);
//Send SW Reset
spi_command[CMND_BYTE_0] = W25_RESET_DEVICE_REG; //Write enable register address
err_code = spi_transfer(spi_command, spi_response, RESET_CMND_LEN, 0, MEM_CS); //Enable writing to NVM
APP_ERROR_CHECK(err_code);
}
Here is a snippet of working code and SPI bus capture:
bool Test_write_and_read_of_NVM()
{
uint8_t mydata[18] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x55, 0x00, 0x10}; //test data
ret_code_t err_code;
uint8_t spi_command[TEST_WR_RD_CMND_LEN] = {0};
uint8_t spi_response[TEST_WR_RD_CMND_LEN] = {0};
uint8_t buffer[18] = {0};
int WR_RD_check = 0;
uint8_t SectorAddr[TRIPLE_BYTES];
spi_command[CMND_BYTE_0] = W25_PAGE_PROGRAM_REG; //Page Program Command
spi_command[CMND_BYTE_1] = NVM_MEM_START_BYTE2; //Address to write MSByte 1st
spi_command[CMND_BYTE_2] = NVM_MEM_START_BYTE1; //Address to write
spi_command[CMND_BYTE_3] = NVM_MEM_START_BYTE0; //Address to write
//
SectorAddr[CMND_BYTE_0] = NVM_MEM_START_BYTE2; //Address to read MSByte 1st
SectorAddr[CMND_BYTE_1] = NVM_MEM_START_BYTE1; //Address to read
SectorAddr[CMND_BYTE_2] = NVM_MEM_START_BYTE0; //Address to read
//Load up SPI command rest of data
for (uint8_t ii = 0; ii < 18; ii++)
{
spi_command[ii + 4] = mydata[ii];
}
w25_write_enable();
//Write test data to NVM
err_code = spi_transfer(spi_command, spi_response, TEST_WR_RD_CMND_LEN, TEST_WR_RD_CMND_LEN, MEM_CS);
APP_ERROR_CHECK(err_code);
//Now Read Data back to compare to expected values. First check if NVM is busy
//while(Check_NVM_Busy() != false) {}
//Read data
// Check_NVM_Busy();
err_code = w25_read_data(SectorAddr, buffer, 18);
NRF_LOG_INFO("Read Test Data from NVM %u, %u, %u\n\r",buffer[0], buffer[1], buffer[2], buffer[3]);
//Compare data with test data with what was read in
WR_RD_check = memcmp(mydata, buffer, sizeof(buffer));
if(WR_RD_check != 0)
{
return (false);
}
else
{
return (true);
}
}

The code writes to NVM and reads the data back and compares it to original data to check it. Outside the BLE_GATTS_EVT_WRITE event it works, but not inside it.
Hello,
Sorry for the late reply. I was out of office yesterday.
I don't understand. Those two snippets are very different. What do you expect to see in your first snippet?
Is this something I will be able to reproduce on a DK? Obviously I will not be able to read back the data, but I should be able to see the same output data from the nRF. If so, can you please zip and send a project (or a minimum project) that can replicate the issue?
Best regards,
Edvin