Hallo zusammen,
ich habe hier ein Problem mit einem atxmega128A1 bzw. D3 (Fehler kommt
bei beiden Projekten). Es ist eine Applikation, in welcher ich EEPROM
nutze. Um zu prüfen, ob im EEPROM was sinnvolles drin ist, prüfe ich zu
Beginn von main ein paar Variablen im EEPROM ab:
1 | int main(void)
|
2 | {
|
3 | cli();
|
4 | if ( (EEPROM_read_byte(&myEE.mainversion) != pgm_read_byte(&myFLASH.mainversion))
|
5 | ||(EEPROM_read_byte(&myEE.version) != pgm_read_byte(&myFLASH.version)) )
|
6 | {
|
7 | // panic! EEPROM falsch
|
Das funktioniert bei normalen Reset.
Das EEPROM lese ich mit den Routinen von Alex Forencich (xboot):
1 | void wait_for_nvm(void)
|
2 | {
|
3 | while (NVM.STATUS & NVM_NVMBUSY_bm) { };
|
4 | }
|
5 |
|
6 | uint8_t EEPROM_read_byte(void *addr)
|
7 | {
|
8 | wait_for_nvm();
|
9 |
|
10 | NVM.ADDR0 = (uint16_t)addr & 0xFF;
|
11 | NVM.ADDR1 = ((uint16_t)addr >> 8) & 0x1F;
|
12 | NVM.ADDR2 = 0;
|
13 |
|
14 | NVM.CMD = NVM_CMD_READ_EEPROM_gc;
|
15 | NVM_EXEC();
|
16 |
|
17 | return NVM.DATA0;
|
18 | }
|
wobei NVM_EXEC() einfach ein inline ist:
1 | // NVM call
|
2 | static inline void NVM_EXEC(void)
|
3 | {
|
4 | void *z = (void *)&NVM_CTRLA;
|
5 |
|
6 | __asm__ volatile("out %[ccp], %[ioreg]" "\n\t"
|
7 | "st z, %[cmdex]"
|
8 | :
|
9 | : [ccp] "I" (_SFR_IO_ADDR(CCP)),
|
10 | [ioreg] "d" (CCP_IOREG_gc),
|
11 | [cmdex] "r" (NVM_CMDEX_bm),
|
12 | [z] "z" (z)
|
13 | );
|
14 | }
|
Problem:
Komme ich nicht aus Kaltstart, sondern vom Bootloader, dann liefert mir
die Routine EEPROM_read_byte immer 0 als Ergebnis zurück. Also ist
offenbar irgendwas durch den Bootloader 'verbogen', ich finde partout
nicht raus, was es sein könnte. Habe hier und auf avrfreaks schon die
Suche durchwühlt, nichts gefunden. Ich hoffe, dass einer der hier
mitlesenden Spezialisten mit dem Finger schnippt und hast Du da schon
... sagen kann. Vielen Dank!
Martin