⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 S3C2410的bootloader
💻 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 + -