/*
  http://snippets.artvolk.sumy.ua/view/141/massiv-massivov-v-progmem-dlya-mikrokontrollerov-avr

  Когда совсем запутался с массивами массивов, хранимых во флеш-памяти
  микроконтроллера AVR решил набросать такую демку и проверить всё в
  симуляторе с отладчиком. Вроде бы разобрался, возможно, кому-нибудь ещё
  пригодится.

  Особенно понравился доступ к массивам не так: a[2], а вот так: 2[a]
  (это работает для любых массивов в C) :-)

*/

#include <avr/io.h>
#include <avr/pgmspace.h>

#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))

const uint8_t array1[] PROGMEM = {1,2,3,4,5};
const uint8_t array2[] PROGMEM = {6,7,8,9,10,11,12};

const uint8_t* my_arrays[] PROGMEM = {
    array1,
    array2
};

uint8_t* current;
uint8_t x, size;

int main(void)
{
    /*
        Description: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38003
    */
    x = pgm_read_byte(&array1[3]); // read 4rd element of first array

    // Read using pointer to array1
    current = (uint8_t*)array1;
    x = pgm_read_byte(current + 2); // read 3rd element of first array

    // Size of one array
    size = NUM_ELEM(array1);

    // Read using pointer to array2
    current = (uint8_t*)array2;
    x = pgm_read_byte(current+1); // read 2nd element of second array

    // Read using pointer from pointer table in Flash
    current = (uint8_t*)pgm_read_word(my_arrays+1);
    x = pgm_read_byte(current+5); // read #6 element of second array

    // Read using pointer from pointer table in Flash (different syntax)
    current = (uint8_t*)pgm_read_word(&my_arrays[1]);
    x = pgm_read_byte(current+6); // read #7 element of second array

    x = pgm_read_byte(&current[5]); // read #6 element of second array

    x = pgm_read_byte(&2[current]); // freaky one :)

    // Size of pointer arrays
    size = NUM_ELEM(my_arrays);

    while(1)
    {

    }
}
