折腾了两个晚上,终于把s3c2440板子上的nand驱动搞定了,把需要注意的地方记下来,供大家参考。
这次使用的u-boot版本为1.3.4,现在还没有加上从nand启动的部分,现在使用从sdram启动的方式,修改好nand驱动后,现在环境变量可以存放到nand中,具体要修改的地方如下:
1、板子配置头文件
在板子的配置头文件中要加入如下代码:
.......................................................
#define CONFIG_CMD_NAND
#define CFG_ENV_IS_IN_NAND 1
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
#define CFG_ENV_OFFSET 0x30000
#define CFG_MAX_NAND_DEVICE 1
#define CFG_NAND_BASE 0x4E000000
..........................................................
2、修改cpu/arm920t/s3c24x0/nand.c文件
2.1、修改寄存器相关宏定义
把该文件的头部定义的一些宏做如下修改:
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x04)
#define NFCMD __REGb(NF_BASE + 0x08)
#define NFADDR __REGb(NF_BASE + 0x0C)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)
#define S3C2410_NFCONF_EN (1<<1)
#define S3C2410_NFCONF_512BYTE (1<<14)
#define S3C2410_NFCONF_4STEP (1<<13)
#define S3C2410_NFCONF_INITECC (1<<12)
#define S3C2410_NFCONF_nFCE (1<<1)
#define S3C2410_NFCONF_TACLS(x) ((x)<<12)
#define S3C2410_NFCONF_TWRPH0(x) ((x)<<8)
#define S3C2410_NFCONF_TWRPH1(x) ((x)<<4)
修改完成后的代码如上。这里主要是由于2440与2410的nand控制器寄存器有一定的区别。
2.2、修改s3c2410_hwcontrol函数
s3c2410_hwcontrol函数修改后的代码如下:
static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip *chip = mtd->priv;
DEBUGN('hwcontrol(): 0x%02x: ', cmd);
switch (cmd) {
case NAND_CTL_SETNCE:
NFCONT &= ~S3C2410_NFCONF_nFCE;
DEBUGN('NFCONF=0x%08xn', NFCONF);
break;
case NAND_CTL_CLRNCE:
NFCONT |= S3C2410_NFCONF_nFCE;
DEBUGN('NFCONF=0x%08xn', NFCONF);
break;
case NAND_CTL_SETALE:
chip->IO_ADDR_W = NF_BASE + 0xc;
DEBUGN('SETALEn');
break;
case NAND_CTL_SETCLE:
chip->IO_ADDR_W = NF_BASE + 0x8;
DEBUGN('SETCLEn');
break;
default:
chip->IO_ADDR_W = NF_BASE + 0x10;
break;
}
return;
}
这里做修改也是因为2410与2440的nand控制器寄存器定义存在差别。
2.3、修改board_nand_init函数
这个函数是初始化nand的时候调用,修改后的代码如下:
int board_nand_init(struct nand_chip *nand)
{
u_int32_t cfg;
u_int8_t tacls, twrph0, twrph1;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
DEBUGN('board_nand_init()n');
clk_power->CLKCON |= (1 << 4);
/* initialize hardware */
twrph0 = 7; twrph1 = 7; tacls = 7;
cfg |= S3C2410_NFCONF_TACLS(tacls);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1);
NFCONF = cfg;
NFCONT = (1 << 4) | (1 << 0);
NFSTAT = 6;
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e000010;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->hwcontrol = s3c2410_hwcontrol;
nand->dev_ready = s3c2410_dev_ready;
#ifdef CONFIG_S3C2410_NAND_HWECC
nand->enable_hwecc = s3c2410_nand_enable_hwecc;
nand->calculate_ecc = s3c2410_nand_calculate_ecc;
nand->correct_data = s3c2410_nand_correct_data;
nand->eccmode = NAND_ECC_HW3_512;
#else
nand->eccmode = NAND_ECC_SOFT;
#endif
#ifdef CONFIG_S3C2410_NAND_BBT
nand->options = NAND_USE_FLASH_BBT;
#else
nand->options = 0;
#endif
DEBUGN('end of nand_initn');
return 0;
}
到这里,nand.c文件就修改完成了。
3、修改include/s3c24x0.h文件
该文件中修改S3C2410_NAND结构体定义如下:
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;
} /*__attribute__((__packed__))*/ S3C2410_NAND;
到此为止,支持nand的代码就修改完成了。
上一篇:S3C2440 初始化时钟
下一篇:有关i2c的问题总结
推荐阅读最新更新时间:2024-11-02 11:54
设计资源 培训 开发板 精华推荐
- [失败]CM1033保护板
- 【物联网】鸿蒙物联网智能WIFI开关+4219114A
- LT1956IGN 正负降压转换器的典型应用电路
- 具有固定输出电压、1.5V 的典型应用电路,适用于 ADP1752ACPZ 0.8A、低 VIN、低压差线性稳压器
- LT3088MPM 高效可调电源的典型应用
- ADR433A 3 Vout 超低噪声 XFET 电压基准的典型应用,具有灌电流和拉电流能力
- 可调输出电压 TS1084 5A 低压降正压稳压器典型应用
- LT1172CT、-10 至 -26/1.25A LCD 对比度电源的典型应用
- 用于同轴无压缩数字视频且经过优化的汽车类百万像素摄像机模块设计
- 适用于 ADP1196、5V、3A 逻辑控制高端或低端负载开关的典型低端负载应用电路