现在的位置: 首页 > 综合 > 正文

Mini2440开发板:U-boot-2008-10之支持nand flash驱动K9F1G08U0B

2013年08月01日 ⁄ 综合 ⁄ 共 6217字 ⁄ 字号 评论关闭

U-boot-2008-10之支持nand flash驱动

 U-Boot版本:U-boot 2008.10   目标板:Mini2440   Nandflash型号: K9F1G08U0B  256M       

 

修改include/configs/mini2440.h。

1)添加命令支持:

#define CONFIG_CMD_ELF

#define  CONFIG_CMD_NAND

2)添加nand flash 参数设置:

/*nand flashsettings******************************************************************************************/

#define CFG_NAND_BASE                       0   /*Nand Flash控制器在SFR区起始寄存器地址*/
#define CFG_MAX_NAND_DEVICE                  1     /*NAND Flash设备最大数*/
#define NAND_MAX_CHIPS                     1               /*NAND Flash芯片数*/
#define SECTORSIZE                                   2048    /*扇区容量2K Bytes*/
#define ADDR_COLUMN                           2/*2Byte Column address*/
#define ADDR_PAGE                                3    //3字节的页块地址
#define ADDR_COLUMN_PAGE         4       //总共4字节的页块地址
#define NAND_ChipID_UNKNOWN      0x00    //未知芯片的ID号
#define NAND_MAX_FLOORS                  4      

#define CONFIG_MTD_NAND_VERIFY_WRITE 1

 

说明:此版的u-boot已自带board_nand_init(),在cpu/arm920t/s3c24x0/nand.c中定义。

因为s3c2410和s3c2440在flash控制器上,有所差别,驱动代码需要改进,主要修改在cpu/arm920t/s3c24x0/nand.c中进行。

cpu/arm920t/s3c24x0/nand.c中修改过程:

先加入 S3C2440 NANDflash 控制器的地址定义,修改后如下:

``````

#if ndef(CONFIG_S3C2440)                 //针对S3C2410这款SOC
#define NF_BASE    0x4e000000
#define NFCONF      __REGi(NF_BASE + 0x0)
#define NFCMD       __REGb(NF_BASE + 0x4)
#define NFADDR      __REGb(NF_BASE + 0x8)
#define NFDATA      __REGb(NF_BASE + 0xc)
#define NFSTAT       __REGb(NF_BASE +0x10)
#define NFECC0      __REGb(NF_BASE +0x14)
#define NFECC1     __REGb(NF_BASE + 0x15)
#define NFECC2      __REGb(NF_BASE +0x16)
#else                                                                                   //S3C2440与S3C2410不太一样
#define NF_BASE    0x4e000000
#define NFCONF      __REGi(NF_BASE + 0x0)
#define NFCONT      __REGi(NF_BASE + 0x4)
#define NFCMD        __REGb(NF_BASE +0x8)
#define NFADDR      __REGb(NF_BASE + 0xc)
#define NFDATA      __REGb(NF_BASE + 0x10)
#define NFMECCD0        __REGi(NF_BASE +0x14)
#define NFMECCD1         __REGi(NF_BASE +0x18)
#define NFSECCD   __REGi(NF_BASE + 0x1C)
#define NFSTAT       __REGb(NF_BASE +0x20)
#define NFSTAT0     __REGi(NF_BASE + 0x24)
#define NFSTAT1     __REGi(NF_BASE + 0x28)
#define NFMECC0   __REGi(NF_BASE + 0x2C)
#define NFMECC1   __REGi(NF_BASE + 0x30)
#define NFSECC      __REGi(NF_BASE + 0x34)
#define NFSBLK       __REGi(NF_BASE +0x38)
#define NFEBLK       __REGi(NF_BASE + 0x3C)

#define S3C2440_NFCONT_nCE  (1<<1)         

    
#define S3C2440_ADDR_NALE      0x0c
#define S3C2440_ADDR_NCLE      0x08
#endif

 

``````

U-Boot.2008.10自带的s3c2410的s3c2410的s3c2410_hwcontrol函数有错。在此函数中,把chip->IO_ADDR_W的值改写了,导致在写数据时出现错误,解决办法是使用一全局变量代替chip->IO_ADDR_W。在s3c2410_hwcontrol函数的上一行定义这个全局变量,然后修改s3c2410_hwcontrol函数,让它支持S3C2440,修改该后如下:

````

ulong IO_ADDR_W =NF_BASE;
static void s3c2410_hwcontrol(structmtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
/*modified by xxx ,for 2440*********************************************************/
#if !defined(CONFIG_S3C2440)
if (ctrl & NAND_CTRL_CHANGE) {
/*modified by xxx ,for2440*********************************************************/
/*ulong IO_ADDR_W = NF_BASE;*/ /*delete ulong,by xxx ********/
IO_ADDR_W = NF_BASE;
if (!(ctrl & NAND_CLE))
IO_ADDR_W |= S3C2410_ADDR_NCLE;
if (!(ctrl & NAND_ALE))
IO_ADDR_W |= S3C2410_ADDR_NALE;
/*chip->IO_ADDR_W = (void *)IO_ADDR_W;*/  /*BUG,delete byxxx******/
if (ctrl & NAND_NCE)
NFCONF &= ~S3C2410_NFCONF_nFCE;
else
NFCONF |= S3C2410_NFCONF_nFCE;
}

if (cmd != NAND_CMD_NONE)
/*writeb(cmd, chip->IO_ADDR_W);*/   /*modified by xxx************/
writeb(cmd, (void *)chip->IO_ADDR_W);
#else
if (ctrl & NAND_CTRL_CHANGE) {
   IO_ADDR_W = NF_BASE;
if (!(ctrl & NAND_CLE))
IO_ADDR_W |= S3C2440_ADDR_NALE;
if (!(ctrl & NAND_ALE))
IO_ADDR_W |= S3C2440_ADDR_NCLE;
/*chip->IO_ADDR_W = (void *)IO_ADDR_W;*/  /*BUG,delete by xxx******/
if (ctrl & NAND_NCE)
NFCONT &= ~S3C2440_NFCONT_nCE;/*Becareful there is NFCONT**********/
else
NFCONT |= S3C2440_NFCONT_nCE;
}

if (cmd != NAND_CMD_NONE)
/*writeb(cmd, chip->IO_ADDR_W);*/   /*modified by xxx************/
writeb(cmd, (void *)IO_ADDR_W);
#endif
}

board_nand_init修改后如下:

····

clk_power->CLKCON |= (1 << 4);
/*add by xxx ,for 2440******************************************************/
#if !defined(CONFIG_S3C2440)
DEBUGN("CONFIG_S3C2410\n");
/* initialize hardware */
twrph0 = 3; twrph1 = 0; tacls = 0;
cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls- 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0- 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1- 1);
NFCONF = cfg;
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e00000c;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s3c2410_hwcontrol;
nand->dev_ready = s3c2410_dev_ready;
#else
DEBUGN("CONFIG_S3C2440\n");
/* initialize hardware */
twrph0 = 4; twrph1 = 2; tacls = 0;  /*modified by dazhi ,for 2440*****/
/*modified by xxx ,for 2440*************************************************/
cfg =(tacls <<12)|(twrph0<<8)|(twrph1<<4);
NFCONF=cfg;
cfg =(1 <<6)|(1<<4)|(0<<1)|(1<<0);
NFCONT=cfg;
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s3c2410_hwcontrol;
nand->dev_ready = s3c2410_dev_ready;
#endif

为了显示芯片型号,将  drivers/mtd/nand/nand_base.c中的nand_get_flash_type函数结尾,修改MTDDEBUG为printf。

在NAND FLASH中保存u-boot 参数,(saveenv功能)

/include/configs/mini2440.h添加:

`````

#define CONFIG_CMD_NAND

#define CONFIG_CMD_ENV

`````

/*#define CONFIG_ENV_IS_IN_FLASH        1 */

#define CONFIG_ENV_IS_IN_NAND                1

#define  CONFIG_ENV_OFFSET                       0x40000/*参数在nand flash中的起始位置位256K*/

#define  CONFIG_ENV_SIZE                              0x20000 /*环境变量总大小,128K*/

保存,在Uboot根目录下先清除make  clean下,然后make,下载测试。

注:中间可能会出现宏未定义的错误,或者redifined 宏。对于这些错误,没办法,得挨个修改,这是调试技术。

出错的宏最好在 u-boot-2008-10/include/configs/mini2440.h里修改,针对本开发板的软硬件配置modify,避免修改参数范围太大,难于控制。比如CONFIG_NAND_BASE为CFG_NAND_BASE。

 

下载NAND FLASH移植测试:

    将编译好的u-boot.bin通过JTAG烧入Mini2440开发板,重启开发板可以看到:

显示的信息中存在一个 bad CRC的警告信息,这是由于在启动时,uboot会从flash中读取环境变量的信息,通常执行save或saveenv后,下次启动就不会出现此警告了。

    在u-boot界面,输入“?nand”命令,查看nand相关的用法:

Jz2440 # ? nand


    可以看到一系列nand readnand
write
命令,以及命令的使用方法。

 

1.擦除NAND FLASH测试

    在u-boot界面输入nand erase
0 1000:

    命令解释:擦除NAND FLASH偏移0个地址后的4K内容(0x1000

 

2.NAND FLASH测试

    在u-boot界面输入nand read
30000000 0 1000:


    命令解释:读NAND FLASH偏移0个地址大小为4K的内容(0x1000),放到内存的0x30000000

    在u-boot界面使用md命令查看内存内容:

    可以看到,内存0x30000000处全是f,说明nand
read
读到的是上一步擦除后NAND FLASH上的内容,说明上一步擦除NAND FLASH成功,本次读操作也OK

 

3.NAND FLASH测试

  

 

【上篇】
【下篇】

抱歉!评论已关闭.