📄 flash.c
字号:
//====================================================================
// File Name : flash.c
// Function : S3C2410 Flash Program
// Program : Kong, In Wook (KIW)
// Date : May 30, 2002
// Version : 0.0
// History
// 0.0 : Programming start (May 30,2002) -> KIW
// Arrangement source code(8/01/2002)-> SOP
//====================================================================
#include <string.h>
#include "def.h"
#include "option.h"
#include "2410addr.h"
#include "2410lib.h"
#include "2410slib.h"
#include "2410usb.h"
#include "mmu.h"
#include "am29f800.h"
#include "strata32.h"
volatile int isUsbdSetConfiguration;
static int DownloadData(void);
extern int NF_MarkBadBlock(U32 block);
extern int NF_EraseBlock(U32 block);
extern int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf);
extern int NF_ReadPage(U32 block,U32 page,U8 *buffer);
extern void Timer_InitEx(void);
extern void Timer_StartEx(void);
extern float Timer_StopEx(void);
extern void ClearEp3OutPktReady(void);
extern void ConfigEp3DmaMode(U32 bufAddr,U32 count);
extern void UsbDownload(void);
extern U32 download_run;
extern unsigned char *downPt;
//extern U32 downloadAddress;
extern U32 downloadFileSize;
int consoleNum;
U8 UsbFinish=1;
extern U16 checkSum;
extern U32 totalDmaCount;
#if 1
// removed because of multiple definition
extern U32 downloadAddress;
extern U32 downloadProgramSize;
#else
U32 downloadAddress;
U32 downloadProgramSize;
#endif
//==========================================================================================
void *flashType[][2]=
{
(void *)ProgramAM29F800, "AM29LV800BB/BA x1 ",
// (void *)Program28F640J3A, "28F640J3A x2 ",
(void *)Program28F128J3A, "28F128J3A(16MB) x2 ",
0,0
};
void (*run)(void);
//==========================================================================================
static int DownloadData(void)
{
int i,tmp;
U16 checkSum=0,dnCS;
U32 fileSize=10;
U8 *downPt;
downPt=(U8 *)downloadAddress;
Uart_Printf("\ndownloadAddress = %x\n",downloadAddress);
Uart_Printf("Download the plain binary file(.BHC) to be written\n");
Uart_Printf("The file format : <n+6>(4)+(n)+CS(2)\n");
Uart_Printf("To transmit .BIN file : wkocm2 xxx.BIN /1 /d:1\n");
Uart_Printf("Download methods : COM:8Bit,NP,1STOP\n");
Uart_Printf("\nSTATUS : ");
rINTMSK=BIT_ALLMSK;
tmp=RdURXH0(); //To remove overrun error state.
i=0;
while(i<fileSize)
{
while(!(rUTRSTAT0&0x1));
*(downPt+i)=RdURXH0();
if(i==3)
{
fileSize=*((U8 *)(downloadAddress+0))+
(*((U8 *)(downloadAddress+1))<<8)+
(*((U8 *)(downloadAddress+2))<<16)+
(*((U8 *)(downloadAddress+3))<<24);
}
if((i%1000)==0)
WrUTXH0('#');
i++;
}
downloadProgramSize=fileSize-6;
for(i=4;i<(fileSize-2);i++)
{
checkSum+=*((U8 *)(i+downloadAddress));
}
dnCS=*((U8 *)(downloadAddress+fileSize-2))+
(*( (U8 *)(downloadAddress+fileSize-1) )<<8);
if(checkSum!=dnCS)
{
Uart_Printf("Checksum Error!!! MEM : %x DN : %x\n",checkSum,dnCS);
return 0;
}
Uart_Printf("\nDownload O.K.\n");
return 1;
}
void Download_Nor(void)
{
int i=0,whichFlash;
char key;
Uart_Printf("\n[ NOR Flash Memory Writer Ver 0.1 ]\n\n");
Uart_Printf("The program buffer : 0x31000000 ~ 0x33ff0000\n");
downloadAddress=0x31000000;
downloadProgramSize=0x0;
//MMU_Init();
ChangeRomCacheStatus(RW_NCNB);
while(1)
{ //display menu
Uart_Printf("%c : %s",'a'+i,flashType[i][1]);
i++;
if((int)(flashType[i][0])==0)
{
Uart_Printf("\n");
break;
}
if((i%4)==0)
Uart_Printf("\n");
}
Uart_Printf("Select the type of a flash memory ? ");
whichFlash=Uart_Getch()-'a';
Uart_Printf("%c\n",(whichFlash+'a'));
//Uart_Printf("\n");
if( i<0 || (i>=(sizeof(flashType)/8)) )
return;
Uart_Printf("Do you want to download through UART0 from 0x%x? [y/n] : ",downloadAddress);
key=Uart_Getch();
Uart_Printf("%c\n",key);
if(key=='y')
{
if(!DownloadData())
return;
}
( (void (*)(void))(flashType[whichFlash][0]) )();
}
void Download_Nand(void)
{
U8 data[512];
U8 i, flag;
U8* ptr;
Uart_Printf("To Program Bootloader To Nand Flash:\n");
downloadAddress=0x31000000;
downloadProgramSize=0x0;
if(!DownloadData())
return;
Uart_Printf("Start to program...\n");
NF_ReadPage(0, 8, data);
flag=NF_EraseBlock(0);
if(flag!=1)
{
Uart_Printf("Error while erase block 0 in nand flash.\n");
return;
}
ptr=(U8*)downloadAddress;
for(i=0; i<8; i++)
{
flag=NF_WritePage(0, i, ptr, NULL);
if(flag!=1)
{
Uart_Printf("Error while program page %d in nand flash.\n", i);
return;
}
ptr+=512;
}
flag=NF_WritePage(0, 8, data, NULL);
if(flag!=1)
{
Uart_Printf("Error while program page %d in nand flash.\n", i);
return;
}
Uart_Printf("Bootloader has been programmed to nand flash.\n");
}
void Download_OS(void)
{
char* mode;
#if USBDMA
mode="DMA";
#else
mode="Int";
#endif
Uart_Printf("\n\n");
Uart_Printf("+---------------------------------------------+\n");
Uart_Printf("| S3C2410X USB Downloader ver R1.12 05/20/03 |\n");
Uart_Printf("+---------------------------------------------+\n");
Uart_Printf("FCLK=%dMHz,%s mode\n",FCLK/1000000,mode);
Uart_Printf("USB: IN_ENDPOINT:1 OUT_ENDPOINT:3\n");
Uart_Printf("FORMAT: <ADDR(DATA):4>+<SIZE(n+10):4>+<DATA:n>+<CS:2>\n");
Uart_Printf("NOTE: 1. Power off/on or press the reset button for 1 sec\n");
Uart_Printf(" in order to get a valid USB device address.\n");
Uart_Printf(" 2. For additional menu, Press any key. \n");
Uart_Printf("\n");
download_run=1; //The default menu is the Download & Run mode.
//while(UsbFinish)
UsbDownload();
}
void UsbDownload(void)
{
U32 i, flag;
//U32 page, block;
U32 block;
U32 j;
U16 cs;
U32 temp;
U16 dnCS;
int first=1;
float time;
U8 tempMem[16];
U8 key;
U8* ptr;
checkSum=0;
downloadAddress=(U32)tempMem; //_RAM_STARTADDRESS;
downPt=(unsigned char *)downloadAddress;
//This address is used for receiving first 8 byte.
downloadFileSize=0;
#if 0
MMU_DisableICache();
//For multi-ICE.
//If ICache is not turned-off, debugging is started with ICache-on.
#endif
/*******************************/
/* Test program download */
/*******************************/
j=0;
if(isUsbdSetConfiguration==0)
{
Uart_Printf("USB host is not connected yet.\n");
}
while(downloadFileSize==0)
{
if(first==1 && isUsbdSetConfiguration!=0)
{
Uart_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 ...."
}
}
Timer_InitEx();
Timer_StartEx();
#if USBDMA
rINTMSK&=~(BIT_DMA2);
ClearEp3OutPktReady();
// indicate the first packit is processed.
// has been delayed for DMA2 cofiguration.
if(downloadFileSize>EP3_PKT_SIZE)
{
if(downloadFileSize<=(0x80000))
{
ConfigEp3DmaMode(downloadAddress+EP3_PKT_SIZE-8,downloadFileSize-EP3_PKT_SIZE);
//wait until DMA reload occurs.
while((rDSTAT2&0xfffff)==0);
//will not be used.
rDIDST2=(downloadAddress+downloadFileSize-EP3_PKT_SIZE);
rDIDSTC2=(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(0);
}
else
{
ConfigEp3DmaMode(downloadAddress+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE);
//wait until DMA reload occurs.
while((rDSTAT2&0xfffff)==0);
if(downloadFileSize>(0x80000*2))//for 1st autoreload
{
rDIDST2=(downloadAddress+0x80000-8); //for 1st autoreload.
rDIDSTC2=(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(0x80000);
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L=0xff;
rEP3_DMA_TTC_M=0xff;
rEP3_DMA_TTC_H=0xf;
}
}
else
{
rDIDST2=(downloadAddress+0x80000-8); //for 1st autoreload.
rDIDSTC2=(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(downloadFileSize-0x80000);
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L=0xff;
rEP3_DMA_TTC_M=0xff;
rEP3_DMA_TTC_H=0xf;
}
}
}
totalDmaCount=0;
}
else
{
totalDmaCount=downloadFileSize;
}
#endif
if(downloadAddress==0)
{
downloadAddress=0x30040000;
}
Uart_Printf("\nNow, Downloading [ADDRESS:%xh,TOTAL:%d]\n",
downloadAddress,downloadFileSize);
Uart_Printf("RECEIVED FILE SIZE:%8d",0);
#if USBDMA
j=0x10000;
while(1)
{
if( (rDCDST2-(U32)downloadAddress+8)>=j)
{
Uart_Printf("\b\b\b\b\b\b\b\b%8d",j);
j+=0x10000;
}
if(totalDmaCount>=downloadFileSize)break;
}
#else
j=0x10000;
while(((U32)downPt-downloadAddress)<(downloadFileSize-8))
{
if( ((U32)downPt-downloadAddress)>=j)
{
Uart_Printf("\b\b\b\b\b\b\b\b%8d",j);
j+=0x10000;
}
}
#endif
time=Timer_StopEx();
Uart_Printf("\b\b\b\b\b\b\b\b%8d",downloadFileSize);
Uart_Printf("(%5.1fKB/S,%3.1fS)\n",(float)(downloadFileSize/time/1000.),time);
#if USBDMA
/*******************************/
/* Verify check sum */
/*******************************/
Uart_Printf("Now, Checksum calculation\n");
cs=0;
i=(downloadAddress);
j=(downloadAddress+downloadFileSize-10)&0xfffffffc;
while(i<j)
{
temp=*((U32 *)i);
i+=4;
cs+=(U16)(temp&0xff);
cs+=(U16)((temp&0xff00)>>8);
cs+=(U16)((temp&0xff0000)>>16);
cs+=(U16)((temp&0xff000000)>>24);
}
i=(downloadAddress+downloadFileSize-10)&0xfffffffc;
j=(downloadAddress+downloadFileSize-10);
while(i<j)
{
cs+=*((U8 *)i++);
}
checkSum=cs;
#else
//checkSum was calculated including dnCS. So, dnCS should be subtracted.
checkSum=checkSum - *((unsigned char *)(downloadAddress+downloadFileSize-8-2))
- *( (unsigned char *)(downloadAddress+downloadFileSize-8-1) );
#endif
dnCS=*((unsigned char *)(downloadAddress+downloadFileSize-8-2))+
(*( (unsigned char *)(downloadAddress+downloadFileSize-8-1) )<<8);
if(checkSum!=dnCS)
{
Uart_Printf("Checksum Error!!! MEM:%x DN:%x\n",checkSum,dnCS);
UsbFinish=0;
return;
}
Uart_Printf("Download O.K.\n\n");
Uart_TxEmpty(consoleNum);
if(download_run==1)
{
rINTMSK=BIT_ALLMSK;
}
//Uart_Printf("Download Completely.\n");
Uart_Printf("Please select the operation.\n");
Uart_Printf("1. Program to Nand Flash 2. Run program\n");
key=Uart_Getch();
if(key=='1')
{
ptr=(U8*)downloadAddress;
Uart_Printf("Erase Block at first.\n");
for(i=0; i<2016; i++)
{
flag=NF_EraseBlock(i+1);
if(flag!=1)
{
Uart_Printf("Erase bad block %d.\n\n\n", (i+1));
}
}
Uart_Printf("Start to program nand flash.\n\n\n");
for(i=0; i<2016; i++)
{
block=i+1;
Uart_Printf("Program block %d.\n", block);
for(j=0; j<32; j++)
{
NF_WritePage(block, j, ptr, NULL);
ptr+=512;
}
}
}
else if(key=='2')
{
Uart_Printf("Start to run program.\n\n\n");
run=(void (*)(void))downloadAddress;
run();
}
UsbFinish=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -