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

📄 eeprom.c

📁 ST公司的upsd dk2000评估板仿真eeprom的源程序。
💻 C
📖 第 1 页 / 共 3 页
字号:

	// set old record to update in progress
	address = last_address;
	for ( i=0; i<sizeof(record); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ );
	}
	record.status = UPDATE_DATA;
	address = last_address;
	for ( i=0; i < sizeof(record); i++ )
	{
		if ( Boot_Flash_Write( address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
	}

	// write data to new address
	address = new_address;
	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
	}
	address = new_address;
	for ( i=0; i < sizeof(record); i++ )
	{
		if ( Boot_Flash_Write( address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
	}

	// update old record to superseded
	address = last_address;
	for ( i=0; i<sizeof(record); i++ )
	{
		ptr[i] = Boot_Flash_Read( address++ );
	}
	record.status = SUPERSEDED;
	record.last_record_update = new_address;
	address = last_address;
	for ( i=0; i < sizeof(record); i++ )
	{
		if ( Boot_Flash_Write( address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
	}

	return 0;
}

/***** Boot_Flash_Write *****/
// Writes data byte to secondary flash.
// Accepts address in flash; data (byte).
// Returns 0 for successful write. If error, returns 1. 
BYTE Boot_Flash_Write(WORD address, BYTE data_byte)
{
	BYTE xdata readback;
	BYTE xdata done;
	BYTE xdata error;
	BYTE xdata err;
	BYTE xdata poll;
	BYTE xdata erase_flag_0 = 0;
	BYTE xdata erase_flag_1 = 0;
	static BYTE reentry_flag;

	// check for re-entrant call to this function
	if ( reentry_flag ) return FLASH_ACCESS_ERROR;

	reentry_flag = 1;

	// un-comment for re-entrancy test
	//EA = 1;		/* enable interrupts */

	done = FALSE;
   	err = FALSE;

	// suspend any erase in progress		
	if ( Eeprom_Sector_Erase_Status(SECTOR_0) )
    {
		if ( Eeprom_Sector_Erase_Suspend(SECTOR_0) ) return SECTOR_ERASE_ERROR;
		erase_flag_0 = 1;
	}
	if ( Eeprom_Sector_Erase_Status(SECTOR_1) )
    {
		if ( Eeprom_Sector_Erase_Suspend(SECTOR_1) ) return SECTOR_ERASE_ERROR;
		erase_flag_1 = 1;
	}

	// disable interrupts during flash write sequence
	EA = 0;

	// write data byte
	*((char xdata *) (SECTOR_0_BASE_ADDRESS + 0x0555)) = 0xAA;
	*((char xdata *) (SECTOR_0_BASE_ADDRESS + 0x0AAA)) = 0x55;
	*((char xdata *) (SECTOR_0_BASE_ADDRESS + 0x0555)) = 0xA0;
	*((char xdata *) address) = data_byte;

	// enable interrupts following write
	EA = 1;

	// now use dat polling method to verify successful write
	do
    {  
   		poll = *((char xdata *) address);	// Read the location that was just programmed
		error = poll & NVM_ERROR;		// save timeout error bit at DQ5
		poll = poll & NVM_DATA_POLL;	// get DQ7 of poll byte read from flash  

		if ((data_byte & NVM_DATA_POLL) == poll)	// compare DQ7 
			done = TRUE;		// dat byte programmed into flash OK, indicate successful exit criteria
		else if (error == NVM_ERROR)	// check for timeout error   
			err = TRUE;					// indicate timeout error occurred

    } while((done == FALSE) && (err == FALSE));

	// make sure timeout error and dat poll didn't occur simultaneously
	if (err == TRUE)                
	{
   		poll = *((char xdata *) address);	// Read location in flash again
		poll = poll & NVM_DATA_POLL;   				// get DQ7 of poll byte read from flash  

		if ((data_byte & NVM_DATA_POLL) == poll)	// compare DQ7 
			done = TRUE;	// dat byte programmed into flash OK at the same time timout 
							//error occured, indicate successful exit criteria

		*((char xdata *) (SECTOR_0_BASE_ADDRESS + 0x0555)) = 0xF0;
		//*((char xdata *) 0x0555) = 0xF0;	// reset the flash array (short reset instruction) 
	}	        							// now delay 3 msec per dat sheet

	// verify successful write by reading back data and comparing with original	
	readback = *((char xdata *) address);	// readback data from flash

	// resume any suspended erase
	if ( erase_flag_0 )
	{
		if ( Eeprom_Sector_Erase_Resume(SECTOR_0) ) return SECTOR_ERASE_ERROR;
	}
	if ( erase_flag_1 )
	{
		if ( Eeprom_Sector_Erase_Resume(SECTOR_1) ) return SECTOR_ERASE_ERROR;
	}

	reentry_flag = 0;

	return !(readback == data_byte);	// if valid return success
}

/***** Read_Record_Data_Structure *****/
// Reads an entire record structure from memory.
// Accepts record id number.
// Returns address of last record. If error, returns error message.
WORD Read_Record_Data_Structure(WORD id_number, BYTE* buffer)
{
	BYTE xdata valid_sector = 0xFF;
	xdata struct sector_header xdata header;
	xdata struct record_entry xdata record;
	BYTE i;
	BYTE *ptr;
	BYTE xdata *data_buf;
	WORD 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;
	 }

	// Get last record
	for (i=0; i<sizeof(record); i++)
	{
		data_buf[i] = Boot_Flash_Read(last_address++);
	}

	// return address of last record
	return last_address - sizeof(record);
}

/***** Boot_Flash_Read *****/
// Reads data from secondary flash.
// Accepts address.
// Returns data at address. 
BYTE Boot_Flash_Read(WORD address)
{	
	BYTE xdata erase_flag_0 = 0;
	BYTE xdata erase_flag_1 = 0;
	BYTE data_byte;
	static BYTE xdata reentry_flag;

	// check for re-entrant call to this function
	if ( reentry_flag ) return FLASH_ACCESS_ERROR;

	reentry_flag = 1;

	// un-comment for re-entrancy test
	//EA = 1;		/* enable interrupts */

	// suspend any erase in progress		
	if ( Eeprom_Sector_Erase_Status(SECTOR_0) )
    {
		if ( Eeprom_Sector_Erase_Suspend(SECTOR_0) ) return SECTOR_ERASE_ERROR;
		erase_flag_0 = 1;
	}
	if ( Eeprom_Sector_Erase_Status(SECTOR_1) )
    {
		if ( Eeprom_Sector_Erase_Suspend(SECTOR_1) ) return SECTOR_ERASE_ERROR;
		erase_flag_1 = 1;
	}

	// read data byte from flash
	data_byte = *((char xdata *) address);

	// resume any suspended erase
	if ( erase_flag_0 )
	{
		if ( Eeprom_Sector_Erase_Resume(SECTOR_0) ) return SECTOR_ERASE_ERROR;
	}
	if ( erase_flag_1 )
	{
		if ( Eeprom_Sector_Erase_Resume(SECTOR_1) ) return SECTOR_ERASE_ERROR;
	}

	reentry_flag = 0;

	return data_byte;
}

/***** Eeprom_Sector_Erase *****/
// Erases one boot flash sector.
// Accepts sector number (0-3).
// Returns 0 for successful erasure. If error, returns 1. 
BYTE Eeprom_Sector_Erase(BYTE sector)
{
	BYTE xdata done;
 	BYTE xdata poll;
 	BYTE xdata error;
 	BYTE xdata err;

	done = FALSE;
   	err = FALSE;

	switch (sector)
	{
	case SECTOR_0:
		*(BOOT_FLASH_SECTOR_0_X555) = 0xAA;		// unlock main flash, write 0xAA to addess 0xX555
		*(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
		do		  			// now use dat polling method to verify successful erase
    	{  
			poll = *((volatile unsigned char xdata *)SECTOR_0_BASE_ADDRESS); 	// read flash status from any address
			error = poll & NVM_ERROR;	// save timeout error bit at DQ5
			poll = poll & NVM_DATA_POLL;	// look at D7   
			if ( poll == NVM_DATA_POLL )	// compare DQ7 
				done = TRUE;		// bulk erase OK,
			else if (error == NVM_ERROR)	// check for timeout error   
				err = TRUE;		// indicate timeout error occurred
    	} while( (done == FALSE) && (err == FALSE) ); 
		if ( err == TRUE )			// make sure timeout error and dat poll didn't occur simultaneously
    	{
			poll = *((volatile unsigned char xdata *)SECTOR_0_BASE_ADDRESS); 	// Read flash status again
			poll = poll & NVM_DATA_POLL;	// get DQ7 of poll byte read from flash  
			if (poll == NVM_DATA_POLL)		// compare DQ7 
				done = TRUE;				// the flash erased OK at the same time timout error occured
			*(BOOT_FLASH_SECTOR_0_X555) = 0xF0;  // reset the flash array (short reset instruction) 
    	}
		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
		do		  			// now use dat polling method to verify successful erase
    	{  
			poll = *((volatile unsigned char xdata *)SECTOR_1_BASE_ADDRESS); 	// read flash status from any address
			error = poll & NVM_ERROR;	// save timeout error bit at DQ5
			poll = poll & NVM_DATA_POLL;	// look at D7   
			if ( poll == NVM_DATA_POLL )	// compare DQ7 
				done = TRUE;		// bulk erase OK,
			else if (error == NVM_ERROR)	// check for timeout error   
				err = TRUE;		// indicate timeout error occurred
    	} while( (done == FALSE) && (err == FALSE) ); 
		if ( err == TRUE )			// make sure timeout error and dat poll didn't occur simultaneously
    	{
			poll = *((volatile unsigned char xdata *)SECTOR_1_BASE_ADDRESS); 	// Read flash status again
			poll = poll & NVM_DATA_POLL;	// get DQ7 of poll byte read from flash  
			if (poll == NVM_DATA_POLL)		// compare DQ7 
				done = TRUE;				// the flash erased OK at the same time timout error occured
			*(BOOT_FLASH_SECTOR_0_X555) = 0xF0;  // reset the flash array (short reset instruction) 
    	}
		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
		do		  			// now use dat polling method to verify successful erase
    	{  
			poll = *((volatile unsigned char xdata *)SECTOR_2_BASE_ADDRESS); 	// read flash status from any address
			error = poll & NVM_ERROR;	// save timeout error bit at DQ5
			poll = poll & NVM_DATA_POLL;	// look at D7   
			if ( poll == NVM_DATA_POLL )	// compare DQ7 
				done = TRUE;		// bulk erase OK,
			else if (error == NVM_ERROR)	// check for timeout error   
				err = TRUE;		// indicate timeout error occurred
    	} while( (done == FALSE) && (err == FALSE) ); 
		if ( err == TRUE )			// make sure timeout error and dat poll didn't occur simultaneously
    	{
			poll = *((volatile unsigned char xdata *)SECTOR_2_BASE_ADDRESS); 	// Read flash status again
			poll = poll & NVM_DATA_POLL;	// get DQ7 of poll byte read from flash  
			if (poll == NVM_DATA_POLL)		// compare DQ7 
				done = TRUE;				// the flash erased OK at the same time timout error occured
			*(BOOT_FLASH_SECTOR_0_X555) = 0xF0;  // reset the flash array (short reset instruction) 
    	}
		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
		do		  			// now use dat polling method to verify successful erase
    	{  
			poll = *((volatile unsigned char xdata *)SECTOR_3_BASE_ADDRESS); 	// read flash status from any address
			error = poll & NVM_ERROR;	// save timeout error bit at DQ5
			poll = poll & NVM_DATA_POLL;	// look at D7   
			if ( poll == NVM_DATA_POLL )	// compare DQ7 
				done = TRUE;		// bulk erase OK,
			else if (error == NVM_ERROR)	// check for timeout error   
				err = TRUE;		// indicate timeout error occurred
    	} while( (done == FALSE) && (err == FALSE) ); 
		if ( err == TRUE )			// make sure timeout error and dat poll didn't occur simultaneously
    	{
			poll = *((volatile unsigned char xdata *)SECTOR_3_BASE_ADDRESS); 	// Read flash status again
			poll = poll & NVM_DATA_POLL;	// get DQ7 of poll byte read from flash  
			if (poll == NVM_DATA_POLL)		// compare DQ7 
				done = TRUE;				// the flash erased OK at the same time timout error occured
			*(BOOT_FLASH_SECTOR_0_X555) = 0xF0;  // reset the flash array (short reset instruction) 
    	}
		break;
	default:
		return 1;
	}

   	return !(done);	
}

/***** Eeprom_Sector_Erase_Start*****/
// Start Erases one boot flash sector.
// Accepts sector number (0-3).
// Returns 0 for successful erasure. If error, returns 1. 
BYTE Eeprom_Sector_Erase_Start(BYTE sector)
{
	switch (sector)
	{
	case SECTOR_0:
		*(BOOT_FLASH_SECTOR_0_X555) = 0xAA;		// unlock main flash, write 0xAA to addess 0xX555
		*(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

⌨️ 快捷键说明

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