23 #include "../../board.h"
25 #if BOARD == BOARD_EA4357
27 #include "lpc_types.h"
28 #include "lpc43xx_scu.h"
29 #include "lpc43xx_timer.h"
37 #define K9F1G_CLE ((volatile uint8_t *)0x1D100000)
38 #define K9F1G_ALE ((volatile uint8_t *)0x1D080000)
39 #define K9F1G_DATA ((volatile uint8_t *)0x1D000000)
43 #define K9FXX_READ_1 0x00
44 #define K9FXX_READ_2 0x30
46 #define K9FXX_SET_ADDR_A 0x00
47 #define K9FXX_SET_ADDR_B 0x01
48 #define K9FXX_SET_ADDR_C 0x50
49 #define K9FXX_READ_ID 0x90
50 #define K9FXX_RESET 0xff
51 #define K9FXX_BLOCK_PROGRAM_1 0x80
52 #define K9FXX_BLOCK_PROGRAM_2 0x10
53 #define K9FXX_BLOCK_ERASE_1 0x60
54 #define K9FXX_BLOCK_ERASE_2 0xd0
55 #define K9FXX_READ_STATUS 0x70
56 #define K9FXX_BUSY (1 << 6)
57 #define K9FXX_OK (1 << 0)
59 #define ID_MARKER_CODE (0xEC)
60 #define ID_SAMSUNG (0xF1)
62 #define ID_PAGE_SZ_1KB (0x00)
63 #define ID_PAGE_SZ_2KB (0x01)
64 #define ID_PAGE_SZ_4KB (0x02)
65 #define ID_PAGE_SZ_8KB (0x03)
67 #define ID_BLOCK_SZ_64KB (0x00)
68 #define ID_BLOCK_SZ_128KB (0x01)
69 #define ID_BLOCK_SZ_256KB (0x02)
70 #define ID_BLOCK_SZ_512KB (0x03)
72 #define ID_PAGE_SZ_1KB (0x00)
73 #define ID_PAGE_SZ_2KB (0x01)
74 #define ID_PAGE_SZ_4KB (0x02)
75 #define ID_PAGE_SZ_8KB (0x03)
77 #define ID_REDUND_SZ_8 (0x00)
78 #define ID_REDUND_SZ_16 (0x01)
83 #define WAIT_READY() (TIM_Waitus(25))
94 static uint32_t pageSize = 0;
95 static uint32_t blockSize = 0;
96 static uint32_t reduntSize = 0;
103 static void pinConfig(
void)
106 scu_pinmux( 2 , 9 , MD_PLN_FAST , 3 );
107 scu_pinmux( 2 , 10 , MD_PLN_FAST , 3 );
108 scu_pinmux( 2 , 11 , MD_PLN_FAST , 3 );
109 scu_pinmux( 2 , 12 , MD_PLN_FAST , 3 );
110 scu_pinmux( 2 , 13 , MD_PLN_FAST , 3 );
111 scu_pinmux( 1 , 0 , MD_PLN_FAST , 2 );
112 scu_pinmux( 1 , 1 , MD_PLN_FAST , 2 );
113 scu_pinmux( 1 , 2 , MD_PLN_FAST , 2 );
114 scu_pinmux( 2 , 8 , MD_PLN_FAST , 3 );
115 scu_pinmux( 2 , 7 , MD_PLN_FAST , 3 );
116 scu_pinmux( 2 , 6 , MD_PLN_FAST , 2 );
117 scu_pinmux( 2 , 2 , MD_PLN_FAST , 2 );
118 scu_pinmux( 2 , 1 , MD_PLN_FAST , 2 );
119 scu_pinmux( 2 , 0 , MD_PLN_FAST , 2 );
120 scu_pinmux( 6 , 8 , MD_PLN_FAST , 1 );
121 scu_pinmux( 6 , 7 , MD_PLN_FAST , 1 );
122 scu_pinmux( 13 , 16 , MD_PLN_FAST , 2 );
123 scu_pinmux( 13 , 15 , MD_PLN_FAST , 2 );
124 scu_pinmux( 14 , 0 , MD_PLN_FAST , 3 );
125 scu_pinmux( 14 , 1 , MD_PLN_FAST , 3 );
126 scu_pinmux( 14 , 2 , MD_PLN_FAST , 3 );
127 scu_pinmux( 14 , 3 , MD_PLN_FAST , 3 );
128 scu_pinmux( 14 , 4 , MD_PLN_FAST , 3 );
129 scu_pinmux( 10 , 4 , MD_PLN_FAST , 3 );
131 scu_pinmux( 1 , 7 , MD_PLN_FAST , 3 );
132 scu_pinmux( 1 , 8 , MD_PLN_FAST , 3 );
133 scu_pinmux( 1 , 9 , MD_PLN_FAST , 3 );
134 scu_pinmux( 1 , 10 , MD_PLN_FAST , 3 );
135 scu_pinmux( 1 , 11 , MD_PLN_FAST , 3 );
136 scu_pinmux( 1 , 12 , MD_PLN_FAST , 3 );
137 scu_pinmux( 1 , 13 , MD_PLN_FAST , 3 );
138 scu_pinmux( 1 , 14 , MD_PLN_FAST , 3 );
139 scu_pinmux( 5 , 4 , MD_PLN_FAST , 2 );
140 scu_pinmux( 5 , 5 , MD_PLN_FAST , 2 );
141 scu_pinmux( 5 , 6 , MD_PLN_FAST , 2 );
142 scu_pinmux( 5 , 7 , MD_PLN_FAST , 2 );
143 scu_pinmux( 5 , 0 , MD_PLN_FAST , 2 );
144 scu_pinmux( 5 , 1 , MD_PLN_FAST , 2 );
145 scu_pinmux( 5 , 2 , MD_PLN_FAST , 2 );
146 scu_pinmux( 5 , 3 , MD_PLN_FAST , 2 );
147 scu_pinmux( 13 , 2 , MD_PLN_FAST , 2 );
148 scu_pinmux( 13 , 3 , MD_PLN_FAST , 2 );
149 scu_pinmux( 13 , 4 , MD_PLN_FAST , 2 );
150 scu_pinmux( 13 , 5 , MD_PLN_FAST , 2 );
151 scu_pinmux( 13 , 6 , MD_PLN_FAST , 2 );
152 scu_pinmux( 13 , 7 , MD_PLN_FAST , 2 );
153 scu_pinmux( 13 , 8 , MD_PLN_FAST , 2 );
154 scu_pinmux( 13 , 9 , MD_PLN_FAST , 2 );
155 scu_pinmux( 14 , 5 , MD_PLN_FAST , 3 );
156 scu_pinmux( 14 , 6 , MD_PLN_FAST , 3 );
157 scu_pinmux( 14 , 7 , MD_PLN_FAST , 3 );
158 scu_pinmux( 14 , 8 , MD_PLN_FAST , 3 );
159 scu_pinmux( 14 , 9 , MD_PLN_FAST , 3 );
160 scu_pinmux( 14 , 10 , MD_PLN_FAST , 3 );
161 scu_pinmux( 14 , 11 , MD_PLN_FAST , 3 );
162 scu_pinmux( 14 , 12 , MD_PLN_FAST , 3 );
164 scu_pinmux( 1 , 3 , MD_PLN_FAST , 3 );
165 scu_pinmux( 1 , 6 , MD_PLN_FAST , 3 );
167 scu_pinmux( 1 , 4 , MD_PLN_FAST , 3 );
168 scu_pinmux( 6 , 6 , MD_PLN_FAST , 1 );
169 scu_pinmux( 13 , 13 , MD_PLN_FAST , 2 );
170 scu_pinmux( 13 , 10 , MD_PLN_FAST , 2 );
172 scu_pinmux( 1 , 5 , MD_PLN_FAST , 3 );
173 scu_pinmux( 6 , 3 , MD_PLN_FAST , 3 );
174 scu_pinmux( 13 , 12 , MD_PLN_FAST , 2 );
175 scu_pinmux( 13 , 11 , MD_PLN_FAST , 2 );
179 static uint32_t nandReadId(
void)
182 volatile uint8_t *pCLE;
183 volatile uint8_t *pALE;
184 volatile uint8_t *pData;
190 *pCLE = K9FXX_READ_ID;
199 return (a << 24) | (b << 16) | (c << 8) | d;
202 static uint8_t nandStatus(
void)
205 volatile uint8_t *pCLE;
206 volatile uint8_t *pALE;
207 volatile uint8_t *pData;
213 *pCLE = K9FXX_READ_STATUS;
219 return (status & 0xC1);
222 static void nandWaitReady(
void)
224 while( !(nandStatus() & (1<<6)) );
242 uint32_t nand_init (
void)
245 TIM_TIMERCFG_Type timerCfg;
248 LPC_EMC->CONTROL = 0x00000001;
249 LPC_EMC->CONFIG = 0x00000000;
253 TIM_ConfigStructInit(TIM_TIMER_MODE, &timerCfg);
254 TIM_Init(LPC_TIMER0, TIM_TIMER_MODE, &timerCfg);
256 LPC_EMC->STATICCONFIG1 = 0x00000080;
258 LPC_EMC->STATICWAITWEN1 = 0x00000002;
259 LPC_EMC->STATICWAITOEN1 = 0x00000002;
260 LPC_EMC->STATICWAITRD1 = 0x00000008;
261 LPC_EMC->STATICWAITPAG1 = 0x0000001f;
262 LPC_EMC->STATICWAITWR1 = 0x00000008;
263 LPC_EMC->STATICWAITTURN1 = 0x0000000f;
265 nandId = nandReadId();
267 if ((nandId & 0xffff0000) !=
268 (((uint32_t)(ID_MARKER_CODE) << 24) | ID_SAMSUNG << 16)) {
273 pageSize = 1024 * (1 << (nandId & 0x03));
274 blockSize = 64*1024 * (1 << ((nandId>>4) & 0x03));
275 reduntSize = 8 * (1 << ((nandId >> 1) & 0x1));
290 uint32_t nand_getPageSize(
void)
304 uint32_t nand_getBlockSize(
void)
318 uint32_t nand_getRedundantSize(
void)
320 return reduntSize * (pageSize/512);
332 uint32_t nand_isBlockValid(uint32_t block)
337 volatile uint8_t *pCLE;
338 volatile uint8_t *pALE;
339 volatile uint8_t *pData;
346 if (block >= NAND_NUM_BLOCKS) {
350 addr = block * (blockSize/pageSize);
360 for (page = 0; page < 2; page++) {
363 *pCLE = K9FXX_READ_1;
364 *pALE = (uint8_t) (pageSize & 0x00FF);
365 *pALE = (uint8_t)((pageSize & 0xFF00) >> 8);
366 *pALE = (uint8_t)((addr & 0x00FF));
367 *pALE = (uint8_t)((addr & 0xFF00) >> 8);
368 *pCLE = K9FXX_READ_2;
372 if (*pData != 0xFF) {
397 uint32_t nand_readPage(uint32_t block, uint32_t page, uint8_t* pageBuf)
402 volatile uint8_t *pCLE;
403 volatile uint8_t *pALE;
404 volatile uint8_t *pData;
411 if (block >= NAND_NUM_BLOCKS) {
415 if (page >= blockSize/pageSize) {
419 addr = block * (blockSize/pageSize) + page;
426 *pCLE = K9FXX_READ_1;
429 *pALE = (uint8_t)((addr & 0x00FF));
430 *pALE = (uint8_t)((addr & 0xFF00) >> 8);
431 *pCLE = K9FXX_READ_2;
436 for (i = 0; i < pageSize; i++) {
459 uint32_t nand_writePage(uint32_t block, uint32_t page, uint8_t* pageBuf)
464 volatile uint8_t *pCLE;
465 volatile uint8_t *pALE;
466 volatile uint8_t *pData;
473 if (block >= NAND_NUM_BLOCKS) {
477 if (page >= blockSize/pageSize) {
481 addr = block * (blockSize/pageSize) + page;
488 *pCLE = K9FXX_BLOCK_PROGRAM_1;
491 *pALE = (uint8_t)((addr & 0x00FF));
492 *pALE = (uint8_t)((addr & 0xFF00) >> 8);
495 for (i = 0; i < pageSize; i++) {
499 *pCLE = K9FXX_BLOCK_PROGRAM_2;
504 return ((nandStatus() & 0x01) != 0x01);
519 uint32_t nand_eraseBlock(uint32_t block)
523 volatile uint8_t *pCLE;
524 volatile uint8_t *pALE;
529 if (block >= NAND_NUM_BLOCKS) {
533 addr = block * (blockSize/pageSize);
535 *pCLE = K9FXX_BLOCK_ERASE_1;
536 *pALE = (uint8_t)(addr & 0x00FF);
537 *pALE = (uint8_t)((addr & 0xFF00) >> 8);
538 *pCLE = K9FXX_BLOCK_ERASE_2;
543 return ((nandStatus() & 0x01) != 0x01);