xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/uffs/src/example/flash-interface-example.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero   This file is part of UFFS, the Ultra-low-cost Flash File System.
3*10465441SEvalZero 
4*10465441SEvalZero   Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
5*10465441SEvalZero 
6*10465441SEvalZero   UFFS is free software; you can redistribute it and/or modify it under
7*10465441SEvalZero   the GNU Library General Public License as published by the Free Software
8*10465441SEvalZero   Foundation; either version 2 of the License, or (at your option) any
9*10465441SEvalZero   later version.
10*10465441SEvalZero 
11*10465441SEvalZero   UFFS is distributed in the hope that it will be useful, but WITHOUT
12*10465441SEvalZero   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*10465441SEvalZero   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*10465441SEvalZero   or GNU Library General Public License, as applicable, for more details.
15*10465441SEvalZero 
16*10465441SEvalZero   You should have received a copy of the GNU General Public License
17*10465441SEvalZero   and GNU Library General Public License along with UFFS; if not, write
18*10465441SEvalZero   to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19*10465441SEvalZero   Boston, MA  02110-1301, USA.
20*10465441SEvalZero 
21*10465441SEvalZero   As a special exception, if other files instantiate templates or use
22*10465441SEvalZero   macros or inline functions from this file, or you compile this file
23*10465441SEvalZero   and link it with other works to produce a work based on this file,
24*10465441SEvalZero   this file does not by itself cause the resulting work to be covered
25*10465441SEvalZero   by the GNU General Public License. However the source code for this
26*10465441SEvalZero   file must still be made available in accordance with section (3) of
27*10465441SEvalZero   the GNU General Public License v2.
28*10465441SEvalZero 
29*10465441SEvalZero   This exception does not invalidate any other reasons why a work based
30*10465441SEvalZero   on this file might be covered by the GNU General Public License.
31*10465441SEvalZero */
32*10465441SEvalZero /**
33*10465441SEvalZero  * \file flash-interface-example.c
34*10465441SEvalZero  * \brief example for using flash driver and multiple partitions, with static memory allocator.
35*10465441SEvalZero  * \author Ricky Zheng, created at 27 Nov, 2007
36*10465441SEvalZero  */
37*10465441SEvalZero 
38*10465441SEvalZero #include <string.h>
39*10465441SEvalZero #include "uffs_config.h"
40*10465441SEvalZero #include "uffs/uffs_os.h"
41*10465441SEvalZero #include "uffs/uffs_device.h"
42*10465441SEvalZero #include "uffs/uffs_flash.h"
43*10465441SEvalZero #include "uffs/uffs_mtb.h"
44*10465441SEvalZero #include "uffs/uffs_fs.h"
45*10465441SEvalZero 
46*10465441SEvalZero #define PFX "ndrv: "
47*10465441SEvalZero 
48*10465441SEvalZero struct my_nand_chip {
49*10465441SEvalZero 	void *IOR_ADDR;
50*10465441SEvalZero 	void *IOW_ADDR;
51*10465441SEvalZero 	UBOOL inited;
52*10465441SEvalZero 	// ...
53*10465441SEvalZero };
54*10465441SEvalZero 
55*10465441SEvalZero /*
56*10465441SEvalZero  * Standard NAND flash commands
57*10465441SEvalZero  */
58*10465441SEvalZero #define NAND_CMD_READ0		0
59*10465441SEvalZero #define NAND_CMD_READ1		1
60*10465441SEvalZero #define NAND_CMD_RNDOUT		5
61*10465441SEvalZero #define NAND_CMD_PAGEPROG	0x10
62*10465441SEvalZero #define NAND_CMD_READOOB	0x50
63*10465441SEvalZero #define NAND_CMD_ERASE1		0x60
64*10465441SEvalZero #define NAND_CMD_STATUS		0x70
65*10465441SEvalZero #define NAND_CMD_STATUS_MULTI	0x71
66*10465441SEvalZero #define NAND_CMD_SEQIN		0x80
67*10465441SEvalZero #define NAND_CMD_RNDIN		0x85
68*10465441SEvalZero #define NAND_CMD_READID		0x90
69*10465441SEvalZero #define NAND_CMD_ERASE2		0xd0
70*10465441SEvalZero #define NAND_CMD_RESET		0xff
71*10465441SEvalZero 
72*10465441SEvalZero 
73*10465441SEvalZero /* impelent the following functions for your NAND flash */
74*10465441SEvalZero #define CHIP_SET_CLE(chip) { chip = chip; }
75*10465441SEvalZero #define CHIP_CLR_CLE(chip) {}
76*10465441SEvalZero #define CHIP_SET_ALE(chip) {}
77*10465441SEvalZero #define CHIP_CLR_ALE(chip) {}
78*10465441SEvalZero #define CHIP_SET_NCS(chip) {}
79*10465441SEvalZero #define CHIP_CLR_NCS(chip) {}
80*10465441SEvalZero #define CHIP_BUSY(chip) {}
81*10465441SEvalZero #define CHIP_READY(chip) {}
82*10465441SEvalZero #define WRITE_COMMAND(chip, cmd) {}
83*10465441SEvalZero #define WRITE_DATA_ADDR(chip, block, page, offset) {}
84*10465441SEvalZero #define WRITE_ERASE_ADDR(chip, block) {}
85*10465441SEvalZero #define WRITE_DATA(chip, data, len) {}
86*10465441SEvalZero #define READ_DATA(chip, data, len) {}
87*10465441SEvalZero 
88*10465441SEvalZero #define PARSE_STATUS(v) (UFFS_FLASH_NO_ERR)	// parse status to UFFS_FLASH_NO_ERR or UFFS_FLASH_BAD_BLK
89*10465441SEvalZero 
90*10465441SEvalZero 
91*10465441SEvalZero 
92*10465441SEvalZero #if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
main()93*10465441SEvalZero int main()
94*10465441SEvalZero {
95*10465441SEvalZero 	uffs_Perror(UFFS_MSG_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1");
96*10465441SEvalZero 	return 0;
97*10465441SEvalZero }
98*10465441SEvalZero #else
99*10465441SEvalZero 
100*10465441SEvalZero 
nand_read_page(uffs_Device * dev,u32 block,u32 page,u8 * data,int data_len,u8 * ecc,u8 * spare,int spare_len)101*10465441SEvalZero static int nand_read_page(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
102*10465441SEvalZero 						u8 *spare, int spare_len)
103*10465441SEvalZero {
104*10465441SEvalZero 	u8 val = 0;
105*10465441SEvalZero 	int ret = UFFS_FLASH_NO_ERR;
106*10465441SEvalZero 	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
107*10465441SEvalZero 
108*10465441SEvalZero 	CHIP_CLR_NCS(chip);
109*10465441SEvalZero 	if (data && data_len > 0) {
110*10465441SEvalZero 		CHIP_SET_CLE(chip);
111*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_READ0);
112*10465441SEvalZero 		CHIP_CLR_CLE(chip);
113*10465441SEvalZero 		CHIP_SET_ALE(chip);
114*10465441SEvalZero 		WRITE_DATA_ADDR(chip, block, page, 0);
115*10465441SEvalZero 		CHIP_CLR_ALE(chip);
116*10465441SEvalZero 		READ_DATA(chip, data, data_len);
117*10465441SEvalZero 
118*10465441SEvalZero 		// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
119*10465441SEvalZero 		memset(data, 0xFF, data_len);
120*10465441SEvalZero 	}
121*10465441SEvalZero 
122*10465441SEvalZero 	if (spare && spare_len > 0) {
123*10465441SEvalZero 		CHIP_SET_CLE(chip);
124*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_READOOB);
125*10465441SEvalZero 		CHIP_CLR_CLE(chip);
126*10465441SEvalZero 		CHIP_SET_ALE(chip);
127*10465441SEvalZero 		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
128*10465441SEvalZero 		CHIP_CLR_ALE(chip);
129*10465441SEvalZero 		READ_DATA(chip, spare, spare_len);
130*10465441SEvalZero 
131*10465441SEvalZero 		// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
132*10465441SEvalZero 		memset(spare, 0xFF, spare_len);
133*10465441SEvalZero 	}
134*10465441SEvalZero 
135*10465441SEvalZero 	if (data == NULL && spare == NULL) {
136*10465441SEvalZero 		// read bad block mark
137*10465441SEvalZero 		CHIP_SET_CLE(chip);
138*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_READOOB);
139*10465441SEvalZero 		CHIP_CLR_CLE(chip);
140*10465441SEvalZero 		CHIP_SET_ALE(chip);
141*10465441SEvalZero 		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
142*10465441SEvalZero 		CHIP_CLR_ALE(chip);
143*10465441SEvalZero 		READ_DATA(chip, &val, 1);
144*10465441SEvalZero 		ret = (val == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);
145*10465441SEvalZero 
146*10465441SEvalZero 		// for now, we return UFFS_FLASH_NO_ERR to pass UFFS mount, you should remove this at your driver
147*10465441SEvalZero 		ret = UFFS_FLASH_NO_ERR;
148*10465441SEvalZero 	}
149*10465441SEvalZero 
150*10465441SEvalZero 	CHIP_SET_NCS(chip);
151*10465441SEvalZero 
152*10465441SEvalZero 	return ret;
153*10465441SEvalZero }
154*10465441SEvalZero 
nand_write_page(uffs_Device * dev,u32 block,u32 page,const u8 * data,int data_len,const u8 * spare,int spare_len)155*10465441SEvalZero static int nand_write_page(uffs_Device *dev, u32 block, u32 page,
156*10465441SEvalZero 							const u8 *data, int data_len, const u8 *spare, int spare_len)
157*10465441SEvalZero {
158*10465441SEvalZero 	u8 val = 0;
159*10465441SEvalZero 	int ret = UFFS_FLASH_NO_ERR;
160*10465441SEvalZero 	UBOOL fall_through = FALSE;
161*10465441SEvalZero 	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
162*10465441SEvalZero 
163*10465441SEvalZero 	CHIP_CLR_NCS(chip);
164*10465441SEvalZero 
165*10465441SEvalZero 	if (data && data_len > 0) {
166*10465441SEvalZero 		CHIP_SET_CLE(chip);
167*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_READ0);
168*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_SEQIN);
169*10465441SEvalZero 		CHIP_CLR_CLE(chip);
170*10465441SEvalZero 		CHIP_SET_ALE(chip);
171*10465441SEvalZero 		WRITE_DATA_ADDR(chip, block, page, 0);
172*10465441SEvalZero 		CHIP_CLR_ALE(chip);
173*10465441SEvalZero 		CHIP_BUSY(chip);
174*10465441SEvalZero 		WRITE_DATA(chip, data, data_len);
175*10465441SEvalZero 		if (data_len == dev->attr->page_data_size)
176*10465441SEvalZero 			fall_through = U_TRUE;
177*10465441SEvalZero 		else {
178*10465441SEvalZero 			CHIP_SET_CLE(chip);
179*10465441SEvalZero 			WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
180*10465441SEvalZero 			WRITE_COMMAND(chip, NAND_CMD_STATUS);
181*10465441SEvalZero 			CHIP_CLR_CLE(chip);
182*10465441SEvalZero 			CHIP_READY(chip);
183*10465441SEvalZero 			READ_DATA(chip, &val, 1);
184*10465441SEvalZero 			ret = PARSE_STATUS(val);
185*10465441SEvalZero 		}
186*10465441SEvalZero 	}
187*10465441SEvalZero 
188*10465441SEvalZero 	if (ret != UFFS_FLASH_NO_ERR)
189*10465441SEvalZero 		goto ext;
190*10465441SEvalZero 
191*10465441SEvalZero 	if (spare && spare_len > 0) {
192*10465441SEvalZero 		if (!fall_through) {
193*10465441SEvalZero 			CHIP_SET_CLE(chip);
194*10465441SEvalZero 			WRITE_COMMAND(chip, NAND_CMD_READOOB);
195*10465441SEvalZero 			WRITE_COMMAND(chip, NAND_CMD_SEQIN);
196*10465441SEvalZero 			CHIP_CLR_CLE(chip);
197*10465441SEvalZero 			CHIP_SET_ALE(chip);
198*10465441SEvalZero 			WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
199*10465441SEvalZero 			CHIP_CLR_ALE(chip);
200*10465441SEvalZero 			CHIP_BUSY(chip);
201*10465441SEvalZero 		}
202*10465441SEvalZero 		WRITE_DATA(chip, spare, spare_len);
203*10465441SEvalZero 		CHIP_SET_CLE(chip);
204*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
205*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_STATUS);
206*10465441SEvalZero 		CHIP_CLR_CLE(chip);
207*10465441SEvalZero 		CHIP_READY(chip);
208*10465441SEvalZero 		READ_DATA(chip, &val, 1);
209*10465441SEvalZero 		ret = PARSE_STATUS(val);
210*10465441SEvalZero 	}
211*10465441SEvalZero 
212*10465441SEvalZero 	if (data == NULL && spare == NULL) {
213*10465441SEvalZero 		// mark bad block
214*10465441SEvalZero 		CHIP_SET_CLE(chip);
215*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_READOOB);
216*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_SEQIN);
217*10465441SEvalZero 		CHIP_CLR_CLE(chip);
218*10465441SEvalZero 		CHIP_SET_ALE(chip);
219*10465441SEvalZero 		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
220*10465441SEvalZero 		CHIP_CLR_ALE(chip);
221*10465441SEvalZero 		CHIP_BUSY(chip);
222*10465441SEvalZero 		val = 0;
223*10465441SEvalZero 		WRITE_DATA(chip, &val, 1);
224*10465441SEvalZero 		CHIP_SET_CLE(chip);
225*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
226*10465441SEvalZero 		WRITE_COMMAND(chip, NAND_CMD_STATUS);
227*10465441SEvalZero 		CHIP_CLR_CLE(chip);
228*10465441SEvalZero 		CHIP_READY(chip);
229*10465441SEvalZero 		READ_DATA(chip, &val, 1);
230*10465441SEvalZero 		ret = PARSE_STATUS(val);
231*10465441SEvalZero 	}
232*10465441SEvalZero 
233*10465441SEvalZero ext:
234*10465441SEvalZero 	CHIP_SET_NCS(chip);
235*10465441SEvalZero 
236*10465441SEvalZero 	return ret;
237*10465441SEvalZero }
238*10465441SEvalZero 
nand_erase_block(uffs_Device * dev,u32 block)239*10465441SEvalZero static int nand_erase_block(uffs_Device *dev, u32 block)
240*10465441SEvalZero {
241*10465441SEvalZero 	u8 val = 0;
242*10465441SEvalZero 	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
243*10465441SEvalZero 
244*10465441SEvalZero 	CHIP_CLR_NCS(chip);
245*10465441SEvalZero 
246*10465441SEvalZero 	CHIP_SET_CLE(chip);
247*10465441SEvalZero 	WRITE_COMMAND(chip, NAND_CMD_ERASE1);
248*10465441SEvalZero 	CHIP_CLR_CLE(chip);
249*10465441SEvalZero 	CHIP_SET_ALE(chip);
250*10465441SEvalZero 	WRITE_ERASE_ADDR(chip, blcok);
251*10465441SEvalZero 	CHIP_CLR_ALE(chip);
252*10465441SEvalZero 	CHIP_SET_CLE(chip);
253*10465441SEvalZero 	WRITE_COMMAND(chip, NAND_CMD_ERASE2);
254*10465441SEvalZero 	WRITE_COMMAND(chip, NAND_CMD_STATUS);
255*10465441SEvalZero 	CHIP_CLR_CLE(chip);
256*10465441SEvalZero 	CHIP_READY(chip);
257*10465441SEvalZero 	READ_DATA(chip, &val, 1);
258*10465441SEvalZero 
259*10465441SEvalZero 	CHIP_SET_NCS(chip);
260*10465441SEvalZero 
261*10465441SEvalZero 	val = val; // just for eliminating warning
262*10465441SEvalZero 
263*10465441SEvalZero 	return PARSE_STATUS(val);
264*10465441SEvalZero }
265*10465441SEvalZero 
266*10465441SEvalZero 
nand_init_flash(uffs_Device * dev)267*10465441SEvalZero static int nand_init_flash(uffs_Device *dev)
268*10465441SEvalZero {
269*10465441SEvalZero 	// initialize your hardware here ...
270*10465441SEvalZero 	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
271*10465441SEvalZero 
272*10465441SEvalZero 	if (!chip->inited) {
273*10465441SEvalZero 		// setup chip I/O address, setup NAND flash controller ... etc.
274*10465441SEvalZero 		// chip->IOR_ADDR = 0xF0000000
275*10465441SEvalZero 		// chip->IOW_ADDR = 0xF0000000
276*10465441SEvalZero 		chip->inited = U_TRUE;
277*10465441SEvalZero 	}
278*10465441SEvalZero 	return 0;
279*10465441SEvalZero }
280*10465441SEvalZero 
nand_release_flash(uffs_Device * dev)281*10465441SEvalZero static int nand_release_flash(uffs_Device *dev)
282*10465441SEvalZero {
283*10465441SEvalZero 	// release your hardware here
284*10465441SEvalZero 	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
285*10465441SEvalZero 
286*10465441SEvalZero 	chip = chip;
287*10465441SEvalZero 
288*10465441SEvalZero 	return 0;
289*10465441SEvalZero }
290*10465441SEvalZero 
291*10465441SEvalZero static uffs_FlashOps g_my_nand_ops = {
292*10465441SEvalZero 	nand_init_flash,	// InitFlash()
293*10465441SEvalZero 	nand_release_flash,	// ReleaseFlash()
294*10465441SEvalZero 	nand_read_page,		// ReadPage()
295*10465441SEvalZero 	NULL,				// ReadPageWithLayout
296*10465441SEvalZero 	nand_write_page,	// WritePage()
297*10465441SEvalZero 	NULL,				// WirtePageWithLayout
298*10465441SEvalZero 	NULL,				// IsBadBlock(), let UFFS take care of it.
299*10465441SEvalZero 	NULL,				// MarkBadBlock(), let UFFS take care of it.
300*10465441SEvalZero 	nand_erase_block,	// EraseBlock()
301*10465441SEvalZero };
302*10465441SEvalZero 
303*10465441SEvalZero /////////////////////////////////////////////////////////////////////////////////
304*10465441SEvalZero 
305*10465441SEvalZero // change these parameters to fit your nand flash specification
306*10465441SEvalZero 
307*10465441SEvalZero #define TOTAL_BLOCKS    1024
308*10465441SEvalZero #define PAGE_DATA_SIZE  512
309*10465441SEvalZero #define PAGE_SPARE_SIZE 16
310*10465441SEvalZero #define PAGES_PER_BLOCK 32
311*10465441SEvalZero #define PAGE_SIZE		(PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
312*10465441SEvalZero #define BLOCK_DATA_SIZE (PAGE_DATA_SIZE * PAGES_PER_BLOCK)
313*10465441SEvalZero 
314*10465441SEvalZero #define NR_PARTITION	2								/* total partitions */
315*10465441SEvalZero #define PAR_1_BLOCKS	100								/* partition 1 */
316*10465441SEvalZero #define PAR_2_BLOCKS	(TOTAL_BLOCKS - PAR_1_BLOCKS)	/* partition 2 */
317*10465441SEvalZero 
318*10465441SEvalZero struct my_nand_chip g_nand_chip = {0};
319*10465441SEvalZero static struct uffs_StorageAttrSt g_my_flash_storage = {0};
320*10465441SEvalZero 
321*10465441SEvalZero /* define mount table */
322*10465441SEvalZero static uffs_Device demo_device_1 = {0};
323*10465441SEvalZero static uffs_Device demo_device_2 = {0};
324*10465441SEvalZero 
325*10465441SEvalZero static uffs_MountTable demo_mount_table[] = {
326*10465441SEvalZero 	{ &demo_device_1,  0, PAR_1_BLOCKS - 1, "/data/" },
327*10465441SEvalZero 	{ &demo_device_2,  PAR_1_BLOCKS, PAR_1_BLOCKS + PAR_2_BLOCKS - 1, "/" },
328*10465441SEvalZero 	{ NULL, 0, 0, NULL }
329*10465441SEvalZero };
330*10465441SEvalZero 
331*10465441SEvalZero /* static alloc the memory for each partition */
332*10465441SEvalZero static int static_buffer_par1[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_1_BLOCKS) / sizeof(int)];
333*10465441SEvalZero static int static_buffer_par2[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_2_BLOCKS) / sizeof(int)];;
334*10465441SEvalZero 
init_nand_chip(struct my_nand_chip * chip)335*10465441SEvalZero static void init_nand_chip(struct my_nand_chip *chip)
336*10465441SEvalZero {
337*10465441SEvalZero 	// init chip IO address, etc.
338*10465441SEvalZero }
339*10465441SEvalZero 
setup_flash_storage(struct uffs_StorageAttrSt * attr)340*10465441SEvalZero static void setup_flash_storage(struct uffs_StorageAttrSt *attr)
341*10465441SEvalZero {
342*10465441SEvalZero 	memset(attr, 0, sizeof(struct uffs_StorageAttrSt));
343*10465441SEvalZero 
344*10465441SEvalZero 	// setup NAND flash attributes.
345*10465441SEvalZero 	attr->total_blocks = TOTAL_BLOCKS;			/* total blocks */
346*10465441SEvalZero 	attr->page_data_size = PAGE_DATA_SIZE;		/* page data size */
347*10465441SEvalZero 	attr->pages_per_block = PAGES_PER_BLOCK;	/* pages per block */
348*10465441SEvalZero 	attr->spare_size = PAGE_SPARE_SIZE;		  	/* page spare size */
349*10465441SEvalZero 	attr->block_status_offs = 4;				/* block status offset is 5th byte in spare */
350*10465441SEvalZero 	attr->ecc_opt = UFFS_ECC_SOFT;              /* ecc option */
351*10465441SEvalZero 	attr->layout_opt = UFFS_LAYOUT_UFFS;        /* let UFFS do the spare layout */
352*10465441SEvalZero }
353*10465441SEvalZero 
my_InitDevice(uffs_Device * dev)354*10465441SEvalZero static URET my_InitDevice(uffs_Device *dev)
355*10465441SEvalZero {
356*10465441SEvalZero 	dev->attr = &g_my_flash_storage;			// NAND flash attributes
357*10465441SEvalZero 	dev->attr->_private = (void *) &g_nand_chip;// hook nand_chip data structure to attr->_private
358*10465441SEvalZero 	dev->ops = &g_my_nand_ops;					// NAND driver
359*10465441SEvalZero 
360*10465441SEvalZero 	init_nand_chip(&g_nand_chip);
361*10465441SEvalZero 
362*10465441SEvalZero 	return U_SUCC;
363*10465441SEvalZero }
364*10465441SEvalZero 
my_ReleaseDevice(uffs_Device * dev)365*10465441SEvalZero static URET my_ReleaseDevice(uffs_Device *dev)
366*10465441SEvalZero {
367*10465441SEvalZero 	return U_SUCC;
368*10465441SEvalZero }
369*10465441SEvalZero 
370*10465441SEvalZero 
my_init_filesystem(void)371*10465441SEvalZero static int my_init_filesystem(void)
372*10465441SEvalZero {
373*10465441SEvalZero 	uffs_MountTable *mtbl = &(demo_mount_table[0]);
374*10465441SEvalZero 
375*10465441SEvalZero 	/* setup nand storage attributes */
376*10465441SEvalZero 	setup_flash_storage(&g_my_flash_storage);
377*10465441SEvalZero 
378*10465441SEvalZero 	/* setup memory allocator */
379*10465441SEvalZero 	uffs_MemSetupStaticAllocator(&demo_device_1.mem, static_buffer_par1, sizeof(static_buffer_par1));
380*10465441SEvalZero 	uffs_MemSetupStaticAllocator(&demo_device_2.mem, static_buffer_par2, sizeof(static_buffer_par2));
381*10465441SEvalZero 
382*10465441SEvalZero 	/* register mount table */
383*10465441SEvalZero 	while(mtbl->dev) {
384*10465441SEvalZero 		// setup device init/release entry
385*10465441SEvalZero 		mtbl->dev->Init = my_InitDevice;
386*10465441SEvalZero 		mtbl->dev->Release = my_ReleaseDevice;
387*10465441SEvalZero 		uffs_RegisterMountTable(mtbl);
388*10465441SEvalZero 		mtbl++;
389*10465441SEvalZero 	}
390*10465441SEvalZero 
391*10465441SEvalZero 	// mount partitions
392*10465441SEvalZero 	for (mtbl = &(demo_mount_table[0]); mtbl->mount != NULL; mtbl++) {
393*10465441SEvalZero 		uffs_Mount(mtbl->mount);
394*10465441SEvalZero 	}
395*10465441SEvalZero 
396*10465441SEvalZero 	return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1;
397*10465441SEvalZero }
398*10465441SEvalZero 
my_release_filesystem(void)399*10465441SEvalZero static int my_release_filesystem(void)
400*10465441SEvalZero {
401*10465441SEvalZero 	uffs_MountTable *mtb;
402*10465441SEvalZero 	int ret = 0;
403*10465441SEvalZero 
404*10465441SEvalZero 	// unmount parttions
405*10465441SEvalZero 	for (mtb = &(demo_mount_table[0]); ret == 0 && mtb->mount != NULL; mtb++) {
406*10465441SEvalZero 		ret = uffs_UnMount(mtb->mount);
407*10465441SEvalZero 	}
408*10465441SEvalZero 
409*10465441SEvalZero 	// release objects
410*10465441SEvalZero 	if (ret == 0)
411*10465441SEvalZero 		ret = (uffs_ReleaseFileSystemObjects() == U_SUCC ? 0 : -1);
412*10465441SEvalZero 
413*10465441SEvalZero 	return ret;
414*10465441SEvalZero }
415*10465441SEvalZero 
416*10465441SEvalZero /* application entry */
main()417*10465441SEvalZero int main()
418*10465441SEvalZero {
419*10465441SEvalZero 	uffs_SetupDebugOutput(); 	// setup debug output as early as possible
420*10465441SEvalZero 
421*10465441SEvalZero 	my_init_filesystem();
422*10465441SEvalZero 
423*10465441SEvalZero 	// ... my application codes ....
424*10465441SEvalZero 	// read/write/create/delete files ...
425*10465441SEvalZero 
426*10465441SEvalZero 	my_release_filesystem();
427*10465441SEvalZero 
428*10465441SEvalZero 	return 0;
429*10465441SEvalZero }
430*10465441SEvalZero 
431*10465441SEvalZero #endif
432*10465441SEvalZero 
433*10465441SEvalZero 
434*10465441SEvalZero /////////////////////////////////////////////////////////////////////////////////
435