| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nandflash.c
Go to the documentation of this file.
1 /*
2 * @brief This example shows how to opertate on external flash operations.
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include "board.h"
33 #include "string.h"
34
65 /*****************************************************************************
66 * Private types/enumerations/variables
67 ****************************************************************************/
68
69 /* The The desired index of block which is used to store string */
70 #define BLOCK_INDEX 1
71 /* The index of page which is used to store string */
72 #define PAGE_INDEX 0
73 /* BUFFER size */
74 #define BUFFER_SIZE 0x40
75
76 /* Tag for checking if a string already exists in Flash */
77 #define CHKTAG "NxP"
78 #define CHKTAG_SIZE 3
79
80 /* ASCII ESC character code */
81 #define ESC_CHAR 27
82
83 /* Read/write buffer (32-bit aligned) */
84 uint32_t buffer[BUFFER_SIZE / sizeof(uint32_t)];
85
86 /*****************************************************************************
87 * Public types/enumerations/variables
88 ****************************************************************************/
89
90 /* Show current string stored in UART */
91 static void ShowString(char *str) {
92 int stSize;
93
94 /* Is data tagged with check pattern? */
95 if (strncmp(str, CHKTAG, CHKTAG_SIZE) == 0) {
96 /* Get next byte, which is the string size in bytes */
97 stSize = (uint32_t) str[3];
98 if (stSize > 32) {
99 stSize = 32;
100 }
101
102 /* Add terminator */
103 str[4 + stSize] = '\0';
104
105 /* Show string stored in Flash */
106 DEBUGSTR("Stored string found in Flash\r\n");
107 DEBUGSTR("-->");
108 DEBUGSTR((char *) &str[4]);
109 DEBUGSTR("<--\r\n");
110 }
111 else {
112 DEBUGSTR("No string stored in the Flash\r\n");
113 }
114 }
115
116 /* Get a string to save from the UART */
117 static uint32_t MakeString(uint8_t *str)
118 {
119 int index, byte;
120 char strOut[2];
121
122 /* Get a string up to 32 bytes to write into Flash */
123 DEBUGSTR("\r\nEnter a string to write into Flash\r\n");
124 DEBUGSTR("Up to 32 bytes in length, press ESC to accept\r\n");
125
126 /* Setup header */
127 strncpy((char *) str, CHKTAG, CHKTAG_SIZE);
128
129 /* Read until escape, but cap at 32 characters */
130 index = 0;
131 strOut[1] = '\0';
132 #if defined(DEBUG_ENABLE)
133 byte = DEBUGIN();
134 while ((index < 32) && (byte != ESC_CHAR)) {
135 if (byte != EOF) {
136 strOut[0] = str[4 + index] = (uint8_t) byte;
137 DEBUGSTR(strOut);
138 index++;
139 }
140
141 byte = DEBUGIN();
142 }
143 #else
144 /* Suppress warnings */
145 (void) byte;
146 (void) strOut;
147
148 /* Debug input not enabled, so use a pre-setup string */
149 strncpy((char *) &str[4], "12345678", 8);
150 index = 8;
151 #endif
152
153 str[3] = (uint8_t) index;
154
155 return (uint32_t) index;
156 }
157
158 /*****************************************************************************
159 * Private functions
160 ****************************************************************************/
161
162 /* Wait for Nand Flash ready */
163 STATIC void waitForReady(void)
164 {
165 if(Board_NANDFLash_GetReady()) {
166 while(Board_NANDFLash_GetReady()){}
167 }
168 while(!Board_NANDFLash_GetReady()){}
169 }
170
171 /* Identify valid blocks */
172 bool checkBadBlock(uint32_t block)
173 {
174 uint8_t valid;
175
176 lpc_nandflash_read_start(block, 0, K9F1G_SPARE_START_ADDR);
177 waitForReady();
178 lpc_nandflash_read_data(&valid, 1);
179 return (bool) (valid != 0xFF);
180 }
181
182 /*****************************************************************************
183 * Public functions
184 ****************************************************************************/
185
190 int main(void)
191 {
192 K9F1G_ID_T nandId;
193 const lpc_nandflash_size_t *flashInfo;
194 uint32_t stSize, useBlock = BLOCK_INDEX;
195 volatile int loop = 1, idx; /* For debug message only */
196
197 Board_Init();
198 Board_NANDFLash_Init();
199 lpc_nandflash_init();
200
201 /* Read flash information */
202 flashInfo = lpc_nandflash_get_size();
203 lpc_nandflash_get_id((uint8_t*)&nandId);
204 DEBUGOUT(" Flash Information: \r\n");
205 DEBUGOUT(" Manufacturer ID: 0x%02x\r\n", nandId.MarkerCode);
206 DEBUGOUT(" Device ID: 0x%02x\r\n", nandId.DeviceCode);
207 DEBUGOUT(" Page Size: %dB\r\n", flashInfo->page_size);
208 DEBUGOUT(" Spare Size: %dB\r\n", flashInfo->spare_size);
209 DEBUGOUT(" Block Size: %dKB\r\n", flashInfo->pages_per_block*flashInfo->page_size/1024);
210 DEBUGOUT(" Block count: %d\r\n", flashInfo->block_cnt);
211
212 /* Show bad block list */
213 DEBUGOUT("Checking bad blocks...\r\n");
214 for (idx = 0; idx < flashInfo->block_cnt; idx++) {
215 if (checkBadBlock(idx)) {
216 DEBUGOUT(" Bad block at %d\r\n", idx);
217 if (useBlock == idx) {
218 /* Skip to next block for the example if this one is bad */
219 useBlock++;
220 }
221 }
222 }
223
224 /* Read data */
225 lpc_nandflash_read_start(useBlock, PAGE_INDEX, 0);
226 waitForReady();
227 lpc_nandflash_read_data((uint8_t *) buffer, BUFFER_SIZE);
228
229 /* Check and display string if it exists */
230 ShowString((char *) buffer);
231
232 /* Get a string to save */
233 stSize = MakeString((uint8_t *) buffer);
234
235 /* Erase flash */
236 lpc_nandflash_erase_block(useBlock);
237 waitForReady();
238
239 /* Check the result of erasing */
240 if(lpc_nandflash_read_status() & NANDFLASH_STATUS_BLOCK_ERASE_FAIL) {
241 DEBUGSTR("Erase failed!!!\r\n");
242 while(1){}
243 }
244
245 /* Write header + size + data to page */
246 DEBUGSTR("\r\nWrite to flash...\r\n");
247 lpc_nandflash_write_page(useBlock, PAGE_INDEX,(uint8_t *) buffer, (4 + stSize));
248 waitForReady();
249
250 /* Check the result of writting */
251 if(lpc_nandflash_read_status() & NANDFLASH_STATUS_PAGE_PROG_FAIL) {
252 DEBUGSTR("Writing failed!!!\r\n");
253 while(1){}
254 }
255
256 DEBUGSTR("Reading back string...\r\n");
257
258 /* Read all data from flash */
259 lpc_nandflash_read_start(useBlock, PAGE_INDEX, 0);
260 waitForReady();
261 lpc_nandflash_read_data((uint8_t *) buffer, BUFFER_SIZE);
262
263 /* Check and display string if it exists */
264 ShowString((char *) buffer);
265
266 /* Wait forever */
267 while (loop) {}
268
269 return 0;
270 }
271