The problem
I can’t get the data from the Flash memory when using the function that return the address of the pattern desired in the Flash (simplified in the example below with only 1 constant : PATTERN_P).
Some code before explication
The type patternp is defined as
typedef prog_uchar patternp[NUM_ROWS];
The global PATTERN_P variable is an array of type patternp, defined as
const patternp PATTERN_P PROGMEM = { 0b11110000 , 0b10010000 , 0b10010000 , 0b10010000 , 0b11110000 , 0b10000000 , 0b10000000 , 0b10000000 };
getpattern():
const patternp * getPattern() { //... return &PATTERN_P; }
main():
const patternp *bufferPattern = getPattern(); uint8_t rowPatternData[NUMBER_ROW_PER_MATRIX]; const patternp *bufferPattern = getPattern(s[iLetter]); for(int iRow = 0; iRow<NUMBER_ROW_PER_MATRIX; iRow++) { rowPatternData[iRow]=pgm_read_byte( &PATTERN_P[iRow] ); // <--- WORK! rowPatternData[iRow]=pgm_read_byte( bufferPattern[iRow] ); // Not Working! }
Explications
As you can see, the code get the pattern (in this example, it will return PATTERN_P every time… than I use pgm_read_byte to get the data from the Flash memory. This use the AVR pgmspace (link below). It takes an address and return the data. The code above work when I use the direct access of a template : &PATTERN_P[iRow], but won’t work when I use bufferPattern[iRow] or &bufferPattern[iRow]. Any idea?
Reference : pgm_read_byte is defined in pgmspace
bufferPattern is a pointer to an array. When you write bufferPattern[iRow], this does NOT evaluate to a pointer to entry iRow of patternp; the [] operation is acting on the pointer, not the array it points to. What you appear to want to write is &((*bufferPattern)[iRow]).
That will fix the immediate problem. However, the code is a bit confusing. It may be that your code would be simplified by passing the array directly (C does not pass arrays by value; so it won’t copy the array – you don’t need to make a pointer to the array to avoid this).