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

📄 main.c

📁 飞思卡尔imx27 wince5.0 bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * MX2 only support 16MHz output        
	 * PerCLK1(31.99998691MHz)/UFCR[RFDIV] (2)= 15.99999673MHz      
	 */
	_reg_UFCR = 0x0a01;		//PerCLK1/2=33.25/2=16.625/2=8.3125M

	_reg_UTS = 0x0000;	/* clear loopback bit */

	_reg_UBIR = 837;

	_reg_UBMR = 9999;	/* configure UBMR */

}

/*
 * Mask to check receive data ready
 */
#define RDR_MASK    0x0001

U8 mxc_uart_dataready(void)
{
	//mxc_wd_reset();
	return _reg_USR2 & RDR_MASK;	/* check RDR bit */
}

/*!
 * This function gets data from UART. It is used to read character by 
 * character of the options and data received by the UART
 *
 * @result      It returns the character received by the UART
 *
 */
U8 mxc_uart_getdata(void)
{
	/* wait until RDR bit set */
	while (!mxc_uart_dataready()) {
		//mxc_wd_reset();
		/* Do nothing */
	}

	return (U8) _reg_URXD;
}

void mxc_uart_putdata(U8 data)
{
	/* wait until TXFE bit set */
	while (!(_reg_USR2 & TXFE_MASK)) {
		/* Do nothing */
	}

	/* write the data to the TX register */
	_reg_UTXD = (U16) data;
	/* if carriage return, append line-feed */

	if (data == '\n') {
		/* wait until TXFE bit set */
		while (!(_reg_USR2 & TXFE_MASK)) {
			/* Do nothing */
		}

		_reg_UTXD = '\r';
	}
}


/*!
 * This function sends hex data to UART. It takes 32 bit integer data, 
 * converts it into ascii characters and sends it to UART.
 *
 * @param       hex_data                hex data to send to UART
 *
 */
void mxc_uart_puthex(U32 hex_data)
{
	U32 data;
	int i;
	for (i = 7; i >= 0; i--) {

		/* 
		 * Shift nibble at i+1 position to last position and 
		 * AND it with 0xF 
		 */
		data = (hex_data >> 4 * i) & 0xF;

		if (data > 9) {
			data += 'A' - 0xa;	/* hex a to f to ascii 'A' to 'F' */
		} else {
			data += '0';	/* hex 0 to 9 to ascii '0' to '9' */
		}

		mxc_uart_putdata(data);	/* send to UART */
	}
}


void mxc_uart_putstring(U8 * line)
{
	while (*line) {
		mxc_uart_putdata(*(line++));
	}
}

/* Maximum length of the string */
#define MAX_STRLEN	150

/*!
 * This function gets a string data from UART. It reads character by character
 * using \b mxc_uart_getdata() function. It takes char pointer as a parameter
 * where the characters of the string are copied
 *
 * @param       str     pointer to string data received by UART
 *
 * @return      This function returns the size of the string read from UART.
 *
 */
int mxc_uart_getstring(U8 * str)
{
	U8 ch;
	int i = 0;		/* counter for size */

	/* 
	 * loop until carriage return is pressed or MAX_STRLEN has reached 
	 */
	do {

		/* wait for key press */
		while (!mxc_uart_dataready()) {
			/* Do nothing */
		}

		/* read the character received by UART */
		ch = mxc_uart_getdata();

		/* check if not carriage return */
		if (ch != '\r') {
			/* check if back space */
			if (ch == '\b') {
				if (i > 0) {
					/* erase the character */
					mxc_uart_putdata('\b');
					mxc_uart_putdata(' ');
					mxc_uart_putdata('\b');
					str--;
					*str = 0;
					i--;
				}
			} else {
				mxc_uart_putdata(ch);
				*(str++) = ch;
				i++;
			}
		}
	} while ((ch != '\r') && (i < MAX_STRLEN - 1));

	/* if and character is typed */
	if (i > 0) {
		*(str++) = 0;	/* mark end of string */
	}

	return i;		/* Size of string */
}

void uarttest(void)
{
	mxc_uart_init();
      // mxc_uart_putstring("gary 0329 \n");
	mxc_uart_putdata('h');
    	mxc_uart_putdata('e');
    	mxc_uart_putdata('l');
    	mxc_uart_putdata('l');
    	mxc_uart_putdata('o');
    	mxc_uart_putdata('!');
    	mxc_uart_putdata('\n'); 
}


/*!
 * This function reads hex data from UART and stores at the char pointer 
 * passed as a parameter.
 *
 * @param       str             pointer which points to ascii hex data
 *
 * @return  This function returns -1 if incorrect hex data is entered or the 
 * correct hex value entered.
 * 
 */
int mxc_uart_gethex(U8 * str)
{
	int size, i = 0;
	U32 addr = 0;
	U8 tmp;
	/* get the ascii hex string from UART */
	size = mxc_uart_getstring(str) - 1;
	/* hex value cannot be greater than 4 bytes or 8 nibbles */
	if (size <= 7) {
		do {

			tmp = 0;
			if (str[size - i] >= '0' && str[size - i] <= '9') {
				tmp = str[size - i] - '0';
			} else {
				if (str[size - i] >= (int)'a'
				    && str[size - i] <= (int)'f') {
					tmp = (str[size - i] - 'a') + 0xa;
				} else {
					if (str[size - i] >= (int)'A'
					    && str[size - i] <= (int)'F') {
						tmp = (str[size - i] - 'A') +
						    0xa;
					} else {
						/* error if not ascii hex */
						return -1;
					}
				}
			}
			addr |= (tmp << (4 * i));
			i++;
		} while ((size - i) >= 0);
	} else {
		return -1;	/* error if more than 8 ascii hex */
	}

	return addr;
}

/*!
 * This function is used for unit test of UART functions. It will be included
 * in the code only if UNIT_TEST is enabled.
 */
void mxc_uart_unit_test(void)
{
	/* U8* str = "Enter data: "; */
	U8 *test_str = (U8 *)"Enter data: ";//(U8 *) DEBUG_ADDR3;
	U32 hex;
	int i;

	mxc_uart_init();
	/* to test 'mxc_uart_putdata' function */
//for (i=0; i<10; i++) {
	mxc_uart_putdata(0x1);	
	mxc_uart_putstring((U8 *)"\nYou entered ha ha ha hello word chianse 16bit nfc internal sram size \n\n");
	mxc_uart_putstring((U8 *)"\nFunctional Muxing Control Reg 16bit nfc block addr for lock chk 16bit nfc buffer number \n\n");
	//mxc_uart_putdata('o');
	//mxc_uart_putdata('!');
	//mxc_uart_putdata('\n');
//}
	/* to test 'mxc_uart_putstring' function */
	//mxc_uart_putstring((U8 *)"\nEnter test data: ");
#if 0
	/* to test 'mxc_uart_getdata' and 'mxc_uart_getstring' */
	mxc_uart_getstring(test_str);
	printf("string: %s\n", test_str);
	/* reprint the string entered */
	mxc_uart_putstring((U8 *)"\nYou entered: ");
	mxc_uart_putstring((U8 *)test_str);
	printf("string1: %s\n", test_str);
	/* to test 'mxcb_uart_gethex' and mxcb_uart_puthex' */
	mxc_uart_putstring((U8 *)"\nEnter 4 bytes hex value: 0x");
	hex = mxc_uart_gethex(test_str);

	/* reprint the hex value entered */
	if (hex != -1) {
		mxc_uart_putstring((U8 *)"\n0x");
		mxc_uart_puthex(hex);
	} else {
		mxc_uart_putstring((U8 *)"\nIncorrect hex value");
	}
#endif
}

////////////////////////////////////////////////////////////////////
//nand test
////////////////////////////////////////////////////////////////////
#define SYS_BASE_ADDR            0x10027800
#define _reg_SYS_FMCR	(*((volatile unsigned long *)(SYS_BASE_ADDR+0x14)))  //  Functional Muxing Control Reg

#define NFC_BASE_ADDR            0xD8000000
#define NFC_REG_BASE                             (NFC_BASE_ADDR+0xE00)	//  register area (3E00 - 3E1C)   
#define _reg_NFC_BUFSIZE		          (*((volatile unsigned short *)(NFC_REG_BASE+0x00)))	//  16bit nfc internal sram size      
#define _reg_NFC_BLK_ADD_LOCK	          (*((volatile unsigned short *)(NFC_REG_BASE+0x02)))	//  16bit nfc block addr for lock chk 
#define _reg_NFC_RAM_BUF_ADDR	          (*((volatile unsigned short *)(NFC_REG_BASE+0x04)))	//  16bit nfc buffer number           
#define _reg_NFC_NAND_FLASH_ADDR     (*((volatile unsigned short *)(NFC_REG_BASE+0x06)))	//  16bit nfc nand flash address      
#define _reg_NFC_NAND_FLASH_CMD	    (*((volatile unsigned short *)(NFC_REG_BASE+0x08)))	//  16bit nfc nand flash command      
#define _reg_NFC_CONFIGURATION	    (*((volatile unsigned short *)(NFC_REG_BASE+0x0A)))	//  16bit nfc internal buf lock ctrl  
#define _reg_NFC_ECC_STAT_RES	           (*((volatile unsigned short *)(NFC_REG_BASE+0x0C)))	//  16bit nfc controller status/result
#define _reg_NFC_ECC_RSLT_MA		    (*((volatile unsigned short *)(NFC_REG_BASE+0x0E)))	//  16bit nfc ecc err position in main
#define _reg_NFC_ECC_RSLT_SA		    (*((volatile unsigned short *)(NFC_REG_BASE+0x10)))	//  16bit nfc ecc err pos in spare    
#define _reg_NFC_NF_WR_PROT		    (*((volatile unsigned short *)(NFC_REG_BASE+0x12)))	//  16bit nfc write protection        
#define _reg_NFC_ULOCK_START_BLK	    (*((volatile unsigned short *)(NFC_REG_BASE+0x14)))	//  16bit nfc start unlock location   
#define _reg_NFC_ULOCK_END_BLK	    (*((volatile unsigned short *)(NFC_REG_BASE+0x16)))	//  16bit nfc end unlock location     
#define _reg_NFC_NF_WR_PROT_STAT	    (*((volatile unsigned short *)(NFC_REG_BASE+0x18)))	//  16bit nfc write protection status 
#define _reg_NFC_NF_CONFIG1		    (*((volatile unsigned short *)(NFC_REG_BASE+0x1A)))	//  16bit nfc configuration 1         
#define _reg_NFC_NF_CONFIG2		    (*((volatile unsigned short *)(NFC_REG_BASE+0x1C)))	//  16bit nfc configuration 2         

#define NFC_MAB3_BASE	(NFC_BASE_ADDR+0x600)	//  main area buffer3 (3600 - 37FE)

#define CONFIG2_SET_FDO_ID() 	  _reg_NFC_NF_CONFIG2=0x10

#define NF_FMS_2KB  0x20
#define NF_FMS_512B 0x00
#define NF_16BIT    0x10
#define NF_8BIT     0x00

#define NAND_FLASH_CONFIG2_INT 	0x8000
#define NAND_FLASH_CONFIG2_FCMD 	0x1
#define NAND_FLASH_CONFIG2_FADD 	0x2
#define NAND_FLASH_CONFIG2_FDI  	0x4

#define ERR_TIME_OUT -1
#define ERR_VERIFY   -2

#define WAIT(condition, timeout_usec) while(condition);

#define NAND_CMD_RESET						0xFFFF
#define NAND_CMD_READ						0x00
#define NAND_CMD_READ_CONFIRM				0x30
#define NAND_CMD_PAGE_PROG					0x80
#define NAND_CMD_PAGE_PROG_CONFIRM_TRUE	0x10
#define NAND_CMD_PAGE_PROG_CONFIRM_DUMMY	0x11 
#define NAND_CMD_BLOCK_ERASE				0x60
#define NAND_CMD_BLOCK_ERASE_CONFIRM	0xD0
#define NAND_CMD_READ_STATUS				0x70
#define NAND_CMD_READ_ID					0x90

#define NAND_FLASH_BLOCK_NUMBER			4096    //	Now PMP(no hdd) use Toshiba 512M Nand Flash TH58NVG2S3BTG
#define NAND_FLASH_PAGE_PER_BLOCK		32
#define NAND_FLASH_PAGE_MAIN_SIZE		512
#define	NAND_FLASH_PAGE_SPARE_SIZE		16	

void nand_init(void)
{
  _reg_SYS_FMCR  &= ~NF_FMS_2KB;    // 512B
  _reg_SYS_FMCR &= ~NF_16BIT;   // 8bit
  
  _reg_CRM_PCDR0  &= ~0x0000F000;
  _reg_CRM_PCDR0  |=  0x00009000;    // NFCDIV: keep even numbers on the NFCDIV to get a clock aligned with the AHB clock edges
  //gary 0329
 //_reg_CRM_PCDR0  |=  0x00007000; 
  
  _reg_CRM_PCCR1 |=  0x00000008;    // Enable NFC


  _reg_NFC_CONFIGURATION = 0x0002; // unlock the internal RAM buffer
  _reg_NFC_NF_CONFIG2    = 0x0000; // clear all operation

  _reg_SYS_FMCR &= ~NF_16BIT;
  _reg_SYS_FMCR &= ~NF_FMS_2KB;
}

void Preset()
{
    // _reg_NFC_CONFIGURATION=0x10; //unlocked first 2 page buffer
                                    //We don't use first 2 page buffer
    _reg_NFC_CONFIGURATION=0x0002;
    _reg_NFC_ULOCK_START_BLK=0;
 //   _reg_NFC_ULOCK_END_BLK=NAND_FLASH_BLOCK_NUMBER-1;

 ///gary 0329
 //_reg_NFC_ULOCK_END_BLK=0x800;
    _reg_NFC_ULOCK_END_BLK=0xFFFF;
 
    _reg_NFC_NF_WR_PROT=0x0004;

//gary 0329
//_reg_NFC_NF_CONFIG1=0x10;		// Mask interrupt
    _reg_NFC_NF_CONFIG1=0x10;	// enable hardware ECC
    _reg_NFC_RAM_BUF_ADDR=0x3;
                      
}

int NAND_Command(U16 command)
{
    _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT;
    
    _reg_NFC_NAND_FLASH_CMD=command;
//    _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_FCMD;
//    _reg_NFC_NF_CONFIG2|=NAND_FLASH_CONFIG2_FCMD;
    _reg_NFC_NF_CONFIG2 = 1;
    
    WAIT((!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)),100000);
   // while((!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)));
    if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT))
        return ERR_TIME_OUT;
    
    return 0;
}

int NAND_SendAddress(U32 addr,int cycle)
{
    int i=0;    
    for(i=0;i<cycle;i++)
    {
		// Send low half-word
		_reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT;

		_reg_NFC_NAND_FLASH_ADDR=(addr>>(i*8))&0xFF;
	 
		_reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_FADD;
		_reg_NFC_NF_CONFIG2|=NAND_FLASH_CONFIG2_FADD;
	
		WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),1000);
		if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT))
	    	return ERR_TIME_OUT;
	}    
    	return 0;
}

// 8bit, K9F1208Q0B,   64MB X 8bit
int NAND_ReadID(U32 * ID)
{
    Preset();
    if(NAND_Command(NAND_CMD_READ_ID))
        return -1;
        
    if(NAND_SendAddress(0x0,1))
        return -1;
        
    //CONFIG1_SET_READ();
    
    _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT;
    _reg_NFC_RAM_BUF_ADDR=0x3;
    
    CONFIG2_SET_FDO_ID();
    
    WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),1000);
    if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT))
        return ERR_TIME_OUT;
    
    *ID=*(volatile U32*)NFC_MAB3_BASE;
    
    return 0;
    
}

///////////////////////////////////////////////////////////////////
//nand test end
///////////////////////////////////////////////////////////////////

void CopytoRAM(void)
{
	volatile unsigned short *src=(volatile unsigned short *)(0xc0000000);
	volatile unsigned short *det=(volatile unsigned short *)(0xb0040000);
	volatile unsigned int length;
	
	for(length=0;length<0x20000;)
	{
		*det=*src;
		if(*det!=*src)
			continue;
		det++;
		src++;
		length++;
	}
	while(1);
}

int main(void)
{
int rc=0;
volatile unsigned short *ROM, *p, dummy;
int cnt;
unsigned short data1;
unsigned int SourceAddress = 0xB1000000;
unsigned int TargetAddress = 0xC0000000;
unsigned int nByte = 256*1024;   //256K bootloader to program into nor flash
unsigned int id;

	printf ("START_TEST\n");
ROM = (unsigned short *)0xC0000000;
ROM[0] = 0x0090;

for (cnt = 200000; cnt > 0; cnt--);

p = ROM;
data1 = *p;

ROM[0] = 0x00FF;
dummy = ROM[0];
   printf("uart test\n");	
 mxc_uart_unit_test();
printf("uart test end\n");
    printf("read ID: 0x%x \n", data1);
//	CopytoRAM();
	//erase nor flash test
	printf ("norflash  test\n");
	norwriteloader();
//	norwritenk();
//	norwriteloaderm();
	while(1);
//flashtest();

printf("nand flash test\n");
	nand_init();
	if(NAND_ReadID(&id))
		printf("read id error!\n");
	else {
		printf("NAND Flash ID: 0x%x\n", id>>24);
		printf("NAND Flash ID: 0x%x\n", id>>16);
		printf("NAND Flash ID: 0x%x\n", id>>8);
		printf("NAND Flash ID: 0x%x\n", id);
	}

//uarttest();
//end
 //     FlashLoader(TargetAddress, SourceAddress, nByte);
// above is read nor flash ID
	// Init timer
//	GPT1Init(500);

//	rc = MEMtest();

//	test_exit(rc);
	
	return rc;
}
void test_exit(int err)
{
	if (err)
	  	printf("TEST FAILED!\n");
	else
	  	printf("\nTEST PASSED!\n");
	
	printf ("END_TEST\n");
	exit (err);
}




⌨️ 快捷键说明

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