📄 intel28f160.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 + -