Chinaunix首页 | 论坛 | 博客
  • 博客访问: 153598
  • 博文数量: 22
  • 博客积分: 1456
  • 博客等级: 上尉
  • 技术积分: 252
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-25 00:08
个人简介

ddd

文章存档

2011年(1)

2010年(21)

我的朋友

分类: 嵌入式

2010-04-25 13:55:51

移植U-Boot-2009.08到友善之臂mini2440(三)

3.1  board/mini2440/目录下加入NAND Flash读取函数(start.S中需要的nand_read_ll函数)文件nand_read.c,新建nand_read.c,这里的开发板使用的是128MB ,大页的读写。下面是nand_read.c文件的内容。(注意和小页的NandFlash的不同)

board/mini2440/nand_read.c

 

#include

#include

 

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGw(x) (*(volatile unsigned short *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

#define NF_BASE 0x4e000000

#if defined(CONFIG_S3C2410)

#define NFCONF __REGi(NF_BASE + 0x0)

#define NFCMD __REGb(NF_BASE + 0x4)

#define NFADDR __REGb(NF_BASE + 0x8)

#define NFDATA __REGb(NF_BASE + 0xc)

#define NFSTAT __REGb(NF_BASE + 0x10)

#define NFSTAT_BUSY 1

#define nand_select() (NFCONF &= ~0x800)

#define nand_deselect() (NFCONF |= 0x800)

#define nand_clear_RnB() do {} while (0)

#elif defined(CONFIG_S3C2440)

#define NFCONF __REGi(NF_BASE + 0x0)

#define NFCONT __REGi(NF_BASE + 0x4)

#define NFCMD __REGb(NF_BASE + 0x8)

#define NFADDR __REGb(NF_BASE + 0xc)

#define NFDATA __REGb(NF_BASE + 0x10)

#define NFDATA16 __REGw(NF_BASE + 0x10)

#define NFSTAT __REGb(NF_BASE + 0x20)

#define NFSTAT_BUSY (1 << 2)

#define nand_select() (NFCONT &= ~(1 << 1))

#define nand_deselect() (NFCONT |= (1 << 1))

#define nand_clear_RnB() (NFSTAT |= NFSTAT_BUSY)

#endif

 

static inline void nand_wait(void)

{

  int i;

 

 while (!(NFSTAT & NFSTAT_BUSY))

  for (i=0; i<10; i++);

}

 

#if defined(CONFIG_S3C2410)

 

#define NAND_PAGE_SIZE 512

#define BAD_BLOCK_OFFSET 517

#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)

#define NAND_BLOCK_SIZE 0x4000

#else

 

#define NAND_5_ADDR_CYCLE

#define NAND_PAGE_SIZE 2048

#define BAD_BLOCK_OFFSET NAND_PAGE_SIZE

#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)

#define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64)

#endif

 

#if defined(CONFIG_S3C2410) && (NAND_PAGE_SIZE != 512)

#error "S3C2410 does not support nand page size != 512"

#endif

static int is_bad_block(unsigned long i)

{

 unsigned char data;

 unsigned long page_num;

 

 nand_clear_RnB();

#if (NAND_PAGE_SIZE == 512)

 NFCMD = NAND_CMD_READOOB;

 NFADDR = BAD_BLOCK_OFFSET & 0xf;

 NFADDR = (i >> 9) & 0xff;

 NFADDR = (i >> 17) & 0xff;

 NFADDR = (i >> 25) & 0xff;

#elif (NAND_PAGE_SIZE == 2048)

 page_num = i >> 11;

 NFCMD = NAND_CMD_READ0;

 NFADDR = BAD_BLOCK_OFFSET & 0xff;

 NFADDR = (BAD_BLOCK_OFFSET >> 8) & 0xff;

 NFADDR = page_num & 0xff;

 NFADDR = (page_num >> 8) & 0xff;

 NFADDR = (page_num >> 16) & 0xff;

 NFCMD = NAND_CMD_READSTART;

#endif

 nand_wait();

 data = (NFDATA & 0xff);

 if (data != 0xff)

  return 1;

 return 0;

}

static int nand_read_page_ll(unsigned char *buf, unsigned long addr)

{

 unsigned short *ptr16 = (unsigned short *)buf;

 unsigned int i, page_num;

 nand_clear_RnB();

 NFCMD = NAND_CMD_READ0;

#if (NAND_PAGE_SIZE == 512)

 

 NFADDR = addr & 0xff;

 NFADDR = (addr >> 9) & 0xff;

 NFADDR = (addr >> 17) & 0xff;

 NFADDR = (addr >> 25) & 0xff;

#elif (NAND_PAGE_SIZE == 2048)

 page_num = addr >> 11;

 

 NFADDR = 0;

 NFADDR = 0;

 NFADDR = page_num & 0xff;

 NFADDR = (page_num >> 8) & 0xff;

 NFADDR = (page_num >> 16) & 0xff;

 NFCMD = NAND_CMD_READSTART;

#else

#error "unsupported nand page size"

#endif

 nand_wait();

 for (i = 0; i < NAND_PAGE_SIZE; i++)

 {

  *buf = (NFDATA & 0xff);

  buf++;

 }

 return NAND_PAGE_SIZE;

}

 

 

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

{

    int i, j;

  

    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))

    {

     return -1;

    }

 

 nand_select();

 nand_clear_RnB();

 for (i=0; i<10; i++);

 for (i=start_addr; i < (start_addr + size);)

 {

  j = nand_read_page_ll(buf, i);

  i += j;

  buf += j;

 }

 

 

 nand_deselect();

 

  return 0;

}

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

3.2修改board/mini2440/Makefile文件,28,nand_read.c编译进u-boot

 

OBJS := mini2440.o nand_read.o flash.o

 

3.3修改board/mini2440/lowlevel_init.S文件

(1)修改 REFRESH 的刷新周期:

/* REFRESH parameter */

#define REFEN                   0x1     /* Refresh enable */

#define TREFMD                  0x0     /* CBR(CAS before RAS)/Auto refresh */

//#define Trp                      0x0     /* 2clk */

 

#define Trc                     0x3     /* 7clk */

#define Tchr                    0x2     /* 3clk */

//#define REFCNT                        0x0459

 

# if defined(CONFIG_S3C2440)

#define Trp            0x2    /* 4clk */

#define REFCNT            1012

#else

#define Trp            0x0    /* 2clk */

#define REFCNT                  0x0459

#endif

 

 

3.4 /board/mini2440/mini2440.c 中对GPIOPLL的配置进行修改

(1)添加网络头文件的支持

#include

#include 3c2410.h>

 

#include

#include

#include

2)修改GPIOPLL的配置

#if FCLK_SPEED==0               /* Fout = 203MHz, Fin = 12MHz for Audio */

#define M_MDIV  0xC3

#define M_PDIV  0x4

#define M_SDIV  0x1

#elif FCLK_SPEED==1             /* Fout = 202.8MHz */

//#define M_MDIV        0x5c

//define M_PDIV 0x4

//#define M_SDIV        0x0

 

//xujun

#if defined(CONFIG_S3C2440)

/* Fout = 405MHz */

#define M_MDIV  0x7f

#define M_PDIV  0x2

#define M_SDIV  0x1

#endif

#endif

 

#if USB_CLOCK==0

#define U_M_MDIV        0xA1

#define U_M_PDIV        0x3

#define U_M_SDIV        0x1

#elif USB_CLOCK==1

//#define U_M_MDIV      0x48

//#define U_M_PDIV      0x3

//xujun

#if defined(CONFIG_S3C2440)

#define U_M_MDIV 0x38

#define U_M_PDIV 0x2

#endif

#define U_M_SDIV        0x2

#endif

3)为连接LED和蜂鸣器的GPIO修改配置寄存器:

        /* set up the I/O ports */

        gpio->GPACON = 0x007FFFFF;

#if defined(CONFIG_MINI2440)

        gpio->GPBCON = 0x00055555;

#else

        gpio->GPBCON = 0x00044556;

#endif

        gpio->GPBUP = 0x000007FF;

。。。。。。

4)为引导linux 内核,修改开发板的类型代码

 

/* arch number of SMDK2410-Board */

        //gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

 

#if defined(CONFIG_S3C2440)

/* arch number ofMINI2440-Board */

        gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;

#endif

5)为使int board_init (void)设置完成后,LED1LED2同时亮起,在int board_init (void)的最后添加:

    /* adress of boot parameters */

gd->bd->bi_boot_params = 0x30000100  

             icache_enable();

        dcache_enable();

# if defined(CONFIG_MINI2440_LED)

    gpio->GPBDAT = 0x181;

#endif

return 0;
}

 (6) 添加对dm9000的初始化函数

#ifdef CONFIG_DRIVER_DM9000

int board_eth_init(bd_t *bis)

{

return dm9000_initialize(bis);

}

#endif

(7)删除自带的nandflash的初始化函数

 

#if 0

#if defined(CONFIG_CMD_NAND)

extern ulong nand_probe(ulong physadr);

 

static inline void NF_Reset(void)

{

int i;

………………

#ifdef DEBUG

printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);

#endif

printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);

}

#endif

#endif

 

 

3.5修改 lib_arm/board.c文件

(1) 添加头文件支持

#include

#include

#include 3c2410.h>

 

 (2)添加LED功能,指示进度

 

#if 0

/************************************************************************

 * Coloured LED functionality

 ************************************************************************

 * May be supplied by boards if desired

 */

void inline __coloured_LED_init (void) {}

……………………

void inline blue_LED_off(void)__attribute__((weak, alias("__blue_LED_off")));

#endif

 

 

static int display_banner (void)

{

#if defined(CONFIG_MINI2440_LED)

                S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

                gpio->GPBDAT = 0x101;

 

#endif

………

if defined(CONFIG_RESET_PHY_R)

debug ("Reset Ethernet PHY\n");

reset_phy();

#endif

#endif

 

#if defined(CONFIG_MINI2440_LED)

               S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

#endif

# if defined(CONFIG_MINI2440_LED)

         gpio->GPBDAT = 0x0;

#endif

        printf("\n**********************************************************");

        printf("\n\thello! this U-BOOT is modified  by  XUJUN, at 2010-04-22\n ");

       printf("\t-USTB--xujun--beijing--mini2440-uboot-\n");

      printf("\t  QQ is 306141829\n");

       printf("\t-LOVE ARM Linux and U-BOOT-\n");

        printf("**********************************************************\n");

 

/* main_loop() can return to retry autoboot, if so just run it again. */

for (;;) {

    main_loop ();

 

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