您的位置:首页 > 其它

2416下Umon和nand的实现过程 [原创 2011-6-8 16:33:41]

2013-12-18 09:52 267 查看


字号:大 中 小

有网友来信要介绍一下Umon和nand在2416上的移植,时间有点久了,大概如下:

一. 需要实现三个文件:

SD卡启动的boot、Nand上启动的Boot、Umon。

二. SD-boot启动文件:

sd-boot主要代码如下,其中加载是利用了2416内置Irom提供的加载函数:

void Lcd_Off(void);

void Clk0_Enable(int clock_sel);

void Clk1_Enable(int clock_sel);

void Clk0_Disable(void);

void Clk1_Disable(void);

void ClearMemory(void);

volatile U32 downloadAddress;

void Uart_SendString(char *str);

volatile U8 dma_done=0;

int download_run=0;

volatile U32 tempDownloadAddress;

int menuUsed=0;

extern char Image$$RW$$Limit[];

U32 *pMagicNum=(U32 *)Image$$RW$$Limit;

int consoleNum;

/**

* This Function copies a block of page to destination memory.( 8-Bit ECC only )

* @param uint32 block : Source block address number to copy.

* @param uint32 page : Source page address number to copy.

* @param uint8 *buffer : Target Buffer pointer.

* @return int32 - Success or failure.

*/

#define NF8_ReadPage(a,b,c) (((int(*)(uint32, uint32, uint8*))(*((uint32 *)0x40004000)))(a,b,c))

/**

* This Function copies a block of page to destination memory( 8-Bit ECC only )

* @param u32 block : Source block address number to copy.

* @param u32 page : Source page address number to copy.

* @param u8 *buffer : Target Buffer pointer.

* @return int - Success or failure.

*/

#define NF8_ReadPage_Adv(a,b,c) (((int(*)(uint32, uint32, uint8*))(*((uint32 *)0x40004004)))(a,b,c))

/**

* This Function copy MMC(MoviNAND/iNand) Card Data to memory.

* Always use EPLL source clock.

* This function works at 25Mhz.

* @param u32 StartBlkAddress : Source card(MoviNAND/iNand MMC)) Address.(It must block address.)

* @param u16 blockSize : Number of blocks to copy.

* @param u32* memoryPtr : Buffer to copy from.

* @param u32 extClockSpeed : External clock speed(per HZ)

* @param bool with_init : determined card initialization.

* @return bool(u8) - Success or failure.

*/

#define GLOBAL_VAL_BASE 0x40004000

// Card Information

#define globalSDHCInfoBit *((volatile unsigned int*) GLOBAL_VAL_BASE -0x8))

// SD/MMC Card Block Size.

#define globalBlockSizeHide *((volatile unsigned int*)( GLOBAL_VAL_BASE -0x4))

// Nand ECC Fail Counter

#define globalNandECCfailureCount *((volatile unsigned int*)(GLOBAL_VAL_BASE-0x10))

// O/S kernel loading…

//CopyMovitoMem( globalBlockSizeHide - 100, 80, (unsigned int*)0x50200000, 12000000, false);

typedef unsigned char BOOL;

typedef unsigned int DWORD;

/*

CopyMovitoMem(HSMMC_CHANNEL, MOVI_BL2_POS, MOVI_BL2_BLKCNT, (uint *)BL2_BASE, MOVI_INIT_REQUIRED);

  HSMMC_CHANNEL这是SD/MMC通道号,手上板子运用的是CH1,而默认是CH0,所以须要对这个实行修改。

  MOVI_BL2_POS 是须要 copy 的数据位于SD的起始扇区,其计算要领 是这样的,

先得到这个SD的总扇区数TOTAL,再减去256K的BL2和8K的BL1所占的扇区数,

结尾减去0.5K 的eFuse和0.5K的保存区所占的扇区数,

而这里还解释SD的扇区为512B。从这里能够看到和IROM_Fusing_tools对SD卡的处理是完全对应的。

这里还有一个疑问,总扇区数TOTAL是如何得到的?从程序来看是从(TCM_BASE - 0x4)这个地址读取到的,

至于TOTAL是如何 被放到这里的就只好从BL0的代码找答案了。

  MOVI_BL2_BLKCNT是须要复制的扇区数目,这里就是解释为256K,

这也是为什么必须把u-boot.bin转换成256K的文件

  BL2_BASE是目标地址,也就是SDRAM中的地址。这里解释为0x57E0000?

是128M 的SDRAM的结尾 2M,因为到这里为止MMU尚未打开,因此这里运用的是物理地址。*/

#define BLOCK_SIZE 512

#define UMON_SIZE 256*1024

#define UMON_BLOCKS (UMON_SIZE/BLOCK_SIZE)

#define KEPT_BLOCKS 2 //保留区

#define BL1_BLOCKS 16

#define UMON_ROBASE 0x33fb0000

#define CopyMovitoMem(a,b,c,d,e) (((bool(*)(u32,u16,u32*,u32,bool))(*((u32 *)0x40004008))) (a,b,c,d,e))

void (*restart)(void)=(void (*)(void))0x0;

void (*run)(void)=(void (*)(void))UMON_ROBASE;

BOOL CopyMMCtoMem(uint32 StartBlkAddr, uint16 BlocksNum,uint32 * MemPtr, BOOL With_Init)

{

return CopyMovitoMem(StartBlkAddr,BlocksNum,MemPtr,12000000,With_Init);

}

//====================================================================

char *hex2char(unsigned int val)

{

static char str[2];

str[1]='\0';

if(val<=9)

str[0]='0'+val;

else

str[0]=('a'+val-10);

return str;

}

//====================================================================

void Uart_SendDWORD(DWORD d, BOOL cr)

{

Uart_SendString("0x");

Uart_SendString(hex2char((d & 0xf0000000) >> 28));

Uart_SendString(hex2char((d & 0x0f000000) >> 24));

Uart_SendString(hex2char((d & 0x00f00000) >> 20));

Uart_SendString(hex2char((d & 0x000f0000) >> 16));

Uart_SendString(hex2char((d & 0x0000f000) >> 12));

Uart_SendString(hex2char((d & 0x00000f00) >> 8));

Uart_SendString(hex2char((d & 0x000000f0) >> 4));

Uart_SendString(hex2char((d & 0x0000000f) >> 0));

if (cr)

Uart_SendString("\n");

}

void Uart_SendString(char *str)

{

while(*str)

Uart_putc(*str++);

}

void MyDelay(int i)

{

unsigned int j,k;

for(;i;i--)

for(j=0;j<120000/5;j++) k=i;

}

int main(void)

{

register int i, block, blockcopy_count;

block=1;

blockcopy_count=1860;

SystemCLK();

if(PCLK!=0x1cf7c58)

{

rGPCUDP=0x00000400;

rGPCDAT=0;

while(1);

}

Console(1); //开发板只提供了Uart1

Isr_Init();

MyDelay(50);

#if 0

for(i=0;i<10;i++) //Just for debug

{

rGPCUDP=0x00000400;

rGPCDAT=0;

MyDelay(500);

printf("start");

rGPCUDP=0x00000800;

rGPCDAT=0x020;

MyDelay(500);

}

#endif

Uart_SendString("HuaTian sd boot.Compile @"__DATE__ ""__TIME__"\n");

Uart_SendString("Total Blocks:");

Uart_SendDWORD(UMON_BLOCKS,1);

if(CopyMMCtoMem(globalBlockSizeHide-UMON_BLOCKS-KEPT_BLOCKS-BL1_BLOCKS,UMON_BLOCKS,(uint32 *)UMON_ROBASE,TRUE))

{

Uart_SendString("Load Umon from MMC ok!\n");

run();

}

else

{

Uart_SendString("Load Umon from MMc failed!\n");

while(1);

}

}

三. Nand-boot代码,和sd-boot差不多。

extern char Image$$RW$$Limit[];

U32 *pMagicNum=(U32 *)Image$$RW$$Limit;

int consoleNum;

/**

* This Function copies a block of page to destination memory.( 8-Bit ECC only )

* @param uint32 block : Source block address number to copy.

* @param uint32 page : Source page address number to copy.

* @param uint8 *buffer : Target Buffer pointer.

* @return int32 - Success or failure.

*/

#define NF8_ReadPage(a,b,c) (((int(*)(uint32, uint32, uint8*))(*((uint32 *)0x40004000)))(a,b,c))

/**

* This Function copies a block of page to destination memory( 8-Bit ECC only )

* @param u32 block : Source block address number to copy.

* @param u32 page : Source page address number to copy.

* @param u8 *buffer : Target Buffer pointer.

* @return int - Success or failure.

*/

#define NF8_ReadPage_Adv(a,b,c) (((int(*)(uint32, uint32, uint8*))(*((uint32 *)0x40004004)))(a,b,c))

/**

* This Function copy MMC(MoviNAND/iNand) Card Data to memory.

* Always use EPLL source clock.

* This function works at 25Mhz.

* @param u32 StartBlkAddress : Source card(MoviNAND/iNand MMC)) Address.(It must block address.)

* @param u16 blockSize : Number of blocks to copy.

* @param u32* memoryPtr : Buffer to copy from.

* @param u32 extClockSpeed : External clock speed(per HZ)

* @param bool with_init : determined card initialization.

* @return bool(u8) - Success or failure.

*/

#define GLOBAL_VAL_BASE 0x40004000

// Card Information

#define globalSDHCInfoBit *((volatile unsigned int*) GLOBAL_VAL_BASE -0x8))

// SD/MMC Card Block Size.

#define globalBlockSizeHide *((volatile unsigned int*)( GLOBAL_VAL_BASE -0x4))

// Nand ECC Fail Counter

#define globalNandECCfailureCount *((volatile unsigned int*)(GLOBAL_VAL_BASE-0x10))

// O/S kernel loading…

//CopyMovitoMem( globalBlockSizeHide - 100, 80, (unsigned int*)0x50200000, 12000000, false);

typedef unsigned char BOOL;

typedef unsigned int DWORD;

/*

CopyMovitoMem(HSMMC_CHANNEL, MOVI_BL2_POS, MOVI_BL2_BLKCNT, (uint *)BL2_BASE, MOVI_INIT_REQUIRED);

  HSMMC_CHANNEL这是SD/MMC通道号,手上板子运用的是CH1,而默认是CH0,所以须要对这个实行修改。

  MOVI_BL2_POS 是须要 copy 的数据位于SD的起始扇区,其计算要领 是这样的,

先得到这个SD的总扇区数TOTAL,再减去256K的BL2和8K的BL1所占的扇区数,

结尾减去0.5K 的eFuse和0.5K的保存区所占的扇区数,

而这里还解释SD的扇区为512B。从这里能够看到和IROM_Fusing_tools对SD卡的处理是完全对应的。

这里还有一个疑问,总扇区数TOTAL是如何得到的?从程序来看是从(TCM_BASE - 0x4)这个地址读取到的,

至于TOTAL是如何 被放到这里的就只好从BL0的代码找答案了。

  MOVI_BL2_BLKCNT是须要复制的扇区数目,这里就是解释为256K,

这也是为什么必须把u-boot.bin转换成256K的文件?

  BL2_BASE是目标地址,也就是SDRAM中的地址。这里解释为0x57E0000?

是128M 的SDRAM的结尾 2M,因为到这里为止MMU尚未打开,因此这里运用的是物理地址。*/

#define BYTES_PERPAGE (2048)

#define PAGES_PERBLOCK (64)

#define BYTES_PERBLOCK (2048*64)

#define NK_SIZE (8*1024*1024) //NK 8M

#define NK_BLOCKS (NK_SIZE/BYTES_PERBLOCK)

#define BL1_PAGES 2 //BOOT size

#define NK_ROBASE 0x30100000

#define NK_STARTBLOCK (1)

#define BLOCKS_INNAND (2048)

#define CopyMovitoMem(a,b,c,d,e) (((bool(*)(u32,u16,u32*,u32,bool))(*((u32 *)0x40004008))) (a,b,c,d,e))

void (*restart)(void)=(void (*)(void))0x0;

void (*run)(void)=(void (*)(void))NK_ROBASE;

BOOL CopyMMCtoMem(uint32 StartBlkAddr, uint16 BlocksNum,uint32 * MemPtr, BOOL With_Init)

{

return CopyMovitoMem(StartBlkAddr,BlocksNum,MemPtr,12000000,With_Init);

}

//====================================================================

char *hex2char(unsigned int val)

{

static char str[2];

str[1]='\0';

if(val<=9)

str[0]='0'+val;

else

str[0]=('a'+val-10);

return str;

}

//====================================================================

void Uart_SendString(char *str)

{

#ifdef DEBUG_MODE

while(*str)

Uart_putc(*str++);

#endif

}

void Uart_SendDWORD(DWORD d, BOOL cr)

{

#ifdef DEBUG_MODE

Uart_SendString("0x");

Uart_SendString(hex2char((d & 0xf0000000) >> 28));

Uart_SendString(hex2char((d & 0x0f000000) >> 24));

Uart_SendString(hex2char((d & 0x00f00000) >> 20));

Uart_SendString(hex2char((d & 0x000f0000) >> 16));

Uart_SendString(hex2char((d & 0x0000f000) >> 12));

Uart_SendString(hex2char((d & 0x00000f00) >> 8));

Uart_SendString(hex2char((d & 0x000000f0) >> 4));

Uart_SendString(hex2char((d & 0x0000000f) >> 0));

if (cr)

Uart_SendString("\n");

#endif

}

void MyDelay(int i)

{

unsigned int j,k;

for(;i;i--)

for(j=0;j<120000/5;j++) k=i;

}

u16 *BlockMap;

int main(void)

{

unsigned int i,j,k;

u8 *p,*p1;

BlockMap=(u16 *)0x32000000;

SystemCLK();

if(0)

if(PCLK!=0x1cf7c58)

{

rGPCUDP=0x00000400;

rGPCDAT=0;

while(1);

}

Console(1); //开发板只提供了Uart1

Isr_Init();

MyDelay(50);

#if 0

for(i=0;i<10;i++) //Just for debug

{

rGPCUDP=0x00000400;

rGPCDAT=0;

MyDelay(500);

printf("start");

rGPCUDP=0x00000800;

rGPCDAT=0x020;

MyDelay(500);

}

#endif

Uart_SendString("HuaTian nand boot.Compile @"__DATE__ ""__TIME__"\n");

Uart_SendString("Total Blocks:");

Uart_SendDWORD(NK_BLOCKS,1);

if(0)

{

Uart_SendString("\nBoot cont:\n");

for(p=(u8 *)0x40000000;p<(u8 *)(0x40000000+8*1024);p++)

{

Uart_SendString(hex2char((*p)>>4));

Uart_SendString(hex2char((*p)&0x0f));

if(((u32)p&0x0f)==0x0f)

Uart_SendString("\n");

else

Uart_SendString(" ");

}

}

// NF8_ReadPage_Adv(0,4,(u8 *)BlockMap);

// NF8_ReadPage_Adv(0,5,(u8 *)BlockMap+(BLOCKS_INNAND/2));

NF8_Init();

Adv_NF8_ReadPage(0,4,(u8 *)BlockMap);

Adv_NF8_ReadPage(0,5,(u8 *)&BlockMap[BLOCKS_INNAND/2]);

p=(u8 *)NK_ROBASE;

for(j=0;j<NK_BLOCKS;j++)

{

p1=p;

k=BlockMap[j+NK_STARTBLOCK];

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

{

//NF8_ReadPage_Adv(k,i,p);

Adv_NF8_ReadPage(k,i,p);

p+=BYTES_PERPAGE;

}

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

{

if((*p1)!=0xff)

break;

p1++;

}

if(i>=BYTES_PERBLOCK)

break;

Uart_SendString("\n Block:");

Uart_SendDWORD(k,0);

}

Uart_SendString("\nkernel:\n");

if(0)

for((u32)p=NK_ROBASE;u32(p)<(NK_ROBASE+2048);p++)

{

Uart_SendString(hex2char((*p)>>4));

Uart_SendString(hex2char((*p)&0x0f));

if(((u32)p&0x0f)==0x0f)

Uart_SendString("\n");

else

Uart_SendString(" ");

}

Uart_SendString("To boot kernel...\n");

run();

}

四. Umon的代码就好说了,把开发板上的拿过来修改下就行了,我这个做了一些有关nand的扩充。另外预定义__NANDBL不要设,现在代码上还有是没来得及删除这些东西。

主程序:

/**

* Project Name : S3C2450 verification project

*

* Copyright 2008 by Samsung Electronics, Inc.

* All rights reserved.

*

* Project Description :

* This software is only for verifying functions of the S3C2443.

* Anybody can use this code without our permission.

*/

/**

* File Name : 2450mon.cpp

* Description : S3C2450 USB monitor main code

* Author : Cha gyu hwan

* Dept : Mobile solution, AP

* Created Date : 2008.02.21

* Version : 0.0

* History

* R0.0 (2008.02.): Cha gyu hwan draft

*/

#include "System.h"

#include "memtest.h"

#include "profile.h"

#include "usbdev.h"

#include "uartdown.h"

#include "Movinand.h"

#include "nand.h"

//#define S3C2450onSMDK2443

#define USBDMA

#ifdef __NANDBL

volatile unsigned char *downPt;

// Normal NAND : 1page = 256B or 512B, 1block = 32pages, total ? blocks..

// Advanced NAND : 1page = 1K or 2KB, 1block = 32pages, total ? blocks..

//#define OS_IMAGE_SIZE 0x20 // block quantity for USB monitor : 512Kbyte(page=512B),

#define OS_IMAGE_SIZE 1860 // block quantity for WinCE : 32Mbyte(page=512B),

//#define OS_START_ADDR_OFFSET (0x00000000) // Mon start address

//#define OS_START_ADDR_OFFSET (0x00200000) // OS start address

#define OS_START_ADDR_OFFSET (0x20) // F/W Code start address

//#define DOWNLOAD_ADDRESS (_NONCACHE_STARTADDRESS+OS_START_ADDR_OFFSET) //for debugging

#define DOWNLOAD_ADDRESS (_RAM_STARTADDRESS+OS_START_ADDR_OFFSET)

#endif

void Lcd_Off(void);

void Clk0_Enable(int clock_sel);

void Clk1_Enable(int clock_sel);

void Clk0_Disable(void);

void Clk1_Disable(void);

void ClearMemory(void);

volatile U32 downloadAddress;

#ifndef __NANDBL

void TestDownLoading(void);

void WaitDownload(void);

void Menu(void);

void UsbMon(void);

static void __irq Isr_Usb(void);

void Vbus_detect_init(void);

void Usb_power_en(void);

void Usb_power_dis(void);

void Usb_Reset(void);

void Usb_Init(void);

void USB_OnOff(void);

static void __irq Vbus_detect(void);

void WhichMemory(void);

void Reset_Status_Check(void);

#endif

void (*restart)(void)=(void (*)(void))0x0;

void (*run)(void);

volatile U8 dma_done=0;

int download_run=0;

int download_promgram=0;

int g_TagetNandBlock=0;

volatile U32 tempDownloadAddress;

int menuUsed=0;

uint16 g_PhBlockNum[BLOCKS_INNAND];

t_strInfo g_SysInfo;

extern char Image$$RW$$Limit[];

U32 *pMagicNum=(U32 *)Image$$RW$$Limit;

int consoleNum;

#ifdef USBDMA

static USB_OP eOpMode = USB_DMA;

#else

static USB_OP eOpMode = USB_CPU;

#endif

int main(void)

{

#ifdef __NANDBL

register int i, block, blockcopy_count;

block=1;

blockcopy_count=1860;

SystemCLK();

#else

SystemCLK(0);

#endif

Console(1);

Isr_Init();

NF8_Init();

#ifdef __NANDBL

downPt=(unsigned char *)(DOWNLOAD_ADDRESS);

while(blockcopy_count<=OS_IMAGE_SIZE)

{

block++;

Uart_putc('B');

if(!NF8_IsBadBlock(block)) continue; // Skip bad block

blockcopy_count++;

for(i=0;i<32;i++) // Read 32 page

{

if(!NF8_ReadPage(block, i, (unsigned char *)downPt)) //1

{

while(1);

}

downPt += 512; // Next page

}

Uart_putc('A');

if (blockcopy_count == OS_IMAGE_SIZE)

{

}

}

run=(void (*)(void))(DOWNLOAD_ADDRESS);

run();

#else

printf("Njs 2416 SD-UMON Compile at: %s--%s\n",__DATE__,__TIME__);

UsbMon();

#endif

}

#ifndef __NANDBL

void UsbMon(void)

{

Usb_power_en();

if (rRSTSTAT&0x8) rRSTCON|=(1<<16); //if reset by sleep wakeup, control the retention I/O cell

//USB Port is Normal mode

rMISCCR=rMISCCR&~(1<<12); // USBD is 0 ,normal mode ,1 is suspend mode /

rPWRCFG |= (0x1<<4); // phy power enable

pISR_USBD =(unsigned)Isr_Usb;

#ifndef S3C2450onSMDK2443

pISR_EINT2 = (U32)Vbus_detect;

Vbus_detect_init();

#endif

Usb_Init();

Delay(0); //calibrate Delay()

// Led_Display(0x6);

rGPCUDP=0x00000400;

rGPCDAT=0;

// rUSB_CLKCON = (0x1<<31)|(0x1<<2)|(0x0<<1)|(0x1<<0); // vbus detect enable...

//D+ pull up , USB2.0 Function clock Enable, USB1.1 HOST disable,USB2.0 PHY test enable

// CLKOUT0/1 select.

printf("CLKOUT0:MPLL in, CLKOUT1:RTC clock.\n");

printf("\n");

printf("+-----------------------------------------------+\n");

printf("| Huartian 2416 USB Downloader %s----%s +\n",__DATE__,__TIME__);

printf("+-----------------------------------------------+\n");

WhichMemory();

printf("MPLL=%.2fMHz, ARMCLK=%.2fMHz (%d:%d:%d), HCLK=%.2fMHz, PCLK=%.2fMHz\n\n",

(float)MPLL/1000000,(float)ARMCLK/1000000,ARMCLKdiv+1,(PREdiv+1)*(HCLKdiv+1),(PREdiv+1)*(HCLKdiv+1)*(PCLKdiv+1),(float)HCLK/1000000,(float)PCLK/1000000);

printf("USB: IN_ENDPOINT:1 OUT_ENDPOINT:3\n");

printf("FORMAT: <ADDR(DATA):4>+<SIZE(n+10):4>+<DATA:n>+<CS:2>\n");

printf("NOTE: 1. Power off/on or press the reset button for 1 sec\n");

printf(" in order to get a valid USB device address.\n");

printf(" 2. For additional menu, Press any key. \n");

printf("\n");

////for 2443 switch to 2450

#ifndef S3C2450onSMDK2443

USB_OnOff();

#endif

download_run=1; //The default menu is the Download & Run mode.

Reset_Status_Check();

AllocateUSBDEV();

while(1)

{

#ifdef USBDMA

eOpMode =USB_DMA;

#else

eOpMode =USB_CPU;

#endif

UsbdMain();

if(menuUsed==1)Menu();

WaitDownload();

}

FreeUSBDEV();

}

void UsbdMain(void)

{

SetOpMode(eOpMode);

// Init();

}

void MarkBadBlock()

{

int blocknum=0;

char key;

printf("Pls input block num(dec or hex):");

blocknum=GetIntNum();

printf("\nDo you confirm mark block %d as bad block? y/n",blocknum);

while(1)

{

key=getchar();

if(key=='y' || key=='n') break;

}

if(key=='y') Adv_NF8_MarkBadBlock(blocknum);

}

void RemoveBadBlockMark()

{

int blocknum=0;

char key;

printf("Pls input block num(dec or hex):");

blocknum=GetIntNum();

printf("\nDo you confirm remove bad mark of block %d and erase? y/n",blocknum);

while(1)

{

key=getchar();

if(key=='y' || key=='n') break;

}

if(key=='y') Adv_NF8_EraseBlock(blocknum);

}

int SpecialFunc()

{

bool exitloop=false;

char key;

while(!exitloop)

{

printf("\n------Select Function------\n");

printf("1. Check Bad Block\n");

printf("2. Read Page \n");

printf("3. Manul mark bad block \n");

printf("4. Remove bad block mark \n");

printf("5. Erase one block \n");

printf("6. back to main menu \n");

key=getchar();

switch (key)

{

case '1':

Adv_NF8_PrintBadBlockNum();

exitloop=true;

break;

case '2':

Test_Adv_NF8_Page_Read();

exitloop=true;

break;

case '3':

MarkBadBlock();

exitloop=true;

break;

case '4':

RemoveBadBlockMark();

exitloop=true;

break;

case '5':

Test_Adv_NF8_Block_Erase();

exitloop=true;

break;

case '6':

exitloop=true;

break;

default:

break;

}

}

#if 0

printf("Mark 2,3,4,5 as bad block!");

NF8_Init();

Adv_NF8_MarkBadBlock(2);

Adv_NF8_MarkBadBlock(3);

Adv_NF8_MarkBadBlock(4);

Adv_NF8_MarkBadBlock(5);

#endif

return TRUE;

}

int FormatNand()

{

uint32 i;

NF8_Init();

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

{

if(Adv_NF8_IsBadBlock(i)!=FAIL)

Adv_NF8_EraseBlock(i);

}

printf("Formate Over!\n");

return TRUE;

}

void Menu(void)

{

U8 key;

menuUsed=1;

while(1)

{

printf("\n###### Select Menu ######\n");

printf(" [0] Download & Run\n");

printf(" [1] Download Only\n");

printf(" [2] Download & Program Nk\n");

printf(" [3] Test SDRAM \n");

printf(" [4] Clear SDRAM \n");

printf(" [5] Special Func.\n");

printf(" [6] Download with UART\n");

printf(" [7] Download & Program Nk with UART\n");

printf(" [8] Upload with USB 2.0 device \n");

printf(" [9] Format Nand Flash \n");

key=getchar();

switch(key)

{

case '0':

printf("\nDownload&Run is selected.\n\n");

download_run=1;

download_promgram=0;

return;

case '1':

printf("\nDownload Only is selected.\n");

printf("Enter a new temporary download address(0x3...):");

tempDownloadAddress=GetIntNum();

if((tempDownloadAddress<0x30000000) || (tempDownloadAddress>0x34000000))

tempDownloadAddress=0x30000000;

download_run=0;

download_promgram=0;

printf("The temporary download address is 0x%x.\n\n",tempDownloadAddress);

return;

case '2':

printf("\nDownload And Program Nk is selected.\n");

printf("Enter a new temporary download address(0x3...):");

tempDownloadAddress=GetIntNum();

if((tempDownloadAddress<0x30000000) || (tempDownloadAddress>0x34000000))

tempDownloadAddress=0x30000000;

download_run=0;

download_promgram=1;

printf("\nThe temporary download address is 0x%x.\n\n",tempDownloadAddress);

printf(" Enter Taget Block : ");

g_TagetNandBlock=GetIntNum();

printf(" \nThe taget nand block is :%d\n\n",g_TagetNandBlock);

return;

case '3':

printf("\nMemory Test is selected.\n");

MemoryTest();

Menu();

return;

case '4':

printf("\nMemory Clear is selected.\n");

ClearMemory();

Menu();

return;

case '5':

printf("This function has been removed! \n");

SpecialFunc();

#if 0

printf("\nWhich UART channel do you want to use for the console?[0/1]\n");

if(getchar()!='1')

{

*pMagicNum=0x0;

printf("UART ch.0 will be used for console at next boot.\n");

}

else

{

*pMagicNum=0x12345678;

printf("UART ch.1 will be used for console at next boot.\n");

printf("UART ch.0 will be used after long power-off.\n");

}

printf("System is waiting for a reset. Please, Reboot!!!\n");

while(1);

#endif

break;

case '6': //

printf("\nDownload with UART\n");

UartMON(0);

return;

case '7': //

printf("\nDownload and program with UART\n");

UartMON(1);

return;

case '8': //

printf("\nUpload file !!\n");

SetOpMode(eOpMode);

getchar();

return;

case '9':

printf("\n Format Nand Disk !!\n");

FormatNand();

break;;

default:

break;

}

}

}

//extern U32 checkTest;

int CheckNandFormat()

{

uint8 *buff;

uint32 i;

buff=(uint8 *)malloc(BYTES_PERPAGE*2);

if(buff==NULL)

{

printf("Can not malloc mem!Progarm Nk failed!\n");

return FALSE;

}

Adv_NF8_ReadPage(0,0,buff);

Adv_NF8_ReadPage(0,0,buff+BYTES_PERPAGE);

for(i=0;i<BYTES_PERPAGE*2;i++)

if(*buff!=0xff)

{

printf("Nand have not format ! Abort!\n");

free(buff);

return FALSE;

}

return TRUE;

}

int MakeSysInfo()

{

uint32 j,i;

//检查坏块,形成Block Remap 信息

j=0; //逻辑,即数组下标

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

{

if(Adv_NF8_IsBadBlock(i)==OK)

{

g_PhBlockNum[j++]=i;

}

}

g_SysInfo.BlocksInNand=BLOCKS_INNAND;

g_SysInfo.BytesPerPage=BYTES_PERPAGE;

g_SysInfo.PagesPerBlock=PAGES_PERBLOCK;

g_SysInfo.TotalBadBlocks=i-j;

printf("Marked bad blocks total number: %d\n",g_SysInfo.TotalBadBlocks);

return TRUE;

}

void ProgramNand()

{

uint32 blocknum=g_TagetNandBlock;

uint32 pagenum=0;

uint32 DataSize=g_uDownloadFileSize;

uint8 *p=(uint8 *)g_uDownloadAddress;

Adv_NF8_EraseBlock(g_PhBlockNum[blocknum]);

while(1)

{

if(DataSize>BYTES_PERPAGE)

{

if(!Adv_NF8_WritePage(g_PhBlockNum[blocknum],pagenum,p))

{

printf("Write page error @ Logic Block: %d Phsical Block:%d Page:%d\n",

g_PhBlockNum[blocknum],blocknum,pagenum);

return;

}

p+=BYTES_PERPAGE;

DataSize-=BYTES_PERPAGE;

pagenum++;

if(pagenum>=PAGES_PERBLOCK)

{

pagenum=0;

blocknum++;

Adv_NF8_EraseBlock(g_PhBlockNum[blocknum]);

}

}

else

{

Adv_NF8_WritePage(g_PhBlockNum[blocknum],pagenum,p);

break;

}

}

if(g_TagetNandBlock==0)

{

Adv_NF8_WritePage(0,4,(uint8 *)g_PhBlockNum);

Adv_NF8_WritePage(0,5,(uint8 *)g_PhBlockNum+BYTES_PERPAGE);

Adv_NF8_WritePage(0,6,(uint8 *) (&g_SysInfo));

}

printf("\nWrite over! Start virify!\n");

blocknum=g_TagetNandBlock;

pagenum=0;

DataSize=g_uDownloadFileSize;

p=(uint8 *)g_uDownloadAddress;

uint8 *buff=(uint8 *)malloc(BYTES_PERPAGE);

if(p==NULL)

{

printf("malloc error! @%s exit \n",__LINE__);

}

while(1)

{

if(DataSize>BYTES_PERPAGE)

{

if(!Adv_NF8_ReadPage(g_PhBlockNum[blocknum],pagenum,buff))

{

printf("Read page error @ Logic Block: %d Phsical Block:%d Page:%d\n",

g_PhBlockNum[blocknum],blocknum,pagenum);

free(p);

return;

}

if(memcmp(p, buff,BYTES_PERPAGE))

{

printf("Verify failed @ Logic Block: %d Phsical Block:%d Page:%d\n",

g_PhBlockNum[blocknum],blocknum,pagenum);

free(buff);

return;

}

p+=BYTES_PERPAGE;

DataSize-=BYTES_PERPAGE;

pagenum++;

if(pagenum>=PAGES_PERBLOCK)

{

pagenum=0;

blocknum++;

}

}

else

{

Adv_NF8_ReadPage(g_PhBlockNum[blocknum],pagenum,buff);

if(memcmp(p, buff,DataSize))

{

printf("Verify failed @ Logic Block: %d Phsical Block:%d Page:%d\n",

g_PhBlockNum[blocknum],blocknum,pagenum);

}

break;

}

}

if(g_TagetNandBlock==0)

{

Adv_NF8_ReadPage(0,4,buff);

if(memcmp((uint8 *)g_PhBlockNum, buff,BYTES_PERPAGE))

{

printf("Verify failed @ block 0, page4\n");

}

Adv_NF8_ReadPage(0,5,buff);

if(memcmp((uint8 *)g_PhBlockNum+BYTES_PERPAGE, buff,BYTES_PERPAGE))

{

printf("Verify failed @ block 0, page5\n");

}

Adv_NF8_ReadPage(0,6,buff);

if(memcmp((uint8 *)(&g_SysInfo), buff,sizeof(g_SysInfo)))

{

printf("Verify failed @ block 0, page6\n");

}

}

free(buff);

printf("Verify Pass!\n");

}

void WaitDownload(void)

{

U32 i;

U32 j;

U16 cs;

U32 temp;

U16 dnCS;

int first=1;

float time;

U8 tempMem[16];

U8 key;

g_uDownloadAddress=(U32)tempMem; //_RAM_STARTADDRESS;

g_uDownloadFileSize=0;

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

/* Test program download */

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

j=0;

if(IsEnumerationDone()==false)

{

printf("USB host is not connected yet.\n");

}

while(g_uDownloadFileSize==0)

{

if(first==1 && IsEnumerationDone()==true)

{

printf("USB host is connected. Waiting a download.\n");

first=0;

}

if(j%0x50000==0)Led_Display(0x6);

if(j%0x50000==0x28000)Led_Display(0x9);

j++;

key=Uart_GetKey();

if(key!=0)

{

Menu();

first=1; //To display the message,"USB host ...."

}

}

StartStopwatch();

printf("\nNow, Downloading [ADDRESS:%xh,TOTAL:%d]\n",

g_uDownloadAddress,g_uDownloadFileSize);

printf("RECEIVED FILE SIZE:%8d",0);

while(1) //((U32)g_pDownPt-g_uDownloadAddress)<(g_uDownloadFileSize-8)

{

U32 tmpu32;

tmpu32=(U32)g_pDownPt-g_uDownloadAddress;

if (tmpu32>(g_uDownloadFileSize-8)) break;

// if ((tmpu32 & (10*1024))==0) //处理不过来.

// {

// printf("\b\b\b\b\b\b\b\b%8d",tmpu32);

// }

if(dma_done ==1)break;

}

dma_done=0;

time=EndStopwatch();

printf("\b\b\b\b\b\b\b\b%8d",g_uDownloadFileSize);

printf("\n(%5.1fKB/S,%3.1fS)\n",(float)(g_uDownloadFileSize/time*1000.),time/1000000);

printf("RECEIVE FILE DONE !! \n");

if(download_run==1)

{

rINTMSK=BIT_ALLMSK;

run=(void (*)(void))g_uDownloadAddress;

run();

}

if(download_promgram==1)

{

// njs add to program file to Nk.

//g_TagetNandBlock

//检查是否已格式化

NF8_Init();

//if(!CheckNandFormat()) return;

MakeSysInfo();

ProgramNand();

}

}

static void __irq Isr_Usb(void)

{

rINTMSK |=(BIT_USBD);

HandleEvent();

ClearPending(BIT_USBD);

rINTMSK &= ~(BIT_USBD);

}

void Vbus_detect_init(void)

{

//for 2443 switch to 2450

#ifndef S3C2450onSMDK2443

rGPFUDP = (rGPFCON & ~(0x3<<4));

#endif

rGPFCON = (rGPFCON & ~(0x3<<4))|(2<<4); //GPF2 = EINT2

rEXTINT0 = (rEXTINT0 & ~(0xf<<8)) | (0x7<<8) ; //EINT2=pull down disable,high level triggered

rEINTPEND = 0xffffff;

rSRCPND = BIT_EINT2; //to clear the previous pending states

rINTPND = BIT_EINT2;

rEINTMASK &= ~((1<<2));

rINTMSK &= ~(BIT_EINT2);

}

void Usb_power_en(void)

{

// In SOM2416, this pin is open

#if 0

rGPHUDP|=(0x1<<28); // for usb power enable....

rGPHCON|=(0x1<<28); // for usb power enable....

rGPHDAT|=(0x1<<14); // for usb power enable....

#endif

}

void Usb_power_dis(void)

{

rGPHUDP|=(0x3<<28); // for usb power disable....

rGPHCON|=(0x1<<28); // for usb power disable....

rGPHDAT&=~(0x1<<14); // for usb power disable....

}

void Usb_Reset(void)

{

rUSB_RSTCON = (0x0<<2)|(0x0<<1)|(0x1<<0);//Function 2.0 S/W reset, Host 1.1 S/W reset,PHY 2.0 S/W reset

Delay(2); // phy reset must be asserted for at 10us

rUSB_RSTCON = (0x1<<2)|(0x1<<1)|(0x0<<0);//Function 2.0 S/W reset, Host 1.1 S/W reset,PHY 2.0 S/W reset

rUSB_RSTCON = (0x0<<2)|(0x0<<1)|(0x0<<0);//Function 2.0 S/W reset, Host 1.1 S/W reset,PHY 2.0 S/W reset

Delay(20);

}

void Usb_Init(void)

{

//for 2443 switch to 2450

#ifdef S3C2450onSMDK2443

rUSB_PHYCTRL =(0x0<<3)|(0x0<<2)|(0x1<<1)|(0x0<<0); //48Mhz,x-tal,External X-tal,device

#else

// rUSB_PHYCTRL =(0x0<<3)|(0x1<<2)|(0x1<<1)|(0x0<<0); //48Mhz,OSC,External X-tal,device

rUSB_PHYCTRL =(0x0<<3)|(0x0<<2)|(0x1<<1)|(0x0<<0); //KIT2416 48Mhz,x-tal,External X-tal,device

#endif

rUSB_PHYPWR = (0x0<<31)|(0x3<<4)|(0x0<<3)|(0x0<<2)|(0x0<<1)|(0x0<<0);

//48Mhz clock on ,PHY2.0 analog block power on,XO block power on,XO block power in suspend mode,PHY 2.0 Pll power on ,suspend signal for save mode disable

rUSB_CLKCON = (0x0<<31)|(0x1<<2)|(0x0<<1)|(0x0<<0); // vbus detect enable...

//D+ pull up , USB2.0 Function clock Enable, USB1.1 HOST disable,USB2.0 PHY test enable

//for 2443 switch to 2450

#ifdef S3C2450onSMDK2443

rUSB_CLKCON = (0x1<<31)|(0x1<<2)|(0x0<<1)|(0x1<<0); // vbus detect enable...

#endif

Init();

MMU_EnableICache();

// rTR |=0x2<<6;

ClearPending(BIT_USBD);

rINTMSK&=~(BIT_USBD); // usb interrupt enable

}

void USB_OnOff(void)

{

if((rGPFDAT&(0x1<<2))==0)

{

printf("disconnected\n");

Usb_power_dis();

rUSB_CLKCON = (0x0<<31)|(0x1<<2)|(0x0<<1)|(0x1<<0); // vbus detect enable...

rMISCCR=rMISCCR|(1<<12); // USBD is 0 ,normal mode ,1 is suspend mode /

rPWRCFG &= ~(0x1<<4); // phy power enable

}

else

{

printf("connected\n");

Usb_power_en();

Delay(10);

//USB Port is Normal mode

rMISCCR=rMISCCR&~(1<<12); // USBD is 0 ,normal mode ,1 is suspend mode /

rPWRCFG |= (0x1<<4); // phy power enable

Usb_Reset(); //

Usb_Init();

rUSB_CLKCON = (0x1<<31)|(0x1<<2)|(0x0<<1)|(0x0<<0); // vbus detect enable...

//D+ pull up , USB2.0 Function clock Enable, USB1.1 HOST disable,USB2.0 PHY test enable

}

}

static void __irq Vbus_detect(void)

{

rEINTMASK |= ((1<<2));

// printf("rGPFDAT =%x \n",rGPFDAT&(0x1<<2));

USB_OnOff();

ClearPending(BIT_EINT2);

rEINTPEND=(1<<2);

rEINTMASK &= ~((1<<2));

}

void WhichMemory(void)

{

if(rBANKCFG & (0x1<<3))

{

printf("mDDR\n");

}else{

printf("mSDR\n");

}

}

#endif

void Reset_Status_Check(void)

{

printf("reset status register = %08x\n", rRSTSTAT);

if( rRSTSTAT & (1<<0) )

{

printf("Power-on Reset\n");

}

else if( rRSTSTAT & (1<<2) )

{

printf("\nWatch-dog Reset\n\n");

run=(void (*)(void))0x30000000;

run();

}

else if( rRSTSTAT & (1<<3) )//Sleep mode wake-up

{

printf("\nSLEEP mode Wake-up\n\n");

run=(void (*)(void))0x30000000;

run();

}

else if( rRSTSTAT & (1<<4) )

{

printf("\nDeep STOP mode Wake-up\n\n");

run=(void (*)(void))0x30000000;

run();

}

else if( rRSTSTAT & (1<<5) )

{

printf("\nSoft Reset\n\n");

run=(void (*)(void))0x30000000;

run();

}

}

五. sd-irom制作

sd-boot注意连接时的地址,编绎完的代码不能超过8K。然后用工具把文件扩充到8K,然后把sd-boot和umon的bin文件合并到一起,命令:

批处理命令:

copy /y ..\SD-BOOT\SDLoader.nb0 .

copy /b/y SD-Umon.bin+SDLoader.nb0 SD-IROM.nb0

pause

另附本人做的小工具下载地址:
http://ishare.iask.sina.com.cn/f/13568428.html
六. nand启动制作

用sd 启动后,把nand-boot和umon烧进去就ok了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: