{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
u32 mecc0;
writel(readl(&nand->nfcont)| S3C2440_NFCONT_MECCL,&nand->nfcont);
mecc0= readl(&nand->nfmecc0);
ecc_code[0]= mecc0 & 0xff;
ecc_code[1] = (mecc0 >> 8) &0xff;
ecc_code[2] = (mecc0 >> 16) &0xff;
ecc_code[3] =(mecc0 >> 24) & 0xff;
debugX(1,'s3c2440_nand_calculate_hwecc(%p,):0xx 0xx 0xx 0xxn',
mtd , ecc_code[0], ecc_code[1], ecc_code[2], ecc_code[3]);
return 0;
}
该函数首先锁定main区ECC,然后读取寄存器NFMECC0,该寄存器存放着由硬件生成的main区ECC,最后把4个1字节的ECC存放到ecc_code数组内。
static int s3c2440_nand_correct_data(struct mtd_info *mtd, u_char*dat,
u_char *read_ecc, u_char *calc_ecc)
{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
u32 meccdata0, meccdata1, estat0, err_byte_addr;
int ret = -1;
u8 repaired;
meccdata0= (read_ecc[1] << 16) | read_ecc[0];
meccdata1= (read_ecc[3] << 16) | read_ecc[2];
writel(meccdata0,&nand->nfmeccd0);
writel(meccdata1,&nand->nfmeccd1);
estat0= readl(&nand->nfestat0);
switch(estat0 & 0x3) {
case 0:
ret= 0;
break;
case 1:
err_byte_addr= (estat0 >> 7) & 0x7ff;
repaired= dat[err_byte_addr] ^ (1 << ((estat0 >> 4) & 0x7));
printf('S3C NAND: 1 bit error detected at byte%ld. '
'Correcting from 0xx to0xx...OKn',
err_byte_addr, dat[err_byte_addr],repaired);
dat[err_byte_addr]= repaired;
ret= 1;
break;
case 2:
case 3:
printf('S3C NAND: ECC uncorrectable errordetected. '
'Not correctable.n');
ret= -1;
break;
}
return ret;
}
该函数首先把read_ecc数组内的ECC存入寄存器NFMECCD0和寄存器NFMECCD1中,这样系统就会自动校验数据,并把状态放入寄存器NFESTAT0中,然后读取该寄存器的后4位,当为0时表示校验正确;当为1时表示发生了1位错误(该类错误可以校正),我们把它校正过来;当为2和3时表示发生其他类型的错误,这类错误是无法校正的。
通过以上内容的修改,我们就实现了NandFlash的硬件ECC。
ECC足以保证所读数据的正确性,并在有些情况下还可以修正错误,但它不能保证所写数据的正确性。为了保证所写数据的正确性,u-boot还可以通过在include/configs/gq2440.h文件内定义宏CONFIG_MTD_NAND_VERIFY_WRITE来实现把所写的数据再读取一遍,然后与被写入的数据之间进行比较来判断所写数据的正确性,这一过程是在drivers/mtd/nand/nand_base.c文件的nand_write_page函数内调用实现的。
6 DM9000移植
实现了UBOOT中关于DM9000的部分,当然都是拿来主意,对于网卡我是相当陌生的。
首先,在include/configs/fl2440.h中去掉原先CS8900网卡的定义,再定义各种关于DM9000网卡的宏:
/*#define CONFIG_CS8900*/ /* we have a CS8900 on-board */
/*#define CONFIG_CS8900_BASE 0x19000300 */
/*#define CONFIG_CS8900_BUS16*/ /* the Linux driver does accesses as shorts */
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4) /* the cmd pin is addr2*/
#define CONFIG_ETHADDR a8:00:3E:26:0A:5B
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.11
#define CONFIG_SERVERIP 192.168.1.234
#define CONFIG_NET_MULTI
/*
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.0.0.110
#define CONFIG_SERVERIP 10.0.0.1
*/
DM9000在FL2440的硬件连接原理图:
图中可以看出DM9000连接到NGCS4,看下地址空间可以知道NGCS4的基址是0x20000000,所以网卡基址是0x20000300,后面这个300据他们说是DM9000内部寄存器是这样定义的,就现实来说我的网卡在这个基址上工作良好,所以应该是对的。
CMD连接的是ADDR2,查DM9000手册上CMD为1时发送的是数据信息,所以,DM9000的数据地址是0x20000304,这个很容易理解。
修改fl2440.c中的board_eth_init函数:
#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
return dm9000_initialize(bis);
}
#endif
修改drivers/net/dm9000x.c,将下面这段注释掉,至于原因,我也不清楚,不管。
i = 0;
while (!(dm9000_phy_read(1) & 0x20)) { /* autonegation complete bit */
udelay(1000);
i++;
if (i == 10000) {
printf('could not establish linkn');
return 0;
}
}
/* see what we've got */
lnk = dm9000_phy_read(17) >> 12;
printf('operating at ');
switch (lnk) {
case 1:
printf('10M half duplex ');
break;
case 2:
printf('10M full duplex ');
break;
case 4:
printf('100M half duplex ');
break;
case 8:
printf('100M full duplex ');
break;
default:
printf('unknown: %d ', lnk);
break;
}
printf('moden');
注释这个函数中的内容,不然网卡会自动断开:
static void dm9000_halt(struct eth_device *netdev)
{
#if 0
DM9000_DBG('%sn', __func__);
/* RESET devie */
dm9000_phy_write(0, 0x8000); /* PHY RESET */
DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
#endif
}
上一篇:ALSA声卡10_从零编写之数据传输_学习笔记
下一篇:摄像头驱动学习
推荐阅读最新更新时间:2024-11-13 16:44
设计资源 培训 开发板 精华推荐
- AD8531ARTZ-REEL 用于多媒体和汽车应用的单电源、平衡线路驱动器的典型应用
- 基于SR1CARU的输入/输出不同电压域中SR1xxxU器件的典型应用电路
- 使用 Panasonic 的 AN33017UA 的参考设计
- PHOTONH,Wi-Fi 开发套件,P-Zero 模块,IoT,带有接头的 Photon,基于 Wi-Fi + STM32 ARM Cortex M3 MCU
- ADA4841-2YRZ-R7 低功耗、低噪声运算放大器的典型应用电路,用于两极 500kHz 重构滤波器原理图
- AD8626ARZ单极输出精密放大器典型应用电路
- usbSwitch
- 使用 Analog Devices 的 LT1587CM-3.45 的参考设计
- LTC6360 演示板驱动 LTC2367-16 16 位、0.5Msps SAR ADC
- LT1317BCMS8 演示板、微功率、600kHz PWM DC/DC 转换器