Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

need variables to be stored in EEPROM

need variables to be stored in EEPROM

2005-04-25 by arhodes19044

I see in the docs how to use the registers to access the EEPROM on 
my ATmega128.

However, Which part of it is allowed to be used?  Is there nothing 
in it unless I use it myself?

Does GCC-avr give me tools to allocate variables in eeprom 
automatically?  Should I use MALLOC in some manner?  I see some 
basic tools in libc to access EEPROM at a very low level.  Are there 
some higher level access routines?

I guess I do not really need much in the way of routines.  But it 
would be nice to have variables taged in some manner as residing in 
EEPROM, then I can read and write to them as normal variables with 
the access taken care-of invisibly in the background.

I only have a few variables of various sizes to save, but I may want 
to use the rest as a data-logging function, in some sort of circular 
buffer.  The circular buffer would be accessed as a big array 
structure, probably.

-Tony

Re: need variables to be stored in EEPROM

2005-04-25 by arhodes19044

Actually, that struct idea is just perfect.

I definitely was planning on keeping an SRAM version of the 
variables, then only save the requesite info when necessary.

One of these will be a "first-run" flag which will allow 
initialization of the EEPROM, then there are some setting and 
calibration values to keep.  Most of the time I will have time to 
write then verify the data.  Maybe once in a while the writes will 
occur during a time-critical period, so those (what is it? 4ms to 
write?).  I can not turn off interrupts because there is a 1ms clock 
tick interrupt.  Other less important interrupts occur at a MAXIMUM 
frequency of every 1.8ms.  And usually those interrupts will be 
every 45ms or so!

Anyway, I can not disable interupts, but I can verify at the end.

From the code I saw, I would not have thought that interrupting the 
register loading process would be a problem, but maybe it uses that 
TEMP register.  I have not looked at the specific doc for the 128 
yet.  About to, tho.

Thanks for the ideas.

-Tony


--- In AVR-Chat@yahoogroups.com, Philipp Adelt <p.adelt@w...> wrote:
> Hi Tony,
> 
> arhodes19044 schrieb:
> > I see in the docs how to use the registers to access the EEPROM 
on 
> > my ATmega128.
> > 
> > However, Which part of it is allowed to be used?  Is there 
nothing 
> > in it unless I use it myself?
> 
> This is correct, you can use each and every byte. There have been 
> rumours that the first types of AVR had a problem with "random" 
> corruption of the very first EEPROM cell at address 0. Most people 
tell 
> that Atmel has fixed the problem in newer (mega) devices. Others 
say 
> that due to the improved startup behavior of newer device types 
> (including the advent of the brown-out detector) bad user design 
is less 
> likely to lead to execution of random commands that could lead to 
> corruption of address 0. (Remember that in a brown-out condition, 
an AVR 
> can easily execute >10million errors per second..)
> 
> > Does GCC-avr give me tools to allocate variables in eeprom 
> > automatically?  Should I use MALLOC in some manner?  I see some 
> > basic tools in libc to access EEPROM at a very low level.  Are 
there 
> > some higher level access routines?
> 
> AFAIK, the avr-libc routines in avr/eeprom.h are as good as it 
gets. You 
> could write your own macros of course. Remember to respect the 
timed 
> write requirements from the data sheet (or the avr-libc routines). 
This 
> includes disabling interrupts or a scheme to re-try writing if you 
can't 
> afford turning them off.
> Malloc won't be your friend, it will allocate you a heap chunk of 
SRAM.
> 
> > I only have a few variables of various sizes to save, but I may 
want 
> > to use the rest as a data-logging function, in some sort of 
circular 
> > buffer.  The circular buffer would be accessed as a big array 
> > structure, probably.
> 
> The easy way is to put all your EEPROM variables into a struct, 
hold an 
> instance of that struct in SRAM and save the entire sizeof(struct) 
bytes 
> into the EEPROM as a block (avr-libc has a nice function for 
that). If 
> SRAM is so tight that you can't afford holding a copy of the data 
in it, 
Show quoted textHide quoted text
> this won't help.
> 
> Philipp

Re: [AVR-Chat] need variables to be stored in EEPROM

2005-04-25 by Philipp Adelt

Hi Tony,

arhodes19044 schrieb:
> I see in the docs how to use the registers to access the EEPROM on 
> my ATmega128.
> 
> However, Which part of it is allowed to be used?  Is there nothing 
> in it unless I use it myself?

This is correct, you can use each and every byte. There have been 
rumours that the first types of AVR had a problem with "random" 
corruption of the very first EEPROM cell at address 0. Most people tell 
that Atmel has fixed the problem in newer (mega) devices. Others say 
that due to the improved startup behavior of newer device types 
(including the advent of the brown-out detector) bad user design is less 
likely to lead to execution of random commands that could lead to 
corruption of address 0. (Remember that in a brown-out condition, an AVR 
can easily execute >10million errors per second..)

> Does GCC-avr give me tools to allocate variables in eeprom 
> automatically?  Should I use MALLOC in some manner?  I see some 
> basic tools in libc to access EEPROM at a very low level.  Are there 
> some higher level access routines?

AFAIK, the avr-libc routines in avr/eeprom.h are as good as it gets. You 
could write your own macros of course. Remember to respect the timed 
write requirements from the data sheet (or the avr-libc routines). This 
includes disabling interrupts or a scheme to re-try writing if you can't 
afford turning them off.
Malloc won't be your friend, it will allocate you a heap chunk of SRAM.

> I only have a few variables of various sizes to save, but I may want 
> to use the rest as a data-logging function, in some sort of circular 
> buffer.  The circular buffer would be accessed as a big array 
> structure, probably.

The easy way is to put all your EEPROM variables into a struct, hold an 
instance of that struct in SRAM and save the entire sizeof(struct) bytes 
into the EEPROM as a block (avr-libc has a nice function for that). If 
SRAM is so tight that you can't afford holding a copy of the data in it, 
this won't help.

Philipp

Re: need variables to be stored in EEPROM

2005-04-25 by arhodes19044

Yes, I can see that the structure will provide a convenient 
technique to read & write the entire block.

It has been a long time since I worked with structures.  Is there a 
way to get the offset of the element within the structure?  
Something like "&structure.element".  This way, I can start with the 
location of the structure in SRAM or in EEPROM and then access the 
individual element by base + offset.  Will sizeof() work with 
structure elements?

I keep forgetting what stuff I used to do was in C++.  Like I was 
sure I could pass a variable by reference and then use it as a 
regular variable in the called subroutine (instead of dereferencing 
by using *var).  Nope that was C++.

I used to get slightly into the object oriented structures, but I 
found it more confusing that more simple structures.  I forget if 
the dot operator (I seem to remember that is its name) is C++ only.

I obviously have more homework to do.

It is impressive (to me) how fast C is coming back to me considering 
I only used it for about 2 years continuously, then 4 years 
intermittently, then not at all for the last 12 years.

-Tony



--- In AVR-Chat@yahoogroups.com, David Kelly <dkelly@h...> wrote:
> On Mon, Apr 25, 2005 at 05:12:13PM -0000, arhodes19044 wrote:
> > 
> > 
> > Actually, that struct idea is just perfect.
> > 
> > I definitely was planning on keeping an SRAM version of the 
> > variables, then only save the requesite info when necessary.
> > 
> > One of these will be a "first-run" flag which will allow 
> > initialization of the EEPROM, then there are some setting and 
> > calibration values to keep.
> 
> You can compile the default values of your EEPROM contents into 
your
> code by placing them in the .eeprom section. This way the ISP 
and/or
> JTAG programmer will write them when the FLASH code is written 
during
> production.
> 
> As for the syntax of compiling EEPROM variables all I can say 
is, "I've
> done it" but don't have an example under my fingertips or in CVS. 
IIRC
> the variables were defined in a .c source file reserved 
specifically for
> this purpose. In the Makefile this one source file was compiled 
with an
> option to map .data to .eeprom, or some such thing.
> 
> It may be one can tag the variable with an attribute to place it in
> EEPROM.
> 
> One has to be careful with this sort of mapping to EEPROM because 
these
> variables can not be reached without special handling, yet appear 
to
> have addresses same as any other variable.
> 
> So one might use a typedef to define the struct which is to contain
> EE-backed data. Then use the typedef to allocate one in eeprom and
> another in sram.
> 
> //  in ee_backed.h file place something like this:
> typedef struct {
> 	uint32_t	serial_number;
> 	uint8_t		cal[8];
> } EE_BACKED;
> 
> // in a code file place something like this:
> #include "ee_backed.h"
> EE_BACKED sram_ee;
> 
> // then in a special file just for ee variables:
> #include "ee_backed.h"
> uint8_t	im_afraid_to_use_byte_0;
> EE_BACKED ee_ee.
> 
> Then someplace, probably your startup code in main():
> 
> eeprom_read_block( &sram_ee, &ee_ee, sizeof(sram_ee) );
> 
> The whole point is to make the compiler do the work of allocating a
> local copy and of keeping track of where the data was stashed in 
eeprom.
> 
> -- 
> David Kelly N4HHE, dkelly@H...
> 
=====================================================================
===
> Whom computers would destroy, they must first drive mad.

Re: need variables to be stored in EEPROM

2005-04-25 by arhodes19044

Great!  I do not remember the "offsetof()" function.  I will look it 
up right now.  THANKS

-Tony

--- In AVR-Chat@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 07:16 PM 4/25/05 +0000, arhodes19044 wrote:
> >It has been a long time since I worked with structures.  Is there 
a
> >way to get the offset of the element within the structure?
> >Something like "&structure.element".  This way, I can start with 
the
> >location of the structure in SRAM or in EEPROM and then access the
> >individual element by base + offset.  Will sizeof() work with
> >structure elements?
> 
> Look for the standard macro offsetof().  And yes sizeof works with 
> structure elements, although depending on the compiler and micro 
adding up 
> the sizes of the previous elements will not necessarily give the 
same 
> answer as offsetof (I expect it would on an AVR).
> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,   be 
> they legal, genetic, or physical.  If you don't believe me, try to 
chew a 
> radio signal. "  -- Kelvin Throop, III
> http://www.aeolusdevelopment.com/

Re: need variables to be stored in EEPROM

2005-04-25 by arhodes19044

Oh yeah.  I remember the pain of figuring when to use the > vs . 
operators.  pointer references or whatever.  OUCH!!!  Well, I will 
go through it again.

2 reasons.  The structure needed for the initializer variables, then 
the data log which is a PERFECT structure application.

so as I remember it will be struct_name>item, but log-array[x].item.

or maybe I have it backward.  I have to check.  Once you get it down 
it is nice and easy.  Confusing otherwise.  

-Tony

--- In AVR-Chat@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 07:16 PM 4/25/05 +0000, arhodes19044 wrote:
> >It has been a long time since I worked with structures.  Is there 
a
> >way to get the offset of the element within the structure?
> >Something like "&structure.element".  This way, I can start with 
the
> >location of the structure in SRAM or in EEPROM and then access the
> >individual element by base + offset.  Will sizeof() work with
> >structure elements?
> 
> Look for the standard macro offsetof().  And yes sizeof works with 
> structure elements, although depending on the compiler and micro 
adding up 
> the sizes of the previous elements will not necessarily give the 
same 
> answer as offsetof (I expect it would on an AVR).
> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,   be 
> they legal, genetic, or physical.  If you don't believe me, try to 
chew a 
> radio signal. "  -- Kelvin Throop, III
> http://www.aeolusdevelopment.com/

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-25 by Dennis Clark

Tony,

   About disabling interrupts during EEPROM writes, see below:

arhodes19044 wrote:
> 
> Actually, that struct idea is just perfect.
> 
> I definitely was planning on keeping an SRAM version of the 
> variables, then only save the requesite info when necessary.
> 
> One of these will be a "first-run" flag which will allow 
> initialization of the EEPROM, then there are some setting and 
> calibration values to keep.  Most of the time I will have time to 
> write then verify the data.  Maybe once in a while the writes will 
> occur during a time-critical period, so those (what is it? 4ms to 
> write?).  I can not turn off interrupts because there is a 1ms clock 
> tick interrupt.  Other less important interrupts occur at a MAXIMUM 
> frequency of every 1.8ms.  And usually those interrupts will be 
> every 45ms or so!
> 
> Anyway, I can not disable interupts, but I can verify at the end.

   You might want to check the data sheet before you think this:
"
1. Wait until EEWE becomes zero.
2. Write new EEPROM address to EEAR (optional).
3. Write new EEPROM data to EEDR (optional).
4. Write a logical one to the EEMWE bit in EECR.
5. Within four clock cycles after setting EEMWE, write a logical one to 
EEWE.
Caution: An interrupt between step 4 and step 5 will make the write 
cycle fail, since the
EEPROM Master Write Enable will time-out. If an interrupt routine 
accessing the
EEPROM is interrupting another EEPROM access, the EEAR or EEDR Register 
will be
modified, causing the interrupted EEPROM access to fail. It is 
recommended to have
the Global Interrupt Flag cleared during all the steps to avoid these 
problems.
"
It is a good idea to disable interrupts before writing a byte to EEPROM.


> From the code I saw, I would not have thought that interrupting the 
> register loading process would be a problem, but maybe it uses that 
> TEMP register.  I have not looked at the specific doc for the 128 
> yet.  About to, tho.
> 
> Thanks for the ideas.
> 
> -Tony
[snip]

DLC
-- 
---------------------------------------
Dennis Clark    TTT Enterprises
---------------------------------------

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-25 by David Kelly

On Mon, Apr 25, 2005 at 05:12:13PM -0000, arhodes19044 wrote:
> 
> 
> Actually, that struct idea is just perfect.
> 
> I definitely was planning on keeping an SRAM version of the 
> variables, then only save the requesite info when necessary.
> 
> One of these will be a "first-run" flag which will allow 
> initialization of the EEPROM, then there are some setting and 
> calibration values to keep.

You can compile the default values of your EEPROM contents into your
code by placing them in the .eeprom section. This way the ISP and/or
JTAG programmer will write them when the FLASH code is written during
production.

As for the syntax of compiling EEPROM variables all I can say is, "I've
done it" but don't have an example under my fingertips or in CVS. IIRC
the variables were defined in a .c source file reserved specifically for
this purpose. In the Makefile this one source file was compiled with an
option to map .data to .eeprom, or some such thing.

It may be one can tag the variable with an attribute to place it in
EEPROM.

One has to be careful with this sort of mapping to EEPROM because these
variables can not be reached without special handling, yet appear to
have addresses same as any other variable.

So one might use a typedef to define the struct which is to contain
EE-backed data. Then use the typedef to allocate one in eeprom and
another in sram.

//  in ee_backed.h file place something like this:
typedef struct {
	uint32_t	serial_number;
	uint8_t		cal[8];
} EE_BACKED;

// in a code file place something like this:
#include "ee_backed.h"
EE_BACKED sram_ee;

// then in a special file just for ee variables:
#include "ee_backed.h"
uint8_t	im_afraid_to_use_byte_0;
EE_BACKED ee_ee.

Then someplace, probably your startup code in main():

eeprom_read_block( &sram_ee, &ee_ee, sizeof(sram_ee) );

The whole point is to make the compiler do the work of allocating a
local copy and of keeping track of where the data was stashed in eeprom.

-- 
David Kelly N4HHE, dkelly@HiWAAY.net
========================================================================
Whom computers would destroy, they must first drive mad.

Re: need variables to be stored in EEPROM

2005-04-25 by arhodes19044

Thanks!  That jump starts my usage of the structures.  You have been 
a geat help!

-Tony

--- In AVR-Chat@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 08:18 PM 4/25/05 +0000, arhodes19044 wrote:
> >Oh yeah.  I remember the pain of figuring when to use the > vs .
> >operators.  pointer references or whatever.  OUCH!!!  Well, I will
> >go through it again.
> 
> name->item is a pointer dereference (it's a two character operator)
> name.item is simply a non-pointer reference.
> 
> Given
> 
> struct sdf {
>     int a;
>     int b;
> } *ptr, non_ptr;
> 
> You would use
> 
> non_ptr.a = ptr->a;
> 
> Or
> 
> non_ptr.a = (*ptr).a;
> 
> Both lines have the same meaning.  It's not really an array/non-
array type 
> of difference although it can show up in that context.
> 
> Of course you should init the pointer to something valid first ;)
> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,   be 
> they legal, genetic, or physical.  If you don't believe me, try to 
chew a 
> radio signal. "  -- Kelvin Throop, III
> http://www.aeolusdevelopment.com/

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-25 by David Kelly

On Mon, Apr 25, 2005 at 01:38:57PM -0500, David Kelly wrote:
> 
> As for the syntax of compiling EEPROM variables all I can say is, "I've
> done it" but don't have an example under my fingertips or in CVS. IIRC
> the variables were defined in a .c source file reserved specifically for
> this purpose. In the Makefile this one source file was compiled with an
> option to map .data to .eeprom, or some such thing.

It was simpler than I remembered. This puts ee_serial_number in EEPROM:

uint32_t ee_serial_number __attribute__ ((section (".eeprom")));

-- 
David Kelly N4HHE, dkelly@HiWAAY.net
========================================================================
Whom computers would destroy, they must first drive mad.

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-25 by Robert Adsett

At 07:16 PM 4/25/05 +0000, arhodes19044 wrote:
>It has been a long time since I worked with structures.  Is there a
>way to get the offset of the element within the structure?
>Something like "&structure.element".  This way, I can start with the
>location of the structure in SRAM or in EEPROM and then access the
>individual element by base + offset.  Will sizeof() work with
>structure elements?

Look for the standard macro offsetof().  And yes sizeof works with 
structure elements, although depending on the compiler and micro adding up 
the sizes of the previous elements will not necessarily give the same 
answer as offsetof (I expect it would on an AVR).

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-25 by Robert Adsett

At 08:18 PM 4/25/05 +0000, arhodes19044 wrote:
>Oh yeah.  I remember the pain of figuring when to use the > vs .
>operators.  pointer references or whatever.  OUCH!!!  Well, I will
>go through it again.

name->item is a pointer dereference (it's a two character operator)
name.item is simply a non-pointer reference.

Given

struct sdf {
    int a;
    int b;
} *ptr, non_ptr;

You would use

non_ptr.a = ptr->a;

Or

non_ptr.a = (*ptr).a;

Both lines have the same meaning.  It's not really an array/non-array type 
of difference although it can show up in that context.

Of course you should init the pointer to something valid first ;)

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-25 by David Kelly

On Mon, Apr 25, 2005 at 07:16:15PM -0000, arhodes19044 wrote:
> 
> Yes, I can see that the structure will provide a convenient 
> technique to read & write the entire block.
> 
> It has been a long time since I worked with structures.  Is there a 
> way to get the offset of the element within the structure?  
> Something like "&structure.element".  This way, I can start with the 
> location of the structure in SRAM or in EEPROM and then access the 
> individual element by base + offset.  Will sizeof() work with 
> structure elements?

Yes, and yes.

But remember if one tries (&structure.element - &structure) pointer
arithmetic may come into play. Make casts to (size_t) before doing the
math. Thats the point of the offsetof() macro mentioned.

#define offsetof(type, field) ((size_t)(&((type *)0)->field))

For the above to work your structure has to be in a typedef.

-- 
David Kelly N4HHE, dkelly@HiWAAY.net
========================================================================
Whom computers would destroy, they must first drive mad.

Re: need variables to be stored in EEPROM

2005-04-26 by arhodes19044

OK, I got EEPROM writes and reads working with a minimum of fuss.  
The macro offsetof() worked beautifully.  I even understood how it 
was working!!!!  Amazing.

I found that I had to cast it as a (void*) when I went to use it in 
an eeprom_write_block() function.  I even made that long instruction 
its own macro.  So, a macro within a macro.  worked the first time.  
I could not believe it.   I was sure it was going to write somewhere 
off in address space causing a major crash!  It simply worked.

I have nearly completed all the "hard" basic interacting-with-
hardware tasks.  Soon, I will be implementing the interaction with 
external input hardware.  Half of which will use pulse detector 
logic and latches.  The rest will function as sense switches to 
alter what the LCD displays are doing. 

All in all it is going very smoothly.  Once I get it finalized I 
will then see what the minimal AVR hardware is necessary and maybe 
make a custom PCB to mount it all.

-Tony

--- In AVR-Chat@yahoogroups.com, David Kelly <dkelly@h...> wrote:
> On Mon, Apr 25, 2005 at 07:16:15PM -0000, arhodes19044 wrote:
> > 
> > Yes, I can see that the structure will provide a convenient 
> > technique to read & write the entire block.
> > 
> > It has been a long time since I worked with structures.  Is 
there a 
> > way to get the offset of the element within the structure?  
> > Something like "&structure.element".  This way, I can start with 
the 
> > location of the structure in SRAM or in EEPROM and then access 
the 
> > individual element by base + offset.  Will sizeof() work with 
> > structure elements?
> 
> Yes, and yes.
> 
> But remember if one tries (&structure.element - &structure) pointer
> arithmetic may come into play. Make casts to (size_t) before doing 
the
> math. Thats the point of the offsetof() macro mentioned.
> 
> #define offsetof(type, field) ((size_t)(&((type *)0)->field))
> 
> For the above to work your structure has to be in a typedef.
> 
> -- 
> David Kelly N4HHE, dkelly@H...
> 
=====================================================================
===
> Whom computers would destroy, they must first drive mad.

Re: need variables to be stored in EEPROM

2005-04-26 by arhodes19044

--- In AVR-Chat@yahoogroups.com, Dennis Clark <dlc@f...> wrote:
> 
> Tony,
> 1. Wait until EEWE becomes zero.
> 2. Write new EEPROM address to EEAR (optional).
> 3. Write new EEPROM data to EEDR (optional).
> 4. Write a logical one to the EEMWE bit in EECR.
> 5. Within four clock cycles after setting EEMWE, write a logical 
one to 
> EEWE.
> Caution: An interrupt between step 4 and step 5 will make the 
write 
> cycle fail, since the
> EEPROM Master Write Enable will time-out. If an interrupt routine 
> accessing the
> EEPROM is interrupting another EEPROM access, the EEAR or EEDR 
Register 
> will be
> modified, causing the interrupted EEPROM access to fail. It is 
> recommended to have
> the Global Interrupt Flag cleared during all the steps to avoid 
these 
> problems.
> "
> It is a good idea to disable interrupts before writing a byte to 
EEPROM.
> DLC
> -- 
> ---------------------------------------
> Dennis Clark    TTT Enterprises
> ---------------------------------------





OOOOPS.  That last part, 4 clock cyles, is pretty critical timing.  
I COULD disable interrupts for just step 4 and 5.

I can modify the code for the  Libc eeprom code to suit that.  This 
is a very brief suspension. of the interrupts.

What I do not want to do is to disable interupts for the entire 
duration of a multi-byte eeprom write.  That could be many many 
milliseconds.  But if the interrupts are suspended briefly, but 
repetetively, then that is not really a problem.

Do you think it is necessary to have interrupts suspended for all 
the steps?  Is there a limit to the duration of data sitting on the 
eeprom data registers?  Actually it does not seem as if all the 
steps between 2-5 would take that long.  While step 1 is waiting, 
interupts could be enabled.

I will check the atmega128 docs on eeprom reading and writing.  I 
printed the pertinent info out, but did not yet read it since the   
I had such luck with the built-in funtions.  Of course right now, I 
only have the millisecond timer interrupt occuring.  In real life I 
would have an external interrupt triggering at a regualr, but 
probably slow (10's of ms) rate.

I will see if I can find the C/ASM code for the eeprom so I can hand-
tune the interrupts.

-Tony

Re: need variables to be stored in EEPROM

2005-04-26 by arhodes19044

--- In AVR-Chat@yahoogroups.com, David Kelly <dkelly@h...> wrote:

> It was simpler than I remembered. This puts ee_serial_number in 
EEPROM:
> 
> uint32_t ee_serial_number __attribute__ ((section (".eeprom")));
> 
> -- 
> David Kelly N4HHE, dkelly@H...
> 
=====================================================================
===
> Whom computers would destroy, they must first drive mad.

OK, I like this technique because _I_ do not have to keep track of 
the address of variables in EEPROM.  But....

Always a but.  How do I use this command.  I tried it in the C 
source inside main().  This gave errors.  

I then put it into the makefile, and I got no errors, but who knows 
what it did with the command.  When I referenced the variable, I got 
an "undeclared" error.

So, where I I put the command you suggest, and then how do I use the 
resulting variable?

-Tony

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-26 by Dennis Clark

arhodes19044 wrote:
> 
> --- In AVR-Chat@yahoogroups.com, Dennis Clark <dlc@f...> wrote:
> 
>>Tony,
>>1. Wait until EEWE becomes zero.
>>2. Write new EEPROM address to EEAR (optional).
>>3. Write new EEPROM data to EEDR (optional).
>>4. Write a logical one to the EEMWE bit in EECR.
>>5. Within four clock cycles after setting EEMWE, write a logical 
> 
> one to 
> 
>>EEWE.
>>Caution: An interrupt between step 4 and step 5 will make the 
> 
> write 
> 
>>cycle fail, since the
>>EEPROM Master Write Enable will time-out. If an interrupt routine 
>>accessing the
>>EEPROM is interrupting another EEPROM access, the EEAR or EEDR 
> 
> Register 
> 
>>will be
>>modified, causing the interrupted EEPROM access to fail. It is 
>>recommended to have
>>the Global Interrupt Flag cleared during all the steps to avoid 
> 
> these 
> 
>>problems.
>>"
>>It is a good idea to disable interrupts before writing a byte to 
> 
> EEPROM.
> 
>>DLC
>>-- 
>>---------------------------------------
>>Dennis Clark    TTT Enterprises
>>---------------------------------------
> 
> 
> 
> 
> 
> 
> OOOOPS.  That last part, 4 clock cyles, is pretty critical timing.  
> I COULD disable interrupts for just step 4 and 5.
> 
> I can modify the code for the  Libc eeprom code to suit that.  This 
> is a very brief suspension. of the interrupts.

Yup.

> What I do not want to do is to disable interupts for the entire 
> duration of a multi-byte eeprom write.  That could be many many 
> milliseconds.  But if the interrupts are suspended briefly, but 
> repetetively, then that is not really a problem.
> 
> Do you think it is necessary to have interrupts suspended for all 
> the steps?  Is there a limit to the duration of data sitting on the 
> eeprom data registers?  Actually it does not seem as if all the 
> steps between 2-5 would take that long.  While step 1 is waiting, 
> interupts could be enabled.

Those are the only timing critical steps, that is what I'd do.

> I will check the atmega128 docs on eeprom reading and writing.  I 
> printed the pertinent info out, but did not yet read it since the   
> I had such luck with the built-in funtions.  Of course right now, I 
> only have the millisecond timer interrupt occuring.  In real life I 
> would have an external interrupt triggering at a regualr, but 
> probably slow (10's of ms) rate.
> 
> I will see if I can find the C/ASM code for the eeprom so I can hand-
> tune the interrupts.
> 
> -Tony
>

DLC
-- 
---------------------------------------
Dennis Clark    TTT Enterprises
---------------------------------------

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-26 by David Kelly

On Tue, Apr 26, 2005 at 03:33:07PM -0000, arhodes19044 wrote:
> 
> OOOOPS.  That last part, 4 clock cyles, is pretty critical timing.  
> I COULD disable interrupts for just step 4 and 5.
> 
> I can modify the code for the  Libc eeprom code to suit that.  This 
> is a very brief suspension. of the interrupts.

I haven't looked at the avr-libc version but wrote my own, it ain't that
hard. However this code hasn't been tested yet:

//
//	write to EEPROM
//		addr is the address within the EEPROM
//		cp is where to read data in RAM
//		n is the number of 8 bit octets to copy
//
void
ee_writes(uint16_t addr, void *cp, uint8_t n)
{
	for( ; n ; n-- ) {
		wdt_reset();
		while( EECR & (1<<EEWE) )	//  wait until ready
			;
		
		EEAR = addr & (2048-1);	//  stripped to 11 bits, 2kB
		EEDR = *((uint8_t*)(cp)++);	//  looks frightening
		addr++;
	
		cli();			//  an IRQ would ruin this timing
		EECR |= (1<<EEMWE);	//  only stays set for 4 clocks
		EECR |= (1<<EEWE);	//  hit EEWE before EEMWE clears
		sei();			//  assume IRQ was enabled
	}
}

-- 
David Kelly N4HHE, dkelly@HiWAAY.net
========================================================================
Whom computers would destroy, they must first drive mad.

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-26 by David Kelly

On Tue, Apr 26, 2005 at 06:10:12PM -0000, arhodes19044 wrote:
> 
> OK, I like this technique because _I_ do not have to keep track of 
> the address of variables in EEPROM.  But....
> 
> Always a but.  How do I use this command.  I tried it in the C 
> source inside main().  This gave errors.  
> 
> I then put it into the makefile, and I got no errors, but who knows 
> what it did with the command.  When I referenced the variable, I got 
> an "undeclared" error.
> 
> So, where I I put the command you suggest, and then how do I use the 
> resulting variable?

I don't quite follow your problem. Does this answer your question?

#include <avr/eeprom.h>

typedef struct {
	int	a,
		b,
		c;
	char	s[32];
} EEDATA;

EEDATA eedata __attribute__ ((section (".eeprom")));
EEDATA data;

void
main()
{
	while(1) {
		data.a = 0;
		eeprom_read_block( &data, &eedata, sizeof(data) );
		
		data.a++;
		eeprom_write_block( &data, &eedata, sizeof(data) );
	}
}

-- 
David Kelly N4HHE, dkelly@HiWAAY.net
========================================================================
Whom computers would destroy, they must first drive mad.

Re: need variables to be stored in EEPROM

2005-04-26 by arhodes19044

This makes sense.  Did you truncate off the high bits down to (2048-
1)because the CPU you were using had only 2k bytes of EERPROM?  
Since the 128 has 4K, I guess then the address would be truncated to 
(4096-1)?

-Tony

--- In AVR-Chat@yahoogroups.com, David Kelly <dkelly@h...> wrote:
> On Tue, Apr 26, 2005 at 03:33:07PM -0000, arhodes19044 wrote:
> > 
> > OOOOPS.  That last part, 4 clock cyles, is pretty critical 
timing.  
> > I COULD disable interrupts for just step 4 and 5.
> > 
> > I can modify the code for the  Libc eeprom code to suit that.  
This 
> > is a very brief suspension. of the interrupts.
> 
> I haven't looked at the avr-libc version but wrote my own, it 
ain't that
> hard. However this code hasn't been tested yet:
> 
> //
> //	write to EEPROM
> //		addr is the address within the EEPROM
> //		cp is where to read data in RAM
> //		n is the number of 8 bit octets to copy
> //
> void
> ee_writes(uint16_t addr, void *cp, uint8_t n)
> {
> 	for( ; n ; n-- ) {
> 		wdt_reset();
> 		while( EECR & (1<<EEWE) )	//  wait until ready
> 			;
> 		
> 		EEAR = addr & (2048-1);	//  stripped to 11 bits, 2kB
> 		EEDR = *((uint8_t*)(cp)++);	//  looks frightening
> 		addr++;
> 	
> 		cli();			//  an IRQ would ruin this 
timing
> 		EECR |= (1<<EEMWE);	//  only stays set for 4 
clocks
> 		EECR |= (1<<EEWE);	//  hit EEWE before EEMWE 
clears
> 		sei();			//  assume IRQ was enabled
> 	}
> }
> 
> -- 
> David Kelly N4HHE, dkelly@H...
> 
=====================================================================
===
> Whom computers would destroy, they must first drive mad.

Re: need variables to be stored in EEPROM

2005-04-26 by arhodes19044

--- In AVR-Chat@yahoogroups.com, David Kelly <dkelly@h...> wrote:
> I don't quite follow your problem. Does this answer your question?
> 
> #include <avr/eeprom.h>
> 
> typedef struct {
> 	int	a,
> 		b,
> 		c;
> 	char	s[32];
> } EEDATA;
> 
> EEDATA eedata __attribute__ ((section (".eeprom")));
> EEDATA data;
> 
> void
> main()
> {
> 	while(1) {
> 		data.a = 0;
> 		eeprom_read_block( &data, &eedata, sizeof(data) );
> 		
> 		data.a++;
> 		eeprom_write_block( &data, &eedata, sizeof(data) );
> 	}
> }
> 
> -- 
> David Kelly N4HHE, dkelly@H...
> 
=====================================================================
===
> Whom computers would destroy, they must first drive mad.


Yes, this does show it explicitly.  I tried something similar, but 
allocated individual variables instead of a structure because I will 
nearly always be accessing them totally individually, only once in 
the beginning as a block.

When I did this and initialized the eeprom variables, I got odd, 
numbers looking like uninitialized data (in avr studio watch 
screens).  When I read and wrote them I still got numbers that were 
not the uninitialized strange #'s.  I will look at this more....

-Tony

Re: [AVR-Chat] Re: need variables to be stored in EEPROM

2005-04-27 by David Kelly

On Apr 26, 2005, at 8:33 PM, arhodes19044 wrote:

> This makes sense.  Did you truncate off the high bits down to (2048-
> 1)because the CPU you were using had only 2k bytes of EERPROM?
> Since the 128 has 4K, I guess then the address would be truncated to
> (4096-1)?

The target is intended to be an ATmega64L, so when I code that is the 
manual I'm looking at. Is only recently I've had my 64L target hardware 
running so previously was loading on a MAVRIC-II and staying within the 
64 subset on the 128.

Masking values to the available range is an old habit in attempt to 
fail in a safe way and doesn't do much good here. No doubt if one tries 
to write a value too large to EEAR the effective address will be masked 
and wrapped-around by the hardware. And if one aims to be safe, thats 
the wrong way to do it. If out of range the read/write should be 
ignored, not forced to fit.

Have spent some time this afternoon looking at the avr-libc routines 
eeprom_read_block() and eeprom_write_block(). If you have looked at the 
source code I don't understand your (previous?) concern about IRQ. The 
write routine only disables IRQ for the minimum possible interval 
exactly the same as mine.

Then I started playing with my ee_writes() and ee_reads() routines in 
C, making them closer to the library's assembly routines. My count is 
only 8 bits rather than size_t's 16 bits, but my C generates smaller 
code by a few bytes. No big deal. But I'd rather have C in my project 
than assembly in a standard library when things are this close, and 
when its not something as common as memcpy().

In imitation of the assembly routines I copied SREG off into a uint8_t 
tmp, cli(), tickled bits, then SREG = tmp;, and only added 2 bytes to 
the generated code.

--
David Kelly N4HHE, dkelly@HiWAAY.net
========================================================================
Whom computers would destroy, they must first drive mad.

Re: need variables to be stored in EEPROM

2005-04-27 by arhodes19044

I did like your C version of the eeprom routines.  When I found out 
how to see the asm source of the library routine, it was hard to see 
what was happening without a listing of all the registers.  Even 
then it was inconvenient.

I also saw that the library routines had CLI just before what 
appeared to be the time-critical instructions.

I had read SOMEWHERE that the library routines did NOT clear 
interrupts, and that it had to be done manually before before eeprom 
access.

This is incorrect.  The library routines DO (seem to) clear the 
interrupts.  So, I do not have to worry about manually doing it, and 
ending up with them cleared for an entire multi-millisecond block 
transfer to eeprom.

THANKS!!!

-Tony

--- In AVR-Chat@yahoogroups.com, David Kelly <dkelly@h...> wrote:
> 
> On Apr 26, 2005, at 8:33 PM, arhodes19044 wrote:
> 
> > This makes sense.  Did you truncate off the high bits down to 
(2048-
> > 1)because the CPU you were using had only 2k bytes of EERPROM?
> > Since the 128 has 4K, I guess then the address would be 
truncated to
> > (4096-1)?
> 
> The target is intended to be an ATmega64L, so when I code that is 
the 
> manual I'm looking at. Is only recently I've had my 64L target 
hardware 
> running so previously was loading on a MAVRIC-II and staying 
within the 
> 64 subset on the 128.
> 
> Masking values to the available range is an old habit in attempt 
to 
> fail in a safe way and doesn't do much good here. No doubt if one 
tries 
> to write a value too large to EEAR the effective address will be 
masked 
> and wrapped-around by the hardware. And if one aims to be safe, 
thats 
> the wrong way to do it. If out of range the read/write should be 
> ignored, not forced to fit.
> 
> Have spent some time this afternoon looking at the avr-libc 
routines 
> eeprom_read_block() and eeprom_write_block(). If you have looked 
at the 
> source code I don't understand your (previous?) concern about IRQ. 
The 
> write routine only disables IRQ for the minimum possible interval 
> exactly the same as mine.
> 
> Then I started playing with my ee_writes() and ee_reads() routines 
in 
> C, making them closer to the library's assembly routines. My count 
is 
> only 8 bits rather than size_t's 16 bits, but my C generates 
smaller 
> code by a few bytes. No big deal. But I'd rather have C in my 
project 
> than assembly in a standard library when things are this close, 
and 
> when its not something as common as memcpy().
> 
> In imitation of the assembly routines I copied SREG off into a 
uint8_t 
> tmp, cli(), tickled bits, then SREG = tmp;, and only added 2 bytes 
to 
> the generated code.
> 
> --
> David Kelly N4HHE, dkelly@H...
> 
=====================================================================
===
> Whom computers would destroy, they must first drive mad.

DWEN

2005-09-15 by Jeffrey Engel

Recently I purchased several Tiny13's, but have been
unable to program them via ISP (my only option at the
moment).  After reading through the manual, I'm
guessing that the DWEN fuse is set.

Will Atmel's programmer be able to re-program the fuse
or do I need to purchase the new JTAG / Debug Wire
dongle?

Advice?  Opinion?

Jeff Engel
Arlington, TX



Happiness is - positive intake manifold pressure.


		
__________________________________ 
Yahoo! Mail - PC Magazine Editors' Choice 2005 
http://mail.yahoo.com

Re: DWEN

2005-09-15 by Don Kinzer

--- In AVR-Chat@yahoogroups.com, Jeffrey Engel <jengeltx@y...> wrote:
> Recently I purchased several Tiny13's, but have been
> unable to program them via ISP (my only option at the
> moment).  After reading through the manual, I'm
> guessing that the DWEN fuse is set.

My reading of the datasheet is that the Tiny13 is programmable via SPI 
as shipped from the factory.  The AVRISP programmer should be capable 
of programming the Tiny13 but it looks like the STK500 cannot.  What 
ISP do you have?  The Tiny13 may or may not be in its list of 
supported devices.

Don

Re: DWEN

2005-09-16 by paul_hvidston

Looking at my notes, I program the ATtiny13 on the STK500 using the
same socket setup as the AT90S2323, AT90S2343, ATtiny12 & ATtiny22.

Paul H.

--- In AVR-Chat@yahoogroups.com, "Don Kinzer" <dkinzer@e...> wrote:
Show quoted textHide quoted text
> --- In AVR-Chat@yahoogroups.com, Jeffrey Engel <jengeltx@y...> wrote:
> > Recently I purchased several Tiny13's, but have been
> > unable to program them via ISP (my only option at the
> > moment).  After reading through the manual, I'm
> > guessing that the DWEN fuse is set.
> 
> My reading of the datasheet is that the Tiny13 is programmable via SPI 
> as shipped from the factory.  The AVRISP programmer should be capable 
> of programming the Tiny13 but it looks like the STK500 cannot.  What 
> ISP do you have?  The Tiny13 may or may not be in its list of 
> supported devices.
> 
> Don

Re: [AVR-Chat] Re: DWEN

2005-09-18 by Jeffrey Engel

--- Don Kinzer <dkinzer@easystreet.com> wrote:

> --- In AVR-Chat@yahoogroups.com, Jeffrey Engel
> <jengeltx@y...> wrote:
> > Recently I purchased several Tiny13's, but have
> been
> > unable to program them via ISP (my only option at
> the
> > moment).  After reading through the manual, I'm
> > guessing that the DWEN fuse is set.
> 
> My reading of the datasheet is that the Tiny13 is
> programmable via SPI 
> as shipped from the factory.  The AVRISP programmer
> should be capable 
> of programming the Tiny13 but it looks like the
> STK500 cannot.  What 
> ISP do you have?  The Tiny13 may or may not be in
> its list of 
> supported devices.
> 
> Don

Don,

Thanks for your reply.  I hadn't thought of that.

I'm using the Olimex products to prototype with. 
They've worked well with the AT90S8223, but I've been
unable to read or program the Tiny13.

Jeff Engel



Happiness is - positive intake manifold pressure.

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.