?? eeprom.c
字號:
*(BOOT_FLASH_SECTOR_0_XAAA) = 0x55; // unlock main flash, write 0x55 to addess 0xXAAA
*(BOOT_FLASH_SECTOR_0_X555) = 0x80; // write 0x80 command to erase entire chip
*(BOOT_FLASH_SECTOR_0_X555) = 0xAA; // continue unlock sequence
*(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;
WORD 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*) (§or_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*) (§or_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 + -