NAND Chip Interface Background

The NAND Flash Controller Command API is specified in cyg/io/flash_nand_ctl_cmd.h.

To understand what a Controller Command device must do, the NAND flash wire interface is discussed first. Then the command interface to NAND flash chips is discussed.

At the wire level, all NAND Flash chips are conformant. They communicate with a NAND Flash controller through these wires:

NAND Chip Wires

nCE
chip enable
nRE
read enable (clock)
nWE
write enable (clock)
nR/B
ready/busy (status output)
nCLE
command latch enable
nALE
address latch enable
IO[0..7], IO[8..15]
data (input/output). Pins IO[8..15] are only used by x16 chips
nWP
write protect

Generally speaking, NAND chips are controlled by performing a sequence of operations that consists of a command (enable nCLE, write the command value to the data lines, toggle nWE), an address (enable nALE, write the address value ...), sending/receiving data (enable nWE/nRE, write/read the values ...), checking status etc. A sequence of operations is usually just named 'command' (and we hope there is no confusion with the wire-level command). The NAND chip datasheets specify which commands in what format are supported.

Until 2006, there was no standard for commands. There were basically two types of NAND flash chip, large-page chips and the older small-page chips. In practice, each of these chip types share a command set, but with many nonstandard extensions or small deviations.

In 2006, ONFI was founded to standardize NAND chip interfacing. Its standard canonicalizes current practice of large-page NAND chip commands and wire definitions, but as an innovation, it has also specified a complete self-defining chip interrogation. At the time of this writing (october 2008), ONFI is young, and ONFI-conformant chips are rare.

Large-page chips (1024 or more bytes per page) that are not ONFI-compliant usually support a subset of the ONFI command set. The most notable exception is the Read Parameter Page command that lets the chip self-describe: it is usually absent. In its place comes an extended implementation of the Read ID command. It may contain so much information that no configuration by hand is necessary. However, in some cases it just returns the manufacturer and model code, and the chip library must come up with page size, block size, number of blocks, etc, coded by the chip device driver writer from the chip's datasheet. Many of the chips follow a common model encoding, and a table of frequent model types is provided in the library. The chip device author should first verify if his chip is correctly presented in that table, cyg_nand_chip_id[] in source file packages/io/flash_nand/src/chip/io_nand_chip.c. Another way in which large-page NAND chips differ from each other and from ONFI is in the way factory-bad blocks are marked. ONFI specifies "any 0 word in the spare area of the first or last page of a block" as the bad-block marker, but pre-ONFI large-page chips have a wide variety of usually more specific patterns. It seems that many of them accept a zero value of the first byte (or word for an x16 chip) of the spare area of the first page as a factory-bad mark. If a chip adheres to both these properties, a device-specific chip driver is usually unnecessary because the common pre-ONFI chip driver can be used.

Small-page chips (256 or 512 byte pages) have a command set that is different from ONFI or large-page chips in many respects, although they share the wire interface.

An example of a large-page (ONFI) command sequence is the page program command. It consists of the following set of operations: send (wire) command 0x80, send address = ca. 5 bytes, then send the data, send (wire) command 0x10, then wait until bit 6 of the status word (a hardware alias of wire nR/B) has a rising flank.

The common part of the controller library implements a (restricted, but hopefully sufficient) number of large-page (ONFI) and small-page commands, by invoking the corresponding sequence of operations on the Command API. The device-specific part of a controller implements the Controller Command API through operations on the wires, like a (wire) command or address operation; the way this is done necessarily depends on the flash controller type at hand.