#define K9F1G_CLE ((volatile uint8_t *)0x90100000)//1<<20
#define K9F1G_ALE ((volatile uint8_t *)0x90080000)//1<<19
#define K9F1G_DATA ((volatile uint8_t *)0x90000000)
#define K9FXX_READ_ID 0x90
static void pinConfig(void)
{
LPC_IOCON->P3_0 |= 1; //D0 @ P3.0
LPC_IOCON->P3_1 |= 1; //D1 @ P3.1
LPC_IOCON->P3_2 |= 1; //D2 @ P3.2
LPC_IOCON->P3_3 |= 1; //D3 @ P3.3
LPC_IOCON->P3_4 |= 1; //D4 @ P3.4
LPC_IOCON->P3_5 |= 1; //D5 @ P3.5
LPC_IOCON->P3_6 |= 1; //D6 @ P3.6
LPC_IOCON->P3_7 |= 1; //D7 @ P3.7
LPC_IOCON->P3_8 |= 1; //D8 @ P3.8
LPC_IOCON->P3_9 |= 1; //D9 @ P3.9
LPC_IOCON->P3_10 |= 1; //D10 @ P3.10
LPC_IOCON->P3_11 |= 1; //D11 @ P3.11
LPC_IOCON->P3_12 |= 1; //D12 @ P3.12
LPC_IOCON->P3_13 |= 1; //D13 @ P3.13
LPC_IOCON->P3_14 |= 1; //D14 @ P3.14
LPC_IOCON->P3_15 |= 1; //D15 @ P3.15
LPC_IOCON->P3_16 |= 1; //D16 @ P3.16
LPC_IOCON->P3_17 |= 1; //D17 @ P3.17
LPC_IOCON->P3_18 |= 1; //D18 @ P3.18
LPC_IOCON->P3_19 |= 1; //D19 @ P3.19
LPC_IOCON->P3_20 |= 1; //D20 @ P3.20
LPC_IOCON->P3_21 |= 1; //D21 @ P3.21
LPC_IOCON->P3_22 |= 1; //D22 @ P3.22
LPC_IOCON->P3_23 |= 1; //D23 @ P3.23
LPC_IOCON->P3_24 |= 1; //D24 @ P3.24
LPC_IOCON->P3_25 |= 1; //D25 @ P3.25
LPC_IOCON->P3_26 |= 1; //D26 @ P3.26
LPC_IOCON->P3_27 |= 1; //D27 @ P3.27
LPC_IOCON->P3_28 |= 1; //D28 @ P3.28
LPC_IOCON->P3_29 |= 1; //D29 @ P3.29
LPC_IOCON->P3_30 |= 1; //D30 @ P3.30
LPC_IOCON->P3_31 |= 1; //D31 @ P3.31
LPC_IOCON->P4_0 |= 1; //A0 @ P4.0
LPC_IOCON->P4_1 |= 1; //A1 @ P4.1
LPC_IOCON->P4_2 |= 1; //A2 @ P4.2
LPC_IOCON->P4_3 |= 1; //A3 @ P4.3
LPC_IOCON->P4_4 |= 1; //A4 @ P4.4
LPC_IOCON->P4_5 |= 1; //A5 @ P4.5
LPC_IOCON->P4_6 |= 1; //A6 @ P4.6
LPC_IOCON->P4_7 |= 1; //A7 @ P4.7
LPC_IOCON->P4_8 |= 1; //A8 @ P4.8
LPC_IOCON->P4_9 |= 1; //A9 @ P4.9
LPC_IOCON->P4_10 |= 1; //A10 @ P4.10
LPC_IOCON->P4_11 |= 1; //A11 @ P4.11
LPC_IOCON->P4_12 |= 1; //A12 @ P4.12
LPC_IOCON->P4_13 |= 1; //A13 @ P4.13
LPC_IOCON->P4_14 |= 1; //A14 @ P4.14
LPC_IOCON->P4_15 |= 1; //A15 @ P4.15
LPC_IOCON->P4_16 |= 1; //A16 @ P4.16
LPC_IOCON->P4_17 |= 1; //A17 @ P4.17
LPC_IOCON->P4_18 |= 1; //A18 @ P4.18
LPC_IOCON->P4_19 |= 1; //A19 @ P4.19
LPC_IOCON->P4_20 |= 1; //A20 @ P4.20
LPC_IOCON->P4_21 |= 1; //A21 @ P4.21
LPC_IOCON->P4_22 |= 1; //A22 @ P4.22
LPC_IOCON->P4_23 |= 1; //A23 @ P4.23
LPC_IOCON->P4_24 |= 1; //OEN @ P4.24
LPC_IOCON->P4_25 |= 1; //WEN @ P4.25
LPC_IOCON->P4_26 |= 1; //BLSN[0] @ P4.26
LPC_IOCON->P4_27 |= 1; //BLSN[1] @ P4.27
LPC_IOCON->P4_28 |= 1; //BLSN[2] @ P4.28
LPC_IOCON->P4_29 |= 1; //BLSN[3] @ P4.29
LPC_IOCON->P4_30 |= 1; //CSN[0] @ P4.30
LPC_IOCON->P4_31 |= 1; //CSN[1] @ P4.31
LPC_IOCON->P2_14 |= 1; //CSN[2] @ P2.14
LPC_IOCON->P2_15 |= 1; //CSN[3] @ P2.15
}
static uint64_t nandReadId(void)
{
uint8_t a, b, c, d, e;
volatile uint8_t *pCLE;
volatile uint8_t *pALE;
volatile uint8_t *pData;
pCLE = K9F1G_CLE;
pALE = K9F1G_ALE;
pData = K9F1G_DATA;
*pCLE = K9FXX_READ_ID;
*pALE = 0;
a = *pData;
b = *pData;
c = *pData;
d = *pData;
e = *pData;
return ((uint64_t)a << 32) | (b << 24) | (c << 16) | (d << 8) | e;
}
bool nand_init (void)
{
volatile uint64_t nandId = 0;
TIM_TIMERCFG_Type timerCfg;
LPC_SC->PCONP |= 0x00000800;
LPC_EMC->Control = 0x00000001;//enable
LPC_EMC->Config = 0x00000000;//little endian
pinConfig();
TIM_ConfigStructInit(TIM_TIMER_MODE, &timerCfg);
TIM_Init(LPC_TIM0, TIM_TIMER_MODE, &timerCfg);
LPC_EMC->StaticConfig1 = 0x00000080;//Byte lane state.
LPC_EMC->StaticWaitWen1 = 0x00000002;
LPC_EMC->StaticWaitOen1 = 0x00000002;
LPC_EMC->StaticWaitRd1 = 0x00000008;
LPC_EMC->StaticWaitPage1 = 0x0000001f;
LPC_EMC->StaticWaitWr1 = 0x00000008;
LPC_EMC->StaticWaitTurn1 = 0x0000000f;
nandId = nandReadId();//returns 0xFF FFFF FFFF
if( nandId != 0x01CC90D556ULL ){
return false;
}
/*
if ((nandId & 0xffff0000) !=
(((uint32_t)(ID_MARKER_CODE) << 24) | ID_SAMSUNG << 16)) {
// unknown NAND chip
return false;
}
*/
pageSize = 1024 * (1 << (nandId & 0x03));
blockSize = 64*1024 * (1 << ((nandId>>4) & 0x03));
reduntSize = 8 * (1 << ((nandId >> 1) & 0x1));
return true;
}
|