Problem mit pgm_read_word_far

Gast #3152203
Lesenswert?

Hi,

ich versteh's nicht.. ;-(

Ich habe im Programmspeicher folgende Daten:
1
const unsigned int daten[] PROGMEM = { 0xf0aa,  0x0f55, .... }

Wenn ich nun mit
1
val = pgm_read_word_far(FAR(daten) + offset);

darauf zugreifen will, bekomme ich nur die einzelnen Bytes (!!), auf die 
'offset' zeigt. D.h. der Reihe nach: 0x00aa, 0x00f0, 0x0055, 0x000f, 
ect.

Das pgm_read_word_far kann ich aktuell gegen ein pgm_read_byte_far 
tauschen, ohne dass es irgendwelche Auswirkungen hat. Keine 
Compiler-Warnung (GCC) ect.. ;-)

Das FAR() habe ich hier aus dem Forum und ist wie folgt definiert:
1
#define FAR(var)                      \
2
({ uint_farptr_t tmp;                 \
3
__asm__ __volatile__(                 \
4
  "ldi    %A0, lo8(%1)"  "\n\t" \
5
  "ldi    %B0, hi8(%1)"  "\n\t" \
6
  "ldi    %C0, hh8(%1)"  "\n\t" \
7
  : "=d" (tmp)                  \
8
  : "p"  (&(var)));             \
9
tmp;                                  \
10
})

Wo liegt der Hund begraben..? :-)
Für Tipps wäre ich sehr dankbar!
#3153218
Lesenswert?

Zeig mal allen relevanten Code, nicht nur Einzeiler. Dazu gehört z.B. 
auch der Code, mit dessen Hilfe du überhaupt feststellst, was gelesen 
wurde.

Davon abgesehen: Dass 'offset' tatsächlich nur ein Byte-Offset darstellt 
und nicht etwa ein Index für das Array, ist hoffentlich klar, oder?
Gast #3153250
Lesenswert?

Stefan Ernst schrieb:
> Zeig mal allen relevanten Code, nicht nur Einzeiler. Dazu gehört z.B.
> auch der Code, mit dessen Hilfe du überhaupt feststellst, was gelesen
> wurde.

Ich habe zu Eingrenzung ein extra Projekt erstellt und gebe ein Wort via 
16 LEDs (PORTA und PORTB) aus. Ansonsten gibt es wirklich nur die paar 
Zeilen..

> Davon abgesehen: Dass 'offset' tatsächlich nur ein Byte-Offset darstellt
> und nicht etwa ein Index für das Array, ist hoffentlich klar, oder?

Das ist wohl mein erstes Problem. Ich dachte, dass dies ein Index 
ist..?!?

Jedoch unabhängig davon: Sollte die Funktion nicht trotzdem (wenn auch 
verschoben) echte 16Bit-Werte liefern? z.B. bei offset=1 => 0x55f0

Ich verstehe jedoch nicht, warum mir pgm_read_word_far immer die oberen 
8Bit auf 0 setzt..?!? :-/
#3153268
Lesenswert?

Der Techniker schrieb:
>> Davon abgesehen: Dass 'offset' tatsächlich nur ein Byte-Offset darstellt
>> und nicht etwa ein Index für das Array, ist hoffentlich klar, oder?
>
> Das ist wohl mein erstes Problem. Ich dachte, dass dies ein Index
> ist..?!?

Nein, denn "FAR(daten) + offset" ist keine Pointer-Arithmetik, sondern 
einfach nur eine Addition zweier Integer.

Der Techniker schrieb:
> Jedoch unabhängig davon: Sollte die Funktion nicht trotzdem (wenn auch
> verschoben) echte 16Bit-Werte liefern? z.B. bei offset=1 => 0x55f0

Ja.

Der Techniker schrieb:
> Ich verstehe jedoch nicht, warum mir pgm_read_word_far immer die oberen
> 8Bit auf 0 setzt..?!? :-/

Tut es mit ziemlicher Sicherheit nicht. Es ist wahrscheinlicher, dass 
irgendwo anders ein Fehler ist, der dich das nur glauben lässt. Aber 
schon klar, im Rest des Codes kann natürlich unter keinen Umständen 
irgendein Fehler sein, richtig?

Der Techniker schrieb:
> Ich habe zu Eingrenzung ein extra Projekt erstellt und gebe ein Wort via
> 16 LEDs (PORTA und PORTB) aus. Ansonsten gibt es wirklich nur die paar
> Zeilen..

Umso unverständlicher, warum man dir den Code aus der Nase pulen muss, 
und du ihn nicht einfach komplett postest.
Gast #3154710
Lesenswert?

Stefan Ernst schrieb:
> Umso unverständlicher, warum man dir den Code aus der Nase pulen muss,
> und du ihn nicht einfach komplett postest.

Frisch aus der Nase:

main.c
1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
3

4
#define FAR(var)                      \
5
({ uint_farptr_t tmp;                 \
6
__asm__ __volatile__(                 \
7
  "ldi    %A0, lo8(%1)"  "\n\t" \
8
  "ldi    %B0, hi8(%1)"  "\n\t" \
9
  "ldi    %C0, hh8(%1)"  "\n\t" \
10
  : "=d" (tmp)                  \
11
  : "p"  (&(var)));             \
12
tmp;                                  \
13
})
14

15
const unsigned int daten[] PROGMEM = { 0xf0aa,  0x0f55 };
16

17
int main (void)
18
{
19
 unsigned int var = 0;
20
 unsigned char offset = 0;
21

22
 DDRA = 0xff;
23
 DDRB = 0xff;
24
 
25
 val = pgm_read_word_far(FAR(daten) + offset);
26
 
27
 PORTA = (val >>8);
28
 PORTB = val;
29
 
30
 while(1);
31
}

Zur Fehlereingrenzung sieht das "Programm" genau so aus.
Nicht mehr und nicht weniger..

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren