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

📄 main.c

📁 飞思卡尔imx27 wince5.0 bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>


int MEMtest(void);
void test_exit(int err);

typedef unsigned int U32;
typedef unsigned short U16;
typedef unsigned char U8;

//-------------------------------------------------------------------------------------------------------
//norflash code start
//-------------------------------------------------------------------------------------------------------

//Flash commands for a single 16 bit Intel Flash chip
#define INTEL16_READ_ARRAY 		0x00FF
#define INTEL16_ERASE_SETUP		0x0020
#define INTEL16_ERASE_CONFIRM	0x00D0
#define INTEL16_PGM_SETUP		0x0040
#define INTEL16_STATUS_CLEAR	0x0050
#define INTEL16_STATUS_READY	0x0080

#define STATUS_ERASE_ERR		0x0020
#define STATUS_PGM_ERR			0x0010
#define STATUS_VPPLOW_ERR		0x0008
#define STATUS_LOCKED_ERR		0x0002

#define WRITE_ERROR_MASK	(STATUS_PGM_ERR|STATUS_VPPLOW_ERR|STATUS_LOCKED_ERR)
#define ERASE_ERROR_MASK	(STATUS_ERASE_ERR|STATUS_VPPLOW_ERR|STATUS_LOCKED_ERR)

#define INTEL16_CONFIG_SETUP	0x0060
#define INTEL16_STATUS_READ	0x0070
#define INTEL16_UNLOCK_SECTOR	0x00D0

#define TMPL_PROGRAM_TIMEOUT	1000000L
#define _base_flash_address (*((volatile unsigned short *)0xc0000000))

U8 TMPL_WaitUntilReady(U32 timeout);

//read status register
static U16 get_status(void)
{
	U16 status;	
	_base_flash_address=INTEL16_STATUS_READ;	
	status = _base_flash_address;
	return status;
}

//wait until reday
static void wait_ready(void)
{
	while((get_status()&INTEL16_STATUS_READY)==0);
}

//clear status register
static void clear_status(void)
{
	_base_flash_address = INTEL16_STATUS_CLEAR;
}


/* erases a flash block at the given address */
static void do_erase(U16 *addr)
{

	clear_status();

	/* prepare for erase */
	*addr = INTEL16_ERASE_SETUP;

	/* erase block */
	*addr = INTEL16_ERASE_CONFIRM;

	wait_ready();

	/* put flash back into Read Array mode */
	_base_flash_address = INTEL16_READ_ARRAY;

}

//unlock block
static void unlock_block(U16 *baddr)
{

	clear_status();	

	*baddr = INTEL16_CONFIG_SETUP;

	*baddr = INTEL16_UNLOCK_SECTOR;
	
	wait_ready();

	/* return device to read array mode */
	_base_flash_address = INTEL16_READ_ARRAY;
	
	
}




static int erase_all(U16 *cur, U16 *end)
{
	int i = 0;
	
	while (cur < end) {
		if (*cur != 0xffff) {
			do_erase(cur);
			continue;
		}
		cur++;
		if ( (i &= 0xFFFF) ==0)
			printf(".");
		i++;
	}
	return 1;
}


void FlashSectorErase(U32 fAddress, U32 nAddress)
{
	U16 *cur_addr = (U16 *)fAddress;
	U16 *end_addr = (U16 *)nAddress;
	
	switch(fAddress) {
		case 0xc0000000:
			printf("Now erasing at 0xc0000000\n");
			erase_all(cur_addr, end_addr);
			break;
		default:
			printf("address error!\n");
			return;
	}
	printf("\nFlash erase complete!\n");
	return;
}

/* write a flash block at a given location */
static void do_write(U16 *dst, const U16* src)
{
	clear_status();

	/* setup flash for writing */
	*dst = INTEL16_PGM_SETUP;

	/* write data */
	*dst = *src;
	//printf("src = 0x%x, dst = 0x%x\n", *src, *dst);

	/* status check */
	wait_ready();
	//printf("status = 0x%x\n", status);

	/* put flash back into Read Array mode */
	_base_flash_address = INTEL16_READ_ARRAY;
	//printf("dst = 0x%x\n", *dst);
}


///@brief	This function programs data into flash memory. It is 
///			assumed that the memory has been erased before calling
///			this function.
///
///@param	dst		start address for write
///@param	src		data to write
///@param	nwords	number of words to write
///                  
///@return	void
void FlashWrite(U16 *dst, const U16 *src, U32 nwords)
{
	U32 i = 0, nskip = 0, nwrite = 0;

	printf("Now writing flash.  \n");

       while (i < nwords) {
	   	//nothing to write
		if (dst[i] == src[i]) {	
			i++;   
			nskip++;
			continue;
		}

		//different, so write to this location
		do_write(&dst[i], &src[i]);
		nwrite++;
		i++;

        if( (i&0xFFFF) == 0 )
            printf("P");
	}
	printf("\nFlash Write Complete\n");
 	return;
}

// ***************************************************************************
//
//  Function:       FlashVerify                  
//
//  Parameters:     U32       rAddress        RAM starting address 
//				U32		fAddress		Flash starting address to be verified
//                  	U32		nWords		number of words to check
//
//  Return Value:   U32		Errors		number of programming errors in word             
//
// ***************************************************************************
U32	FlashVerify(U32 fAddress, U32 rAddress, U32 nWords)
{
	U32		i;
	U32		Errors = 0;
	U16*	fWalk = (U16*)fAddress;
	U16*	rWalk = (U16*)rAddress;
	U32		nAddress;
	
	nAddress = fAddress + (nWords - 1) * sizeof(*fWalk);
	printf("Flash Verifing at [0x%08X - 0x%08X]...\n", fAddress, nAddress);
	
	for (i = 0; i < nWords;i++)
	{ 
		if (*fWalk != *rWalk)
		{
			printf("Programming Error at 0x%08X\n", (U32)fWalk);
			Errors++;	
		}
		else
			if ((i & 0xFFFF) == 0)
				printf("S");
			
		fWalk++;
		rWalk++;
	}
	return Errors;
}


U8 TMPL_WaitUntilReady(U32 timeout)
{
	U16 status;

	while(timeout)
	{
		_base_flash_address =   INTEL16_STATUS_READ;
		status = _base_flash_address;
		
		if ((status & 0x0080) == 0x0080)
			return 1;
		
		timeout--;
	}

	return 0;
}

void FlashUnlockAllBlocks(void)
{
	int stat;
	U16 status;

	_base_flash_address = INTEL16_STATUS_CLEAR;	

	_base_flash_address = INTEL16_CONFIG_SETUP;

	_base_flash_address = INTEL16_UNLOCK_SECTOR;

	if ( !TMPL_WaitUntilReady(TMPL_PROGRAM_TIMEOUT))
		stat = -1;
	else
		stat = 1;

	_base_flash_address =   INTEL16_STATUS_READ;
	status = _base_flash_address;
}

// ***************************************************************************
//
//  Function:       FlashLoader
//
//  Parameters:     U32		rAddress        RAM starting address
//				U32		fAddress		Flash starting address to be programmmed
//                  	U32		nByte		number of bytes to write           
//
// ***************************************************************************
void FlashLoader(U32 fAddress, U32 rAddress, U32 nByte)
{
		U32	nAddress;
		U32	Errors;
		U32 nWords;
		
		printf("\nStarting Flash Programming\n");
		nWords = (nByte)/2;
		printf("nWords = 0x%x\n", nWords);
		//nAddress = fAddress + (nWords - 1)*2;
		nAddress = fAddress + nByte;
 
		FlashUnlockAllBlocks();

		FlashSectorErase(fAddress, nAddress);
		FlashWrite((U16*)fAddress, (U16*)rAddress, nWords);
		Errors = FlashVerify(fAddress, rAddress, nWords);
		
		if (Errors)
		{
			printf("\nFlash Programming Error:\n");
			printf("Total Errors: %d words\n",Errors);
		}
		else
		{
			printf("\nFlash Programming Complete\n");
		}
		return;
}





void norwriteloader(void)
{
	U16 *cur_addr=((U16*)0xC0000000);
	U16 *buf=((U16*)0xa0040000);
		
	
	//unlock
	unlock_block(cur_addr);
	unlock_block(cur_addr+0x4000);
	unlock_block(cur_addr+(0x4000*2));
	unlock_block(cur_addr+(0x4000*3));
	unlock_block(cur_addr+(0x4000*4));
	
	//erase 
	//erase block 0	
	do_erase(cur_addr);	
	printf("erase 0 ok\n");

	do_erase(cur_addr+0x4000);
	printf("erase 1 ok\n");
	

	do_erase(cur_addr+(0x4000*2));
	printf("erase 2 ok\n");
	

	do_erase(cur_addr+(0x4000*3));
	printf("erase 3 ok\n");
	
	
	do_erase(cur_addr+(0x4000*4));
	printf("erase 4 ok\n");
	
	
		
	printf("cur_addr=0x%x\n",cur_addr);	
	FlashWrite(cur_addr,buf,0x20000);
}

void norwriteloaderm(void)
{
	U16 *cur_addr=((U16*)0xC0040000);
	U16 *buf=((U16*)0xb0040000);
	int i;	
	
	//unlock
	unlock_block(cur_addr);
	unlock_block(cur_addr+1);
	
	do_erase(cur_addr);	
	printf("erase 0 ok\n");

	do_erase(cur_addr+1);
	printf("erase 1 ok\n");
		
	printf("cur_addr=0x%x\n",cur_addr);	
	FlashWrite(cur_addr,buf,0x20000);
}


void norwritenk(void)
{
	U16 *cur_addr=((U16*)0xC0040000);
	U16 *buf=((U16*)0xb0200000);
	int i;	
	
	//unlock
	for(i=0;i<126;i++)
	{
		unlock_block(cur_addr+(i*0x20000));
		printf("one 0x%d block\n",i);
	}
	for(i=0;i<126;i++)
	{
		unlock_block(cur_addr+1+(i*0x20000));
		printf("two 0x%d block\n",i);
	}
	
	//erase 
	for(i=0;i<126;i++)
	{
		do_erase(cur_addr+(i*0x20000));
		printf("erase one 0x%d block\n",i);
	}
	for(i=0;i<126;i++)
	{
		do_erase(cur_addr+1+(i*0x20000));
		printf("erase two 0x%d block\n",i);
	}
		
	printf("cur_addr=0x%x\n",cur_addr);	
	FlashWrite(cur_addr,buf,(0x1F00000/2));
}


void flashtest(void)
{
	FlashUnlockAllBlocks();
	FlashSectorErase(0xC0000000, 0xC1000000);
}

#define MXC_UART1_BASE		0x1000a000
#define MXC_UART2_BASE		0x1000b000
#define MXC_UART3_BASE		0x1000c000

#define MXC_UART_BASE         MXC_UART1_BASE
/*
 * This defines the addresses for UART registers for 16 bit access 
 */
#define _reg_URXD       (*((volatile U32 *)(MXC_UART_BASE+0x00)))
#define _reg_UTXD       (*((volatile U32 *)(MXC_UART_BASE+0x40)))
#define _reg_UCR1       (*((volatile U32 *)(MXC_UART_BASE+0x80)))
#define _reg_UCR2       (*((volatile U32 *)(MXC_UART_BASE+0x84)))
#define _reg_UCR3       (*((volatile U32 *)(MXC_UART_BASE+0x88)))
#define _reg_UCR4       (*((volatile U32 *)(MXC_UART_BASE+0x8C)))
#define _reg_UFCR       (*((volatile U32 *)(MXC_UART_BASE+0x90)))
#define _reg_USR1       (*((volatile U32 *)(MXC_UART_BASE+0x94)))
#define _reg_USR2       (*((volatile U32 *)(MXC_UART_BASE+0x98)))
#define _reg_UESC       (*((volatile U32 *)(MXC_UART_BASE+0x9C)))
#define _reg_UTIM       (*((volatile U32 *)(MXC_UART_BASE+0xA0)))
#define _reg_UBIR       (*((volatile U32 *)(MXC_UART_BASE+0xA4)))
#define _reg_UBMR       (*((volatile U32 *)(MXC_UART_BASE+0xA8)))
#define _reg_UBRC       (*((volatile U32 *)(MXC_UART_BASE+0xAC)))
#define _reg_UTS       (*((volatile U32 *)(MXC_UART_BASE+0xB4)))

#define CRM_BASE_ADDR	0x10027000
#define _reg_CRM_CSCR	(*((volatile unsigned long *)(CRM_BASE_ADDR+0x00)))	/*  32bit Clock Source Control Reg */
#define _reg_CRM_MPCTL0	(*((volatile unsigned long *)(CRM_BASE_ADDR+0x04)))	/*  32bit MCU PLL Control0 Reg      */
#define _reg_CRM_MPCTL1	(*((volatile unsigned long *)(CRM_BASE_ADDR+0x08)))	/*  32bit MCU PLL Control1 Reg      */
#define _reg_CRM_PCDR0	(*((volatile unsigned long *)(CRM_BASE_ADDR+0x18)))	/*  32bit Serial Perpheral Clk Div Reg */
#define _reg_CRM_PCDR1	(*((volatile unsigned long *)(CRM_BASE_ADDR+0x1C)))
#define _reg_CRM_PCCR0	(*((volatile unsigned long *)(CRM_BASE_ADDR+0x20)))  
#define _reg_CRM_PCCR1	(*((volatile unsigned long *)(CRM_BASE_ADDR+0x24)))

#define SOC_CRM_BASE                0x10027000
#define SOC_CRM_CSCR                (SOC_CRM_BASE + 0x0)
#define SOC_CRM_MPCTL0              (SOC_CRM_BASE + 0x4)
#define SOC_CRM_MPCTL1              (SOC_CRM_BASE + 0x8)



#define GPIOA	0
#define GPIOB	1
#define GPIOC	2
#define GPIOD	3
#define GPIOE	4
#define GPIOF	5
/* Use as GPIO_BASE_ADDR(GPIOA)- GPIO_BASE_ADDR(GPIOF)*/
#define GPIO_BASE_ADDR(x)    (0x10015000+x*0x100)
#define _reg_GPIO_GIUS(x)    (*((volatile unsigned long *)(GPIO_BASE_ADDR(x)+0x20))) /*  32bit gpio pta in use reg */
#define _reg_GPIO_GPR(x)     (*((volatile unsigned long *)(GPIO_BASE_ADDR(x)+0x38))) /*  32bit gpio pta general purpose reg*/

/*
 * Mask to check Tx buffer empty
 */
#define TXFE_MASK   0x4000


static void setup_iomux(void)
 {

    _reg_CRM_CSCR =0x33f01107;		//fclock-266M HCLOCK-133M IP_CLCOK-66.5M

    // MPLL
   _reg_CRM_MPCTL0 = 0x01ef15d5;	//MPLL-266.008944M

    // Restart MPLL
    _reg_CRM_CSCR |=0x00040003; 
    
	while(!(_reg_CRM_MPCTL1&0x8000));  //locked

   	//_reg_CRM_PCDR1 |= 0x5;	
	//_reg_CRM_PCDR1 &= 0xFFFFFFC5;
	_reg_CRM_PCDR1 &= ~0x3F;	
	_reg_CRM_PCDR1 |= 5;				//ipg_perclock1 33.25M
	
  	/* enable clock for HCLK BROM and UART_1, 2, 3, 4 */
	_reg_CRM_PCCR1 |= 0xF0400400;
	
	/* Set up GPIO/IOMUX for UART_1  */
	_reg_GPIO_GIUS(GPIOE) &= 0xFFFF0FFF;	/* clear bit 12-bit 15 of GIUS_E */
	_reg_GPIO_GPR(GPIOE) &= 0xFFFF0FFF;	/* clear bit 12-bit 15 of GPR_E  */

        _reg_GPIO_GIUS(GPIOE) &= ~0x00000fd8;    /* port E pin 3,4,6,7 for uart2 */  //port E pin 8,9,10,11 for uart3
        _reg_GPIO_GPR(GPIOE) &= ~0x00000fd8;     /* port E pin 3,4,6,7 for primary function */
	
}   
/*!
 * This function configures MXC UART and its I/O pins. In order to use UART,
 * IOMUX configuration is required. This function configures IOMUX pins used by
 * UART to send and receive the data. UART is configured in polling mode.  The
 * transmitter FIFO is set to 2 characters and receiver to 1 characters.
 *
 * Refer to gpio.h in the respective MXC arch include directory for generating
 * the value of the IOMUX initialization constants for UART referred in this
 * function.
 */
void mxc_uart_init(void)
{	
	setup_iomux();

	/* config UART */
	//software reset
#if 1
	_reg_UCR2 = 0x6e16;
	_reg_UCR1 = 0x0;
	_reg_UCR3 = 0x4;
	_reg_UCR4 = 0x8000;	/* configure appropriate pins for UART_1_RX, UART_1_TX, UART2_RX and UART2_TX */
#endif
	_reg_UCR1 = 0x0005;
	_reg_UCR2 = 0x6026;
	_reg_UCR3 = 0x4;
	_reg_UCR4 = 0x8000;	
	/* Set up reference freq divide for UART module         

⌨️ 快捷键说明

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