xref: /nrf52832-nimble/rt-thread/components/drivers/include/drivers/mtdnand.h (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author        Notes
8    2018-09-10     heyuanjie87   first version
9 
10  */
11 
12 #ifndef _MTDNAND_H_
13 #define _MTDNAND_H_
14 
15 #include "mtd.h"
16 
17  /* Status bits */
18 #define NAND_STATUS_FAIL        0x01
19 #define NAND_STATUS_FAIL_N1     0x02
20 #define NAND_STATUS_WP          0x80
21 
22 typedef enum
23 {
24     NAND_CMD_PAGE_RD,   /* read data to chip's page buffer,do WaitBusy after this cmd in low driver */
25     NAND_CMD_PAGE_WR0,  /* write data to chip's page buffer */
26     NAND_CMD_PAGE_WR1,  /* do flash programe */
27     NAND_CMD_BLK_ERASE, /* erase block */
28     NAND_CMD_ECC_EN,    /* enable gen HWECC */
29     NAND_CMD_ECC_DIS    /* disable gen HWECC */
30 } nand_cmd_t;
31 
32 typedef enum
33 {
34     NAND_ECCM_NONE,
35     NAND_ECCM_HW,
36 } nand_eccmode_t;
37 
38 struct nand_chip;
39 struct nand_ops;
40 
41 /**
42 * struct nand_buffers - buffer structure for read/write
43 * @ecccalc:    buffer pointer for calculated ECC, size is oobsize.
44 * @ecccode:    buffer pointer for ECC read from flash, size is oobsize.
45 *
46 */
47 struct nand_buffers
48 {
49     uint8_t *ecccalc;
50     uint8_t *ecccode;
51 };
52 
53 struct nand_ecc
54 {
55     uint8_t mode;    /* nand_eccmode_t */
56     uint8_t bytes;   /* gen ecc bytes per ecc step(usually 3) */
57     uint16_t stepsize:12; /* min 256 */
58     uint16_t _step:4;     /*  */
59 
60     /* driver must set the two interface if HWECC */
61     void (*calculate)(struct nand_chip *chip, const uint8_t *dat, uint8_t *ecc_code);
62     /* return max bit flips if can't correct,return -1 ECC is error(0 success) */
63     int(*correct)(struct nand_chip *chip, uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc);
64     /* ignore if NONECC */
65     const struct mtd_oob_region *layout;
66 };
67 
68 typedef struct nand_chip
69 {
70     rt_mtd_t parent;
71 
72     /* driver must init these */
73     const struct nand_ops *ops;
74     struct nand_ecc ecc;
75     const struct mtd_oob_region *freelayout;
76 
77     /* driver do not touch */
78     struct nand_buffers buffers;
79     uint8_t *oob_poi;
80     uint8_t *pagebuf;
81     uint32_t size;
82     uint16_t oobsize;
83     uint8_t pages_pb;
84     uint16_t page_size;
85     int(*read_page)(struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
86     int(*write_page)(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page);
87 }rt_nand_t;
88 
89 struct nand_ops
90 {
91     int(*cmdfunc)(rt_nand_t *nand, int cmd, int page, int offset); /* send nand operation cmd, return Status bits(0 success),
92                                                                       if nand is busy please wait in low driver */
93     int(*read_buf)(rt_nand_t *nand, uint8_t *buf, int len);        /* read data from nand chip's page buffer */
94     int(*write_buf)(rt_nand_t *nand, const  uint8_t *buf, int len);/* write data to nand chip's page buffer */
95     int(*isbad)(rt_nand_t *nand, uint32_t blk);   /* if NULL OOB[0] used as bad mark(not 0xff is bad) */
96     int(*markbad)(rt_nand_t *nand, uint32_t blk); /* if NULL OOB[0] used as bad mark(set to 0x00) */
97 };
98 
99 int rt_mtd_nand_init(rt_nand_t *nand, int blk_size, int page_size, int oob_size);
100 
101 #endif /* MTD_NAND_H_ */
102