EEMEM usage problem

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

I've been trying to use EEPROM in my current ATmega328P project. To make sure it's working, I start with a uint32_t value of 180,000,000, write a slightly different value to EEPROM and read it back. I'm not getting back what I've written. As an experiment, I dropped the EEMEM usage and went to absolute addresses. Now I get the correct result. But I don't know why.

Original code (copied from a couple different files):

Here I define the original value of sysclk and the new value I want to write / recall from EEPROM. Then statements to do that. In reality, I did the write statement in one run, commented it out, and did the read statement.

   	uint32_t sysclk = 180000000UL; //
   	uint32_t newsys = 179995960UL; // for testing

(snip ...)

	DDS_write_osc_ee(); // A TEST WRITE TO EEPROM DID ONCE 

	DDS_read_osc_ee(); // GET SYS CLOCK FREQ FROM EEPROM 

Here I define an EEPROM location and have two short routines to write and read back my value ...

/* I'm declaring EEPROM names here.  EEPROM will be handled in DDS.c
	because its main use is the calibration routine.
*/

	uint32_t EEMEM sysclk_ee;


// ************ Save current reference freq to EE memory ****************

    void DDS_write_osc_ee()
	{
		eeprom_write_dword(&sysclk_ee, newsys); // newsys is for testing

	}

// *********** Read stored reference clock freq from EE memory *************

	void DDS_read_osc_ee()
	{
		sysclk = eeprom_read_dword(&sysclk_ee);

	}

Changes I made to get expected results:

What I did was just hard code the read and write functions to use EEPROM address 0 instead of using the address assigned by EEMEM. It's still in the source code but I don't reference the label sysclk_ee anywhere.

// ************ Save current reference freq to EE memory ****************

    void DDS_write_osc_ee()
	{
	//	eeprom_write_dword(&sysclk_ee, newsys); // newsys is for testing
		eeprom_write_dword((uint32_t*) 0, newsys); // newsys is for testing
	}

// *********** Read stored reference clock freq from EE memory *************

	void DDS_read_osc_ee()
	{
	//	sysclk = eeprom_read_dword(&sysclk_ee);
	sysclk = eeprom_read_dword((uint32_t*) 0);

	}

Now that I've got it working I'm tempted to just move on, but I'd like to know what I'm doing wrong when I use EEMEM.

Thanks,

Nick

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

Pararameter-less/return-less functions? You sure? Presumably newsys is global is it?

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

nickkennedy wrote:
I'm not getting back what I've written.
Not very descriptive. What did you get, exactly? Was it reproducible? Did you try writing different values? How did it change what was read back, if at all?

Quote:
In reality, I did the write statement in one run, commented it out, and did the read statement.
Huh? You mean you:
  1. commented out the read statement
  2. built and uploaded to flash
  3. ran application on device
  4. uncommented the read, commented the write
  5. built and uploaded to flash
  6. ran application on device
  7. observed the value read from EEPROM
If that's what you did, you should know that step 5 causes EEPROM to be erased, so the value written during step 3 is lost.

Unless you've programmed the EESAVE fuse, a flash write operation over ISP will erase all of EEPROM. Every EEPROM location will contain 0xFF. Taken as a uint32_t you would see the value 4,294,967,295.

Is that what you're seeing?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Thanks for that information. I can't believe I've gone this long without knowing about the EESAVE fuse. Now it appears that my writes are persistent and also that EEMEM was not part of my problem.

Quote:

Not very descriptive. What did you get, exactly? Was it reproducible? Did you try writing different values? How did it change what was read back, if at all?

I hadn't written any code to have it read back the value, so I could only see the effect in the frequency produced (this is a DDS synthesizer control program, among other things). It did appear consistent and now I see that the result I was getting was consistent with reading back a full house value of 0xFFFFFFFF as you suggested.

So now I've cleared the EESAVE bit and restored the use of EEMEM and the function seems to be working normally.

Thanks,

Nick

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

Quote:

Presumably newsys is global is it?

My guess is indeed that newsys is e.g. uint16_t.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
My guess is indeed that newsys is e.g. uint16_t.
Huh?
uint32_t newsys = 179995960UL; // for testing 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]