Strange EEPROM behavior on Xmega

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

Hi,

 

Two weeks ago I wrote this piece of c++ code to use the EEPROM on atxmega32d4 and atxmega16d4 devices. The code worked perfectly fine back then, but now the code seems to be malfunctioning in some way. The EEPROM gets cleared when I remove and connect the power to the chip. I can read the EEPROM directly after I've written it successfully, but when I cycle power I read 0xFF no matter what was written to the EEPROM before the power cycle. I've tried this on 3 devices. Is there maybe some error in my code that causes it to behave unpredictable or has anybody got another explanation for this?

 

Thank you in advance,

Jasper

void EEPROM_write(uint32_t addr, uint32_t data, uint8_t bytesToWrite){
	int i;
	for(i = 0; i < bytesToWrite; i++){
		while(NVM_STATUS & NVM_NVMBUSY_bm){}
		NVM_CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
		NVM_ADDR0 = (addr + i) & 0xFF;
		NVM_ADDR1 = ((addr + i) & 0x0F00) >> 8;
		NVM_ADDR2 = 0x00;
		NVM_DATA0 =  ((data & (0xFF << (8 * i))) >> (8 * i));

		NVM_CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;
		//uint32_t tempAddr = addr << 12;
		//NVM_ADDR0 = (addr + i) & 0xFF;
		//NVM_ADDR1 = ((addr + i) & 0x0F00) >> 8;
		//NVM_ADDR2 = 0x00;
		CCP = CCP_IOREG_gc; //Trigger protection mechanism
		NVM_CTRLA = NVM_CMDEX_bm;
	}

}

uint32_t EEPROM_read(uint32_t addr, uint8_t bytesToRead){
	uint32_t tempDataOut = 0;
	int i;
	for(i = 0; i < bytesToRead; i++){
		while(NVM_STATUS & NVM_NVMBUSY_bm){}
		NVM_ADDR0 = (addr + i) & 0xFF;
		NVM_ADDR1 = ((addr + i) & 0x0F00) >> 8;
		NVM_ADDR2 = 0x00;
		NVM_CMD = NVM_CMD_READ_EEPROM_gc;
		CCP = CCP_IOREG_gc; //Trigger protection mechanism
		NVM_CTRLA = NVM_CMDEX_bm;
		tempDataOut |= NVM_DATA0 << (i * 8);
	}

	return tempDataOut;

}

 

Last Edited: Wed. May 10, 2017 - 08:25 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is the BOD set up correctly?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

The chip does have BOD enabled at the correct level for Vcc? As the Vcc rail comes up or dies down when power is applied/removed capacitance means the voltage will move through a "mid zone" between 0 and full Vcc where the operation of the chip is not guaranteed. One thing that can occur as it transits this region is EEPROM corruption. BOD will hold the chip in Reset until the Vcc has reached your given operating voltage.

 

Almost all the Xmega datasheets will have a section similar to this....

 

 

BTW why have you written EEPROM routines from scratch? Surely the C++ compiler comes with EEPROM support routines?

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

Thank you for your reply! I haven't looked into the BOD settings. What settings do you recommend for the BOD?

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

I thought that premade functions were only available in C. Where should I be able to find these functions?

 

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

It should be set to trigger at a level just below your intended operating Vcc.

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

Okay thank you! I'll try this when I get home

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

One other thing, might be worth disabling interrupts while you write to EEPROM. Not strictly necessary but a good idea for safety.

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

Hi there,

 

Setting up the BOD and disabling interrupts didn't cut it..... Still experiencing the same issues. Is there maybe something wrong with my code?? (I doubt it because it didn't have any problems functioning before). Any other suggestions?

 

Jasper

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void EEPROM_write(uint32_t addr, uint32_t data, uint8_t bytesToWrite){

I wonder if you are somehow writing to SRAM and not EEPROM. Your symptoms suggest it.

Because it is possible to memory map the EEPROM to 0x1000 so it works like it's SRAM when reading the EEPROM (very fast and easy access).

 

 

 

 

 

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

If you are using mapping, remember to disable it before writing to EEPROM.

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

I'll ask again why you are reinventing the wheel? Surely your C compiler already has (tried/tested) EEPROM support?

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

Hi,

 

The mapping works perfectly! Thanks for the tip. And I couldn't find an easy EEPROM library or something like that...

 

Jasper

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

Which C compiler is that then? For example the GCC compiler has this...

 

http://www.nongnu.org/avr-libc/u...

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

clawson wrote:

Which C compiler is that then? For example the GCC compiler has this...

 

http://www.nongnu.org/avr-libc/u...

 

Does anyone use this for XMEGA? It seems like it is aimed more at the other 8 bit models.

 

I use just code based off AVR1315, which is focused more on whole page writes.

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

Well it's there for the users of the C compiler if they want it (just as it always was for tiny and mega before).

 

As one can see in the source...

 

http://svn.savannah.gnu.org/view...

 

The majority of the code is actually there for the __AVR_XMEGA__ case in fact.