cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F439 incorrect NAND ID read

jaspervandenakker
Associate II
Posted on January 23, 2014 at 08:08

Hello,

I'm using a STM32F439 with the MT29F2G08 NAND from Micron. When I read the NAND ID on Address 0x20, I receive the correct ONFI codes. When I Read the ID on address 0x00, I read the correct Maker ID, but the following bytes are incorrect. I expect the following Byte values:

Byte0 should be 0x2C and i read also 0x2C. That one is fine

Byte1 should be 0xDA and i read 0x01

Byte2 should be 0x90 and i read 0x02

Byte3 should be 0x95 and i read 0x03

Byte4 should be 0x86 and i read 0x00

Does anybody have the same problem before?

3 REPLIES 3
troy1818
Senior
Posted on January 24, 2014 at 15:47

Hi Jasper,

Are you using FSMC  (bank2 or bank3)? in that case make sure that the timing is correct according to the NAND memory that you are using. Also check the HW for any soldering problems. The base address must also be correct or strange values can be obtained.

Regards,

rygelxvi

jaspervandenakker
Associate II
Posted on January 27, 2014 at 08:31

Thank you for your reply.

Soldering seems to be ok. when i do a read on address 0x20, i'll receive the correct bytes as specified in the datasheet. But not on address 00. I use the MT29F2G I am using FMC bank 2 on the STM32F4 Below a code snippet of my initialization: Maybe I'm doing something wrong. I've tried several timing settings but none of them works for me.

void FSMC_NAND_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; 
FMC_NANDInitTypeDef FMC_NANDInitStructure;
FMC_NAND_PCCARDTimingInitTypeDef p;
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | 
RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE);
/*-- GPIO Configuration ------------------------------------------------------*/
/* CLE, ALE, D0->D3, NOE, NWE and NCE2 NAND pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 | 
GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
GPIO_Pin_7; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* NWAIT NAND pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* D4->D7 NAND pin configuration */ 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOE, &GPIO_InitStructure);
//map gpio port D to FMC port
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_FMC); 
GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC);
//map gpio port E to FMC port
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FMC);
/*-- FSMC Configuration ------------------------------------------------------*/
FMC_NANDInitStructure.FMC_Bank = FMC_Bank2_NAND;
FMC_NANDInitStructure.FMC_Waitfeature = FMC_Waitfeature_Enable;
FMC_NANDInitStructure.FMC_MemoryDataWidth = FMC_NAND_MemoryDataWidth_8b;
FMC_NANDInitStructure.FMC_ECC = FMC_ECC_Enable; //ECC in NAND flash
FMC_NANDInitStructure.FMC_ECCPageSize = FMC_ECCPageSize_2048Bytes;
FMC_NANDInitStructure.FMC_TCLRSetupTime = 2;
FMC_NANDInitStructure.FMC_TARSetupTime = 2;
FMC_NANDInitStructure.FMC_CommonSpaceTimingStruct->FMC_SetupTime = 0x2;
FMC_NANDInitStructure.FMC_CommonSpaceTimingStruct->FMC_WaitSetupTime = 0x2; 
FMC_NANDInitStructure.FMC_CommonSpaceTimingStruct->FMC_HoldSetupTime = 0x1;
FMC_NANDInitStructure.FMC_CommonSpaceTimingStruct->FMC_HiZSetupTime = 0x2;
FMC_NANDInitStructure.FMC_AttributeSpaceTimingStruct->FMC_SetupTime = 0x2;
FMC_NANDInitStructure.FMC_AttributeSpaceTimingStruct->FMC_WaitSetupTime = 0x2;
FMC_NANDInitStructure.FMC_AttributeSpaceTimingStruct->FMC_HoldSetupTime = 0x1;
FMC_NANDInitStructure.FMC_AttributeSpaceTimingStruct->FMC_HiZSetupTime = 0x2;
FMC_NANDInit(&FMC_NANDInitStructure);
/* FSMC NAND Bank Cmd Test */
FMC_NANDCmd(FMC_Bank2_NAND, ENABLE);
}

troy1818
Senior
Posted on January 27, 2014 at 16:22

Hi again,

If you are not using D8 then you can skip this line:

GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FMC);

if you use A16 -> CLE and A17 -> ALE then the address should look like this for address and command:

#define NAND_BASE 0x70000000

#define CMD_AREA (u32)(1<<16)

#define ADDR_AREA (u32)(1<<17)

#define DATA_AREA (u32)(0)

#define NAND_CMD (*((volatile uint8_t *)(NAND_BASE | CMD_AREA)))

#define NAND_ADDR (*((volatile uint8_t *)(NAND_BASE | ADDR_AREA)))

#define NAND_DATA (*((volatile uint8_t *)(NAND_BASE | DATA_AREA)))

Usually to get the chip ID you need to first issue a command and then read address 0x00 followed by the actual reading of the data.

You mention that reading onfi is working so I assume that this is done and you understand the basic stuff?

e.g.

  uint_32 data = 0;

  int i = 0;

  NAND_CMD = 0x90;

  NAND_ADDR = 0x00;

  data = NAND_DATA;

  data <<= 8;

  data += NAND_DATA;

  data <<= 8;

  data += NAND_DATA;

  data <<= 8;

  data += NAND_DATA;

If you are already doing it like this, then I honestly don't know what the problem is.

Regards,

/rygelxvi