在S3C2440的板子上移植U-BOOT-1.1.6时,使用的NAND Flash为Samsung K9F1208U0B。模仿vivi对nand flash的操作,运用如下代码读取manufacture ID和device ID,能够获取正确的值:
void get_manufacture_device_id(char *manuID, char *deviceID)
{
int i;
NAND_CHIP_ENABLE;
NAND_CLEAR_RB;
NFCMD = 0xFF;
for(i = 0; i < 0x10; i++)
{
}
NFCMD = 0x90;
NFADDR = 0x00;
for(i = 0; i < 0x10; i++)
{
}
NAND_DETECT_RB;
*manuID = (NFDATA & 0xff);
*deviceID = (NFDATA & 0xff);
}
{
int i;
NAND_CHIP_ENABLE;
NAND_CLEAR_RB;
NFCMD = 0xFF;
for(i = 0; i < 0x10; i++)
{
}
NFCMD = 0x90;
NFADDR = 0x00;
for(i = 0; i < 0x10; i++)
{
}
NAND_DETECT_RB;
*manuID = (NFDATA & 0xff);
*deviceID = (NFDATA & 0xff);
}
但是在U-BOOT中,通过nand_probe()->NanD_ScanChips()->NanD_IdentChip()来读取manufacture ID和device ID时,几乎是同vivi一样的sequence,但是却不能获得正确的值:
mfr = READ_NAND(nand->IO_ADDR);
id = READ_NAND(nand->IO_ADDR);
id = READ_NAND(nand->IO_ADDR);
获得的mfr和id都是0xec,而正确的id应该为0x76。调试半天,终于发现问题所在,当将include/S3c2440.h的结构:
typedef struct {
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFECC;
}S3C2440_NAND;
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFECC;
}S3C2440_NAND;
改变为:
typedef struct {
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG8 NFDATA;
S3C24X0_REG8 Dummy1;
S3C24X0_REG8 Dummy2;
S3C24X0_REG8 Dummy3;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFECC;
}S3C2440_NAND;
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG8 NFDATA;
S3C24X0_REG8 Dummy1;
S3C24X0_REG8 Dummy2;
S3C24X0_REG8 Dummy3;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFECC;
}S3C2440_NAND;
再在NanD_IdentChip()中,通过
mfr = READ_NAND(nand->IO_ADDR);
id = READ_NAND(nand->IO_ADDR);
id = READ_NAND(nand->IO_ADDR);
获取的值分别为0xEC和0x76。正确!
要说这是由于volatile引起的,则在include/S3c24x0.h中已经定义了:
typedef volatile u8 S3C24X0_REG8;
typedef volatile u16 S3C24X0_REG16;
typedef volatile u32 S3C24X0_REG32;
typedef volatile u16 S3C24X0_REG16;
typedef volatile u32 S3C24X0_REG32;
故这可能是有crosstool chain引起的。