Author Topic: XMEGA EEPROM Read and Write  (Read 19383 times)

0 Members and 1 Guest are viewing this topic.

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
XMEGA EEPROM Read and Write
« on: September 15, 2013, 05:17:48 am »
I've read and Googled, but the answer still eludes me.  Using C (Atmel Studio) with an XMEGA, I'm wanting simply read and write the EEPROM using constant addresses.

The C function eeprom_write_byte takes two parameters; the address to write and the value to write at that address.

But the address parameter is of type uint8_t, so how can it work with more than 256 EE locations?  I'm obviously missing something here.   :-[
 

Offline edavid

  • Super Contributor
  • ***
  • Posts: 2946
  • Country: us
Re: XMEGA EEPROM Read and Write
« Reply #1 on: September 15, 2013, 05:39:54 am »
The address parameter is a pointer to a uint8_t.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #2 on: September 15, 2013, 05:46:38 am »
OK, but what if I want to write to a specific EE address (such as 0x140), not at an address derived from another variable?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #3 on: September 15, 2013, 06:01:59 am »
Also, since the pointer is to an uint8_t type, doesn't that imply that the value pointed to can only be in the 0.255 value range?
 

Offline andete

  • Contributor
  • Posts: 19
  • Country: be
  • famous for its killer edible poets
Re: XMEGA EEPROM Read and Write
« Reply #4 on: September 15, 2013, 06:06:42 am »
you cast your address to a pointer:

something like this:

int address = 0x140;
uint8_t value = 32;

eeprom_write_byte((uint8_t *) address, value);
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #5 on: September 15, 2013, 06:15:21 am »
Sounds like I will need to either;

1) Wrap the ee_read_byte and ee_write_byte functions so I can easily call them with with literal addresses

2) Ditch the ee library and write my own functions
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #6 on: September 15, 2013, 06:33:17 am »
So you're saying that the data type that the pointer points to is not limited to an uint8_t type?

Also, is it the address of the pointer that's limited to the 0.255 range?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #7 on: September 15, 2013, 08:10:27 am »
OK, this is what I ended up with:

Code: [Select]
struct sSettings
{
uint8_t PresetNo;
        // More settings to go here
};

struct sSettings Settings;

Code: [Select]
void EE_Load_Settings(void)
{
_Bool UpdateRequired = 0;
uint16_t Address = 0x200;
// Read the whole structure into RAM
eeprom_read_block((void*)&Settings,(void*) Address,sizeof(Settings));
// Check validity of Preset No
if((Settings.PresetNo > 9))
{
Settings.PresetNo = 0;
UpdateRequired = 1;
}
// Check to see if we need to write any fixes back out
if(UpdateRequired==1)
EE_Save_Settings();
}

void EE_Save_Settings(void)
{
uint16_t Address = 0x200;
eeprom_update_block((const void*)&Settings,(void*) Address,sizeof(Settings));
}
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #8 on: September 15, 2013, 09:05:02 am »
I understand how pointers work, but my earlier understanding was that the pointer was to a 8 bit variable.  This means that the value returned by the pointer could only be an 8 bit value.

Then it seemed that the pointer itself was 8 bits in size, which would limit its addressing range.

The fact that the function has byte in its name only means that the value read from / written to the selected EE location is an 8 bit value.  That makes perfect sense.  The confusion for me was how the function could address more than 256 bytes of EE via a pointer that seemed to be limited.

I did look at the ASF and to be honest didn't like the way it hid so much.  Coming from an assembler code background I like seeing the nuts and bolts of the code.
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1427
  • Country: dk
Re: XMEGA EEPROM Read and Write
« Reply #9 on: September 15, 2013, 09:16:51 am »
But you said it your self ....
The "Object the pointer points at" is uint8_t or "8-bit" ...
The pointer (aka address/offset/index) is not , so the pointer could easily be a 16-bit value (index) , "pointing to/on a 8-bit value".


Code: [Select]
uint8_t *pointer;

pointer = 0x300;  //Pointer points at the value @ 0x300 (This one just loads the pointer address)
*pointer = 0x100 //Sets the (uint8_t) value @ pointer to 0x100; (This one changes the value that pointer points at)

/Bingo
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #10 on: September 15, 2013, 09:28:53 am »
I think you're missing the key thing about declaring pointers and what is actually happening.

// here you're declaring a simple variable foo and the uint8_t means foo can store 8bits;
uint8_t Foo;

// here the * means this is a pointer called Foo.  (keep in mind that the uint8_t here means something quite different)
uint8_t *Foo

Foo can be refereed to in two ways. 
Foo = The memory address number
*Foo = The contents of that memory address (that's where the type comes in).

The pointer variable Foo is always whatever size is needed on your CPU to store an address in memory. I think they're 16bit on AVR but don't quote me. So it doesn't matter if you go "uint16_t *Foo;"  or "uint64_t *Foo;"  Foo is always the same length variable because it only ever needs to contain a memory address that points to the start of something.

(I'm probably going to explain this next bit a little wrong from a low level perspective but it may help explain the concept....)

You can think of the type part (uint8_t in this example) as a message to the C compiler to expect an 8bit number at the Foo memory address. 

This becomes important when you think about larger variables.
Say you want a pointer to a uint32_t which is of course 4 bytes long.
uint32_t *Bar

Bar is only a single 16bit memory address. It points to the memory for the first byte of this 4 byte number.
The type (uint32_t) helps the compiler out by letting it know what you're going to be doing with *Bar.

If you increment Bar by 1 the address is incremented by 4.
Bar++;    //jump forward 4 bytes because bar is uint32_t and that is a 4 byte type.
You'd be stupid to do that here since that's unknown memory but if you had an array of uint32_t you could correctly step through memory in increments of 4.

« Last Edit: September 16, 2013, 10:13:45 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1427
  • Country: dk
Re: XMEGA EEPROM Read and Write
« Reply #11 on: September 15, 2013, 09:29:26 am »

Hmmm ... PSI beat me to it :-)



But you said it your self ....
The "Object the pointer points at" is uint8_t or "8-bit" ...
The pointer (aka address/offset/index) is not , so the pointer could easily be a 16-bit value (index) , "pointing to/on a 8-bit value".


Code: [Select]
uint8_t *pointer;

pointer = 0x300;  //Pointer points at the value @ 0x300 (This one just loads the pointer address)
*pointer = 0x100 //Sets the (uint8_t) value @ pointer to 0x100; (This one changes the value that pointer points at)

/Bingo
Code: [Select]
In pseudo asm ....
X= 16bit index reg
A= 8bit accum.

LD    X,#0x300   //Init pointer
LD    A,#0x100
ST    [X],A
The confusion comes from us old asm guyzz in why should the compiler know what the pointer points at .......

But that makes sense here .....


Code: [Select]
uint8_t *pointer;

pointer = 0x300;  //Pointer points at the value @ 0x300 (This one just loads the pointer address)
*pointer++ = 0x100 //Sets the (uint8_t) value @ pointer to 0x100; (This one changes the value that pointer points at , [b]and increments the pointer to point at the next element[/b])


Code: [Select]
LD    X,#0x300   //Init pointer
LD    A,#0x100   //
ST    [X],A          //Store A , where X points
INC   X               // Point @ next element.

But what of the element pointed at  was a 16bit ??

Then the compiler had to do
INC   X
INC   X

Or

ADD  X,#2


In "C" Notation ....

ADD   X,"sizeof element pointed at".

That's why you have to tell the C compiler what the pointer is pointing at

/Bingo
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1427
  • Country: dk
Re: XMEGA EEPROM Read and Write
« Reply #12 on: September 15, 2013, 09:40:01 am »

If you use the * symbol when using bar in code it means you want to work on the actual memory address number instead of what it points to.
so
*Bar = *Bar + 1  would make Bar point to the next memory location (2nd byte of the 4 byte number.)

Naahhh ....

The above would actually increment the *Bar memory location by 1 , not change the pointer (Bar) it self  ;)

/Bingo
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #13 on: September 15, 2013, 09:44:44 am »
Isn't that what i said?

Maybe i should reword it from "next memory location"  to "next location in memory" ?

(You can see why people say pointers are confusing)
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1427
  • Country: dk
Re: XMEGA EEPROM Read and Write
« Reply #14 on: September 15, 2013, 10:01:17 am »
Isn't that what i said?

Maybe i should reword it from "next memory location"  to "next location in memory" ?

(You can see why people say pointers are confusing)

But it doesn't do anything "next" it just increments "location"

*Bar = *Bar + 1  "==>" (*Bar)++  not Bar++

Quote
(You can see why people say pointers are confusing)
Yuppp , especially for asm programmers that doesn't expect the C-Compiler to handle the pointer arithmatik automatically ... Witch is excactly why you need to tell the compiler what the objecttype is that the pointer is pointing at.

/Bingo
« Last Edit: September 15, 2013, 10:03:45 am by bingo600 »
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #15 on: September 15, 2013, 10:02:41 am »
Yeah, "Next" was a bad word to use.

It could mean next <type> or next number
« Last Edit: September 15, 2013, 10:11:42 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline baljemmett

  • Supporter
  • ****
  • Posts: 666
  • Country: gb
Re: XMEGA EEPROM Read and Write
« Reply #16 on: September 15, 2013, 11:42:18 am »
Sounds like I will need to either;

1) Wrap the ee_read_byte and ee_write_byte functions so I can easily call them with with literal addresses

2) Ditch the ee library and write my own functions

You might want to take a quick read of http://www.avrfreaks.net/?name=PNphpBB2&file=viewtopic&t=38417 which shows some examples, including how you can use literal addresses by casting the constant as appropriate.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #17 on: September 15, 2013, 11:49:25 am »
For EE access, there is an address (where the EE data is held) and the data (the data at that EE address).

In the world of asm, you'd set the address high and low bytes, then do the read or write.

My confusion about the pointer is in relation the the function:

Code: [Select]
eeprom_write_byte((uint8_t *) address, value);
To me, the uint8_t could mean one of two things;
1) The address pointer is 8 bits in width, but that would mean you could only have 256 pointers (assuming they pointed to 8-bit data types)
2) The value returned by the address pointer is 8 bits in width, but that would mean the effective EE address could only access EE locations 0.255

Obviously neither of those is true.  The value ultimately used as the EE address is actually 16 bits.

I'm sure it's just a case of moving from asm (and Delphi on PC) to C being in some ways be worse than starting from scratch.  Some things in C seem so bat shit crazy compared to other languages.   :D
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #18 on: September 15, 2013, 11:51:38 am »
You might want to take a quick read of http://www.avrfreaks.net/?name=PNphpBB2&file=viewtopic&t=38417 which shows some examples, including how you can use literal addresses by casting the constant as appropriate.

I saw those examples, but they have one glaring problem;  they only deal with literals that are within the 8-bit data size.  For someone new to C, examples showing larger address ranges would be better.
 

Offline baljemmett

  • Supporter
  • ****
  • Posts: 666
  • Country: gb
Re: XMEGA EEPROM Read and Write
« Reply #19 on: September 15, 2013, 12:26:00 pm »
To me, the uint8_t could mean one of two things;
1) The address pointer is 8 bits in width, but that would mean you could only have 256 pointers (assuming they pointed to 8-bit data types)
2) The value returned by the address pointer is 8 bits in width, but that would mean the effective EE address could only access EE locations 0.255

Obviously neither of those is true.  The value ultimately used as the EE address is actually 16 bits.
No, you're right with the second one -- the value the pointer points to is indeed 8 bits in width.  However, you're making the mistake (quite reasonably) of thinking that the value it points to is going to be used as the EE address -- it isn't.  The actual value of the pointer, i.e. the address it represents, is what's going to be used as the EE address -- so it's actually a pointer into the EEPROM address space (literally a pointer to the 8-bit value in the EEPROM), with 0 being the first byte of EEPROM, etc.

I'm sure it's just a case of moving from asm (and Delphi on PC) to C being in some ways be worse than starting from scratch.  Some things in C seem so bat shit crazy compared to other languages.   :D
To be honest, even as a seasoned C programmer I think your confusion is understandable -- I would usually expect the 'address' parameter of an EEPROM read/write routine to be an integral type, not a pointer to an object of the transaction size.  However, from a quick glance at some of the library documentation (not having used any AVR chips myself), I get the impression that the EEPROM is actually mapped into the processor's address space, so using pointers may make some sense.

I still think it's a trifle weird, though, as surely you can't actually use them as pointers (otherwise why do you need the library functions?)  It does let you do things like struct { uint8_t foo; unit16_t bar; } *p = 0x42; eeprom_write_word(&p->bar, 0x4242); though, I suppose.

I saw those examples, but they have one glaring problem;  they only deal with literals that are within the 8-bit data size.  For someone new to C, examples showing larger address ranges would be better.
Yes, there is that -- I don't know how large the EEPROM is on 'common' AVRs.  Some of the popular PICs that people choose to get started with have <= 256 bytes, for instance, so perhaps people writing tutorial material stick to smaller addresses to make sure it all fits -- or they just pick numbers off the top of their head ;)
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 4950
  • Country: de
  • A qualified hobbyist ;)
Re: XMEGA EEPROM Read and Write
« Reply #20 on: September 15, 2013, 12:33:05 pm »

My confusion about the pointer is in relation the the function:

Code: [Select]
eeprom_write_byte((uint8_t *) address, value);

If you like to write a 8 bit value to 0x0140:

Code: [Select]
eeprom_write_byte((uint8_t *) 0x0140, value);
The "(uint8_t *)" is necessary to keep the compiler happy. And it's a good coding style because it reminds the reader what the function expects for input.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #21 on: September 15, 2013, 01:09:17 pm »
At it's core a pointer is just a number.

Usually the number is used to interact with ram but in this case the function uses it to point to an eeprom location.
I think the function does it that way because eeprom is kinda like ram.

Basically the function just want a number that means the eeprom location from 0 to 2048 or however much eeprom you have.
But it wants this number in the form of a pointer because that is how the person who wrote the function decide to do it.

The fact that the pointer is of type uint8_t is only because he had to tell the compiler something about this pointer as it's a function parameter (or he could have used a void pointer (pointer to unknown type)).
It makes more sense to call it uint8_t because the function is about writing a byte.
It doesn't play a roll in whats going on other than that.
« Last Edit: March 10, 2014, 10:30:35 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: XMEGA EEPROM Read and Write
« Reply #22 on: September 15, 2013, 01:10:19 pm »
The key to understand this all is to recognize that the address pointer, (uint8_t *), is a multi-byte type, :)

After that, everything is clear.
================================
https://dannyelectronics.wordpress.com/
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #23 on: September 15, 2013, 09:38:31 pm »
To me, the uint8_t could mean one of two things;
1) The address pointer is 8 bits in width, but that would mean you could only have 256 pointers (assuming they pointed to 8-bit data types)
2) The value returned by the address pointer is 8 bits in width, but that would mean the effective EE address could only access EE locations 0.255

Obviously neither of those is true.  The value ultimately used as the EE address is actually 16 bits.
No, you're right with the second one -- the value the pointer points to is indeed 8 bits in width.  However, you're making the mistake (quite reasonably) of thinking that the value it points to is going to be used as the EE address -- it isn't.  The actual value of the pointer, i.e. the address it represents, is what's going to be used as the EE address -- so it's actually a pointer into the EEPROM address space (literally a pointer to the 8-bit value in the EEPROM), with 0 being the first byte of EEPROM, etc.

According to the help docs, the EE address value (0x00..0x7FF) is shifted up into the 0x2000..0x27FF address space by the EE library.  I understand that.  The pointer itself and the value pointed to must both be 16-bit values though as otherwise you could never have enough range to access all of the EE space.

Anyway, I *think* I have a handle on it now.  I'll have to read up and see how to read back the EE data into Atmel Studio so I can confirm that the data is being stored where I want.

Some of you are probably wondering why I care exactly where the data is stored in the EE.  I need to allocate the areas used for the settings in such a way that they will persist during a firmware upgrade.  There will also be other generic read/write EE routines that are used for configuration via a PC application, so I need to know that existing data addresses won't change if more are added with later firmware revisions.

There are 10 preset modes of operation and I am leaving space so the structure for each mode (currently 22 bytes) can grow in the future to a max of 32 bytes.  There is 2K of EE space on the chip I'm using so I may space them out even more (64 bytes for example) to be sure.

As usual, I'd like to thank you guys for being patient with me and taking the time to answer my questions.   :-+
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #24 on: September 16, 2013, 03:22:55 am »
The number located at a memory address stored in a pointer is always

8bits if the memory is organised in bytes
16bits if the memory is organised in words
etc.


Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #25 on: September 16, 2013, 03:28:41 am »
The number located at a memory address stored in a pointer is always

8bits if the memory is organised in bytes
16bits if the memory is organised in words
etc.

So you mean the contents of the pointer (not the address of the pointer) for the address argument in that EE function is only 8 bits ?

EDIT: I assumed that the EE was organised as bytes.
« Last Edit: September 16, 2013, 03:30:44 am by David_AVD »
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #26 on: September 16, 2013, 03:30:31 am »
I've never used an XMega so i dunno how it structures the memory and the eeprom.

But a pointer always points to a single memory location be it 8bit, 16bit, 32bit etc.. depending on the hardware

eg,

For a cpu that has memory/eeprom stored in bytes...

uint32_t  *MyPointer;

When you use *MyPointer in code you're working with a 32bit number only because the compiler has itself taken care of reading/writing the next 3 bytes ahead of the pointer every time you interact with it.
The pointer still only points to one byte, the first one.


If the memory is stored in words it's the same except a single memory location is 16bit. So the compiler only needs to read ahead in memory by 1 to get all 32bits.
And the pointer still only points to one unit/address, except this time its a word. The first word of the 32bits
« Last Edit: September 16, 2013, 10:01:30 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline Kremmen

  • Super Contributor
  • ***
  • Posts: 1283
  • Country: fi
Re: XMEGA EEPROM Read and Write
« Reply #27 on: September 16, 2013, 06:55:58 am »
I've read and Googled, but the answer still eludes me.  Using C (Atmel Studio) with an XMEGA, I'm wanting simply read and write the EEPROM using constant addresses.

The C function eeprom_write_byte takes two parameters; the address to write and the value to write at that address.

But the address parameter is of type uint8_t, so how can it work with more than 256 EE locations?  I'm obviously missing something here.   :-[
Actually, as stated here already, the address parameter is a _pointer_ _to_ uint8_t. The address variable is of pointer type, not uint8_t.
You can simply typecast a constant into a pointer. The EEPROM is mapped form 0 to EEPROM_SIZE-1 and the compiler/linker will handle any address translations for you.
so you should be able to do this:
Code: [Select]
nvm_eeprom_write_byte( (eeprom_addr_t) 0, 0xaa); (assuming you used the Studio ASF NVM driver library). That will write the byte 0xaa at EEPROM address 0.
Nothing sings like a kilovolt.
Dr W. Bishop
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #28 on: September 16, 2013, 09:26:08 am »
Actually, as stated here already, the address parameter is a _pointer_ _to_ uint8_t. The address variable is of pointer type, not uint8_t.

I understand that the pointer is a 16 bit value that points to a memory location.

When you say "the address parameter is a _pointer_ _to_ uint8_t.", are you saying that the value in the memory location pointed to is an 8 bit type?
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #29 on: September 16, 2013, 10:00:22 am »
Er, no, you have it backwards :-)

Foo is a pointer to a byte. In AVR-GCC all pointers are 16 bit by default, so Foo is actually a uint16_t.

Foo = the pointer, i.e. a memory address stored as a uint16
*Foo = dereferenced pointer, i.e. the value that Foo points to which is a uint8


ops,  sorry guys.  :-[

I really should have refreshed my knowledge of pointers before posting instead of trying to remember.

I've gone back and edited my original posts so they make sense.

And sorry bingo600, i see you also noticed my mistake and i didn't quite realise what you were saying :(
« Last Edit: September 16, 2013, 10:16:24 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: XMEGA EEPROM Read and Write
« Reply #30 on: September 16, 2013, 10:26:34 am »
Quote
When you say "the address parameter is a _pointer_ _to_ uint8_t.", are you saying that the value in the memory location pointed to is an 8 bit type?
Quote

When you typecast a literal (let's say 0x0140) to a uint8_t *, all it does is to say that that pointer is a two-byte type pointing to 0x0140. The reason it is uint8_t is to make it easier to increment the pointer in the future, as the data you are writing to it is a uint8_t (byte) type.

If you were to write a word or a double word, you would then typecast 0x0140 to a pointer to a word or double word, so the same increment code would work, regardless of the data type to be written to eeprom.

Again, all you need to remember is that regardless of the data it points to, the pointer is always a multi-byte type.
================================
https://dannyelectronics.wordpress.com/
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 4950
  • Country: de
  • A qualified hobbyist ;)
Re: XMEGA EEPROM Read and Write
« Reply #31 on: September 16, 2013, 10:36:52 am »
Actually, as stated here already, the address parameter is a _pointer_ _to_ uint8_t. The address variable is of pointer type, not uint8_t.

I understand that the pointer is a 16 bit value that points to a memory location.

When you say "the address parameter is a _pointer_ _to_ uint8_t.", are you saying that the value in the memory location pointed to is an 8 bit type?

I think you got it :-)
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 3138
  • Country: us
Re: XMEGA EEPROM Read and Write
« Reply #32 on: September 16, 2013, 04:28:17 pm »
I think you're all making it much more complicated than it needs to be.
eeprom_writes_byte() reads a byte into chunk of memory; therefore its destination argument is a pointer to a byte.
There are similar eeprom_write_word() and eeprom_write_dword() that take pointers to uint_16 and uint_32.
This way you can seamlessly do things like:
Code: [Select]
typedef struct chartdata_ {  // chart recorder data record.
  uint32_t timestamp;
  uint8_t temperature;
  uint8_t humidity;
} chartdata_t;

chartdata_t *logfile = (chartdata_t *)(0);  // logfile starts at the beginning of eeprom
  :
  eeprom_write_dword(&logfile[n]->timestamp, now);
  eeprom_write_byte(&logfile[n]->temperature, currenttemp);
Yes, since eeprom and data have separate address spaces, you can screw yourself over by using the pointer to point to the wrong kind of memory.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #33 on: September 16, 2013, 09:12:24 pm »
The function definitions still look weird to me, but I'm sure it will click totally one day.  For now I'm happy knowing how to use them, even if I don't know how they operate internally.

Where does one find the source for those functions?  The header file is easy to find, but there doesn't appear to be a matching C file?
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: XMEGA EEPROM Read and Write
« Reply #34 on: September 17, 2013, 11:08:52 am »
AS is based on win-avr so you should be able to download the source if you google.
================================
https://dannyelectronics.wordpress.com/
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7509
  • Country: nz
Re: XMEGA EEPROM Read and Write
« Reply #35 on: September 17, 2013, 12:25:37 pm »
There's no real need to search/download it, the library and source is in the AS folders somewhere.
Searching for a copy online is probably faster though.

Finding the core functions can be a bit tricky in avr-gcc, due to how they all fit together and provide support for all micros with a single h file.
« Last Edit: September 17, 2013, 12:33:05 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: XMEGA EEPROM Read and Write
« Reply #36 on: September 17, 2013, 02:54:04 pm »
Quote
Atmel like to include small macro-like functions in their header files

Everyone does that - it makes the code a lot easier to port and understand.
================================
https://dannyelectronics.wordpress.com/
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: XMEGA EEPROM Read and Write
« Reply #37 on: September 17, 2013, 09:13:54 pm »
The function definitions still look weird to me, but I'm sure it will click totally one day.  For now I'm happy knowing how to use them, even if I don't know how they operate internally.

Where does one find the source for those functions?  The header file is easy to find, but there doesn't appear to be a matching C file?

In Atmel Studio you can just right click on the function and select "Goto Implementation". A lot of those functions are only actually defined in the header file.

I know how to get to the header file, but that doesn't show me the nuts and bolts of the actual implementation.   :-//
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 3138
  • Country: us
Re: XMEGA EEPROM Read and Write
« Reply #38 on: September 18, 2013, 12:12:50 am »
http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/libc/misc/eerd_byte.S?root=avr-libc&view=markup

As Psi said, it's rather obscured by the bits that allow the same source tree to support so many chips and sub-architectures.   Note that avr-libc is not maintained by Atmel; it's an open source software thing (and they look a bit aggressively non-gnu as well, which is a good thing for embedded software.)  I doubt that the source is included in AS.  For Xmega, I think there are similar functions as part of "Atmel Software Foundation" ( http://asf.atmel.com/docs/2.9.0/xmegaa/html/group__nvm__eeprom__group.html ), and THAT source might be included as part of AS.

Older versions of avr-libc (for instance, the version shipped with Arduino) actually implement eeprom_read_byte() in the .h file, as an inline function.

Quote
Finding the core functions can be tricky...
Allow me to introduce y'all to the "ID Database" utility: http://www.gnu.org/software/idutils/manual/idutils.html
This is sort-of a bunch of those IDE "find implementation" capabilities in a zippy little command-line utility.
So you pull your svn copy of avr-libc/trunk, connect to the top-level directory and say "mkid", and it builds a database of all the identifiers in all the source files in all the directories (recursively.)  Then you can search and gets lists of files that contain the identifier, and etc.  Combined with things like eTags, this is one of the things that prevents old-timers from getting excited about "modern IDEs."
 

Offline happylex

  • Contributor
  • Posts: 11
Re: XMEGA EEPROM Read and Write
« Reply #39 on: March 10, 2014, 07:59:39 pm »
I've never used an XMega so i dunno how it structures the memory and the eeprom.

But a pointer always points to a single memory location be it 8bit, 16bit, 32bit etc.. depending on the hardware

Ok, so the XMEGA A is capable of using 32 bit pointers, since this can access all my megabytes of external SDRAM:

Code: [Select]

uint32_t my_own_pointer= 0x00010000; // > 0xFFFF, and thus > 16 bit :-)
uint8_t value = 5;
*(uint8_t *)my_own_pointer = value;

Great this works, but then there is the point mentioned by mojo-chan.

In AVR-GCC all pointers are 16 bit by default

Yes I found out. How difficult can it be? There was a statement from AVR that 16 bit pointers will not be supported till GCC 4.7. Now I am already using 4.8.2 and still it uses 16 bit pointers.

I couldn't find the source indeed, or else I would have changed the uint16_t into uint32_t. (Or am I missing something complex here?)

So I should write my own allocate() bla bla bla? I am usin three arrays to divide my SDRAM in sectors. Structures can then access the arrays to find a free sector. The speed of my software is going down a lot this way! And also my flash memory and valuable real life time. Moreover, I am not using my RAM efficiently with free memory in every sector.

How do I solve the speed and efficiency issues? It must be possible, since the custom '32 bit pointer' works.

Edit: Here is an old version of the AVR-LIBC with a malloc.c I could addapt  http://download.savannah.gnu.org/releases/avr-libc/
However, if I use my custom pointer in an existing function it converts it to 16 bit.
« Last Edit: March 10, 2014, 08:59:21 pm by happylex »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf