Chinaunix首页 | 论坛 | 博客
  • 博客访问: 371566
  • 博文数量: 56
  • 博客积分: 1449
  • 博客等级: 中尉
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-08 10:24
文章分类

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类:

2010-12-01 17:23:05

   老是受4KB的steppingstone的限制... 往后比较大一些的程序就无法继续进行实验了...
   可以利用4KB的steppingstone对nand flash进行初始化, 并将代码从nand flash中读出来拷贝到sdram中。
   然后跳转到sdram中执行... 由于自行对nand flash进行编程.. 所以程序的大小就不受限于4KB了...

  这4KB真的很像X86里的超级块.当然肯定是磁盘里的第一个扇区了...不过X86里更逊色了...只有512个字节...

    不过在X86里可以直接调用BIOS提供的中断函数.来从外设存储器读取程序代码... 而这里只能自己编写这样功能的函数了...



我的板子上的nand flash是256MB,准确的说多于这个数.. 型号为K9F2G08U0A。
 结合s3c2440中的nand flash控制器的介绍以及nand flash的芯片手册. 进行对nand flash的编程。

对nand flash编程的代码如下:
nand.c


#define GPACON    (*(volatile unsigned long *)0x56000000)
#define NAND_FUNCTION_PIN    (0x3f << 17)

#define NFCONF    (*(volatile unsigned long *)0x4e000000)
#define NFCONT    (*(volatile unsigned long *)0x4e000004)
#define NFCMMD    (*(volatile unsigned long *)0x4e000008)
#define NFADDR    (*(volatile unsigned long *)0x4e00000c)
#define NFDATA    (*(volatile unsigned char *)0x4e000010)

#define NFSTAT    (*(volatile unsigned long *)0x4e000020)

#define NAND_RDY    1
#define NAND_SECTOR_SIZE 2048UL
#define NAND_SECTOR_MASK    (~(NAND_SECTOR_SIZE - 1))

#define NAND_SELECT_CHIP    (~(1 << 1))
#define NAND_DESELECT_CHIP    (1 << 1)

#define NAND_PRE_READ_CMD    0x00
#define NAND_END_READ_CMD    0x30
#define NAND_READ_ID_CMD 0x90
#define NAND_RESET_CMD    0xff

static inline void delay (unsigned long loops)
{
    __asm__ volatile ("1:\n"
      "subs %0, %1, #1\n"
      "bne 1b":"=r" (loops):"0" (loops));
}
 
static void nand_wait_complete_cmd(void)
{
    while(!(NFSTAT & NAND_RDY))
        delay(5);
}

static void nand_select_chip(void)
{
    NFCONT &= NAND_SELECT_CHIP;
    delay(20);
}

static void nand_deselect_chip(void)
{
    NFCONT |= NAND_DESELECT_CHIP;
    delay(20);
}

static void nand_write_cmd(int cmd)
{
    NFCMMD = cmd;
}



static void nand_reset(void)
{
    nand_select_chip();
    nand_write_cmd(NAND_RESET_CMD);
    nand_wait_complete_cmd();
    nand_deselect_chip();
}

static void nand_write_addr(unsigned long addr)
{
    NFADDR = (addr & 0xff);
    delay(10);
    NFADDR = (addr >> 8) & 0x07;
    delay(10);
    NFADDR = (addr >> 11) & 0xff;
    delay(10);
    NFADDR = (addr >> 19) & 0xff;
    delay(10);
    NFADDR = (addr >> 27) & 0x01;
    delay(10);
}

static unsigned char nand_read_data(void)
{
    volatile unsigned char data = NFDATA;
    return data;
}

static unsigned char nand_readID(void)
{
    unsigned char id, dummy;
    nand_select_chip();
    nand_write_cmd(NAND_READ_ID_CMD);
    NFADDR = 0x00;
    unsigned long *b = (unsigned long *)0x31000000    ;
    dummy = nand_read_data();
    *b++ = dummy;
    id = nand_read_data();
    *b++ = id;
    dummy = nand_read_data();
    *b++ = dummy;
    dummy = nand_read_data();
    *b++ = dummy;
    dummy = nand_read_data();
    *b++ = dummy;

    nand_deselect_chip();
    return id;
}


void nand_init(void)
{
    /* set the gpio function pin, nand flash controler needs them */
    GPACON = (GPACON & ~NAND_FUNCTION_PIN) | NAND_FUNCTION_PIN;
    NFCONF = 0x1310; /* TACLS = 1, TWRPH0 = 3, WRRPH1 = 1 */
    NFCONT = 73;     /* initECC, disable nand select, enable nand controler */
    nand_reset();
}

void nand_read(unsigned char *buf, unsigned long start_addr, unsigned long length)
{
    int i, j;
   
    if(!buf || (start_addr & ~NAND_SECTOR_MASK))
        return;

    nand_select_chip();
   
    for(i = start_addr; i < (start_addr + length);) {
        nand_write_cmd(NAND_PRE_READ_CMD);
        nand_write_addr(i);
        nand_write_cmd(NAND_END_READ_CMD);

        nand_wait_complete_cmd();
       
        for(j = 0; j < NAND_SECTOR_SIZE; j++, i++)
            *buf++ = nand_read_data();
    }
   
    nand_deselect_chip();
}
   
在start.s中增加对nand flash的初始化,调用nand_init, 然后调用nand_read将目标实验代码从nand flash中读出来.拷贝到目标地址中.即sdram. 然后跳转到sdram中继续执行即可.

阅读(2324) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~