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

📄 eeprom.c

📁 ST公司的upsd dk2000评估板仿真eeprom的源程序。
💻 C
📖 第 1 页 / 共 3 页
字号:
		*(BOOT_FLASH_SECTOR_0_XAAA) = 0x55;		// continue unlock sequence
		*((volatile unsigned char xdata *)SECTOR_0_BASE_ADDRESS) = 0x30;// erase sector
		break;
	case SECTOR_1:
		*(BOOT_FLASH_SECTOR_1_X555) = 0xAA;		// unlock main flash, write 0xAA to addess 0xX555
		*(BOOT_FLASH_SECTOR_1_XAAA) = 0x55;		// unlock main flash, write 0x55 to addess 0xXAAA
		*(BOOT_FLASH_SECTOR_1_X555) = 0x80;		// write 0x80 command to erase entire chip
		*(BOOT_FLASH_SECTOR_1_X555) = 0xAA;     // continue unlock sequence
		*(BOOT_FLASH_SECTOR_1_XAAA) = 0x55;		// continue unlock sequence
		*((volatile unsigned char xdata *)SECTOR_1_BASE_ADDRESS) = 0x30;// erase sector
		break;
	case SECTOR_2:
		*(BOOT_FLASH_SECTOR_2_X555) = 0xAA;		// unlock main flash, write 0xAA to addess 0xX555
		*(BOOT_FLASH_SECTOR_2_XAAA) = 0x55;		// unlock main flash, write 0x55 to addess 0xXAAA
		*(BOOT_FLASH_SECTOR_2_X555) = 0x80;		// write 0x80 command to erase entire chip
		*(BOOT_FLASH_SECTOR_2_X555) = 0xAA;     // continue unlock sequence
		*(BOOT_FLASH_SECTOR_2_XAAA) = 0x55;		// continue unlock sequence
		*((volatile unsigned char xdata *)SECTOR_2_BASE_ADDRESS) = 0x30;// erase sector
		break;
	case SECTOR_3:
		*(BOOT_FLASH_SECTOR_3_X555) = 0xAA;		// unlock main flash, write 0xAA to addess 0xX555
		*(BOOT_FLASH_SECTOR_3_XAAA) = 0x55;		// unlock main flash, write 0x55 to addess 0xXAAA
		*(BOOT_FLASH_SECTOR_3_X555) = 0x80;		// write 0x80 command to erase entire chip
		*(BOOT_FLASH_SECTOR_3_X555) = 0xAA;     // continue unlock sequence
		*(BOOT_FLASH_SECTOR_3_XAAA) = 0x55;		// continue unlock sequence
		*((volatile unsigned char xdata *)SECTOR_3_BASE_ADDRESS) = 0x30;// erase sector
		break;
	default:
		return 1;

	}
   	return 0;
}

/***** Eeprom_Sector_Erase_Suspend*****/
// Susupend Erases one boot flash sector.
// Accepts sector number (0-3).
// Returns 0 for successful erasure. If error, returns 1. 
BYTE Eeprom_Sector_Erase_Suspend(BYTE sector)
{
	switch (sector)
	{
	case SECTOR_0:
		*((volatile unsigned char xdata *)SECTOR_0_BASE_ADDRESS) = 0xB0;// Suspend erase sector
		break;
	case SECTOR_1:
		*((volatile unsigned char xdata *)SECTOR_1_BASE_ADDRESS) = 0xB0;// Suspend erase sector
		break;
	case SECTOR_2:
		*((volatile unsigned char xdata *)SECTOR_2_BASE_ADDRESS) = 0xB0;// Suspend erase sector
		break;
	case SECTOR_3:
		*((volatile unsigned char xdata *)SECTOR_3_BASE_ADDRESS) = 0xB0;// Suspend erase sector
		break;
	default:
		return 1;
	}


   	return 0;
}

/***** Eeprom_Sector_Erase_Resume*****/
// Resume Erases one boot flash sector.
// Accepts sector number (0-3).
// Returns 0 for successful erasure. If error, returns 1. 
BYTE Eeprom_Sector_Erase_Resume(BYTE sector)
{
	switch (sector)
	{
	case SECTOR_0:
		*((volatile unsigned char xdata *)SECTOR_0_BASE_ADDRESS) = 0x30;// Resume erase sector
		break;
	case SECTOR_1:
		*((volatile unsigned char xdata *)SECTOR_1_BASE_ADDRESS) = 0x30;// Resume erase sector
		break;
	case SECTOR_2:
		*((volatile unsigned char xdata *)SECTOR_2_BASE_ADDRESS) = 0x30;// Resume erase sector
		break;
	case SECTOR_3:
		*((volatile unsigned char xdata *)SECTOR_3_BASE_ADDRESS) = 0x30;// Resume erase sector
		break;
	default:
		return 1;
	}

   	return 0;
}

/***** Eeprom_Sector_Erase_Status *****/
// Gets status of sector erase.
// Accepts sector number (0-3).
// Returns 0 if erase cycle finished. Returns 1 if erase in progress. 
BYTE Eeprom_Sector_Erase_Status(BYTE sector)
{
	BYTE poll;

	switch (sector)
	{
	case SECTOR_0:
		poll = *((volatile unsigned char xdata *)SECTOR_0_BASE_ADDRESS);
		return !( poll & 0x80); 
	case SECTOR_1:
		poll = *((volatile unsigned char xdata *)SECTOR_1_BASE_ADDRESS);
		return !( poll & 0x80); 
	case SECTOR_2:
		poll = *((volatile unsigned char xdata *)SECTOR_2_BASE_ADDRESS);
		return !( poll & 0x80); 
	case SECTOR_3:
		poll = *((volatile unsigned char xdata *)SECTOR_3_BASE_ADDRESS);
		return !( poll & 0x80); 
	default:
		return 1;
	}
   	return 0;
}

/***** Find_Next_Address *****/
// Finds next available address for data record.
// Returns next available address. 
WORD Find_Next_Address(void)
{
	BYTE xdata valid_sector;
	xdata struct sector_header xdata header;
	xdata struct record_entry xdata record;
	WORD address;
	BYTE *ptr;
	WORD i;

	// Find valid sector
	valid_sector = Find_Active_Sector(F_WRITE);
	if ( valid_sector == SECTOR_ID_ERROR ) return SECTOR_ID_ERROR;

	// Get sector header
	ptr = (BYTE*) (&header);
	address = SECTOR_0_BASE_ADDRESS + ((WORD)valid_sector * SECTOR_SIZE);	
	for ( i=0; i<(WORD)sizeof(header); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ );
	}

	// Calculate address
	address = SECTOR_0_BASE_ADDRESS + ((WORD)valid_sector * SECTOR_SIZE) + 	// sector base address
	(WORD)sizeof(header) + 													// sector header
	(header.max_records * (WORD)sizeof(record));							// first instance of each record
	ptr = (BYTE*) (&record);
	for ( i=0; i < SECTOR_SIZE; i += sizeof(record) )
	{
		if ( Boot_Flash_Read( address ) == UNINITIALIZED ) return address;
		address += sizeof(record);
		if ( address >= (SECTOR_0_BASE_ADDRESS + ((WORD)valid_sector * SECTOR_SIZE) 
			+ SECTOR_SIZE - (WORD)sizeof(record)) ) return SECTOR_FULL;
	}
	return ADDRESS_ERROR;
}


/***** Find_Active_Sector *****/
// Finds active sector.
// Returns sector number. 
// If error, returns error code. 
BYTE Find_Active_Sector(BYTE io)
{
	xdata struct sector_header xdata header0;
	xdata struct sector_header xdata header1;
	WORD address;
	BYTE *ptr;
	BYTE i;

	// Check sector 0 for status	
	ptr = (BYTE*) (&header0);
	address = SECTOR_0_BASE_ADDRESS;
	for ( i=0; i < sizeof(header0); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ );
	}
	// Check sector 1 for status	
	ptr = (BYTE*) (&header1);
	address = SECTOR_1_BASE_ADDRESS;
	for ( i=0; i < sizeof(header1); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ ); 
	}	

	switch (io)
	{
	case F_WRITE: // write
		if( header0.sector_status == VALID__SECTOR )
		{
			if( header1.sector_status == RECEIVE_DATA )
			{
				return (SECTOR_1);
			} 
			else
			{
				return (SECTOR_0); 
			}
		}
		else if( header1.sector_status == VALID__SECTOR )			 
		{
			if( header0.sector_status == RECEIVE_DATA )
			{
				return (SECTOR_0);
			}
			else
			{
				return (SECTOR_1); 
			}
		}
	case F_READ:  // read  
		if( header0.sector_status == VALID__SECTOR )
		{	    
			return (SECTOR_0); 
		}
		else if( header1.sector_status == VALID__SECTOR )           
		{
			return (SECTOR_1); 
		}			 
	default: 
	        return (SECTOR_0); 		
	}
	return 1;
}


/***** Eeprom_Sector_Swap *****/
// Transfers data from full sector to empty one.
// Returns new sector number. 
 BYTE Eeprom_Sector_Swap(WORD inn, BYTE xdata *buf)
{
	xdata struct sector_header xdata sector_header_old;
	xdata struct sector_header xdata sector_header_new; 
	xdata struct record_entry xdata buffer; 		   	
	BYTE *ptr; 
	BYTE xdata id;
	BYTE *ptr_old;
	BYTE *ptr_new;
	WORD address;
	BYTE xdata status;
	BYTE i;
	BYTE xdata valid_sector;
	WORD xdata new_sector; // place holder for the sector we are moving to
	WORD xdata old_sector; // place holder for the sector we are moving from
        
	// get active sector  (This is the sector we are moving from)
	valid_sector = Find_Active_Sector(F_READ);
		if ( valid_sector == SECTOR_ID_ERROR ) return SECTOR_ID_ERROR;

	if(valid_sector == SECTOR_1)
	{
		new_sector = SECTOR_0_BASE_ADDRESS;  // move data to this sector
		old_sector = SECTOR_1_BASE_ADDRESS;  // move data from this sector
		sector_header_new.sector = SECTOR_0;
	}
	else
	{
		new_sector = SECTOR_1_BASE_ADDRESS; // move data to this sector
		old_sector = SECTOR_0_BASE_ADDRESS; // move data from this sector
		sector_header_new.sector = SECTOR_1;
	}
		
	// Get old sector header
	ptr_old = (BYTE*) (&sector_header_old);
	address = old_sector;
	for ( i=0; i < sizeof(sector_header_old); i++ )
	{		
        ptr_old[i] = Boot_Flash_Read(address++);
	}

	// Verify new sector is erased
	if ( Eeprom_Sector_Erase(sector_header_new.sector) ) return SECTOR_ERASE_ERROR;

	sector_header_new.sector_checksum = ~(sector_header_new.sector);
	sector_header_new.max_records = sector_header_old.max_records;
	sector_header_new.rec_length = (WORD)EEPROM_RECORD_SIZE;
	sector_header_new.sector_status = RECEIVE_DATA;

	// mark receiving sector (new sector)      
	// mark new sector to receive 
	address = new_sector; 
	ptr_new = (BYTE*) (&sector_header_new);
	for ( i=0; i < sizeof(sector_header_new); i++ )
	{  
		if ( Boot_Flash_Write( address++, ptr_new[i] ) ) return FLASH_WRITE_ERROR;      
	}
                    
	for (id=0; id < sector_header_old.max_records; id++)
	{                       
		if(id == inn) 
		{ 
			ptr = buf; // add the new record as the data is swapped into the new sector 
			status = 0;
		}
		else
		{
			ptr = (BYTE*) (&buffer);
			status = Read_Record(id, ptr);
		}
		if( status != UNINITIALIZED ) Write_Record( id, ptr );			            
	}
      
	// mark good and bad sectors

	// mark old sector TRANSFER_COMPLETE BEFORE marking new sector ACTIVE 
	sector_header_old.sector_status =  TRANSFER_COMPLETE;                      
	address = old_sector; 
	for ( i=0; i < sizeof(sector_header_old); i++ )
	{  
		if ( Boot_Flash_Write( address++, ptr_old[i] ) ) return FLASH_WRITE_ERROR;      
	}

	// mark new sector ACTIVE AFTER marking old TRANSFER_COMPLETE   
	sector_header_new.sector_status =   VALID__SECTOR;      
	address = new_sector; 
	for ( i=0; i < sizeof(sector_header_new); i++ )
	{  
		if ( Boot_Flash_Write( address++, ptr_new[i] ) ) return FLASH_WRITE_ERROR;      
	}
	
	// Start erase of old sector
	if ( Eeprom_Sector_Erase_Start(valid_sector) ) return SECTOR_ERASE_ERROR;
			
	return 0;
}

/***** ERASE and FORMAT SECTOR *****/
// Erases and formats a sector.
// Accepts sector number, type of operation and max records allowed.
// Legal sectors are:
// 	SECTOR_0 for address 0x8000
//	SECTOR_1 for address 0xA000
// If error, returns error code.
BYTE E_andF_Sector(BYTE sector, WORD max_rec)
{                                          
	xdata struct sector_header xdata header;           
	BYTE i;
	WORD address;
	BYTE *ptr;

	header.sector_status = VALID__SECTOR;
	header.sector = sector;
	header.sector_checksum = ~(sector);
	header.max_records = max_rec;
	header.rec_length = (WORD)EEPROM_RECORD_SIZE;

	if(sector == SECTOR_0) address = SECTOR_0_BASE_ADDRESS;
	if(sector == SECTOR_1) address = SECTOR_1_BASE_ADDRESS;

	if ( Eeprom_Sector_Erase(sector) ) return SECTOR_ERASE_ERROR;

	ptr = (BYTE*) (&header);

	// write sector header		
	for ( i=0; i < sizeof( header ); i++ ) 
	{
		if ( Boot_Flash_Write( address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
	}

	return 0;
}

/***** Get_Sector_Status *****/
// Returns sector status.
// If error, returns INVALID_STATUS. 
BYTE Get_Sector_Status(BYTE sector)
{
	xdata struct sector_header xdata header;
	WORD address;
	BYTE *ptr;
	BYTE i;

	// Get sector header	
	ptr = (BYTE*) (&header);
	address = SECTOR_0_BASE_ADDRESS + (sector * SECTOR_SIZE);
	for ( i=0; i < sizeof(header); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ );
	}
	
	switch (header.sector_status)
	{
		case ERASED:
			return ERASED;
		case RECEIVE_DATA:
			return RECEIVE_DATA;
		case VALID__SECTOR:
			return VALID__SECTOR;
		case TRANSFER_COMPLETE:
			return TRANSFER_COMPLETE;
		default:
			return INVALID_STATUS;			
	}
}

⌨️ 快捷键说明

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