AnsweredAssumed Answered

Page Read Problem with NAND Flash on STM32F2xx

Question asked by tze_wan.foo on Nov 18, 2013
Latest reply on Feb 1, 2018 by AlexSmart

Hi all,

I am working on porting STM3210e FSMC Nand flash evaluation code to STM32F207. The board I am using is:
http://www.ebay.com/itm/STM32F207ZG-module-HY-STM32F2xxCore144-Core-Dev-Board-/170874320152?pt=LH_DefaultDomain_0&hash=item27c8e73518

On this board, the NAND flash is Samsung K9F1G08U0C. This is the datasheet:
http://www.insidegadgets.com/wp-content/uploads/2013/03/K9F1G08X0C.pdf

From the datasheet, I gathered that the structure of the NAND is:

-        Total 1024 blocks.
-        1 block = 64 pages.
-        1 page = 2048 bytes excluding the spare area.
-        Thus, total capacity is 1024 x 64 x 2048 = 128 MByte. 

On this board, bank2 of the FSMC is used to interface with the NAND. Altogether, the following lines are connected between the STM32F207 chip and the flash:

K9F1G08U0C      STM32F207        
==========       ==========
    D0  -                     PD14      
    D1  -                       PD15
    D2  -                       PD0
    D3  -                       PD1
    D4  -                       PE7
    D5  -                       PE8
    D6  -                       PE9
    D7  -                       PE10
    CLE -                     PD11
    ALE -                      PD12
    NOE -                     PD4
    NWE -                   PD5
    NCE2-                    PD7
    NWAIT-                 PD6 (This is not connected. Instead use INT2)

    INT2 -                    PG

Manual and schematic for this board are at:
http://www.haoyuelectronics.com/Attachment/HY-STM32F2xxCore144/

I am able to read the Maker ID (0xEC) from the NAND, which tallies with the datasheet.

However, upon doing a page write-read compare, the contents of the read is all 0x00s. I am not sure which part could possibly be wrong.

Have attached my initialization code here, as well as some pertinent constants.

Would appreciate any help or suggestions. BTW, my objective is to port the code finally to STM32F429. I am using this STM32F207 board as a springboard. Thank you.

// My comment: This is what I gathered from the datasheet. My guess for zone 1.
#define NAND_PAGE_SIZE          ((uint16_t)0x0800) /* 2048 bytes per page w/o Spare Area */
#define NAND_BLOCK_SIZE         ((uint16_t)0x0040) /* 64x2048 bytes pages per block */
#define NAND_ZONE_SIZE          ((uint16_t)0x0400) /* 1024 Block per zone */
#define NAND_SPARE_AREA_SIZE    ((uint16_t)0x0040) /* last 64 bytes as spare area */
#define NAND_MAX_ZONE           ((uint16_t)0x0001) /* 1 zone of 1024 block ??*/

#define Bank_NAND_ADDR          Bank2_NAND_ADDR
#define Bank2_NAND_ADDR         ((uint32_t)0x70000000) 

void NAND_Init (void)
{
GPIO_InitTypeDef                    GPIO_InitStructure;
FSMC_NANDInitTypeDef                FSMC_NANDInitStructure;
FSMC_NAND_PCCARDTimingInitTypeDef   p;

/* Clock to the IOs that are involved in the FSMC module */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE |
RCC_AHB1Periph_GPIOG, ENABLE);   

/* Enable FSMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);   

/* some default values */
GPIO_StructInit (&GPIO_InitStructure);

/*-- GPIO Configuration OUTPUT Lines -----------------------------*/
/*!< CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  */

/* GPIOD configuration */
GPIO_PinAFConfig(GPIOD, NAND_CLE_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, NAND_ALE_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, NAND_D0_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, NAND_D1_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, NAND_D2_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, NAND_D3_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, NAND_NOE_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, NAND_NWE_s, GPIO_AF_FSMC);

// My comments: Since NWAIT is not used, it is commented.     
//GPIO_PinAFConfig(GPIOD, NAND_NWAIT_s, GPIO_AF_FSMC);
//GPIO_PinAFConfig(GPIOD, NAND_NWAIT_s, GPIO_AF_SDIO);

GPIO_InitStructure.GPIO_Pin =  NAND_CLE | NAND_ALE | NAND_D0 | NAND_D1 | 
NAND_D2 | NAND_D3 | NAND_NOE | NAND_NWE /*NAND_NWAIT*/;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    /* FSMC, Alternate function */   

/* configure */
GPIO_Init(GPIOD, &GPIO_InitStructure);

// My comments: Since NWAIT is not used, it is commented.
//GPIO_InitStructure.GPIO_Pin =  NAND_NWAIT;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
//GPIO_Init(GPIOD, &GPIO_InitStructure);

/*!< D4->D7 NAND pin configuration  */ 
GPIO_PinAFConfig(GPIOE, NAND_D4_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, NAND_D5_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, NAND_D6_s, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, NAND_D7_s, GPIO_AF_FSMC);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    /* FSMC, Alternate function */ 
GPIO_InitStructure.GPIO_Pin = NAND_D4 | NAND_D5 | NAND_D6 | NAND_D7;   

/* configure */
GPIO_Init(GPIOE, &GPIO_InitStructure);


// My comment: FSMC Bank 2 is used.
GPIO_PinAFConfig(GPIOD, NAND_NCE2_s, GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = NAND_NCE2;   
GPIO_Init(GPIOD, &GPIO_InitStructure);

/*-- FSMC Configuration ------------------------------------------------------*/
FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
FSMC_NANDStructInit (&FSMC_NANDInitStructure);

/* overwrite defaults */
p.FSMC_SetupTime = 0x0;
p.FSMC_WaitSetupTime = 0x2;
p.FSMC_HoldSetupTime = 0x1;
p.FSMC_HiZSetupTime = 0x0;

// My comments: I have also tried these values:       
//p.FSMC_SetupTime = 0x02;
//p.FSMC_WaitSetupTime = 0x02;
//p.FSMC_HoldSetupTime = 0x02;
//p.FSMC_HiZSetupTime = 0x02;

/* NAND is connected to Bank 2 Chip Select */
FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;

// Disable wait feature.
FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Disable; 
// FSMC_Waitfeature_Enable;
FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;

/* NAND in used has built in ECC, 5 bit detection and 4 bit correction */
FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Disable;   
FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;

/* Commit the FSMC settings */
FSMC_NANDInit(&FSMC_NANDInitStructure);

/*!< FSMC NAND Bank Cmd Test */
FSMC_NANDCmd(FSMC_Bank_NAND, ENABLE);
}


#define BUFFER_SIZE         NAND_PAGE_SIZE
#define NAND_ST_MakerID     0xEC
#define NAND_ST_DeviceID    0xF1

NAND_IDTypeDef NAND_ID;
NAND_ADDRESS WriteReadAddr;
uint8_t TxBuffer[BUFFER_SIZE], RxBuffer[BUFFER_SIZE];
uint32_t PageNumber = 2, WriteReadStatus = 0, status= 0;
uint32_t j = 0;

int main(void)
{

/* Enable the FSMC Clock */
RCC_AHB1PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

/* FSMC Initialization */
NAND_Init();

/* NAND read ID command */
NAND_ReadID(&NAND_ID);

/* Verify the NAND ID */
if((NAND_ID.Maker_ID == NAND_ST_MakerID) && (NAND_ID.Device_ID == NAND_ST_DeviceID))
{
/* NAND memory address to write to */
WriteReadAddr.Zone = 0x00;
WriteReadAddr.Block = 0x00;
WriteReadAddr.Page = 0x00;

/* Erase the NAND first Block */
status = NAND_EraseBlock(WriteReadAddr);

/* Write data to FSMC NAND memory */
/* Fill the buffer to send */
Fill_Buffer(TxBuffer, BUFFER_SIZE , 0x66);

// My comments: make it simple to write/read one page first.
//status = NAND_WriteSmallPage(TxBuffer, WriteReadAddr, PageNumber);
status = NAND_WriteSmallPage(TxBuffer, WriteReadAddr, 1);

/* Read back the written data */
// My comments: make it simple to write/read one page first.
//status = NAND_ReadSmallPage (RxBuffer, WriteReadAddr, PageNumber);
status = NAND_ReadSmallPage (RxBuffer, WriteReadAddr, 1);

/* Verify the written data */
for(j = 0; j < BUFFER_SIZE; j++)
{
if(TxBuffer[j] != RxBuffer[j])
{
WriteReadStatus++;
}
}

:
:


}
 

Outcomes