Flash endurance and partial flash page writes

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello

I am in the process of sacrificing a mega163 to find out how many times I can write and erase a single page of the flash memory. I'm not specifically interested in the actual number of writes possible, but whether multiple writes to a page between erasures would lower the endurance.

In my program I need to write to the flash in blocks of only 8 bytes, and because it's possible that I only need to write a single block of 8 bytes to the flash at one time, Erasing the entire flash page to and rewriting it with the existing contents would be wasteful as far as flash endurance. Normally you must clear the page and rewrite it because you can only set the flash bits to 0 without erasing the entire page, but if you write 0xFF's to unused bytes, you may perform another write to the page without affecting portions that have already been written.

My mega163 is up to around 300,000 full page writes and subsequent erasures, so I'm curious if anybody knows what the expected endurance is, simply because I'm getting tired of waiting for it to fail. My simulation of the flash failing worked, right? :shock:

John Butera

/* John Butera */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's done over 2 millions writes and erasures to the same flash page. Is this right or is there something wrong with my code?

#include "common.h"
#include 

#pragma segment="Boot"

void PageErase(void __flash* addr) @ "Boot";
void PageLoad(void __flash* addr, unsigned short data) @ "Boot";
void PageWrite(void __flash* addr) @ "Boot";
void PageFillChar(void __flash* addr, unsigned char data);
unsigned char PageCmpChar(unsigned char __flash* addr, unsigned char data);

int main(void)
{
	void __flash* addr = (void __flash *)0x3780;
	unsigned long count = 0;	
	unsigned char value = 1;
	unsigned char data = 0;
	
	__disable_interrupt();
	LCD_init();
	
	while(value == 1)
	{
		PageErase(addr);
		PageFillChar(addr, data);
		PageWrite(addr);
		value = PageCmpChar(addr, data);
		LCD_instr(0x02);
		LCD_hex32(count);
		count++;
		data++;
	}
}

unsigned char PageCmpChar(unsigned char __flash* addr, unsigned char data)
{
	unsigned char x;
	
	for (x = 0; x < 128; addr++, x++)
	{
		if (__load_program_memory(addr) != data)
			return 0;
	}
	
	return 1;
}

void PageFillChar(void __flash* addr, unsigned char data)
{
	unsigned int address = (unsigned int)addr;
	unsigned char x;
	
	for (x = 0; x < 64; address += 2, x++)
		PageLoad((void __flash*)address, (data*0x100)+data);
}

void PageErase(void __flash* addr)
{
	__AddrToZByteToSPMCR_SPM(addr, 0x03);
	__insert_opcode(0xFFFF);
	__insert_opcode(0x0000);
	while(SPMCR & (1 << SPMEN));
}

void PageLoad(void __flash* addr, unsigned short data)
{
	__AddrToZWordToR1R0ByteToSPMCR_SPM(addr, data, 0x01);
	__insert_opcode(0xFFFF);
	__insert_opcode(0x0000);
	while(SPMCR & (1 << SPMEN));
}

void PageWrite(void __flash* addr)
{
	__AddrToZByteToSPMCR_SPM(addr, 0x05);
	__insert_opcode(0xFFFF);
	__insert_opcode(0x0000);
	while(SPMCR & (1 << SPMEN));
}

/* John Butera */