I am trying to understand how a NAND flash memory chip works. Specifically, I am communicating with one via SPI protocol.
The memory has a certain number of blocks in it. A block is the smallest erasable unit of a NAND flash memory. A block contains a number of pages. However, a individual page can not be erased. Also, a page is a smallest writable and readable unit. That being said, for writing and reading memory pages, only the address of the block and page are needed (this is my assumption). That is the so called row address. So my question is, what is the purpose of the column address, how does it work and what is it used for?
In the datasheet of the memory I am using, it is said that the column address is the byte location in a page. But why is that needed if a single byte in a page cannot be read, erased or written. Only the whole page can be written at once (and read). Non the less, a column address is required in order to read and write data into the flash memory. Can someone please explain this to me?
Not having dug into that specific datasheet the following may still be true.
The internal architecture of the chip is such that when reading always a whole page is read from the flash and then copied into the output buffer. Data inside the output buffer can be accessed byte-wise.
Since you are accessing the device via SPI it may well be that it feels like you have a normal random access memory in front of you, but you may experience varying delays when reading data, depending on whether the page for our byte address to be read must be copied into the output buffer of whether the byte to be read is already inside the output buffer.
When it comes to writing you probably can write single bytes but must be aware that you always affect all bytes in a page. Imagine this: For writing you write the data to be written into the input buffer, which is a page. Once the data is inside that input buffer you send the write command and the data gets written into the flash. During writing you can change bits only from 1 to 0 but not vice versa, so if you initialize all data in the input buffer to 0xFF and change only those bytes you want to write, only those bytes will be altered - and in fact only those bits which are 1 in the flash and 0 in the buffer.
Does that make sense and match the datasheet?
Let me see if I understand what you are saying.
In the process of reading, the column address is the address of the byte location from which I am starting to read the data. However, if I try to read from a location that is not the first byte of the page (by specifying the column address in the SPI transaction), I will experience delay because in reality, the whole page has to be transferred from the memory matrix to the internal buffer in order to read from that byte.
For example: Lets say that the page contains 256 bytes. If i try to read the memory content starting from the fifth byte of the page, all the 256 bytes of the page must be transferred from the memory matrix to the internal buffer, however since I specified the fifth column address, the internal buffer will output to me the 251 bytes of data starting from the fifth address. There will be a small time delay as it skips the first four bytes.
In the process of writing, by specifying the column address, i am actually specifying the byte location within a page which content I am changing.
For example: Lets say again that the page has 256 bytes and I previously erased the content of the block that contains that page. Also, lets say i want to write data content into the fifth and sixth byte of the page. That means that in the SPI transaction sequence i have to specify the fifth column address and the two bytes that I am inserting into the memory. Internally whats really happening is that I am inputting the internal buffer with 256 bytes, but the fifth and sixth byte location of the internal buffer ire filled with the data that is not 0xFF and the reset of the bytes are filled with 0xFF. That being said, the buffer puts its content into the whole page, but only the fifth and sixth byte are actually changed because the rest of the content of the buffer was 0xFF for each byte.
Please correct me if I misunderstood.