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

📄 intel28f160.c

📁 为了满足每个项目终端的需求
💻 C
字号:
/***************************************************************************
*	 This is the custom implement File for flash 28f160c3b
*		PROGRAM:        flash.c
*		Revision:       22-3-2000
*		Author:			zuo jun rui
********************************************************************************/
/*
*NOTES:
*
*	FLASH is orgnized by blocks.
*	28f160c3b is a 16Mbits FLASH.We use it with 16bits bus wide.
*	Blocks include parameter block and main block.
*	Parameter block is 4KWords=8KBytes,total is 8.
*	Main Block is 32KWords=64KBytes,total is 31.
*	FLASH must erased by block.
*	FLASH can programmed or readed by word.
*	But FLASH can programmed only once before next erasure.******
*	Because FLASH's bit can only programmed from '1' to '0',not from '0' to '1'.
*	Default FLASH's blocks is locked.To programm or erase it,you must unlock it first.
*
*USES:
*	We use structure containing system parameters.
*	All elements of structure should less than INT16.
*	Then one element occupy one address.It's simplest.
*
*/
#include <stdio.h>
#include "../inc/version.h"
#include "../inc/gendef.h"
#include "../inc/intel28f160.h"

/************************************************************************
*	CONSTANTS
**************************************************************************/


/************************************************************************
*	DATA ALLOCATION
*************************************************************************/

static INT16 * flash_addr;
static int status;
int	DEBUG_FLASH=1;	/*For display FLASH read/write debug message.*/

/************************************************************************
* FUNCTION PROTOTYPES
*************************************************************************/
PRIVATE void Flash_Clear_Status(void);
PRIVATE int Flash_Read_Status(void);
PRIVATE void Flash_Unlock(void);
PUBLIC int Flash_Erase(int addr);
PUBLIC int Flash_Write_Data(int addr,INT16 data);
PUBLIC INT16 Flash_Read_Array(int addr);

/***************************************************************************
*	PUBLIC FUNCTIONS
********************************************************************************/
PUBLIC int FLASH_EraseBlock(int block_index)
{
	int addr;

	if((block_index < 8) && (block_index >= 0))
	{
		addr = block_index * PARA_BLOCK_SIZE;
	}
	else if((block_index < 39) && (block_index >= 8))
	{
		addr = (block_index - 8) * DATA_BLOCK_SIZE
				+ 8 * PARA_BLOCK_SIZE;
	}
	else
	{
		printf("\nFIRMWARE UPDATE: FLASH_EraseBlock,block_index err:%x",block_index);
		return -1;
	}

	return Flash_Erase(addr);
}

PUBLIC int FLASH_WriteBlock(int block_index,U16* buf,U32 buf_len)
{
	int addr;
	int block_size;
	int i;

	if((block_index < 8) && (block_index >= 0))
	{
		addr = block_index * PARA_BLOCK_SIZE;
		block_size = PARA_BLOCK_SIZE;
	}
	else if((block_index < 39) && (block_index >= 8))
	{
		addr = (block_index - 8) * DATA_BLOCK_SIZE
				+ 8 * PARA_BLOCK_SIZE;

		block_size = DATA_BLOCK_SIZE;
	}
	else
	{
		printf("\nFIRMWARE UPDATE: FLASH_WriteBlock,block_index err:%x",block_index);
		return -1;
	}

	for(i = 0; (i < buf_len) && (i < block_size); i++)
	{
		if(Flash_Write_Data((addr + i), buf[i]) != 0)
		{
			return -1;
		}
	}

	return 0;

}
PUBLIC int FLASH_ReadBlock(int block_index,U16* buf,U32 buf_len)
{
	int addr;
	int block_size;
	int i;

	if((block_index < 8) && (block_index >= 0))
	{
		addr = block_index * PARA_BLOCK_SIZE;
		block_size = PARA_BLOCK_SIZE;
	}
	else if((block_index < 39) && (block_index >= 8))
	{
		addr = (block_index - 8) * DATA_BLOCK_SIZE
				+ 8 * PARA_BLOCK_SIZE;

		block_size = DATA_BLOCK_SIZE;
	}
	else
	{
		printf("\nFIRMWARE UPDATE: FLASH_ReadBlock,block_index err:%x",block_index);
		return -1;
	}

	for(i = 0; (i < buf_len) && (i < block_size); i++)
	{
		buf[i] = Flash_Read_Array(addr + i);
	}

	return 0;
}

/******************************************************************************
*	Flash_Erase
*******************************************************************************
*	Erase the flash.
*	Input: block_addr is the address of the block erased(in BYTES,should convert to flash address).
*/
PUBLIC int Flash_Erase(int block_addr)
{
	int ret_code;

	/*Read WSM register and check.*/
	do
	{
		status=Flash_Read_Status();
	}while((status & WSM_STATUS) !=WSM_STATUS);

	/*Calculate the block address to erase.*/
	flash_addr=(INT16 *)(DATA_FLASH_BASE+block_addr*2);

	/*Unlock block*/
	Flash_Unlock();

	/*Change to Erase set-up mode.*/
	*flash_addr=FLASH_ERASE_SETUP;

	/*Start erase.*/
	*flash_addr=FLASH_ERASE_CONFIRM;

	/*Read WSM register and check.*/

	do
	{
		status=*flash_addr;
	}while((status & WSM_STATUS) !=WSM_STATUS);

	/*Check for erro indications.*/
	if((status & WSM_VPP_STATUS) == WSM_VPP_STATUS)
	{
		ret_code=ERR_VPP_LOW;
		goto errout1;
	}
	else if((status & WSM_ERASE_STATUS) == WSM_ERASE_STATUS)
	{
		if((status & WSM_PROGRAM_STATUS) == WSM_PROGRAM_STATUS)
			ret_code=ERR_COMMAND_SEQUENCE;
		else
			ret_code=ERR_ERASE;

		goto errout1;
	}
	else if((status & WSM_LOCK_STATUS) == WSM_LOCK_STATUS)
	{
		ret_code=ERR_BLOCK_LOCKED;
		goto errout1;
	}

	/*Restore to Read Array mode.*/
	*flash_addr=FLASH_READ_ARRAY;

	return 0;

errout1:
	/*Clear WSM register.*/
	Flash_Clear_Status();

	/*Restore to Read Array mode.*/
	*flash_addr=FLASH_READ_ARRAY;

	if(DEBUG_FLASH)
		printf("\r\nFIRMWARE UPDATE: Flash_Erase() error.error code is ox%x\n",ret_code);

	return ret_code;
}

/******************************************************************************
*	Flash_Erase_All
*******************************************************************************
*	Erase all blocks of the flash.
*/
PUBLIC void Flash_Erase_All(void)
{
	int i;

	/*Erase parameter blocks*/
	for(i=0;i<0;i++)
	{
		Flash_Erase(0x1000*i);
	}

	/*Erase main blocks*/
	for(i=1;i<32;i++)
	{
		Flash_Erase(i*0x8000);
	}
}

/******************************************************************************
*	Flash_Write_Data
*******************************************************************************
*	Write data to flash.
*	Input: block_addr is the address writed(in BYTES,should convert to flash address).
*/
PUBLIC int Flash_Write_Data(int addr,INT16 data)
{
	int ret_code;
	/*Read WSM register and check.*/

	do
	{
		status=Flash_Read_Status();
	}while((status & WSM_STATUS) !=WSM_STATUS);

	/*Calculate the flash address to write.*/
	flash_addr=(INT16 *)(DATA_FLASH_BASE+addr*2);
	/*If locked,unlock it.*/
	Flash_Unlock();
	/*Change to Program set-up mode.*/
	*flash_addr=FLASH_WRITE;

	/*Write data to flash.*/
	*flash_addr=data;

	/*Read WSM register and check.*/

	do
	{
		status=*flash_addr;
	}while((status & WSM_STATUS) !=WSM_STATUS);

	/*Check for erro indications.*/
	if((status & WSM_VPP_STATUS) == WSM_VPP_STATUS)
	{
		ret_code=ERR_VPP_LOW;
		goto errout;
	}
	else if((status & WSM_PROGRAM_STATUS) == WSM_PROGRAM_STATUS)
	{
		ret_code=ERR_PROGRAMMING;
		goto errout;
	}
	else if((status & WSM_LOCK_STATUS) == WSM_LOCK_STATUS)
	{
		ret_code=ERR_BLOCK_LOCKED;
		goto errout;
	}


	/*Restore to Read Array mode.*/
	*flash_addr=FLASH_READ_ARRAY;
	return 0;

errout:
	/*Clear WSM register.*/
	Flash_Clear_Status();

	/*Restore to Read Array mode.*/
	*flash_addr=FLASH_READ_ARRAY;

	if(DEBUG_FLASH)
		printf("\r\nFIRMWARE UPDATE: Flash_Write_Word() error.error code is 0x%x\n",ret_code);

	return ret_code;
}

/******************************************************************************
*	Flash_Read_Array
*******************************************************************************
*	Read the flash for data.
*	Input: addr is the address readed(in BYTES,should convert to flash address).
*/
PUBLIC INT16 Flash_Read_Array(int addr)
{
	INT16 data_ret;

	/*Calculate the flash address to read.*/
	flash_addr=(INT16 *)(DATA_FLASH_BASE+addr*2);		/*Bus wide is 16bits.*/

	/*Default mode is read array.must be sure of this.*/
	*flash_addr=FLASH_READ_ARRAY;
	data_ret=0;
	data_ret=*flash_addr;

	return(data_ret);
}

/******************************************************************************
*	Flash_Read_ID
*******************************************************************************
*	Read the flash for manufacturer or device identifier.
*/
PUBLIC int Flash_Read_ID(void)
{
	int FlashID;

	/*Select the flash.*/
	flash_addr=(INT16 *)DATA_FLASH_BASE;

	/*Change to Read ID mode.*/
	*flash_addr=FLASH_READ_ID;

	/*Read.*/
	FlashID=*flash_addr;

	return(FlashID);
}

/*******************************************************************************
*	PRIVATE FUNCTIONS
********************************************************************************/

/******************************************************************************
*	Flash_Read_Status
*******************************************************************************
*	Read the flash for WSM register.
*/
PRIVATE int Flash_Read_Status()
{
	/*Select the flash.*/
	flash_addr=(INT16 *)DATA_FLASH_BASE;

	/*Change to Read Status Register mode.*/
	*flash_addr=FLASH_READ_STATUS;
	/*Read.*/
	return(*flash_addr);
}

/******************************************************************************
*	Flash_Clear_Status
*******************************************************************************
*	Clear the flash WSM register.
*/
PRIVATE void Flash_Clear_Status()
{
	/*Select the flash.*/
	flash_addr=(INT16 *)DATA_FLASH_BASE;

	/*Write command to clear Write Status Register.*/
	*flash_addr=FLASH_CLEAR_STATUS;
}

/******************************************************************************
*	Flash_Unlock
*******************************************************************************
*	Unlock the block.
*	Must insure flash_addr is the correct address of block.
*/
PRIVATE void Flash_Unlock()
{
	INT16 * block_base;

	/*Get block base address*/
	block_base=flash_addr-((int)flash_addr%0x10000)/2;

	/*Check lock status of block*/

	*flash_addr=FLASH_READ_ID;
	status=*(block_base+2);

	if((status & 0x03)!=0)	/*If locked*/
	{
unlockp:
		/*Unlock block*/
		*flash_addr=FLASH_CONFIG;
		*flash_addr=FLASH_UNLOCK;

		/*Check status,until operation is complete*/
		*flash_addr=FLASH_READ_STATUS;


		do
		{
			status=*flash_addr;
		}while((status & WSM_STATUS) !=WSM_STATUS);

		/*Check lock status of block*/
		*flash_addr=FLASH_READ_ID;

		status=*(block_base+2);
		if((status & 0x03)!=0)
			goto unlockp;

	}
}

⌨️ 快捷键说明

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