I'm working on a project based on the ESP32 that uses a NAND chip from the GD5F1 family (link to the datasheet). Sorry for the long question, but it's a bit convoluted, and it's driving me nuts for the last week.

I managed to write consistently and without issue for a long time. Now, I had an idea about signing some pages after a certain process, so I can keep track of the pages processed and in case of power loss, restart from the first unprocessed page.

As I have a bit of extra memory on each page, I thought, "why not add a certain pattern, e.g 0x11223344, on the last 4B, as they are always 0xFFFFFFFF". As far as I know, and based on some preliminary tests, I can write on a page that has data. If the sector of the page that I'm writing is still 0xFF, I get whatever I want and if it's not, I get the AND of what I wanted to write and whatever was there first. So far so good, and all working as expected.

As I said, I did some tests, and all worked as expected, but now, on my app, the behaviour is very erratic. In my application, I use the first page of the NAND to store some metadata (60B), and then I write a variable number of pages with 2016B (the page size is 2048B). When I try to write something on the header page, I get garbage written if I write on a position below 2016, and what I wanted to get if I write after the 2016B mark.

If I change the amount of data on pages 1 and onwards, to let's say 1500B, and then try to write on the metadata page, I get garbage before the 1500B and whatever I wanted to write after the 1500B.

I'm really puzzled by this behaviour. Can somebody shed some light?

The most relevant test that I've done so far is writing 4 bytes on the first 4 blocks (256 pages) at position 0, then repeat at position 4, 8, ... 2048. Result: all the pages are correctly written, proving that I can write on a page as long as it's content are 1's. Tried also with other sizes, no problem whatsoever in going back and forth writing on unused areas of the flash.

What doesn't work: Write 60B on page 0, then write 2016B on the next pages, and try to write back on page 0 again, on any location < than 2016. There are no other references in my code to that 2016 other than the "write 2016B" commands.

The code that I'm using is quite a big chunk split in several libraries. I think it will take quite a while to review. It's quite a complex problem I'm struggling even to try to explain it, so I'm looking more for ideas of things to try than really somebody auditing my code.


  • \$\begingroup\$ Without being able to review the code, the only thing to do is divide and conquer. Find a case where it works, and a case where it doesn't work and trace the execution of both paths to see where they deviate. I would absolutely post the code you are using to calculate the map/unmap of data in the NV-memory back to the application. \$\endgroup\$ – pgvoorhees May 16 '18 at 14:57
  • \$\begingroup\$ I'll try to get a barebones version of the code and update the question. I know that I'm asking a LOT by not posting it, but I would like to know how feasible what I'm doing is, and then get into more detail. Cheers \$\endgroup\$ – Joel Santos Rico May 16 '18 at 18:07
  • \$\begingroup\$ Hi. Sorry for the lack of updates. The behaviour is quite random. I found out that the part in our prototypes is not the one we requested, but an alternative part that had a lesser lead time at the time of the production, so we switched to it. I ordered some alternative chips from Digikey and will do some tests. If the original part works, then I will blame the Gigadevice part and close this, and if it doesn't, then I will post the code. \$\endgroup\$ – Joel Santos Rico May 21 '18 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.