目录:

1. Form factor

2. Diagram与pin group

3. CH/CE/LUN的连接关系

4. 用GPIO驱动pin

5. 理解Command cycle,address cycle以及timing diagram

6. 基本NAND操作说明和演示:

    1. Reset

    2. Read status/Read status enhanced

    3. Read ID

    4. Read UID

    5. Set IO timming mode

    6. Scan bad block

    7. Erase/program/read,以及理解page map

    8. 切换SLC、TLC模式

7. 理解ECC

8. NAND的性能与功耗参数


    • Form factor

目前常见的NAND颗粒有132Ball和272Ball的BGA; 长宽尺寸分别为12mm*18mm 和14*18mm; ball pitch 1mm; 典型高度为1.2mm(ODP及以上stack为1.35mm)

下图分别是BGA的剖面示意图,以及BGA132的ball assignment;

BGA132有两组IO ball(ONFI SPEC称每组为八位数据总线), 标记为DQx_0和DQx_1 (x=0…7); BGA272有4组IO Ball;

某个rNAND其package signal与ball的准确对应关系可参照datasheet.


    • Diagram与pin group


        下图是NAND的框图, 以及标注的动作过程;



    Pin可大致分为三类:power pin(Vcc/Vss, Vccq/Vssq, Vpp ), IO pin(DQ0-DQ7), control pin(CE、ALE、CLE、WE、RE、DQS等等的其他pin)

    Control Pin的电平组合决定了NAND的工作模式,如下表所示:


不同的Interface设置下,pin name对应关系可参照下表



CH、CE、lun(die)的连接

        见下图示例;此NAND颗粒有两个Channel, 4个CE(channel 0下有CE#0_0 和CE #1_0, Channel 1下有CE#0_1和CE#1_1),每个CE下只有一个lun(die)

         共享Channel的多个CE#, 在同一时刻只允许其中一个CE#有效

        不同Channel之间是完全独立的,可以并行操作多个Channel



        high level 视角如下图



    • GPIO驱动NAND

        GPIO是“外设”的一种,是“通用输入输出“,由用户软件控制的引脚,既能设置成输入也能设置成输出。





        硬件连接图参考AVR32136: AVR32 UC3 NAND flash GPIO driver (microchip.com)




        软件部分参考JimmyB.Goode的源码softNAND, 部分代码示例:

        ……

        #define CLE  (1<<0)

        #define ALE  (1<<1)

        #define WE  (1<<2)

        #define RE_T (1<<3)

        #define RE_C (1<<4)

        #define DQS_T (1<<5)

        #define DQS_C (1<<6)

        ……

        static XGpio cmd_gpios[NR_CHANNELS];

        static XGpio data_gpios[NR_CHANNELS];

        ……

        static int ce_pins[]={30,27,37,43,31,21,38,53,67,64,60,66,56,59,55,75};

        ……

        static void init_gpio(void)

        {

            ……

            for(init i=0;i<NR_CHANNELS;i++) {

                XGpio* cmd_gpio=&cmd_gpios[i];

                XGpio* data_gpio=&data_gpios[i];

                ……

                If (XGpio_Initialized(cmd_gpio, cmd_gpio_ids[i]) != XST_SUCCESS) {

                           xil_printf("Cmd GPIO for channel %d init failed\n\r", i);

                           return;

                                                                    }



                If (XGpio_Initialized(data_gpio, data_gpio_ids[i]) != XST_SUCCESS) {

                       xil_printf("Data GPIO for channel %d init failed\n\r", i);

                       return;

                                                                }

                ……


            ……

        }

        ……


        static void write_command(XGpio* cmd_gpio, XGpio* data_gpio, int channel, u8 command)

        {

            XGpio_SetDataDirection(data_gpio, channel, 0x00);    //set NAND IO pin connected GPIO as output mode

            /* A command is written from DQ[7:0] to flash command register on the rising edge of WE# when CE# is LOW, ALE is LOW, CLE is HIGH, and RE# is HIGH */

            XGpio_DiscreteWrite(cmd_gpio, channel, DQS_T | RE_T | CLE );    // NAND control pin connected GPIO output, DQS high, RE# high, CLE high

            XGpio_DiscreteWrite(data_gpio, channel, command);    // NAND IO pin connected GPIO output

            XGpio_DiscreteWrite(cmd_gpio, channel, DQS_T | RE_T | WE | CLE );    // NAND control pin connected GPIO output , WE trigger rising edge

        }

        ……


        使用GPIO来驱动NAND比较灵活,可用于新NAND的调试;实际产品上追求效率,会把NAND控制模块固化成hardware IP, 提升速度,简化软件层面的操作。

        iliefu/NandFlashController: AXI Interface Nand Flash Controller (Sync mode) (github.com)



    • Command cycle, Address cycle, Timing diagram

        下图是command cycle和address cycle的时序图;此外,还有data-in和data-out的cycle;

        根据CLE/ALE的不同电平状态, DQ上的电平在WE#的上升沿被锁存到命令寄存器或地址寄存器;




        因为NAND的容量原因及地址译码逻辑原因,NAND的address需要多个address cycle(单个cycle传输8bit address), 对page level的操作而言常见的有5各或6各address cycle;

        目前的NAND基本上都是1个page为16K byte,对应2个column address cycle; page/block/plane/lun这些合成为row address cycle;


• 基本NAND操作说明和演示:

        1. Reset, Reset LUN, hard reset

            i. 用在初次上电后复位NAND,或NAND出现异常(不是single block program/erase fail这类异常,而是寄存器紊乱一类的异常)时

            ii. 对CE下发reset 0xFF命令,该CE下的所有LUN都同步reset;

            iii. 代码参考: fcmd_reset函数

        2. Read status/Read status enhanced

            i. 用于读取NAND操作状态,或者用于切换LUN

            ii. 对CE下发read status 0x70命令,将返回上一次操作的LUN的状态;

            iii. 代码参考: read_status函数

        3. Read ID, Read UID

            i. 用在读取NAND的manufacturing ID, device ID, 或者UID(lot/wafer/die XYcoordinate)

            ii. 代码参考:fcmd_read_id函数



        4. Set IO timming mode

            i. 通过NAND set feathur来 设置IO interface和timming mode

            ii. 代码参考:fcmd_activate_nvddr2函数

        5. Erase/program/read,one-pass program, 以及理解page map

            i. 代码参考:fcmd_program_page_sync函数

            ii. One-pass program参考datasheet, TLC one pass program sequence 是 CMD 80h ->LP address cycle --> LP data-in cycle -->CMD 1Ah --> CMD 80h ->MP address cycle --> MP data-in cycle -->CMD 1Ah --> CMD 80h ->UP address cycle --> UP data-in cycle -->CMD 10h


            iii. Page-map参考DAS, page-map是逻辑page到物理位置(WL,TSG)的转换关系表


        6. Scan bad block

            i. 用在开卡时创建BB table; factory BB的第一页和最后一页的首个byte为0x00, (vs 0xFF from good block)

            ii. ONFI 参考代码


        7. 切换SLC、TLC模式

            i. 参考NAND datasheet. YMTC NAND使用命令DAh命令使能SLC模式,DFh命令退出SLC模式



    • 理解ECC

        AN0271V1-NAND Error Correction Codes Introduction-0217.pdf (macronix.com)

        FMS2017_PreConfH_FlashManagement_Haratsch_080717 (flashmemorysummit.com)



    • NAND的性能与功耗参数(部分)

        tProg; 页数据从page buffer写入到NAND array所需的时间,直观的与program pulse count正相关,本质上是array的特性和trim设定所决定的。

        tR:页数据从Nand array读出到page buffer所需的时间;

        Icc_stdby(ISB): Vcc current @ standby, ONFI规定max 100uA

        Icc1/2/3: Vcc current @read/program/erase, ONFI规定max 100mA


    • YMTC rNAND UID 16 bytes解析:

        ○ byte0~4: ASCII表示的internal part number;

        ○ byte5: revision number;

        ○ byte12: wafer ID;

        ○ byte13: DieX, byte14: DieY;

        ○ byte15/byte6-11: ASCII表示的lot number;