Hello, Community!
In my project, I'm using the GD25Q128ESIGR flash memory and an nRF52832. However, I'm encountering an issue: the GD25Q128ESIGR isn't performing read or erase operations correctly. I need to create, write, read, and erase 1024 bytes from an external flash using SPI.
here is a function for reading:
uint32_t gd25_data_read(uint32_t flash_address, uint8_t *rxd, uint32_t size)
{
uint8_t txd[4];
txd[0] = GD25_READDATA;
txd[1] = (flash_address >> 16) & 0xff;
txd[2] = (flash_address >> 8) & 0xff;
txd[3] = flash_address & 0xff;
nrf_gpio_pin_clear(MK_CS_MEM_PIN);
nrf_delay_ms(TRANSFER_DELAY_MS);
nrf_drv_spi_transfer(&spi_flash, txd, sizeof(txd), rxd, size);
while(flash_spi_xfer_done == false);
flash_spi_xfer_done = false;
nrf_drv_spi_transfer(&spi_flash, txd, sizeof(txd), rxd, size);
while(flash_spi_xfer_done == false);
flash_spi_xfer_done = false;
nrf_gpio_pin_set(MK_CS_MEM_PIN);
NRF_LOG_INFO("[255] byte (in read function) = %.2X" ,rxd[255]);
}
Page program:
int8_t gd25_page_write(uint32_t flash_address, uint8_t *flash_data_buf)
{
uint8_t txd[4];
uint8_t rxd[GD25_PAGESIZE];
uint8_t sr[2] = {0, 0};
int uwTick = 10;
txd[0] = GD25_PAGEPROG;
txd[1] = (flash_address >> 16) & 0xff;
txd[2] = (flash_address >> 8) & 0xff;
txd[3] = flash_address & 0xff;
nrf_gpio_pin_clear(MK_CS_MEM_PIN);
nrf_delay_ms(TRANSFER_DELAY_MS);
nrf_drv_spi_transfer(&spi_flash, txd, sizeof(txd), rxd, 0);
while(flash_spi_xfer_done == false);
flash_spi_xfer_done = false;
nrf_delay_ms(TRANSFER_DELAY_MS);
nrf_drv_spi_transfer(&spi_flash, flash_data_buf, 0, rxd, (uint8_t)GD25_PAGESIZE);
while(flash_spi_xfer_done == false);
flash_spi_xfer_done = false;
nrf_gpio_pin_set(MK_CS_MEM_PIN);
//Wait while writing is done
uint32_t end_time = uwTick + 10;
txd[0] = GD25_RSR;
txd[1] = 0;
while (1)
{
nrf_gpio_pin_clear(MK_CS_MEM_PIN);
nrf_drv_spi_transfer(&spi_flash, txd, sizeof(txd), sr, sizeof(sr));
while(flash_spi_xfer_done == false);
flash_spi_xfer_done = false;
nrf_gpio_pin_set(MK_CS_MEM_PIN);
if ((sr[1] & STATUS_WIP) == 0)
{
return GD25_OK;
}
else if (uwTick > end_time)
{
return GD25_TIMEOUT;
}
}
}
also for Page Program I use this:
void gd25_data_write(uint32_t flash_address, uint8_t *flash_data_buf, uint16_t size)
{
if (size <= GD25_PAGESIZE)
{
gd25_page_write(flash_address, flash_data_buf);
}
else
{
uint8_t n = size / GD25_PAGESIZE;
for (int pp = 0; pp < n; pp++)
{
gd25_page_write(flash_address + pp * GD25_PAGESIZE, flash_data_buf + pp * GD25_PAGESIZE);
}
}
}
sector erase:
int8_t gd25_sector_erase(uint32_t flash_address)
{
uint8_t sr1 = 0;
int uwTick = 10;
uint8_t txd[4];
uint8_t rxd[4];
//Erase sector
txd[0] = GD25_SECTORERASE;
txd[1] = (flash_address >> 16) & 0xff;
txd[2] = (flash_address >> 8) & 0xff;
txd[3] = flash_address & 0xff;
nrf_gpio_pin_clear(MK_CS_MEM_PIN);
nrf_delay_ms(TRANSFER_DELAY_MS);
nrf_drv_spi_transfer(&spi_flash, txd, sizeof(txd), 0, 0);
while(flash_spi_xfer_done == false);
flash_spi_xfer_done = false;
nrf_gpio_pin_set(MK_CS_MEM_PIN);
//Wait while erasing is done
uint32_t end_time = uwTick + 550;
while (1)
{
//SR s0-s7
txd[0] = GD25_RSR;
nrf_gpio_pin_clear(MK_CS_MEM_PIN);
nrf_drv_spi_transfer(&spi_flash, txd, sizeof(txd), rxd, sizeof(rxd));
while(flash_spi_xfer_done == false);
flash_spi_xfer_done = false;
nrf_gpio_pin_set(MK_CS_MEM_PIN);
sr1 = rxd[1];
if (sr1 == 0)
{
return GD25_OK;
}
else if (uwTick > end_time)
{
return GD25_TIMEOUT;
}
}
}
and part of main.c:
gd25q127c_init();
gd25_mdid_read (&man_id, &dev_id);
NRF_LOG_INFO("Reading REMS. Man id: %.2x, Dev id: %.2x", (int)man_id, (int)dev_id);
nrf_delay_ms(FUNC_DELAY_MS);
gd25_write_disable();
gd25_status_read();
flash_address=FLASH_TEST_ADDR;
NRF_LOG_INFO("Erase data at address %.8X", flash_address);
gd25_write_enable();
int8_t result_of_erase = gd25_sector_erase(flash_address);
if (result_of_erase == GD25_OK)
{
NRF_LOG_INFO("Successful erasing data at address %.8X", flash_address);
}
else if (result_of_erase == GD25_TIMEOUT)
{
NRF_LOG_INFO("Timeout of erasing");
}
uint32_t size = READ_WRITE_LENGTH;
gd25_data_read(flash_address, flash_data_buf, size);
NRF_LOG_INFO("Reading address %.8x: ", flash_address);
NRF_LOG_INFO("[9] byte = %.2X" ,(uint8_t)flash_data_buf[9]);
NRF_LOG_INFO("[1000] byte = %.2X" ,(uint8_t)flash_data_buf[1000]);
NRF_LOG_INFO("\n");
NRF_LOG_INFO("Programming data at address %.8X", flash_address);
for (int i = 0; i < READ_WRITE_LENGTH; i++)
{
flash_data_buf[i] = i;
}
gd25_write_enable();
gd25_data_write(flash_address, flash_data_buf, size);
int8_t result = gd25_page_write(flash_address, flash_data_buf);
if (result == GD25_OK)
{
NRF_LOG_INFO("Successful programming data at address %.8X", flash_address);
}
else if (result == GD25_TIMEOUT)
{
NRF_LOG_INFO("Timeout of programming");
}
nrf_delay_ms(FUNC_DELAY_MS);
gd25_data_read(flash_address, flash_data_buf, size); // читает по адресу и сохраняет в массиве размером size
NRF_LOG_INFO("Reading address %.8x: ", flash_address);
NRF_LOG_INFO("[9] byte = %.2X" ,(uint8_t)flash_data_buf[9]);
NRF_LOG_INFO("[1000] byte = %.2X" ,(uint8_t)flash_data_buf[1000]);
NRF_LOG_INFO("\n");
nrf_delay_ms(FUNC_DELAY_MS);
NRF_LOG_INFO("Erase data at address %.8X", flash_address);
gd25_write_enable();
result_of_erase = gd25_sector_erase(flash_address);
if (result_of_erase == GD25_OK)
{
NRF_LOG_INFO("Successful erasing data at address %.8X", flash_address);
}
else if (result_of_erase == GD25_TIMEOUT)
{
NRF_LOG_INFO("Timeout of erasing");
}
nrf_delay_ms(TRANSFER_DELAY_MS);
gd25_data_read (flash_address, flash_data_buf, size);
NRF_LOG_INFO("Reading address %.8x: ", flash_address);
NRF_LOG_INFO("[9] byte = %.2X" ,(uint8_t)flash_data_buf[9]);
NRF_LOG_INFO("[1000] byte = %.2X" ,(uint8_t)flash_data_buf[1000]);
NRF_LOG_INFO("\n");
gd25_write_enable();
int8_t result_of_chip_erase = gd25_chip_erase();
if (result_of_chip_erase == GD25_OK)
{
NRF_LOG_INFO("Successful erasing of chip");
}
else if (result_of_chip_erase == GD25_TIMEOUT)
{
NRF_LOG_INFO("Timeout of erasing");
}
//nrf_delay_ms(260000);
//gd25_status_read();
nrf_delay_ms(TRANSFER_DELAY_MS);
gd25_data_read(flash_address, flash_data_buf, size);
NRF_LOG_INFO("Reading address %.8x: ", flash_address);
NRF_LOG_INFO("[9] byte = %.2X" ,(uint8_t)flash_data_buf[9]);
NRF_LOG_INFO("[1000] byte = %.2X" ,(uint8_t)flash_data_buf[1000]);
NRF_LOG_INFO("________________________________________________________\r\n");
while(1)
{}
The result of executing all code:
<info> app: Reading REMS. Man id: C8, Dev id: 17
<info> app: Running write disable
<info> app: SR s0-s7: 0
<info> app: SR s8-s15: 0
<info> app: SR s16-s23: 32
<info> app: Erase data at address 00001000
<info> app: Running write enable
<info> app: Successful erasing data at address 00001000
<info> app: [255] byte (in read function) = 00
<info> app: Reading address 00001000:
<info> app: [9] byte = 00
<info> app: [1000] byte = 00
<info> app: Programming data at address 00001000
<info> app: Running write enable
<info> app: Successful programming data at address 00001000
<info> app: [255] byte (in read function) = FF
<info> app: Reading address 00001000:
<info> app: [9] byte = 09
<info> app: [1000] byte = E8
<info> app: Erase data at address 00001000
<info> app: Running write enable
<info> app: Successful erasing data at address 00001000
<info> app: [255] byte (in read function) = FF
<info> app: Reading address 00001000:
<info> app: [9] byte = 09
<info> app: [1000] byte = E8
<info> app: Running write enable
<info> app: Successful erasing of chip
<info> app: [255] byte (in read function) = FF
<info> app: Reading address 00001000:
<info> app: [9] byte = 09
<info> app: [1000] byte = E8
I've checked the status registers during page/sector writing and attempted reducing the byte count to 256. Of course, I'm using the 'Write Enable' command before writing data and erasing a sector. I even tried erasing the entire chip, but the result remains the same. It seems like I might have an issue with data reading. I would appreciate any advice. Thanks in advance!