Hallo,
ich habe hier zwei Funktionen:
1 | void Fls_WritePage(uint16_t page, const uint8_t *buf)
|
2 | {
|
3 | uint32_t addr = page * SPM_PAGESIZE;
|
4 |
|
5 | uint8_t sreg;
|
6 | // Disable interrupts.
|
7 | sreg = SREG;
|
8 | cli();
|
9 |
|
10 | // clear page
|
11 | eeprom_busy_wait ();
|
12 | boot_page_erase (addr);
|
13 | boot_spm_busy_wait (); // Wait until the memory is erased.
|
14 |
|
15 | for (uint16_t i=0; i<SPM_PAGESIZE; i+=2)
|
16 | {
|
17 | // Set up little-endian word.
|
18 | uint16_t w = *buf++;
|
19 | w += (*buf++) << 8;
|
20 | boot_page_fill (addr+i, w);
|
21 | }
|
22 |
|
23 | boot_page_write (page); // Store buffer in flash page.
|
24 | boot_spm_busy_wait(); // Wait until the memory is written.
|
25 | // Reenable RWW-section again. We need this if we want to jump back
|
26 | // to the application after bootloading.
|
27 | boot_rww_enable ();
|
28 | // Re-enable interrupts (if they were ever enabled).
|
29 | SREG = sreg;
|
30 | }
|
31 |
|
32 | void Fls_ReadPage(uint16_t page, uint8_t *buf)
|
33 | {
|
34 | uint32_t addr = page * SPM_PAGESIZE;
|
35 |
|
36 | uint8_t sreg;
|
37 |
|
38 | // Disable interrupts.
|
39 | sreg = SREG;
|
40 | cli();
|
41 |
|
42 | for (uint16_t i=0; i<SPM_PAGESIZE; i+=2u)
|
43 | {
|
44 | uint16_t dataWord = pgm_read_word_far( addr+i );
|
45 |
|
46 | buf[0] = (uint8_t) dataWord;
|
47 | buf[1] = (uint8_t) (dataWord >> 8);
|
48 |
|
49 | buf += 2;
|
50 | }
|
51 |
|
52 | SREG = sreg;
|
53 | }
|
Die erste sollte mir Daten in den Flash speichern, und zwar eine
komplette Page auf einmal.
Die zweite liest eine komplette Page und schreibt sie in den Puffer.
Zum Testen schreibe ich:
1 | uint8_t TEST_pbRead[256];
|
2 | uint8_t TEST_pbWrite[256];
|
3 | ...
|
4 | for (uint16_t i=0; i<256; i++)
|
5 | {
|
6 | TEST_pbWrite[i] = i;
|
7 | }
|
8 | ...
|
9 | ...
|
10 | Fls_WritePage(0, TEST_pbWrite);
|
11 | ...
|
12 | ...
|
13 | Fls_ReadPage(0, TEST_pbRead);
|
Eigentlich einfach: ich fülle mir ein Array mit Daten, schreibe sie in
Page 0.
Danach lese ich Page 0 in ein zweites Array.
Die Arrays gebe ich mir mittels UART später aus.
So, wo liegt also das Problem.
Grundsätzlich läuft das Ganze. Allerdings nur, wenn ich Page 0
lese/schreibe.
Ändere ich den Code in Page 1,2,3 ... geht entweder das Lesen oder das
Schreiben daneben.
Das Lesearray enthält dann nur lauter 0xFF, deswegen gehe ich davon aus
dass aus einem jungfräulichen Flashbereich gelesen wird.
Passt evtl. was in der Adressenberechnung nicht?
Ich denke, alle Makros aus der avr-libc arbeiten mit Byteaddressen. Sagt
zumindest die Doku.
Was mich eben irritiert ist dass es mit Page 0 klappt...
Jemand ne Idee?
Achja:
ATmega1284P, Code wird aus dem Bootloaderbereich ausgeführt.