您的位置:首页 > 其它

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

2012-12-07 14:07 323 查看

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 read、nand
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测试
  
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: