pgm_read_byte_far doesn't work as it should because GCC compiler uses 16 bit addressing for pgm by default and cannot be changed. The only way to go beyond 64K is to use the GET_FAR_ADDRESS routine I found on the internet and keep track of indexes in case of arrays, because indexing won't work with this routine.
#define GET_FAR_ADDRESS(var) \
({ \
uint_farptr_t tmp; \
\
__asm__ __volatile__( \
\
"ldi %A0, lo8(%1)" "\n\t" \
"ldi %B0, hi8(%1)" "\n\t" \
"ldi %C0, hh8(%1)" "\n\t" \
"clr %D0" "\n\t" \
: \
"=d" (tmp) \
: \
"p" (&(var)) \
); \
tmp; \
})
The code above retrieves the 24-bit address in flash where your array's beginning is stored. Then you combine this with pgm_read like this:
pgm_read_byte_far(GET_FAR_ADDRESS(GSLX680_FW[0].offset)+source_line*5);
F_byte = pgm_read_dword_far(GET_FAR_ADDRESS(GSLX680_FW[0].val)+source_line*5);
and you get the constants from the array. Number 5 is the struct size: 1uchar(1 byte) + 1 long int (4 bytes) = 5 bytes total
It was hard to get it right but I'm proud I sorted it out in the end
#define GET_FAR_ADDRESS(var) \
({ \
uint_farptr_t tmp; \
\
__asm__ __volatile__( \
\
"ldi %A0, lo8(%1)" "\n\t" \
"ldi %B0, hi8(%1)" "\n\t" \
"ldi %C0, hh8(%1)" "\n\t" \
"clr %D0" "\n\t" \
: \
"=d" (tmp) \
: \
"p" (&(var)) \
); \
tmp; \
})
The code above retrieves the 24-bit address in flash where your array's beginning is stored. Then you combine this with pgm_read like this:
pgm_read_byte_far(GET_FAR_ADDRESS(GSLX680_FW[0].offset)+source_line*5);
F_byte = pgm_read_dword_far(GET_FAR_ADDRESS(GSLX680_FW[0].val)+source_line*5);
and you get the constants from the array. Number 5 is the struct size: 1uchar(1 byte) + 1 long int (4 bytes) = 5 bytes total
It was hard to get it right but I'm proud I sorted it out in the end