LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1474|回复: 1

s3c2440 nand flash初始化代码,奇怪问题

[复制链接]
发表于 2010-1-31 23:31:25 | 显示全部楼层 |阅读模式
我下了一个简单的bootloader,我把nand flash的初始化代码,换为书上的就不能用了
这个就是书上的代码
widon@widon-laptop$ cat Desktop/boot_diy/start/nand.c_own
#define BUSY    1

typedef unsigned long S3C24x0_REG32;

typedef struct {
    S3C24x0_REG32    NFCONF;
    S3C24x0_REG32    NFCONT;
    S3C24x0_REG32    NFCMD;
    S3C24x0_REG32    NFADDR;
    S3C24x0_REG32    NFDATA;
    S3C24x0_REG32    NFMECCD0;
    S3C24x0_REG32    NFMECCD1;
    S3C24x0_REG32    NFSECCD;
    S3C24x0_REG32    NFSTAT;
    S3C24x0_REG32    NFESTAT0;
    S3C24x0_REG32    NFESTAT1;
    S3C24x0_REG32    NFMECC0;
    S3C24x0_REG32    NFMECC1;
    S3C24x0_REG32    NFSECC;
    S3C24x0_REG32    NFSBLK;   
    S3C24x0_REG32    NFEBLK;
}S3C2440_NAND;

static S3C2440_NAND *s3c2440nand = (S3C2440_NAND *)0x4e000000;

void nand_init(void);
void nand_read(unsigned char *buf, unsigned long start_addr, int size);

static void s3c2440_nand_reset(void);
static void s3c2440_wait_idle(void);
static void s3c2440_nand_select_chip(void);
static void s3c2440_nand_deselect_chip(void);
static void s3c2440_write_cmd(int cmd);
static void s3c2440_write_addr(unsigned int addr);
static unsigned char s3c2440_read_data(void);

static void s3c2440_nand_reset(void)
{
    s3c2440_nand_select_chip();
    s3c2440_write_cmd(0xff);
    s3c2440_wait_idle();
    s3c2440_nand_deselect_chip();
}

static void s3c2440_wait_idle(void)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;
    while(!(*p & BUSY))
        for(i=0; i<10; i++);
}

static void s3c2440_nand_select_chip(void)
{
    int i;
    s3c2440nand->NFCONT &= ~(1<<1);
    for(i=0; i<10; i++);
}

static void s3c2440_nand_deselect_chip(void)
{
    s3c2440nand->NFCONT |= (1<<1);
}

static void s3c2440_write_cmd(int cmd)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;
    *p = cmd;
}

static void s3c2440_write_addr(unsigned int addr)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
    *p = addr & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 9) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 17) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 25) & 0xff;
    for(i=0; i<10; i++);
}

static unsigned char s3c2440_read_data(void)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;
    return *p;
}

void nand_init(void)
{
#define TACLS    0
#define TWRPH0  3
#define TWRPH1    0

    s3c2440nand->NFCONF = (TACLS<<12) | (TWRPH0 << 8) | (TWRPH1 << 4);
    s3c2440nand->NFCONT = (1<<4) | (1<<1) | (1<<0);

    s3c2440_nand_reset();
}

#define NAND_SECTOR_SIZE    512
#define NAND_BLOCK_MASK        (NAND_SECTOR_SIZE - 1)

void nand_read(unsigned char *buf, unsigned long start_addr, int size)
{
    int i,j;

    if((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)){
        return;
    }
    s3c2440_nand_select_chip();
    for(i=start_addr; i < (start_addr + size);){
        s3c2440_write_cmd(0);
        s3c2440_write_addr(i);
        s3c2440_wait_idle();
        for(j=0; j < NAND_SECTOR_SIZE; j++, i++){
            *buf = s3c2440_read_data();
            buf++;
        }
    }
    s3c2440_nand_deselect_chip();
    return ;
}
 楼主| 发表于 2010-1-31 23:32:13 | 显示全部楼层
经过一些简单的修改才可以用,不知道为什么,我觉得这两个代码是一样的啊
还有不知道为什么NFCMD 要声明为volatile unsigned char ,long却不行
widon@widon-laptop$ cat Desktop/nand.c
#define BUSY        1

typedef unsigned long S3C24x0_REG32;
/*
typedef struct {
        S3C24x0_REG32        NFCONF;                        //0x4e000000
        S3C24x0_REG32        NFCONT;                        //0x4e000004
        S3C24x0_REG32        NFCMD;                        //0x4e000008
        S3C24x0_REG32        NFADDR;                        //0x4e00000C
        S3C24x0_REG32        NFDATA;                    //0x4e000010
        S3C24x0_REG32        NFMECCD0;                //0x4e000014
        S3C24x0_REG32        NFMECCD1;            //0x4e000018                       
        S3C24x0_REG32        NFSECCD;                //0x4e00001C
        S3C24x0_REG32        NFSTAT;                        //0x4e000020
        S3C24x0_REG32        NFESTAT0;
        S3C24x0_REG32        NFESTAT1;
        S3C24x0_REG32        NFMECC0;
        S3C24x0_REG32        NFMECC1;
        S3C24x0_REG32        NFSECC;
        S3C24x0_REG32        NFSBLK;      
        S3C24x0_REG32        NFEBLK;
}S3C2440_NAND;

static S3C2440_NAND *s3c2440nand = (S3C2440_NAND *)0x4e000000;
*/
#define NFCONF                (*(volatile unsigned long *)0x4e000000)
#define NFCONT                (*(volatile unsigned long *)0x4e000004)
#define NFCMMD                (*(volatile unsigned char *)0x4e000008)
#define NFADDR                (*(volatile unsigned char *)0x4e00000c)
#define NFDATA                (*(volatile unsigned char *)0x4e000010)
#define NFSTAT                (*(volatile unsigned char *)0x4e000020)

void nand_init(void);
void nand_read(unsigned char *buf, unsigned long start_addr, int size);

static void s3c2440_nand_reset(void);
static void s3c2440_wait_idle(void);
static void s3c2440_nand_select_chip(void);
static void s3c2440_nand_deselect_chip(void);
static void s3c2440_write_cmd(int cmd);
static void s3c2440_write_addr(unsigned int addr);
static unsigned char s3c2440_read_data(void);

static void s3c2440_nand_reset(void)
{
        s3c2440_nand_select_chip();
        s3c2440_write_cmd(0xff);
        s3c2440_wait_idle();
        s3c2440_nand_deselect_chip();
}

static void s3c2440_wait_idle(void)
{
        int i;
//        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;
        while(!(NFSTAT & BUSY))
                for(i=0; i<10; i++);
}

static void s3c2440_nand_select_chip(void)
{
        int i;
//  s3c2440nand->NFCONT &= ~(1<<1);
        NFCONT &= ~(1<<1);
        for(i=0; i<10; i++);
}

static void s3c2440_nand_deselect_chip(void)
{
//        s3c2440nand->NFCONT |= (1<<1);
        NFCONT |= (1<<1);
}

static void s3c2440_write_cmd(int cmd)
{
//        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;
        NFCMMD = cmd;
}

static void s3c2440_write_addr(unsigned int addr)
{
        int i;
//        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
        volatile unsigned char *p = &NFADDR;
        *p = addr & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 9) & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 17) & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 25) & 0xff;
        for(i=0; i<10; i++);
}

static unsigned char s3c2440_read_data(void)
{
//        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;
        return NFDATA;
}

void nand_init(void)
{
#define TACLS        0
#define TWRPH0  3
#define TWRPH1        0

//        s3c2440nand->NFCONF = (TACLS<<12) | (TWRPH0 << 8) | (TWRPH1 << 4);
//        s3c2440nand->NFCONT = (1<<4) | (1<<1) | (1<<0);

        NFCONF = (TACLS<<12) | (TWRPH0 << 8) | (TWRPH1 << 4);
        NFCONT = (1<<4) | (1<<1) | (1<<0);

        s3c2440_nand_reset();
}

#define NAND_SECTOR_SIZE        512
#define NAND_BLOCK_MASK                (NAND_SECTOR_SIZE - 1)

void nand_read(unsigned char *buf, unsigned long start_addr, int size)
{
        int i,j;

        if((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)){
                return;
        }
        s3c2440_nand_select_chip();
        for(i=start_addr; i < (start_addr + size);){
                s3c2440_write_cmd(0);
                s3c2440_write_addr(i);
                s3c2440_wait_idle();
                for(j=0; j < NAND_SECTOR_SIZE; j++, i++){
                        *buf = s3c2440_read_data();
                        buf++;
                }
        }
        s3c2440_nand_deselect_chip();
        return ;
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表