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

📄 2440loader-8bit.c

📁 三星arm9 cpu s3c2440a bootloader
💻 C
字号:
/************************************************
 * NAME    : 2440loader.c
 * DESC    : 
 * History : 2002.02.25 ver 0.0
 * rev0.1  : 2003. 05.xx modified for 2440
 * rev0.2  : 2004. 02.xx modified for 2440A(xtal 16.9344MHz)
************************************************/

#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440slib.h"
#include "Nand.h"
//#include "mmu.h"

// Downfile Size, OS Start Address Offset, Core voltage, download address setting
#if 1
#ifdef DOWNFILE_SIZE
#define OS_IMAGE_BLOCK_SIZE ( ((DOWNFILE_SIZE/512)/32) +1 )
#else 
#define OS_IMAGE_BLOCK_SIZE (0x7b0)	// blocks
//#define OS_IMAGE_BLOCK_SIZE (0x800)	// blocks
//#define OS_IMAGE_BLOCK_SIZE (700)	// blocks
#endif

#ifndef OS_START_ADDR_OFFSET
#define	OS_START_ADDR_OFFSET (0x00200000)		// 0x3020_0000
#endif
//PPC2003 offset	(0x02040000)
//WINCE	offset		(0x00040000)
//Firmware offset	(0x00000000)


#ifndef	COREVOLT_M100
#define	COREVOLT_M100	(120)	// value = voltage(0.8V ~ 1.3V)x100. -> 100->1.0V
#endif

#define DOWNLOAD_ADDRESS (_RAM_STARTADDRESS+OS_START_ADDR_OFFSET)

#else
#define OS_IMAGE_BLOCK_SIZE (0x7b0)	// blocks
#define	OS_START_ADDR_OFFSET (0x02040000)		// 0x3204_0000
#define	COREVOLT_M100	(135)	// value = voltage(0.8V ~ 1.3V)x100. -> 100->1.0V
#define DOWNLOAD_ADDRESS (_RAM_STARTADDRESS+OS_START_ADDR_OFFSET)
#endif

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

void Port_Init(void);
void Led_Display(int);
void Delay(int);

volatile unsigned char *downPt;

void Timer4_Start(void);
void Timer4_Stop(void);
char *hex2char(int val);

void Set_Pre(void);	// for current test


void Main(void)
{
    register page, block, blockcopy_count;
    int i, j;

    MMU_EnableICache();
	
//   	ChangeClockDivider(12,12);	// 1:2:4
//  	ChangeClockDivider(13,12);	// 1:3:6
// 	ChangeClockDivider(14,12);	// 1:4:8
//	ChangeMPllValue(88, 1, 1);	// FCLK=192MHz
//	ChangeMPllValue(246, 13, 0); 	// FCLK=203.2MHz
//	ChangeMPllValue(92, 1, 0); 	// FCLK=400MHz
//	ChangeMPllValue(214, 3, 0);	// FCLK=532MHz


    	Port_Init();

    	Uart_Init(PCLK, 115200);
    	Uart_Select(1);
	
    	downPt=(unsigned char *)DOWNLOAD_ADDRESS;

 	// GPA    22         21         20     19      18    17
	//         nFCE   nRSTOUT  nFRE  nFWE  ALE  CLE
    	rGPACON = (rGPACON &~(0x3f<<17)) | (0x3f<<17);
	
    	NF8_Init();
  


  	Max1718_Set(COREVOLT_M100);	// ex)120:1.2V

  	Led_Display(1);

	// To calculation copy time.
     	Timer4_Start();
	
    	block=0;
    	blockcopy_count=0;
    	while(blockcopy_count<(OS_IMAGE_BLOCK_SIZE)) {		 // Read OS image
		block++;
		if(!NF8_IsBadBlock(block))  continue;      // Skip bad block
		blockcopy_count++;
		for(page=0;page<32;page++) {  // Read 32 page
			if(!NF8_ReadPage(block, page, (U8 *)downPt)) {  //(U32 block,U32 page,U32 *buffer)
			 Led_Display(0x8);   // real ECC Error
			 while(1);
			}
	  	downPt += 512;	
             }
	}
   	 Led_Display(0xf);
 
    	Timer4_Stop();

    	Set_Pre();

	//rCLKCON = (0x0<<16)|(0x6<<12)|(0x9<<8)|(0x2<<4);	// for test
	//Uart_SendString(" Setting CLKCON]\n");

    	run();
	
}


#define TIMER_IINIT_VAL	(0xffff)

void Timer4_Start(void)
{
    Uart_SendString("\n\nNAND Boot Start\n");
    
    rTCFG0=0xff00;		// Prescaler 0xff+1(256)
    rTCFG1=(0x3<<16);	//T4=PCLK period*256*16 = 
    rTCNTB4=TIMER_IINIT_VAL;
    rTCON=(1<<22)|(1<<21);  //Manual update, to validate TCNTB4 value.
    rTCON=(1<<22)|(1<<20);  //Start T4
}

void Timer4_Stop(void)
{
    int cnt;
	
	rTCON=(1<<22)|(0<<20);  //Stop T4
    cnt=TIMER_IINIT_VAL-rTCNTO4;	// actual count number

    Uart_SendString("NAND Boot End\n");
    Uart_SendString("Boot time=nTCNT*82uS. nTCNT=0x");
    Uart_SendString(hex2char((cnt&0xf000)>>12));
    Uart_SendString(hex2char((cnt&0x0f00)>>8));
    Uart_SendString(hex2char((cnt&0x00f0)>>4));
    Uart_SendString(hex2char((cnt&0x000f)>>0));
	Uart_SendString(". \n");
	
}


char *hex2char(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 Set_Pre(void)
{

	int i;

	i = rGPDCON; 

	rGPDCON = (rGPFCON & ~(3<<4)) | (0<<4);
	if((rGPFDAT&(1<<2))==0) {    // If EINT2 key is pressed.
		Uart_SendString("I/O Strength Max\n");
		// Set I/O strength control.
		rDSC0 = (0<<31)|(0<<8)|(0<<0);
		rDSC1 = (0<<28)|(0<<26)|(0x000000<<0);
	} else {
		Uart_SendString("I/O Strength Min\n");
		// Set I/O strength control.
		rDSC0 = (0<<31)|(3<<8)|(3<<0);
		// nEN_DSC  [31]    : 0:I/O drive strength enable, 1:Disable
		// DSC_ADR  [9:8]   : Addr drive strength, 0:10mA, 1:8mA, 2:6mA, 3:4mA
		// DSC_DATA [7:0]   : DATA drive strength, 0:12mA, 1:10mA, 2:8mA, 3:6mA
		
		rDSC1 = (3<<28)|(3<<26)|(0xffffff<<0);
		// DSC_SCK1 [29:28] : SCLK1, 0:16mA, 1:12mA, 2:8mA, 3:6mA 
		// DSC_SCK0 [27:26] : SCLK0, 0:16mA, 1:12mA, 2:8mA, 3:6mA 
		// DSC_SCKE [25:24] : SCLKE, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_SDR  [23:22] : nRAS/nCAS, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_NFC  [21:20] : Nand flash(nFCE,nFRE,nFWE,CLE,ALE), 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_BE   [19:18] : nBE[3:0], 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_WOE  [17:16] : nBE[3:0], 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS7  [15:14] : nGCS7, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS6  [13:12] : nGCS6, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS5  [11:10] : nGCS5, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS4  [9:8]   : nGCS4, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS3  [7:6]   : nGCS3, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS2  [5:4]   : nGCS2, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS1  [3:2]   : nGCS1, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS0  [1:0]   : nGCS0, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
	
		}
	rGPDCON = i;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -