XMEGA E eeprom writes to wrong adddress

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

Hello,

I have new project with following code:

#include <avr/io.h>
#include <avr/eeprom.h>


int main(void)
{
eeprom_update_word((uint16_t*)0x11,0xCAFE);
eeprom_update_word((uint16_t*)0x11,0xFECA);
eeprom_update_word((uint16_t*)0x19,0xCAFE);
eeprom_update_word((uint16_t*)0x19,0xFECA);
eeprom_update_word((uint16_t*)0x21,0xCAFE);
eeprom_update_word((uint16_t*)0x21,0xFECA);
    /* Replace with your application code */
    while (1) 
    {
    }
}

writing to address below 0x20 works as expected, but any write to address above 0x20 is written to address modulo 20. That means write to address 0x21 makes actual write to address 0x01.

Am I doing something wrong?

Note that this is happening in AS7 , same program in AS6 is working,

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

Can you show us some of the generated assembler code? The .lst file.

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

In the absence of a code editor that works I get:

 

Last Edited: Tue. Mar 6, 2018 - 05:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

.lst file attached.

Disassembly here:

 

--- No source file -------------------------------------------------------------
00000000  JMP 0x00000056        Jump
00000002  JMP 0x00000060        Jump
00000004  JMP 0x00000060        Jump
00000006  JMP 0x00000060        Jump
00000008  JMP 0x00000060        Jump
0000000A  JMP 0x00000060        Jump
0000000C  JMP 0x00000060        Jump
0000000E  JMP 0x00000060        Jump
00000010  JMP 0x00000060        Jump
00000012  JMP 0x00000060        Jump
00000014  JMP 0x00000060        Jump
00000016  JMP 0x00000060        Jump
00000018  JMP 0x00000060        Jump
0000001A  JMP 0x00000060        Jump
0000001C  JMP 0x00000060        Jump
0000001E  JMP 0x00000060        Jump
00000020  JMP 0x00000060        Jump
00000022  JMP 0x00000060        Jump
00000024  JMP 0x00000060        Jump
00000026  JMP 0x00000060        Jump
00000028  JMP 0x00000060        Jump
0000002A  JMP 0x00000060        Jump
0000002C  JMP 0x00000060        Jump
0000002E  JMP 0x00000060        Jump
00000030  JMP 0x00000060        Jump
00000032  JMP 0x00000060        Jump
00000034  JMP 0x00000060        Jump
00000036  JMP 0x00000060        Jump
00000038  JMP 0x00000060        Jump
0000003A  JMP 0x00000060        Jump
0000003C  JMP 0x00000060        Jump
0000003E  JMP 0x00000060        Jump
00000040  JMP 0x00000060        Jump
00000042  JMP 0x00000060        Jump
00000044  JMP 0x00000060        Jump
00000046  JMP 0x00000060        Jump
00000048  JMP 0x00000060        Jump
0000004A  JMP 0x00000060        Jump
0000004C  JMP 0x00000060        Jump
0000004E  JMP 0x00000060        Jump
00000050  JMP 0x00000060        Jump
00000052  JMP 0x00000060        Jump
00000054  JMP 0x00000060        Jump
--- ../../../../crt1/gcrt1.S ---------------------------------------------------
00000056  CLR R1        Clear Register
00000057  OUT 0x3F,R1        Out to I/O location
00000058  SER R28        Set Register
00000059  OUT 0x3D,R28        Out to I/O location
0000005A  LDI R29,0x2F        Load immediate
0000005B  OUT 0x3E,R29        Out to I/O location
0000005C  CALL 0x00000062        Call subroutine
0000005E  JMP 0x000000B6        Jump
00000060  JMP 0x00000000        Jump
--- c:\users\jirka\Documents\Atmel Studio\7.0\GccApplication1\GccApplication1\Debug/.././main.c
{
eeprom_update_word((uint16_t*)0x11,0xCAFE);
00000062  LDI R22,0xFE        Load immediate
00000063  LDI R23,0xCA        Load immediate
00000064  LDI R24,0x11        Load immediate
00000065  LDI R25,0x00        Load immediate
00000066  CALL 0x00000087        Call subroutine
eeprom_update_word((uint16_t*)0x11,0xFECA);
00000068  LDI R22,0xCA        Load immediate
00000069  LDI R23,0xFE        Load immediate
0000006A  LDI R24,0x11        Load immediate
0000006B  LDI R25,0x00        Load immediate
0000006C  CALL 0x00000087        Call subroutine
eeprom_update_word((uint16_t*)0x19,0xCAFE);
0000006E  LDI R22,0xFE        Load immediate
0000006F  LDI R23,0xCA        Load immediate
00000070  LDI R24,0x19        Load immediate
00000071  LDI R25,0x00        Load immediate
00000072  CALL 0x00000087        Call subroutine
eeprom_update_word((uint16_t*)0x19,0xFECA);
00000074  LDI R22,0xCA        Load immediate
00000075  LDI R23,0xFE        Load immediate
00000076  LDI R24,0x19        Load immediate
00000077  LDI R25,0x00        Load immediate
00000078  CALL 0x00000087        Call subroutine
eeprom_update_word((uint16_t*)0x21,0xCAFE);
0000007A  LDI R22,0xFE        Load immediate
0000007B  LDI R23,0xCA        Load immediate
0000007C  LDI R24,0x21        Load immediate
0000007D  LDI R25,0x00        Load immediate
0000007E  CALL 0x00000087        Call subroutine
eeprom_update_word((uint16_t*)0x21,0xFECA);
00000080  LDI R22,0xCA        Load immediate
00000081  LDI R23,0xFE        Load immediate
00000082  LDI R24,0x21        Load immediate
00000083  LDI R25,0x00        Load immediate
00000084  CALL 0x00000087        Call subroutine
00000086  RJMP PC-0x0000        Relative jump
--- C:\home\toolsbuild\jenkins-mcu-knuth\workspace\avr8-devices-pack\src\avr-libc\libc\misc\eeupd_word.S

00000087  ADIW R24,0x01        Add immediate to word

00000088  MOV R18,R23        Copy register

00000089  CALL 0x0000008E        Call subroutine

0000008B  JMP 0x0000008D        Jump
--- C:\home\toolsbuild\jenkins-mcu-knuth\workspace\avr8-devices-pack\src\avr-libc\libc\misc\eeupd_byte.S

0000008D  MOV R18,R22        Copy register

0000008E  CALL 0x000000B2        Call subroutine

00000090  LDD R0,Z+0        Load indirect with displacement

00000091  CP R0,R18        Compare

00000092  BREQ PC+0x04        Branch if equal

00000093  CALL 0x00000099        Call subroutine

00000095  SBIW R24,0x01        Subtract immediate from word

00000096  SBIW R24,0x01        Subtract immediate from word

00000097  RET         Subroutine return
--- C:\home\toolsbuild\jenkins-mcu-knuth\workspace\avr8-devices-pack\src\avr-libc\libc\misc\eewr_byte.S

00000098  MOV R18,R22        Copy register

00000099  PUSH R26        Push register on stack

0000009A  PUSH R27        Push register on stack

0000009B  LDI R30,0xC0        Load immediate

0000009C  LDI R31,0x01        Load immediate

0000009D  LDD R19,Z+15        Load indirect with displacement

0000009E  SBRC R19,7        Skip if bit in register cleared

0000009F  RJMP PC-0x0002        Relative jump

000000A0  MOVW R26,R24        Copy register pair

000000A1  SUBI R26,0x00        Subtract immediate

000000A2  SBCI R27,0xF0        Subtract immediate with carry

000000A3  ST X,R18        Store indirect

000000A4  LDI R18,0x35        Load immediate

000000A5  STD Z+10,R18        Store indirect with displacement

000000A6  LDI R18,0xD8        Load immediate

000000A7  LDI R19,0x01        Load immediate

000000A8  OUT 0x34,R18        Out to I/O location

000000A9  STD Z+11,R19        Store indirect with displacement

000000AA  ADIW R24,0x01        Add immediate to word

000000AB  POP R27        Pop register from stack

000000AC  POP R26        Pop register from stack

000000AD  RET         Subroutine return
--- C:\home\toolsbuild\jenkins-mcu-knuth\workspace\avr8-devices-pack\src\avr-libc\libc\misc\eerd_byte.S

000000AE  RCALL PC+0x0004        Relative call subroutine

000000AF  LDD R24,Z+0        Load indirect with displacement

000000B0  CLR R25        Clear Register

000000B1  RET         Subroutine return

000000B2  MOVW R30,R24        Copy register pair

000000B3  SUBI R30,0x00        Subtract immediate

000000B4  SBCI R31,0xF0        Subtract immediate with carry

000000B5  RET         Subroutine return
--- No source file -------------------------------------------------------------
000000B6  CLI         Global Interrupt Disable
000000B7  RJMP PC-0x0000        Relative jump
000000B8  NOP         Undefined
000000B9  NOP         Undefined
000000BA  NOP         Undefined
000000BB  NOP         Undefined
000000BC  NOP         Undefined
000000BD  NOP         Undefined
000000BE  NOP         Undefined
000000BF  NOP         Undefined
000000C0  NOP         Undefined
000000C1  NOP         Undefined
000000C2  NOP         Undefined
000000C3  NOP         Undefined
000000C4  NOP         Undefined
000000C5  NOP         Undefined

Attachment(s): 

Last Edited: Tue. Mar 6, 2018 - 05:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just reminded myself how AWFUL Atmel's disassembler is !

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

Well not only its disassembler but that's another story.

Compiled with -O1 just for info. In case I can send any other relevant info, just tell me.

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

Threre is nothing wrong in your code. EEPROM write functions in eeprom.h are buggy for xmegaE5. To fix this probem, I've created my own eeprom write functions.

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

Is it me or is that code not setting the NVM.ADDR register? It used ERASE_WRITE_EEPROM_PAGE (0x35) which requires the page address in the NVM.ADDR register.

 

Can you try something? Before writing to 0x21, try doing setting NVM.ADDR. 33.11.4.1 in the manual explains it, but you can probably just try something like (1<<5) because I think all E5s have 32 byte pages.

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

Just to note that the source for the EEPROM functions is (in part) here:

 

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

 

Note the revision history. The last change was by "pitchumani" (who is an Atmel engineer working on avr-gcc) made 2.5 years ago but it seems it was to specifically add Xmega support. Here is a "diff of what he added:

 

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

 

The comment even mentions "Xmega E" so the intention clearly was to add support for those devices.

 

I'll leave it to others who understand Xmega to study the actual code and comment on what it is doing. You will probably want to step back up to:

 

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

 

and study the other ee*.S files there.

 

Note of course that the above site is the "open" version of AVR-LibC, it may not be the same as the one in Atmel's private development branch (though they do put the source for use/study on the GPL site I believe).

 

If someone has "working" EEPROM support for Xmega-E would you not consider donating/integrating it into AVR-LibC so all other avr-gcc users may benefit (that's the nature of an open development after all!)?

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

I'm willing to look at it. Do they have an official git repo somewhere? I might try the SVN I suppose, I'm not familiar with the workflow for it...

 

I think the fix is pretty simple, just sort out the ADDR register and it should work fine as far as I can tell. The command and the data are correct, it's just that the page is always set to zero.

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

mojo-chan wrote:
I'm not familiar with the workflow for it...
I've only "dabbled" a bit myself. But basically it would involve raising an issue on the Bugzilla and attaching a patch to that showing how you think the code should be expanded/changed. That triggers posts to the avr-libc developers list and you will get feedback about better approaches or possibly just straight acceptance that what you have done is the "right solution". A test program that shows the existing implementation not working but that is fixed by your patch will demonstrate the need and efficacy of it.

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

Thank you Sierra. That is just "AWESOME" . Is there some list of know bugs so I don't need to reinvent broken wheel?

 

Mojo-chan, you are right too. eeprom_write is just not setting page in eeprom so anything is written to right address but to page0 only.

Writing NVM_ADDR0=0x20; before calling eeprom_write makes no difference.

 

Thank  you clawson for links.

I have no idea how it will help but in AS6 was this library fully working. So something that Atmel did for AS7 (in they mighty DFP packs) it broke it.

Last Edited: Wed. Mar 7, 2018 - 10:17 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm sharing in this joy as well.  I just ran into this problem when upgrading from Atmel Studio 6.2 to 7.  EEPROM functionality breaks on my XMEGA32E5 after the update.  I spent a while trying to get it working in Studio 7, importing the old eeprom libraries, etc., but was never successful.  Until I get more time to revisit this I'm just going to keep 6.2 on a machine and use it for this one project.  Oh bother.

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

Yes, up to this date I'm still using Studio 6.2 for xmega family. I need to work and have no more joy in fixing errors in TOOLs i'm using (as I did my early years). 

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

darkness_master wrote:

Yes, up to this date I'm still using Studio 6.2 for xmega family. I need to work and have no more joy in fixing errors in TOOLs i'm using (as I did my early years). 

And what do you expect the others to do with this 9 months overdue totally superfluous comment?

 

Have you tried the latest Studio 7 release and found it to be faulty too?