上一節我們移植了uboot,S3C2440移植uboot之支持NORFLASH。這節我們繼續移植,支持NANDFLASH。
文章目錄
編譯報錯
之前由於nand部分報錯,直接註釋了 u-boot-
2012.04.01\include\configs\smdk2440.h 中的#define CONFIG_CMD_NAND。現在我們去掉註釋,重新編譯。報錯如下
我們沒有定義CONFIG_S3C2410導致的
可以看到下面有2440的NAND結構體
拷貝s3c2410_nand.c,修改宏定義支持SC32440
所以我們可以拷貝一份s3c2410_nand.c給2440使用2410的NandFlash位於drivers/mtd/nand/s3c2410_nand.c,首先複製s3c2410_nand.c,改爲s3c2440_nand.c,改Makefile,如下圖所示:
在上一章分析過CONFIG_NAND_S3C2410宏,位於include/configs/smdk2440.h:
如上圖所示,其中CONFIG_CMD_NAND宏:表示uboot是否支持nand,在上章裏,我們把它屏蔽了,接下來便取消屏蔽CONFIG_CMD_NAND宏。
繼續添加對CONFIG_NAND_S3C2440宏的支持,將:
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x4E000000
#endif
改爲
#ifdef CONFIG_CMD_NAND
#ifdef CONFIG_S3C2410
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#else // CONFIG_S3C2440
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC
#endif
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x4E000000
#endif
由於smdk2410.h中定義的是CONFIG_S3C2410,而smdk2440.h中定義的是CONFIG_S3C2440,所以便會根據上面的#ifdef來動態定義宏
修改s3c2440_nand.c 中的NFCONF,NFCONT,支持S3C2440
往下看代碼發現原來的NFCONF設置並不能匹配我們的2440
2440的NFCONF的15位是保留的
所以註釋掉這部分代碼
2410 NFCONF的其他位設置也不匹配我們的2440
2440NFCONF 時序參數設置
s3c2440_hwcontrol中使能選中
對照2440手冊修改爲支持2440的
修改爲
/*2440的NAND時序設置*/
cfg = ((tacls-1)<<12)|((twrph0-1)<<8)|((twrph1-1)<<4);
nand_reg->nfcont=(1<<1)|(1<<0); // bit1:關閉片選(), bit0:開啓nand flash 控制器
nand_reg->nfconf = (tacls<<12) | (twrph0<<8) | (twrph1<<4); //設置時序
writel(cfg, &nand_reg->nfconf);
/* 使能NAND Flash控制器, 初始化ECC, 禁止片選 */
writel((1<<4)|(1<<1)|(1<<0), &nand_reg->nfcont);
/* initialize nand_chip data structure */
nand->IO_ADDR_R= (void *)&nand_reg->nfdata;
nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
nand->select_chip = s3c2440_select_chip; //設置CE ;
修改s3c2440_hwcontrol區分命令和地址
/*ctrl:表示做什麼,選中芯片/取消選中,發命令還是發地址
* cmd :命令值或者地址值
*/
static void s3c2440_hwcontrol(struct mtd_info *mtd, int dat, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
struct s3c2440_nand *nand = s3c2440_get_base_nand(); //獲取nand寄存器地址
if (ctrl & NAND_CLE)
// 傳輸的是命令
writeb(dat,&nand->nfcmd);
else if (ctrl & NAND_ALE)
// 傳輸的是地址
writeb(dat,&nand->nfaddr);
}
修改完成
添加選中芯片函數
修改選中芯片函數
nand->select_chip = NULL; //設置CE ;
改爲
nand->select_chip = s3c2440_select_chip; //設置CE ;
選中芯片函數如下
static void s3c2440_select_chip(struct mtd_info *mtd, int chipnr)
{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
switch (chipnr) {
case -1:
/*取消選中*/
nand->nfcont |=(1<<1);
break;
case 0:
/*選中*/
nand->nfcont &=~(1<<1);
break;
default:
BUG();
}
}
編譯燒寫
如下圖所示,可以看到已支持Nand Flash:
試驗nand是否能讀寫:
nand erase 0 2000 //擦除
mw.b 30000000 0x55 2000 //向30000000 寫入0x55,長度爲2000
nand write 30000000 0 2000 //將0x55寫入nand,
nand dump 0 2000 //打印
如下圖所示, 可以看到讀寫nand都沒問題
下一節S3C2440移植uboot之支持DM9000我們將移植DM9000網卡程序。