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

📄 _flash.c

📁 at91rm9200 mac control源码
💻 C
字号:

/****************************************************************
 *                                                              *
 *  Program : FLASH.C                                           *
 *                                                              *
 *  Purpose : Handler for SST39VF800AT Flash memory.            *
 *                                                              *
 *  Compile : ARM SDT Ver2.51                                   *
 *                                                              *
 *  Version : 1.00                                              *
 *                                                              *
 *  Create  : 2002-09-01 Sunday              By KWM             *
 *                                                              *
 *  Copyright (C) 2002  Amnokgang Technology Development Corp.  *
 *  All Rights Reserved.                                        *
 *                                                              *
 ****************************************************************/

#include <string.h>

#include "_MyType.H"  
#include "_Bios.H"  

#define FlashSector_SZ	0x1000

WORD gFlashWriteBuff[FlashSector_SZ/2];
WORD gFlashEraseBuff[FlashSector_SZ/2];

/*========================================================================
 Function    : EraseFlashChip
 Description :  
 Return type : BOOL 
 Argument
    (In/Out) : void *apDst
// Create      : 2003-01-23 8:40:55 AM		   By KWM
========================================================================*/
BOOL EraseFlashChip( void *apDst )
{
	// Watchdog timer reset


	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaa;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x55;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0x80;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaa;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x55;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0x10;

	/* DQ7: Data# Polling */
	while( ((*(volatile WORD *)apDst)&0x80) == 0 ) ;


	return TRUE; 
}

/*========================================================================
// Function    : EraseFlashSector
// Description : Erase Sector.
// Return type : BOOL
// Argument
//    (  In  ) : apSrc=Address of data(64K) to write.
//    (  In  ) : apDst=First address of flash sector to write.
// Date        : 2002/06/13  PM 5:30    - Ver.1.0 -   By Kim Won Myong
//========================================================================*/
BOOL EraseFlashSector( void *apDst )
{
	WORD	vToggle;
//	volatile int	i;

	// Watchdog timer reset


	memset( gFlashEraseBuff, 0xff, FlashSector_SZ );
	if( memcmp( gFlashEraseBuff, apDst, FlashSector_SZ ) == 0 ) return TRUE;



	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaaaa;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x5555;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0x8080;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaaaa;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x5555;
	*(volatile WORD *)((DWORD)apDst & 0xfffff000) = 0x30;

	while(1)
	{
		vToggle = *(volatile WORD *)((DWORD)apDst & 0xfffff000) & 0x40;
		if( vToggle != (*(volatile WORD *)((DWORD)apDst & 0xfffff000) & 0x40) )		//D6 == D6
			continue;
		// DQ7: Data# Polling
		if( (*(volatile WORD *)((DWORD)apDst & 0xfffff000)) & 0x80 )
			break;					//D7 == 1
	}

//	for( i=0; i<100;i++){ mcrCPULED_ON; };



	return TRUE; 
}

/*========================================================================
// Function    : FlashWriteWord
// Description : Write 1byte to flash.
// Return type : BOOL
// Argument
//    (  In  ) : apSrc=Address of data(64K) to write.
//    (  In  ) : apDst=First address of flash sector to write.
// Date        : 2002/06/13  PM 5:30    - Ver.1.0 -   By Kim Won Myong
//========================================================================*/
BOOL FlashWriteWord( void *apDst, WORD aData )
{
	WORD	vToggle;

	if( *(WORD *)apDst == aData ) return TRUE;

	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaa;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x55;
	*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xa0;
	*(volatile WORD *)apDst = aData;

	while(1)
	{
		vToggle = *(volatile WORD *)apDst & 0x40;
		if( vToggle != *(volatile WORD *)apDst & 0x40 )		//D6 == D6
			continue;
		// DQ7: Data# Polling
		if( ((*(volatile WORD *)apDst) & 0x80) == (aData & 0x80) )
			break;					//D7 == D7
	}

	return TRUE; 
}

/*========================================================================
// Function    : UpdateFlashSector
// Description : Erase and Write the any sector of flash memory.
// Return type : BOOL
// Argument
//    (  In  ) : apSrc=Address of data(64K) to write.
//    (  In  ) : apDst=First address of flash sector to write.
// Date        : 2002/06/13  PM 5:30    - Ver.1.0 -   By Kim Won Myong
//========================================================================*/
BOOL UpdateFlashSector( void *apSrc, void *apDst )
{
//	register int vLoop;
//	register WORD *vpSrc = (WORD *)apSrc;
//	register WORD *vpDst = (WORD *)apDst;

	int vLoop;
	WORD *vpSrc = (WORD *)apSrc;
	WORD *vpDst = (WORD *)apDst;

	if( memcmp( apSrc, apDst, FlashSector_SZ ) == 0 ) return TRUE;

	EraseFlashSector( apDst );
	

	vLoop = FlashSector_SZ/2;
	while( vLoop-- ){  
		FlashWriteWord( vpDst++, *vpSrc++ );
	}



	if( memcmp( apSrc, apDst, FlashSector_SZ ) == 0 ) return TRUE;
	return FALSE; 
}

/*========================================================================
// Function    : WriteFlashSmallThanSector
// Description :  
// Return type : BOOL 
// Argument
//    (In    ) : void *apSrc
//    (In    ) : void *apDst
//    (In    ) : int aSize
// Create      : 2002-09-12 6:09:24 PM		   By Kim Won Myong
//========================================================================*/
BOOL WriteFlashSmallThanSector( void *apSrc, void *apDst, int aSize )
{
//	register DWORD vpSectStart, vpOffset, vBytes;
	DWORD vpSectStart, vpOffset, vBytes;

	/* when destination address is sector boundary */
	if( ((DWORD)apDst%FlashSector_SZ) == 0 ){
		memcpy( gFlashWriteBuff, apDst, FlashSector_SZ ) ;
		memcpy( gFlashWriteBuff, apSrc, aSize ) ;
		return UpdateFlashSector( gFlashWriteBuff, apDst );
	}

	/* when destination address is not sector boundary */
	vpSectStart = (DWORD)apDst / FlashSector_SZ * FlashSector_SZ;/*Start address of sector with [apDst]*/
	vpOffset = (DWORD)apDst % FlashSector_SZ;/*Offset of modify data in buffer */
	vBytes = FlashSector_SZ - vpOffset;/*Bytes of modify data in buffer */
	if( vBytes >= aSize ){
		/* when there is in one sector */
		memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
		memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, aSize );/*modify data to 1st sector */
		return UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart );/* write to flash */
	}
	else{
	/* when there is in two sector */
		/* 1st sector write */
		memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
		memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, vBytes );/*modify data to 1st sector */
		if( !UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart ) ) return FALSE;/* write to flash */

		/* next sector write */
		memcpy( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes), FlashSector_SZ ) ;
		memcpy( gFlashWriteBuff, (void*)((DWORD)apSrc+vBytes), aSize-vBytes ) ;
		return UpdateFlashSector( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes) );
	}
}

/*========================================================================
// Function    : WriteFlash
// Description :  
// Return type : BOOL 
// Argument
//    (In/Out) : void *apSrc
//    (In/Out) : void *apDst
//    (In/Out) : int aSize
// Create      : 2002-09-12 12:02:51 PM		   By Kim Won Myong
//========================================================================*/
BOOL WriteFlash( void *apSrc, void *apDst, int aSize )
{	DWORD vpData, vpFlash;
	DWORD vLoop, vnSector;

	/* aSize < FlashSector_SZ */
	if( aSize <= FlashSector_SZ ){
		if( !WriteFlashSmallThanSector( apSrc, apDst, aSize ) ) return FALSE;
		Delay_Nms(10);
		return TRUE;
	}

	vpData = (DWORD)apSrc;
	vpFlash = (DWORD)apDst;

	/* when destination address is not sector boundary */
	if( ((DWORD)apDst%FlashSector_SZ) != 0 ){
		register DWORD vBytes;
		vBytes = FlashSector_SZ - ((DWORD)apDst%FlashSector_SZ); /* Bytes of data to write in that sector */
		if( !WriteFlashSmallThanSector( apSrc, apDst, vBytes ) ) return FALSE;
		vpData += vBytes;/* move src pointer */
		vpFlash += vBytes;/* move dest pointer */
		aSize -= vBytes;
	}	

	/* when destination address is sector boundary */
	vnSector = aSize / FlashSector_SZ;
	for( vLoop=0; vLoop<vnSector; vLoop++ ){ 
		if( !WriteFlashSmallThanSector( (void *)vpData, (void *)vpFlash, FlashSector_SZ ) ) return FALSE;
		vpData += FlashSector_SZ;
		vpFlash += FlashSector_SZ;
	}

	/* remainder */
	if( (aSize%FlashSector_SZ) == 0 ) {Delay_Nms(10); return TRUE;}
	if( !WriteFlashSmallThanSector( (void *)vpData, (void *)vpFlash, (aSize%FlashSector_SZ) ) ) return FALSE;
	Delay_Nms(10);
	return TRUE;

}

/*========================================================================
// Function    : EraseFlashSmallThanSector
// Description :  
// Return type : BOOL 
// Argument
//    (In    ) : void *apDst
//    (In    ) : int aSize
// Create      : 2002-09-12 6:09:24 PM		   By Kim Won Myong
//========================================================================*/
BOOL EraseFlashSmallThanSector( void *apDst, int aSize )
{
//	register DWORD vpSectStart, vpOffset, vBytes;
	DWORD vpSectStart, vpOffset, vBytes;
	char *apSrc=(char*)gFlashEraseBuff;

	memset( gFlashEraseBuff, 0xff, sizeof(gFlashEraseBuff) );
	/* when destination address is sector boundary */
	if( ((DWORD)apDst%FlashSector_SZ) == 0 ){
		memcpy( gFlashWriteBuff, apDst, FlashSector_SZ ) ;
		memcpy( gFlashWriteBuff, apSrc, aSize ) ;
		return UpdateFlashSector( gFlashWriteBuff, apDst );
	}

	/* when destination address is not sector boundary */
	vpSectStart = (DWORD)apDst / FlashSector_SZ * FlashSector_SZ;/*Start address of sector with [apDst]*/
	vpOffset = (DWORD)apDst % FlashSector_SZ;/*Offset of modify data in buffer */
	vBytes = FlashSector_SZ - vpOffset;/*Offset of modify data in buffer */
	if( vBytes >= aSize ){
		/* when there is in one sector */
		memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
		memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, aSize );/*modify data to 1st sector */
		return UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart );/* write to flash */
	}
	else{
	/* when there is in two sector */
		/* 1st sector write */
		memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
		memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, vBytes );/*modify data to 1st sector */
		if( !UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart ) ) return FALSE;/* write to flash */

		/* next sector write */
		memcpy( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes), FlashSector_SZ ) ;
		memcpy( gFlashWriteBuff, (void*)((DWORD)apSrc+vBytes), aSize-vBytes ) ;
		return UpdateFlashSector( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes) );
	}
}

/*========================================================================
// Function    : EraseFlash
// Description :  
// Return type : BOOL 
// Argument
//    (In/Out) : void *apDst
//    (In/Out) : int aSize
// Create      : 2002-09-12 12:02:51 PM		   By Kim Won Myong
//========================================================================*/
BOOL EraseFlash( void *apDst, int aSize )
{	DWORD vpFlash;
	DWORD vLoop, vnSector;

	/* aSize < FlashSector_SZ */
	if( aSize <= FlashSector_SZ ){
		return EraseFlashSmallThanSector( apDst, aSize );
	}

	vpFlash = (DWORD)apDst;

	/* when destination address is not sector boundary */
	if( ((DWORD)apDst%FlashSector_SZ) != 0 ){
		register DWORD vBytes;
		vBytes = FlashSector_SZ - ((DWORD)apDst%FlashSector_SZ); /* Bytes of data to write in that sector */
		if( !EraseFlashSmallThanSector( apDst, vBytes ) ) return FALSE;
		vpFlash += vBytes;/* move dest pointer */
		aSize -= vBytes;
	}	

	/* when destination address is sector boundary */
	vnSector = aSize / FlashSector_SZ;
	for( vLoop=0; vLoop<vnSector; vLoop++ ){ 
		if( !EraseFlashSector( (void *)vpFlash ) ) return FALSE;
		vpFlash += FlashSector_SZ;
	}

	/* remainder */
	if( (aSize%FlashSector_SZ) == 0 ) return TRUE;
	return EraseFlashSmallThanSector( (void *)vpFlash, (aSize%FlashSector_SZ) );

}

/*========================================================================
// Function    : GetFlashSectorSize
// Description :  
// Return type : DWORD
// Argument
//    (In    ) : Chip
//    (   Out) : aSize
// Create      : 2004-10-25 12:02:51 PM		   By S.I.G
//========================================================================*/
DWORD GetFlashSectorSize( void )
{
	return FlashSector_SZ;
}

/****************************************************************
 *
 *                End of file : FLASH.C
 *
 ****************************************************************/

⌨️ 快捷键说明

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