亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? eeprom.c

?? uPSD3200系列MCU的EEPROM的仿真實例
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*--------------------------------------------------------------------------
eeprom.c

Version:
10/2004 Ver 0.2 - Corrected Eeprom_Sector_Swap to properly handle smaller
                   sized records.
11/2002 Ver 0.1 - Initial Version

Description:
Device driver for EEPROM emulation using boot (secondary) flash.

*****************************************************************************
Important Note:
XDATA must be initialized to 0 in the startup file for this driver to work
properly.  This will be investigated and corrected in future releases.
*****************************************************************************


Copyright (c) 2004 STMicroelectronics

This example demo code is provided as is and has no warranty,
implied or otherwise.  You are free to use/modify any of the provided
code at your own risk in your applications with the expressed limitation
of liability (see below) so long as your product using the code contains
at least one uPSD products (device).

LIMITATION OF LIABILITY:   NEITHER STMicroelectronics NOR ITS VENDORS OR 
AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
--------------------------------------------------------------------------*/


#include "eeprom.h"
#include "upsd3200.h"			// special function register declarations for UPSD


/***** EEPROM_Format *****/
// Formats sectors 0 and 1 to accept record data
// Accepts maximum number of records allowed.
// Returns 0 on success. If error, returns 1.
// ********** WARNING ********** // 
// This function erases any existing data in both sectors
// ********** WARNING ********** // 
BYTE EEPROM_Format(WORD max_records)
{
	xdata struct record_entry xdata record;

	// Verify data will fit into half of sector
	if  ( (sizeof(record) * max_records)  > (SECTOR_SIZE/2) )
		return ILLEGAL_RECORD_NUMBER;

	// Format sector 0
	if ( E_andF_Sector(SECTOR_0, max_records) ) return FORMAT_FAILED;
	// Erase sector 1
	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;

	return 0;
}

/***** Eeprom_Init *****/
// Verifies database integrity after power loss.
// Attempts to recover data corruption after power loss.
// Re-formats database if corrupted. 
BYTE Eeprom_Init(void)
{
	xdata struct sector_header xdata sector_header_0;
	xdata struct sector_header xdata sector_header_1;
	xdata struct record_entry xdata record;
	WORD i, j;
	BYTE *ptr;
	WORD xdata max_rec;
	WORD xdata last_address;
	WORD xdata base_address;
	WORD xdata new_address;
	BYTE xdata valid_sector;

	// Get both sector headers
	ptr = (BYTE*) (&sector_header_0);
	base_address = SECTOR_0_BASE_ADDRESS;
	for ( i=0; i < sizeof(sector_header_0); i++ )
	{
		ptr[i] = Boot_Flash_Read( base_address++ );
	}
	ptr = (BYTE*) (&sector_header_1);
	base_address = SECTOR_1_BASE_ADDRESS;
	for ( i=0; i < sizeof(sector_header_1); i++ )
	{
		ptr[i] = Boot_Flash_Read( base_address++ );
	}

	// Check for corrupted sectors
	// This would occur if a sector erase was interrupted by a power loss
	// In this case, the sector must be re-erased
	if ( ~(sector_header_0.sector ^ sector_header_0.sector_checksum) )
	{
		if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;
		sector_header_0.sector_status = ERASED;
	}
	if ( ~(sector_header_1.sector ^ sector_header_1.sector_checksum) )
	{
		if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
		sector_header_1.sector_status = ERASED;
	}

	// Get maximum number of records from header
	// If unable, return error
	if ( sector_header_0.max_records != 0xFFFF )
		max_rec = sector_header_0.max_records;
	else if ( sector_header_1.max_records != 0xFFFF )
		max_rec = sector_header_1.max_records;
	else
		return ILLEGAL_RECORD_NUMBER;

	// Check for invalid header states and repair
	switch(sector_header_0.sector_status)
	{
    case ERASED:
		if( sector_header_1.sector_status == VALID__SECTOR )  // sector 1 is valid
		{		    
          	if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;			
		}     
		else  // invalid state re-format database
		{
          	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;			
			if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
			return INVALID_SECTOR_STATE;
     	}
		break;
	case RECEIVE_DATA:	
       	if ( sector_header_1.sector_status == VALID__SECTOR ) // use sector 1
       	{
          	if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;			
      	}
		else if(sector_header_1.sector_status == TRANSFER_COMPLETE) //use sector 0
		{
          	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;	
			// update sector 0 header to valid data 
			sector_header_0.sector_status = VALID__SECTOR;
			ptr = (BYTE*) (&sector_header_0);
			base_address = SECTOR_0_BASE_ADDRESS;
			for ( i=0; i < sizeof(sector_header_0); i++ )
			{
				if ( Boot_Flash_Write( base_address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
			}
		}
		else  // invalid state erase both sectors
		{
          	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;			
			if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
			return INVALID_SECTOR_STATE;
     	}
		break;
	case VALID__SECTOR:	
		if ( sector_header_1.sector_status == VALID__SECTOR ) // invalid state erase both sectors
		{		    
          	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;			
			if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
			return INVALID_SECTOR_STATE;
       	}
		else // sector 0 is valid sector, erase sector 1
       	{
          	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;			
		}
		break;
   	case TRANSFER_COMPLETE:
		if ( sector_header_1.sector_status == VALID__SECTOR ) // erase sector 0
		{		    
          	if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;			
		}				
		else if (sector_header_1.sector_status == RECEIVE_DATA) // erase sector 0, use sector 1
		{
          	if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;	
			// mark sector 1 as valid sector 
			sector_header_1.sector_status = VALID__SECTOR;
			ptr = (BYTE*) (&sector_header_1);
			base_address = SECTOR_1_BASE_ADDRESS;
			for ( i=0; i < sizeof(sector_header_1); i++ )
			{
				if ( Boot_Flash_Write( base_address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
			}
		}
		else // invalid state, format both sectors
		{
          	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;			
			if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
			return INVALID_SECTOR_STATE;
 		}
		break;
	default:  // any other state, erase both sectors
 	
          	if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;			
			if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
			return INVALID_SECTOR_STATE;
		break;
	}

	// Check for corrupted data 
	// This would happen if a data write/update was interrupted by a power loss
	for ( i=0; i<max_rec; i++ )
	{
		// get address of last entry of each record
		last_address = Read_Record_Data_Structure( i, (BYTE*) (&record) );
		// repair record entry if necessary
		if ( record.status == UPDATE_DATA )
  		{
			// get sector	
			valid_sector = Find_Active_Sector(F_WRITE);
			if ( valid_sector == SECTOR_ID_ERROR ) return SECTOR_ID_ERROR;
			// get base address of sector
			base_address = 	SECTOR_0_BASE_ADDRESS + ((WORD)valid_sector * SECTOR_SIZE);
 	  		// get address for repaired entry
	   		new_address = Find_Next_Address();
			if( new_address == SECTOR_FULL ) return SECTOR_FULL; // abort if sector is full
			// set status and pointer to next data
			record.status = VALID_DATA;
			record.last_record_update = 0xFFFF;
			// write new record with old data
			ptr = (BYTE*) (&record);
			for ( j=0; j<sizeof(record); j++ )
			{
				 if ( Boot_Flash_Write(new_address++, ptr[j]) ) return FLASH_WRITE_ERROR;
			}
			// fix status and pointer of old record
			record.status = SUPERSEDED;
			record.last_record_update = new_address - sizeof(record);
			for ( j=0; j < sizeof(record); j++ )
			{
				if ( Boot_Flash_Write( last_address++, ptr[j] ) ) return FLASH_WRITE_ERROR;
			}
		}
	}

	return 0;
}

/***** Update_Record *****/
// Update record in EEPROM.
// Accepts record id and new record data.
// Swaps to empty sector if current sector is full
BYTE Update_Record(WORD id, BYTE xdata *buf)
{
    BYTE i;
    BYTE xdata status;
	BYTE xdata bufover[EEPROM_RECORD_SIZE];

	status = Write_Record(id, buf);
   
	// when the sector is full, save the new record to ram and transfer to a blank sector	
	if( status == SECTOR_FULL ) 
	{
		// store new data in temporary buffer
		for ( i=0; i < sizeof(bufover); i++ )
		{
			bufover[i] = buf[i];
		}
		// perform sector swap
		status = Eeprom_Sector_Swap(id, &bufover);
	}
	
	return status;	
}

/***** Read_Record *****/
// Reads a data element from EEPROM.
// Accepts record id number.
// Returns record data byte. If error, returns error code.
BYTE Read_Record(WORD id_number, BYTE* buffer)
{
	BYTE xdata valid_sector = 0xFF;
	xdata struct sector_header xdata header;
	xdata struct record_entry xdata record;
	WORD i;
	BYTE *ptr;
	BYTE xdata *data_buf;
	WORD xdata address;
	WORD xdata base_address;
	WORD xdata last_address;

	// get active sector
	valid_sector = Find_Active_Sector(F_READ);
	if ( valid_sector == SECTOR_ID_ERROR ) return SECTOR_ID_ERROR;

	// get pointer to data
	data_buf = buffer;

	// calculate base address of data
	base_address = 	SECTOR_0_BASE_ADDRESS + ((WORD)valid_sector * SECTOR_SIZE) + 
					(WORD)sizeof(header) + ( id_number * (WORD)sizeof(record) );

	// get base record
	ptr = (BYTE*) (&record);
	address = base_address;
	for ( i=0; i<sizeof(record); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ );
	}

	// get last record
	if ( record.last_record_update != 0xFFFF )
	{
		address = base_address;
		do	
		{
			ptr = (BYTE*) (&record);
			last_address = address;
			for ( i=0; i<sizeof(record); i++ )
			{
				ptr[i] = Boot_Flash_Read( address++ );
			}
			address = record.last_record_update;
		} while ( record.last_record_update != 0xFFFF );
	 }
	 else
	 {
	 	last_address = base_address;
	 }

	 if( record.status == UNINITIALIZED ) return UNINITIALIZED;

	// Set data buffer
	for ( i=0; i<EEPROM_RECORD_SIZE; i++ )
	{
		data_buf[i] = record.record_data[i];
	}

	return 0;
}

/***** Write_Record *****/
// Write or update record in EEPROM.
// Accepts record id and new record data.
// If error, returns error code.
BYTE Write_Record(WORD id, BYTE xdata *buffer)
{
	xdata struct sector_header xdata header;
	xdata struct record_entry xdata record;
	WORD i;
	BYTE xdata valid_sector;
	WORD xdata last_address;
	WORD xdata base_address;
	WORD xdata new_address;
	WORD address;
	BYTE *ptr;
	BYTE xdata *data_buf;

	// get active sector
	valid_sector = Find_Active_Sector(F_WRITE);
	if ( valid_sector == SECTOR_ID_ERROR ) return SECTOR_ID_ERROR;

	// get pointer to data
	data_buf = buffer;

	// calculate base address of data
	base_address = 	SECTOR_0_BASE_ADDRESS + ((WORD)valid_sector * SECTOR_SIZE) + 
					(WORD)sizeof(header) + ( id * (WORD)sizeof(record) );

	// get base record
	ptr = (BYTE*) (&record);
	address = base_address;
	for ( i=0; i<sizeof(record); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ );
	}

	// write data if record not initialized
	if ( record.status == UNINITIALIZED )
	{
		record.status = VALID_DATA;
		record.last_record_update = 0xFFFF;
		for ( i=0; i < EEPROM_RECORD_SIZE; i++ )
		{
			record.record_data[i] = data_buf[i];	// set data byte
		}

		// write record to flash
		ptr = (BYTE*) (&record);
		address = base_address;
		for ( i=0; i < sizeof(record); i++ )
		{
			if ( Boot_Flash_Write( address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
		}

		return 0;
	}
	
	// find last entry if record initialized	
	address = base_address;
	do
	{
		ptr = (BYTE*) (&record);
		for ( i=0; i<sizeof(record); i++ )
		{
			ptr[i] = Boot_Flash_Read( address++ );
		}
		if ( record.status == SUPERSEDED )
		{
			address = record.last_record_update;
		}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
三级成人在线视频| 久久一日本道色综合| 亚洲妇熟xx妇色黄| 欧美三级资源在线| 免费成人性网站| 中文字幕五月欧美| 欧亚洲嫩模精品一区三区| 亚洲一区二区三区四区不卡| 欧美日韩大陆在线| 精品一区二区三区在线视频| 亚洲精品在线电影| av在线不卡免费看| 亚洲国产一区二区三区青草影视 | 韩国v欧美v日本v亚洲v| 精品国产乱码久久久久久免费| 激情五月激情综合网| 欧美国产国产综合| 欧美熟乱第一页| 精品一区二区三区在线观看国产| 欧美激情一区二区三区不卡| 91丨porny丨中文| 天天综合色天天| 欧美激情在线观看视频免费| 欧美性受xxxx黑人xyx性爽| 秋霞午夜av一区二区三区| 国产婷婷精品av在线| 色一区在线观看| 免费高清成人在线| 亚洲视频一区二区在线观看| 欧美精三区欧美精三区| 国产91高潮流白浆在线麻豆| 亚洲精品ww久久久久久p站| 日韩精品一区二区三区三区免费| 99久久婷婷国产精品综合| 日韩高清欧美激情| 国产精品国产精品国产专区不片| 欧美精品v国产精品v日韩精品 | 五月天激情综合| 欧美一区二区美女| av午夜精品一区二区三区| 午夜精品久久久久久久99水蜜桃| 久久精品一区八戒影视| 欧美性猛交一区二区三区精品| 国产精品一区二区久久精品爱涩| 亚洲一区二区三区国产| 国产欧美一区视频| 欧美一区二视频| 色视频一区二区| 国产高清久久久久| 欧美aa在线视频| 亚洲国产综合色| 亚洲欧美偷拍三级| 久久久久久亚洲综合影院红桃| 欧美日韩在线亚洲一区蜜芽| 国产91高潮流白浆在线麻豆 | 一色屋精品亚洲香蕉网站| 日韩一区二区免费高清| 91麻豆文化传媒在线观看| 国产精选一区二区三区| 天天av天天翘天天综合网| 国产精品乱码一区二区三区软件| 日韩一区二区三区免费看| 精品视频在线视频| 94-欧美-setu| thepron国产精品| 亚洲靠逼com| 久久精品欧美日韩精品| 欧美成人video| 51久久夜色精品国产麻豆| 一本久久综合亚洲鲁鲁五月天| 成人精品鲁一区一区二区| 国产一区二区三区久久悠悠色av| 香蕉av福利精品导航| 亚洲一区二区高清| 亚洲精品视频自拍| 亚洲婷婷综合色高清在线| 中文一区一区三区高中清不卡| 2021久久国产精品不只是精品| 日韩西西人体444www| 91精品国产综合久久精品麻豆| 欧美亚一区二区| 欧美三级韩国三级日本一级| 欧洲视频一区二区| 欧美三级视频在线| 欧美日韩国产成人在线免费| 欧美性受xxxx黑人xyx性爽| 欧美日韩一本到| 91麻豆精品国产91久久久更新时间| 精品视频资源站| 日韩写真欧美这视频| 久久先锋影音av鲁色资源| 国产日韩精品一区二区三区| 国产蜜臀av在线一区二区三区| 国产精品久线在线观看| 一区二区三区在线视频观看58| 香港成人在线视频| 蜜桃传媒麻豆第一区在线观看| 精品一区二区免费视频| 国产黄色精品视频| 91丨porny丨蝌蚪视频| 欧美日韩一区二区三区在线| 日韩女优毛片在线| 国产精品日韩精品欧美在线| 亚洲精品午夜久久久| 奇米精品一区二区三区在线观看| 狠狠色丁香九九婷婷综合五月| 国产成人午夜片在线观看高清观看| voyeur盗摄精品| 777欧美精品| 国产拍欧美日韩视频二区| 一区二区三区小说| 美国av一区二区| 99久久久无码国产精品| 91精品国产综合久久小美女| www激情久久| 欧美国产精品一区二区三区| 亚洲福利一区二区| 国产一区二区三区免费播放| 一本到三区不卡视频| 91精品国产一区二区三区| 国产精品三级视频| 日韩制服丝袜av| www.成人在线| 精品日韩一区二区三区免费视频| 国产精品久久一级| 午夜精品福利视频网站| 国产黄色91视频| 欧美一区二区三区视频免费| 国产精品久久看| 久久超碰97人人做人人爱| 色94色欧美sute亚洲线路一ni| 欧美mv日韩mv国产| 亚洲gay无套男同| 成人午夜视频免费看| 欧美一区二区在线看| 亚洲男女一区二区三区| 国产一区二区在线电影| 91麻豆精品久久久久蜜臀| 亚洲欧洲精品成人久久奇米网| 蜜臀va亚洲va欧美va天堂| 在线日韩av片| 国产精品久久久久国产精品日日| 蜜桃视频免费观看一区| 91久久人澡人人添人人爽欧美| 久久久99精品免费观看| 蜜臀av性久久久久蜜臀aⅴ| 欧美性做爰猛烈叫床潮| 亚洲视频一区二区在线观看| 丁香婷婷综合色啪| 久久精品一区蜜桃臀影院| 免费观看在线色综合| 欧美性三三影院| 尤物av一区二区| 91免费看视频| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 一区二区三区91| 99国产精品久久久久| 国产精品久久夜| 成人免费视频网站在线观看| 欧美精品一区二区三区视频| 蜜臀国产一区二区三区在线播放| 欧美三级电影一区| 一区二区三区国产精品| av在线这里只有精品| 国产精品久久久久毛片软件| 国产福利一区二区三区| 久久久蜜桃精品| 国产大片一区二区| 日本一区二区视频在线| 成人少妇影院yyyy| 国产精品伦一区二区三级视频| 成人18视频在线播放| 国产精品区一区二区三区 | 国产传媒日韩欧美成人| 久久亚洲影视婷婷| 激情久久五月天| 久久久99免费| 成人av免费网站| 国产精品乱码一区二三区小蝌蚪| 丰满少妇久久久久久久| 国产欧美一区二区三区网站| 国产1区2区3区精品美女| 国产精品视频观看| 在线观看视频91| 亚洲成人高清在线| 欧美岛国在线观看| 毛片一区二区三区| 国产日韩欧美综合在线| 91丨九色丨国产丨porny| 亚洲成av人片一区二区梦乃| 91精品在线观看入口| 美女www一区二区| 国产精品人人做人人爽人人添| 日本高清不卡在线观看| 舔着乳尖日韩一区| 久久久久久久久蜜桃| 一本一道久久a久久精品| 视频在线观看一区| 久久久久97国产精华液好用吗| 99久久精品免费|