PROGMEM pointer question

I want an array of pointers to arrays in program memory. But when I declare the array of pointers with PROGMEM I get inconsistent results. Sometimes it works and sometimes it doesn't.

In the example code below the first value (pointer in program memory) is incorrect whereas the second value (pointer in sram) is correct.

How can I successful put the pointers in program memory?

static uint8_t f0 [] PROGMEM = { 1, 2, 3, 4, 5, 6, 7 };
static uint8_t f1 [] PROGMEM = { 10, 20, 30, 40, 50 };
static uint8_t f2 [] PROGMEM = { 100, 200 };

static uint8_t *tbl [] PROGMEM = {f0, f1, f2};
static uint8_t *tbl2 [] = {f0, f1, f2};

void setup()
{
  Serial.begin(115200);
}

void loop() {

  Serial.println("\nType 0, 1 or 2:");
  while (!Serial.available()) {}
  char c = Serial.read();
    
  Serial.print("value = ");
  Serial.println(uint8_t(pgm_read_byte(tbl[c-'0'])));

  Serial.print("value2 = ");
  Serial.println(uint8_t(pgm_read_byte(tbl2[c-'0'])));


}

As both arrays are in PROGMEM, you need to read the pointer from PROGMEM then use that to read the data.

You need to use the addressof operator or use pointer arithmetic to get the PGM location, otherwise you try and access the value from RAM.
&tbl[c-'0']
or
tbl + (c-'0')

Serial.println(uint8_t( pgm_read_byte( pgm_read_word(&tbl[c-'0']) ) ) );

Thank you!