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

📄 flash.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/***************************************************************************
 * File:  flash.c
 * Modified By: Naresh Gupta (nkgupta@hotmail.com)
 * Organization: Hitachi Semiconductor America Inc.
 * Date: Oct 29, 1999
 ***************************************************************************/

/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1998 Hitachi,Ltd.

--*/

/***************************************************************************
 * Synopsis:
 *  This file would contain the following:
 *     1. Flash routines.
 **************************************************************************/

#include "windows.h"
#include "platform.h"

#if ((SH_PLATFORM == PLATFORM_ASPEN)||(SH_PLATFORM==PLATFORM_BIGSUR))



#define DEBUG_SERIAL_ON 1

#if (SH_PLATFORM == PLATFORM_ASPEN)
#define UNLOCK_FLASH() 		(*((unsigned long *)0xa4040000) |= 1)
#define LOCK_FLASH() 		(*((unsigned long *)0xa4040000) &= ~1)
#elif (SH_PLATFORM == PLATFORM_BIGSUR)
#define UNLOCK_FLASH() 		(*((unsigned char *)BIGSUR_SW1) |= BIGSUR_SW1_FLWREN)
#define LOCK_FLASH() 		(*((unsigned char *)BIGSUR_SW1) &= ~BIGSUR_SW1_FLWREN)
#endif (SH_PLATFORM == PLATFORM_ASPEN)

static unsigned UnErased = 0;		// Last Address erased in Flash

// #define DEBUG_FLASH

/*****************************************************************************
 * Function: FlashReadRst
 * Input:    Address
 * Output:   None
 * Purpose:  Reset the Flash back to normal state.
 ****************************************************************************/
void FlashReadRst(volatile unsigned *addr) 
{
	// UNLOCK_FLASH();

	addr[0] = 0x50505050;
	addr[1] = 0x50505050;
	addr[0] = 0xffffffff;
	addr[1] = 0xffffffff;

	// LOCK_FLASH();
}

/****************************************************************************
 * Function: OEMFlashWrite
 * Input:    ulAddress: Address in Flash to write to (Must be dword aligned)
 *           ulValue:   Dword value to write.
 * Output 	0: success
 *			non-zero: failure
/***************************************************************************/
unsigned int OEMFlashWrite(unsigned int ulAddress, unsigned int ulValue) 
{
	volatile unsigned *addr;

	// UNLOCK_FLASH();

	/* Check whether the address to which you are about to write to has been
	 * erased or not. */
	if( (ulAddress & 0x00FFFFFF) >= UnErased) {
		OutputFormatString("ERROR: attempt to write to unerased flash. ulAddress = 0x%x, UnErased = 0x%x\r\n", ulAddress, UnErased);
		EraseFlash(ulAddress);
	}

#ifdef DEBUG_FLASH
	OutputFormatString("OemFlashWrite: ulAddress=0x%X, ulValue=0x%X\r\n", ulAddress, ulValue);
#endif DEBUG_FLASH

	if (ulAddress & 3) {
		OutputFormatString("ERROR: attempting to write on not word boundary at %Xh\r\n",ulAddress);
		OutputFormatString("Skipping write to Flash \r\n");
		return 1;
	}

	addr = (unsigned *) (ulAddress | FLASH_START);
	*addr = 0x40404040;
	while( FLASH_READY != (FLASH_READY & *(addr)) ) ;
	*addr = ulValue;
	while( FLASH_READY != (FLASH_READY & *(addr)) ) ;


	// FlashReadRst is required only when you want to readback from Flash
	FlashReadRst(addr);

	if (*addr != ulValue) {
		OutputFormatString("Error: OEMFlashWrite: Wrote 0x%x, read back 0x%x at address 0x%x\r\n", ulValue, *addr, addr);
		return(1);
	}


	return 0;
}

/****************************************************************************
 * Function: GetUnalignedDword
 * Input:    addr: Address to fetch dword from
 * Output 	0: success
 *			non-zero: failure
/***************************************************************************/
unsigned GetUnalignedDword(unsigned char *addr)
{
	unsigned val;

#ifdef DEBUG_FLASH
	OutputFormatString("+GetUnalignedDword(addr=%X, val=%B%B%B%B)\r\n", addr, *addr, *(addr+1), *(addr+2), *(addr+3));
#endif DEBUG_FLASH
	val = *addr | (*(addr+1) << 8) | (*(addr+2)<<16) | (*(addr+3)<<24);
#ifdef DEBUG_FLASH
	OutputFormatString("-GetUnalignedDword returning %X\r\n", val);
#endif DEBUG_FLASH
	return val;
}

/****************************************************************************
 * Function: OEMFlashWriteByte
 * Input:    ulAddress: Address in Flash to write to 
 *           ulValue:   byte value to write.
 * Output 	0: success
 *			non-zero: failure
/***************************************************************************/
unsigned OEMFlashWriteByte(unsigned ulAddress, unsigned char val)
{
	unsigned ulValue;
	unsigned addr;

#ifdef DEBUG_FLASH
	OutputFormatString("+OEMFlashWriteByte(ulAddress=%X, val=%B)\r\n", ulAddress, val);
#endif DEBUG_FLASH

	addr = ulAddress & ~3;
	ulValue = *(volatile unsigned *)addr;

	switch(ulAddress & 3) {
		case 0:
			ulValue = (ulValue & 0xFFFFFF00) | val;
			break;
		case 1:
			ulValue = (ulValue & 0xFFFF00FF) | (val << 8);
			break;
		case 2:
			ulValue = (ulValue & 0xFF00FFFF) | (val << 16);
			break;
		case 3:
			ulValue = (ulValue & 0x00FFFFFF) | (val << 32);
			break;
	}
	return OEMFlashWrite(addr, ulValue);
}

/****************************************************************************
 * Function: OEMFlashWriteBuffer
 * Input   : dst       : Destination Address
 *         : src       : Buffer address
 *         : length    : Number of bytes
 * Output  :  Don't care
 * Synopsis: Writes a buffer to Flash. It takes care of writes to unaligned
 *           boundaries.
/***************************************************************************/
unsigned OEMFlashWriteBuffer(unsigned char *dst, unsigned char *src, unsigned int length)
{
	unsigned val;

#ifdef DEBUG_FLASH
	OutputFormatString("+OEMFlashWriteBuffer(dst=%X, src=%X, length=%d)\r\n", dst, src, length);
#endif DEBUG_FLASH

	// Write all unaligned bytes at beginning of dst.
	while((unsigned)dst % 4) {
		OEMFlashWriteByte((unsigned)dst++, *src++);
		length --;
	}

	// Now dst is dword aligned. src may not be dword aligned.
	// Write all dword aligned bytes.
	while(length >= 4) {
		// Get a dword from src, it may be unaligned.
		val = GetUnalignedDword(src);
		OEMFlashWrite((unsigned)dst, val);
		src += 4; dst += 4; length -= 4;
	}

	// Now write the rest of the bytes.
	while(length --) {
		OEMFlashWriteByte((unsigned)dst++, *src++);
	}
	return 0;
}

/****************************************************************************
 * Function: OEMFlashWriteBegin
 * Input   : ulPhysStart       : Start of image
 *         : ulPhysLen         : Length of image
							   : 0: Erase all Flash, if it's a flash image
 * Output  :  FL_ADDRESS_ERROR : image is not for Flash.
 *            0                : Image is for Flash.
 * Synopsis: Selects whether the image would go to RAM or Flash. Incase it
 *           is for Flash, erase the required amount of Flash.
/***************************************************************************/
unsigned int OEMFlashWriteBegin(unsigned int ulPhysStart, unsigned int ulPhysLen) 
{
	unsigned int i;
	unsigned int ulPhysEnd;
	unsigned int ulFlashStart,ulFlashEnd, ulCurBlock;
	unsigned int ulStartBlock, ulNumBlocks;
	volatile unsigned *addr;

#ifdef DEBUG
	OutputFormatString("OEMFlashWriteBegin called with 0x%x, 0x%x\n", ulPhysStart, ulPhysLen);
#endif DEBUG

	ulPhysEnd=ulPhysStart+ulPhysLen;

#if 0
	ulPhysEnd|=0x20000000;
	ulPhysStart|=0x20000000;
#endif

	/* Get all the addresses in same area (P0) for comparisons.*/
	ulPhysEnd    &= 0x0fffffff;
	ulPhysStart  &= 0x0fffffff;
	ulFlashStart = FLASH_START&0x0fffffff;
	ulFlashEnd   = FLASH_END&0x0fffffff;

	/* If it is a Flash image, it must be linked to Address between 0x00000000
	 * and 0x04000000 */
	if ( (ulPhysStart >= 0) && (ulPhysStart <= 0x04000000) )
	{
#if 0
		if(ulPhysLen == 0) {
			// This is a Flash image of unknown length.
			// Erase all Flash
			ulStartBlock = 0;
			ulNumBlocks = FLASH_SIZE / FLASH_BLOCK_SIZE;
			// ulNumBlocks = 2; // Temporary FLASH_SIZE / FLASH_BLOCK_SIZE;
		}
		else 
#endif 0
		{
			/* compute starting block number and number of blocks*/
			ulStartBlock = ulPhysStart / FLASH_BLOCK_SIZE;
			ulNumBlocks = ulPhysLen / FLASH_BLOCK_SIZE;
			if (ulPhysLen % FLASH_BLOCK_SIZE)
				ulNumBlocks++;
		}
	} 
	else 
		return 1;

#if (SH_PLATFORM == PLATFORM_BIGSUR)
	// Check to see whether you are permitted to write to Flash. S1-3 should
	// be on.
	if( ! ( BIGSUR_SW1_FLASH_PROT_N & REG8(BIGSUR_SW1, 0) ) ) {
		// Can't write to Flash buddy. Switch OFF SW1 first.
		OutputFormatString("Can't write to Flash. Switch off S1-3 to enable Flash writing\r\n\n");
		return -1;
	}
	WriteOutput("MISCSW switch set, SW1 = 0x%x...\r\n\n", REG8(BIGSUR_SW1, 0));
#endif (SH_PLATFORM == PLATFORM_BIGSUR)

	/* Erase the FLASH blocks which are required.*/
	OutputFormatString("Erasing %d blocks starting at block %d ... ",ulNumBlocks,ulStartBlock);


	UNLOCK_FLASH();

	for(ulCurBlock = 0; ulCurBlock < ulNumBlocks; ulCurBlock++) {
		OutputFormatString(".");
		/* Erase at ulCurBlock + ulStartBlock*/

		/* Don't forget this step. This is because the FLASH is*/
		/* mapped to a different address in CMON.*/
		addr = (unsigned *) (((ulCurBlock + ulStartBlock) << SECTOR_SHIFT) | FLASH_START);


		addr[0] = 0x20202020;
		addr[1] = 0x20202020;
		while( FLASH_READY != (FLASH_READY & addr[0]) ) ;
		while( FLASH_READY != (FLASH_READY & addr[1]) ) ;

		addr[0] = 0xd0d0d0d0;
		addr[1] = 0xd0d0d0d0;

		while( FLASH_READY != (FLASH_READY & addr[0]) ) ;
		while( FLASH_READY != (FLASH_READY & addr[1]) ) ;

#if 0
		addr[0] = 0x50505050;
		addr[1] = 0x50505050;

		while( FLASH_READY != (FLASH_READY & addr[0]) ) ;
		while( FLASH_READY != (FLASH_READY & addr[1]) ) ;
#endif 0

	}

	FlashReadRst(addr);

	addr = (unsigned *) (((ulCurBlock + ulStartBlock) << SECTOR_SHIFT) | FLASH_START);
	UnErased = (unsigned)addr & 0x00FFFFFF;

	OutputFormatString("done\r\n",ulNumBlocks,ulStartBlock);
	// OutputFormatString("OEFWB: UnErased = 0x%x, addr = 0x%x, ulCurBlock=0x%x\r\n",UnErased, addr, ulCurBlock);

	// Do not LOCK Flash after erasing, so that the user can write data
	// to it.
	// LOCK_FLASH();
	return 0;
}
/****************************************************************************
// OEMFlashWriteEnd
//
//
//**************************************************************************/
unsigned int OEMFlashWriteEnd(void) 
{
	LOCK_FLASH();
	return 0;
}

/***************************************************************************
 * Function:  OEMFlashWriteStatus
 * Input:     Address to check out.
 * returns - 0 flash address not ready for write
 *			 1 flash address ready for write
 ***************************************************************************/
unsigned int OEMFlashWriteStatus(unsigned int ulAddress)
{
	/* Return 1 always for the time being, since the other routines make
	 * Sure that the Flash is in the ready state. */
	return 1;
}

/****************************************************************************
 * Function: EraseFlash
 * Input   : ulAddress       : Erase a sector of Flash at specified address
 * Output  :  FL_ADDRESS_ERROR : image is not for Flash.
 *            0                : Image is for Flash.
 * Synopsis: Erase a sector of Flash
/***************************************************************************/
unsigned int EraseFlash(unsigned int ulAddress) 
{
	unsigned int i;
	unsigned int ulPhysEnd;
	unsigned int ulFlashStart,ulFlashEnd, ulCurBlock;
	unsigned int ulStartBlock, ulNumBlocks;
	volatile unsigned *addr;

	// No error checking is done initially.

	addr = (unsigned *) ( ulAddress | FLASH_START );

		addr[0] = 0x20202020;
		addr[1] = 0x20202020;
		while( FLASH_READY != (FLASH_READY & addr[0]) ) ;
		while( FLASH_READY != (FLASH_READY & addr[1]) ) ;

		addr[0] = 0xd0d0d0d0;
		addr[1] = 0xd0d0d0d0;

		while( FLASH_READY != (FLASH_READY & addr[0]) ) ;
		while( FLASH_READY != (FLASH_READY & addr[1]) ) ;

	UnErased = ulAddress + (1 << SECTOR_SHIFT); 

#ifdef FLASH_DEBUG
	OutputFormatString("EraseFlash Address:%X, UnErased=%X\r\n", ulAddress, UnErased);
#endif FLASH_DEBUG

	FlashReadRst(addr);

#ifdef DEBUG_FLASH
	OutputFormatString("done\r\n",ulNumBlocks,ulStartBlock);
#endif DEBUG_FLASH

	return 0;
}

#endif ((SH_PLATFORM == PLATFORM_ASPEN)||(SH_PLATFORM==PLATFORM_BIGSUR))


#ifdef JUNK
#if 0
	if (ulAddress & 3) {
		OutputFormatString("ERROR: attempting to write on not word boundary at %Xh\r\n",ulAddress);

		/* Assume that it would be at least 16 bit aligned */
		if(ulAddress & 1) {
			OutputFormatString("Skipping write to Flash \r\n");
			return 1;
		}

		if(ulAddress & 2) {
			ulValue = (ulValue << 16) | (*(volatile unsigned short *) (ulAddress - 2) );
		}
		else {
			ulValue = (ulValue) | ( (*(volatile unsigned short *) (ulAddress + 2) ) << 16);
		}
		ulAddress &= 0xfffffff4;
	}
#endif 0

#endif JUNK

⌨️ 快捷键说明

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