need help getting S34ML04G2 NAND flash to work with lpc1788

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

need help getting S34ML04G2 NAND flash to work with lpc1788

922 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by shoeloader on Mon Nov 10 06:56:59 MST 2014
I have a custom board with a lpc1788 with IS42S16400F SDRAM and S34ML04G200TF100 NAND flash.
I got the SDRAM to work but the flash won't initialize.
I use the code for the embedded artist oem board. The difference is that the embedded artist board uses the K9F1G08U0C chip and that I don't use buffers.
The command for requesting an id is 0x90 in both chips
When I request the ID of the chip it returns only 1's.

Here's how the flash is connected:
[list]
  [*]IO0 to IO7 connected to EMC_D0 to EMC_D7(same as oem1788)
  [*]nRE connected to EMC_OE (same as oem1788)
  [*]CLE connected to EMC_A20(same as oem1788)
  [*]ALE connected to EMC_A19(same as oem1788)
  [*]nCE connected to EMC_CS1 + 10k pull-up(same as oem1788)
  [*]nWE connected to EMC_WE(same as oem1788)
  [*]nWP connected to 3v3(same as oem1788)
  [*]nR/B connected to EMC_A23 + 10k pull-up (is not connected on oem1788 )
[/list]

Here is part of my code:

#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;
}


What am I doing wrong?
Labels (1)
0 Kudos
Reply
1 Reply

830 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by shoeloader on Tue Nov 18 08:14:26 MST 2014
I found the error. It turns out data4 and data5 were swapped. We copied this from an example.
0 Kudos
Reply