Commit 796ad04c20592c21b24cb048f5300a9143e2ea27
receivedThu, 15. Aug 2024, 12:04:11 (by user sx)
Thu, 15 Aug 2024 10:04:11 +0000 (12:04 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Thu, 15 Aug 2024 10:04:04 +0000 (12:04 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Thu, 15 Aug 2024 10:04:04 +0000 (12:04 +0200)
5 files changed:
software/nano-644/test_2024-07-23/Makefile
software/nano-644/test_2024-07-23/src/main.cpp
software/nano-644/test_2024-07-23/src/main.hpp
software/nano-644/test_2024-07-23/src/units/cc1101.cpp
software/nano-644/test_2024-07-23/src/units/cc1101.hpp

index 06747cfefdbba6692bdc5a2c7961d365556b8cc0..4ceec530eb42298a9df9bcfeedb9d0c5180cdc01 100644 (file)
@@ -60,6 +60,10 @@ dist/%.hex: dist/%.elf
 sim/$(NAME).elf: .depend $(OBJ_SIM)
                $(CC) $(LFLAGS_SIM) -o $@ $(OBJ_SIM)
 
+# ensure that __DATE__ and __TIME__ macros are up to date
+build/main.o: src/main.cpp $(SRC) $(HDR)
+       @mkdir -p $(dir $@)
+       $(CC) $(CFLAGS) -o $@ $<
 
 build/%.o: src/%.c
        @mkdir -p $(dir $@)
index befbb74c3067cff010f0350d9759b582a09de40e..9c1aefdf51649055404ab514a2f09bd7cb0ce198 100644 (file)
 #include "units/rtc8563.hpp"
 #include "units/cc1101.hpp"
 
+
+const char MAIN_CPP_DATE[] PROGMEM = __DATE__;
+const char MAIN_CPP_TIME[] PROGMEM = __TIME__;
+
 extern "C" {
    void __cxa_pure_virtual () {}
    int  __cxa_guard_acquire(uint8_t *g) { return 0; }
@@ -144,6 +148,12 @@ int wait (uint32_t ms) {
    return keyUart0;
 }
 
+int waitAndReadKey (uint32_t ms) {
+   int key = wait(ms);
+   keyUart0 = EOF;
+   return key;
+}
+
 int main () {
 
    #ifdef __AVR_ATmega644P__
@@ -196,7 +206,13 @@ int main () {
       uint16_t i;
       char s[4];
       do {
-         printf_P(PSTR("\n\n=============================\n\n"));
+         printf_P(PSTR("\n"));
+         printf_P(PSTR("\n=================================\n"));
+         printf_P(PSTR("  Version: "));
+         printf_P(MAIN_CPP_DATE); printf_P(PSTR(" / "));
+         printf_P(MAIN_CPP_TIME);
+         printf_P(PSTR("\n=================================\n"));
+         printf_P(PSTR("\n"));
          printf_P(PSTR("Available units:\n\n"));
          for (i = 0; i < sizeof(unit) / sizeof(unit[0]); i++) {
             TestUnit *pu = unit[i];
index e5bf840f8f7e2856f222065ac4cbb9eb89dad664..11d75347a8a7b51b9bcef79226ce953355a186d0 100644 (file)
@@ -6,8 +6,10 @@
 
 #define ENTER '\r'
 #define CTRLC '\003'
+#define ESCAPE 0x1b
 
 extern int wait (uint32_t ms);
+extern int waitAndReadKey (uint32_t ms);
 extern uint64_t millis ();
 
 #ifdef __AVR_ATmega644P__
index b3eb1d8e1a73cdc2b52493b31f1ad37c07df4c38..25a11de88672abd6e3724b6520f7c364097c49ca 100644 (file)
    // PB6 ... MISO
    // PB7 ... SCK
 
+   // --------------------------------------------------------
+
+   // Output power table from CC1101 datasheet page 59
+   const Cc1101::PATABLE_INIT_ITEM_t PMEM_CC1101_PATABLE_INIT[] PROGMEM = {
+      { 0xc6, "9.6" }, // 9.6 dBm / 29.4mA (default value)
+      { 0xc0, "11"  }, //  11 dBm / 34.2mA
+      { 0xc5, "10"  }, //  10 dBm / 30.0mA
+      { 0xcd, "7"   }, //   7 dBm / 25.8mA
+      { 0x86, "5"   }, //   5 dBm / 19.9mA
+      { 0x50, "0"   }, //   0 dBm / 16.8mA
+      { 0x37, "-6"  }, //  -6 dBm / 16.4mA
+      { 0x26, "-10"  }, //  10 dBm / 14.5mA
+      { 0x1d, "-15"  }, //  15 dBm / 13.3mA
+      { 0x17, "-20"  }, //  20 dBm / 12.6mA
+      { 0x03, "-30"  }, //  30 dBm / 12.0mA
+   }; 
+   const Cc1101::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = { 
+      /* 0x00: iocfg2    0x0b (----) */ { Cc1101::CHIP_NOT_READY, 0, 0 }, // GDO2
+      /* 0x01: iocfg1    0x2e (----) */ { Cc1101::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // GDO1/MISO
+      /* 0x02: iocfg0    0x06 (----) */ { Cc1101::SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET, 0, 0 },  // GDO0 -> PA5
+      /* 0x03: fifothr   0x47 (0x07) */ { 7, 0, 1, 0 }, // fifo_thr = 0b111, close_in_rx=0, adc_retention = 1, (bit7=0)
+      /* 0x04: sync1     0x7a (0xd3) */ 0x7a,
+      /* 0x05: sync0     0x0e (0x91) */ 0x0e,
+      /* 0x06: pktlen    0x14 (0x3d) */ PACKET_LENGTH,
+      /* 0x07: pktctrl1  0x04 (----) */ { Cc1101::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000
+      /* 0x08: pktctrl0  0x05 (----) */ { Cc1101::FIXED, 1, 0, Cc1101::NORMAL_USE_FIFO, 0, 0 }, // length_config=0b01, crc_en=1, (bit3=0), pkt_format=0b00, white_data=0, (bit7=0)
+      /* 0x09: addr      0x00 (----) */ 0x00,
+      /* 0x0a: channr    0x00 (----) */ 0x00,
+      /* 0x0b: fsctrl1   0x06 (0x08) */ { 6, 0, 0 }, // frqu_if=6, (bit5=0), (bit76=0b00)
+      /* 0x0c: fsctrl0   0x00 (----) */ { 0 }, // freqoff = 0
+      /* 0x0d: frequ2    0x21 (----) */ 0x21,
+      /* 0x0e: frequ1    0x62 (----) */ 0x62,
+      /* 0x0f: frequ0    0x76 (----) */ 0x76,
+      /* 0x10: mdmcfg4   0xca (0x5b) */ { 0x0a, 0, 3 }, // drate_e=0x0a, chanbw_m=0, chanbw_e=3
+      /* 0x11: mdmcfg3   0xf8 (----) */ { 0xf8 }, // drate_m=0xf8
+      /* 0x12: mdmcfg2   0x16 (0x03) */ { Cc1101::SYNC_16_16_CARRIER_SENSE, 0, Cc1101::GFSK, 0}, // sync_mode=0b110, manchester_en=0, mod_format=0b001, dem_dcfilt_off=0
+      /* 0x13: mdmcfg1   0x22 (----) */ { 2, 0, Cc1101::FOUR, 0 }, // chanspc_e=0b10, bit32=0, num_preamble=0b010, fec_en=0
+      /* 0x14: mdmcfg0   0xf8 (----) */ { 0xf8 }, // chanspc_m = 0x08
+      /* 0x15: deviatn   0x40 (0x47) */ { 0, 0, 4, 0 }, // deviation_m=0, (bit3=0), deviation_e=4, (bit7=0)
+      /* 0x16: mcsm2     0x07 (----) */ { 7, 0, 0, 0 }, // rx_time=7 (NA), rx_time_qual=0, rx_time_rssi=0, (bit76=0b00)
+      /* 0x17: mcsm1     0x30 (----) */ { Cc1101::TXOFF_IDLE, Cc1101::RXOFF_IDLE, Cc1101::RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET, 0 }, // mcsm1 (txoff_mode=0b00, rxoff_mode=0b00, cca_mode=0b11, (bit76=0b00) )
+      /* 0x18: mcsm0     0x18 (----) */ { 0, 0, 2, Cc1101::IDLE_TO_RX_OR_TX, 0 }, // xosc_force_on=0, pin_ctrl_en=0, po_timeout=2 (149-155us), fs_autocal=0b01, (bit76=0b00)
+      /* 0x19: foccfg    0x16 (0x1d) */ 0x16,
+      /* 0x1a: bscfg     0x6c (0x1c) */ 0x6c,
+      /* 0x1b: agcctrl2  0x43 (0xc7) */ 0x43,
+      /* 0x1c: agcctrl1  0x49 (0x00) */ 0x49,
+      /* 0x1d: agcctrl0  0x91 (0xb2) */ 0x91,
+      /* 0x1e: worevt1   0x87 (----) */ 0x87,
+      /* 0x1f: worevt0   0x6b (----) */ 0x6b,
+      /* 0x20: worctrl   0xfb (0xf8) */ 0xfb,
+      /* 0x21: frend1    0x56 (0xb6) */ 0x56,
+      /* 0x22: frend0    0x10 (----) */ { 0, 0, 1, 0 }, // pa_power = 0, (bit3 = 0), lodiv_buf_current = 1, (bit76=0b00)
+      /* 0x23: fscal3    0xe9 (0xea) */ 0xe9,
+      /* 0x24: fscal2    0x2a (----) */ 0x2a,
+      /* 0x25: fscal1    0x00 (----) */ 0x00,
+      /* 0x26: fscal0    0x1f (0x11) */ 0x1f,
+      /* 0x27: rcctrl1   0x41 (----) */ 0x41,
+      /* 0x28: rcctrl0   0x00 (----) */ 0x00,
+      /* 0x29: fstest    0x59 (----) */ 0x59,
+      /* 0x2a: ptest     0x7f (----) */ 0x7f,
+      /* 0x2b: agctest   0x3f (----) */ 0x3f,
+      /* 0x2c: test2     0x81 (0x88) */ 0x81,
+      /* 0x2d: test1     0x35 (0x31) */ 0x35,
+      /* 0x2e: test0     0x09 (0x0b) */ 0x09
+   };
+
+   // --------------------------------------------------------------------------------------
+
    int8_t Cc1101::runSend (uint8_t subtest) {
       if (subtest == 0) {
          bool ok = true;
          return -1;
       }
 
+      printf_P(PSTR(" use + and - for power change (other key -> back to default)"));
+
       uint16_t cnt = 0;
+      uint8_t paIndex = 0;
+      uint8_t pa_power;
+      int key = EOF;
       do {
+         // if ((cnt & 0x0f) == 0) {
+         //    paIndex = (cnt >> 4) & 0x07;
+         //    union { FREND0_t value; uint8_t byte; } frend0 = { paIndex, 0, 1, 0 };
+         //    printf_P(PSTR("\n switch power "));
+         //    if (writeRegister(FREND0, frend0.byte )) {
+         //       printf_P(PSTR("to %d (FREND0 = 0x%02X)"), frend0.value.pa_power, frend0.byte);
+         //    } else {
+         //       printf_P(PSTR("fails"));
+         //    }
+         // }
+         if (key != EOF) {
+            uint8_t max = (sizeof(PMEM_CC1101_PATABLE_INIT) / sizeof(PMEM_CC1101_PATABLE_INIT[0])) - 1;
+            switch (key) {
+               case '+': if (paIndex == 0) paIndex = 1; else if (paIndex > 1) paIndex--; break;
+               case '-': if (paIndex == 0) paIndex = max; else if (paIndex < max) paIndex++; break;
+               default: paIndex = 0; break; // default value
+            }
+
+            const PATABLE_INIT_ITEM_t *values = PMEM_CC1101_PATABLE_INIT;
+            
+            memcpy_P(&pa_power, &((values[paIndex]).pa_power), 1);
+            PGM_P info = (values[paIndex]).dbm;
+            printf_P(PSTR("\n switch power to ")); printf_P(info);
+            printf_P(PSTR("dBm "));
+            if (writeRegister(0x3e, pa_power )) {
+               printf_P(PSTR("(PATABLE = 0x%02X)"), pa_power);
+            } else {
+               printf_P(PSTR("fails"));
+            }
+         }
+
          MainRadioControlState state = UNKNOWN;
          uint8_t data[PACKET_LENGTH];
          printf_P(PSTR("\n [%04x]: state="), cnt++);
          } else {
             printf_P(PSTR("0x%02x"), state);
          }
-         printf_P(PSTR(" --> send %d bytes (HEX:"), sizeof(data));
-         for (uint8_t i = 0; i < sizeof(data); i++) {
-            data[i] = uint8_t((cnt + i) & 0xff);
+         data[0] = pa_power;
+         printf_P(PSTR(" --> send %d bytes (HEX: %02X"), sizeof(data), paIndex);
+         for (uint8_t i = 1; i < sizeof(data); i++) {
+            data[i] = uint8_t((cnt + i - 1) & 0xff);
             printf_P(PSTR(" %02X"), data[i]);
          }
          printf_P(PSTR("] -> "));
             continue;
          }
          flashGreenLed(100);
+         key = waitAndReadKey(2000);
          printf_P(PSTR("OK"));
-      } while (wait(2000) == EOF);
+         
+      } while (key == EOF || (key != ESCAPE));
 
       return 0;
    }
       }
    }
 
-   // --------------------------------------------------------
-
-   const Cc1101::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = { 
-      /* 0x00: iocfg2    0x0b (----) */ { Cc1101::CHIP_NOT_READY, 0, 0 }, // GDO2
-      /* 0x01: iocfg1    0x2e (----) */ { Cc1101::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // GDO1/MISO
-      /* 0x02: iocfg0    0x06 (----) */ { Cc1101::SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET, 0, 0 },  // GDO0 -> PA5
-      /* 0x03: fifothr   0x47 (0x07) */ { 7, 0, 1, 0 }, // fifo_thr = 0b111, close_in_rx=0, adc_retention = 1, (bit7=0)
-      /* 0x04: sync1     0x7a (0xd3) */ 0x7a,
-      /* 0x05: sync0     0x0e (0x91) */ 0x0e,
-      /* 0x06: pktlen    0x14 (0x3d) */ PACKET_LENGTH,
-      /* 0x07: pktctrl1  0x04 (----) */ { Cc1101::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000
-      /* 0x08: pktctrl0  0x05 (----) */ { Cc1101::FIXED, 1, 0, Cc1101::NORMAL_USE_FIFO, 0, 0 }, // length_config=0b01, crc_en=1, (bit3=0), pkt_format=0b00, white_data=0, (bit7=0)
-      /* 0x09: addr      0x00 (----) */ 0x00,
-      /* 0x0a: channr    0x00 (----) */ 0x00,
-      /* 0x0b: fsctrl1   0x06 (0x08) */ { 6, 0, 0 }, // frqu_if=6, (bit5=0), (bit76=0b00)
-      /* 0x0c: fsctrl0   0x00 (----) */ { 0 }, // freqoff = 0
-      /* 0x0d: frequ2    0x21 (----) */ 0x21,
-      /* 0x0e: frequ1    0x62 (----) */ 0x62,
-      /* 0x0f: frequ0    0x76 (----) */ 0x76,
-      /* 0x10: mdmcfg4   0xca (0x5b) */ { 0x0a, 0, 3 }, // drate_e=0x0a, chanbw_m=0, chanbw_e=3
-      /* 0x11: mdmcfg3   0xf8 (----) */ { 0xf8 }, // drate_m=0xf8
-      /* 0x12: mdmcfg2   0x16 (0x03) */ { Cc1101::SYNC_16_16_CARRIER_SENSE, 0, Cc1101::GFSK, 0}, // sync_mode=0b110, manchester_en=0, mod_format=0b001, dem_dcfilt_off=0
-      /* 0x13: mdmcfg1   0x22 (----) */ { 2, 0, Cc1101::FOUR, 0 }, // chanspc_e=0b10, bit32=0, num_preamble=0b010, fec_en=0
-      /* 0x14: mdmcfg0   0xf8 (----) */ { 0xf8 }, // chanspc_m = 0x08
-      /* 0x15: deviatn   0x40 (0x47) */ { 0, 0, 4, 0 }, // deviation_m=0, (bit3=0), deviation_e=4, (bit7=0)
-      /* 0x16: mcsm2     0x07 (----) */ { 7, 0, 0, 0 }, // rx_time=7 (NA), rx_time_qual=0, rx_time_rssi=0, (bit76=0b00)
-      /* 0x17: mcsm1     0x30 (----) */ { Cc1101::TXOFF_IDLE, Cc1101::RXOFF_IDLE, Cc1101::RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET, 0 }, // mcsm1 (txoff_mode=0b00, rxoff_mode=0b00, cca_mode=0b11, (bit76=0b00) )
-      /* 0x18: mcsm0     0x18 (----) */ { 0, 0, 2, Cc1101::IDLE_TO_RX_OR_TX, 0 }, // xosc_force_on=0, pin_ctrl_en=0, po_timeout=2 (149-155us), fs_autocal=0b01, (bit76=0b00)
-      /* 0x19: foccfg    0x16 (0x1d) */ 0x16,
-      /* 0x1a: bscfg     0x6c (0x1c) */ 0x6c,
-      /* 0x1b: agcctrl2  0x43 (0xc7) */ 0x43,
-      /* 0x1c: agcctrl1  0x49 (0x00) */ 0x49,
-      /* 0x1d: agcctrl0  0x91 (0xb2) */ 0x91,
-      /* 0x1e: worevt1   0x87 (----) */ 0x87,
-      /* 0x1f: worevt0   0x6b (----) */ 0x6b,
-      /* 0x20: worctrl   0xfb (0xf8) */ 0xfb,
-      /* 0x21: frend1    0x56 (0xb6) */ 0x56,
-      /* 0x22: frend0    0x10 (----) */ 0x10,
-      /* 0x23: fscal3    0xe9 (0xea) */ 0xe9,
-      /* 0x24: fscal2    0x2a (----) */ 0x2a,
-      /* 0x25: fscal1    0x00 (----) */ 0x00,
-      /* 0x26: fscal0    0x1f (0x11) */ 0x1f,
-      /* 0x27: rcctrl1   0x41 (----) */ 0x41,
-      /* 0x28: rcctrl0   0x00 (----) */ 0x00,
-      /* 0x29: fstest    0x59 (----) */ 0x59,
-      /* 0x2a: ptest     0x7f (----) */ 0x7f,
-      /* 0x2b: agctest   0x3f (----) */ 0x3f,
-      /* 0x2c: test2     0x81 (0x88) */ 0x81,
-      /* 0x2d: test1     0x35 (0x31) */ 0x35,
-      /* 0x2e: test0     0x09 (0x0b) */ 0x09
-   };
-
    uint8_t Cc1101::sendSpiByte (uint8_t b) {
       SPDR = b;
       while (!(SPSR & (1<<SPIF))) {}
 
    PGM_P Cc1101::getName () {
       switch (mode) {
-         case Send: return PSTR("CC-1101-New-Send");
-         case Receive: return PSTR("CC-1101-New-Receive");
-         case Test: return PSTR("CC-1101-New-Test");
-         default: return PSTR("CC-1101-New-?");
+         case Send: return PSTR("CC-1101-Send");
+         case Receive: return PSTR("CC-1101-Receive");
+         case Test: return PSTR("CC-1101-Test");
+         default: return PSTR("CC-1101-?");
       }
    }
 
    void Cc1101::init () {
 
-      printf_P(PSTR("\n sizeof(status)=%d "), sizeof(status));
-
       // trigger for debugging
       PORTB &= ~(1 << PB0);
       DDRB |= ( 1 << PB0);
          printf_P(PSTR("fails"));
          return;
       }
+      printf_P(PSTR("OK, init PATABLE ... "));;
+      if (!initPaTable()) {
+         printf_P(PSTR("fails"));
+         return;
+      }
       printf_P(PSTR("OK"));
+
+      debugPrint.byte = 0xff; // print all
+      printRegisters();
+      debugPrint.byte = 0x00; // print nothing
+
    }
 
    void Cc1101::cleanup () {
    bool Cc1101::initRegister () {
       const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
       bool ok = true;
-      DebugPrint_t tmp = debugPrint.print;
-      debugPrint.byte = 0xff; // print all
-      printRegisters();
+      // DebugPrint_t tmp = debugPrint.print;
+      // debugPrint.byte = 0xff; // print all
+      // printRegisters();
 
       for (uint8_t addr = 0; ok && addr < sizeof(Register_t); addr++) {
          uint8_t regValue;
          }
       }
 
-      printRegisters();
-      debugPrint.print = tmp;
+      // debugPrint.print = tmp;
       return ok;
    }
 
+   bool Cc1101::initPaTable () {
+      const PATABLE_INIT_ITEM_t *values = PMEM_CC1101_PATABLE_INIT;
+      uint8_t patable[8];
+      uint8_t initValuesIndex = 0;
+      for (uint8_t i = 0; i < 8; i++) {
+         memcpy_P(&patable[i], &(values[initValuesIndex++].pa_power), 1);
+         if (initValuesIndex >= (sizeof(PMEM_CC1101_PATABLE_INIT) / sizeof(PATABLE_INIT_ITEM_t))) {
+            initValuesIndex = 0;
+         }
+         if (debugPrint.print.writePaTable) {
+            printf_P(PSTR("\nPTABLE %d: 0x%02x"), i, patable[i]);
+         }
+      }
+      return writeRegisters(0x3e, patable, 8);
+   }
+
 #endif
 
 
index 3603d4d59edb67b6cad80602a9f04fb56bb5a6ae..e0676505334d8d27c51135ccdd4a26f95b20b76e 100644 (file)
@@ -44,7 +44,7 @@ class Cc1101 : public TestUnit {
    private:
       typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SFRX = 0x3a, SFTX = 0x3b, SIDLE = 0x36 } StrobeCommand_t;
       typedef enum { MARCSTATE = 0x35, TXBYTES = 0x3A, RXBYTES = 0x3B } StatusAddress_t;
-      typedef struct { uint8_t writeRegister:1; uint8_t writeRegisters:1; uint8_t readRegister:1; uint8_t readRegisters:1; } DebugPrint_t;
+      typedef struct { uint8_t writeRegister:1; uint8_t writeRegisters:1; uint8_t readRegister:1; uint8_t readRegisters:1; uint8_t writePaTable:1; } DebugPrint_t;
 
    private:
       int8_t runSend (uint8_t subtest);
@@ -73,6 +73,7 @@ class Cc1101 : public TestUnit {
 
       bool resetCC1101 ();
       bool initRegister ();
+      bool initPaTable ();
       
 
    private:
@@ -90,7 +91,21 @@ class Cc1101 : public TestUnit {
          FIFOTHR = 0x03,
          SYNC1 = 0x04, SYNC0 = 0x05,
          PKTLEN = 0x06,
-         PKTCTRL1 = 0x07, PKTCTRL0 = 0x08
+         PKTCTRL1 = 0x07, PKTCTRL0 = 0x08,
+         ADDR = 0x00, CHANNR = 0x0a,
+         FSCTRL1 = 0x0b, FSCTRL0 = 0x0c,
+         FREQU2 = 0x0d, FREQU1 = 0x0e, FREQU0 = 0x0f,
+         MDMCFG4 = 0x10, MDMCFG3 = 0x11, MDMCFG2 = 0x12, MDMCFG1 = 0x13, MDMCFG0 = 0x14,
+         DEVIATN = 0x15,
+         MCSM2 = 0x16, MCSM1 = 0x17, MCSM0 = 0x18,
+         FOCCFG = 0x19, BSCFG = 0x1a,
+         AGCCTRL2 = 0x1b, AGCCTRL1 = 0x1c, AGCCTRL0 = 0x1d,
+         WOREVT1 = 0x1e, WOREVT0 = 0x1f, WORCTRL = 0x20,
+         FREND1 = 0x21, FREND0 = 0x22,
+         FSCAL3 = 0x23, FSCAL2 = 0x24, FSCAL1 = 0x25, FSCAL0 = 0x26,
+         RCCTRL1 = 0x27, RCCTRL0 = 0x28,
+         FSTEST = 0x29, PTEST = 0x2a, AGCTEST = 0x2b,
+         TEST2 = 0x2c, TEST1 = 0x2d, TEST0 = 0x2e
       } RegisterAddress_t;
 
       typedef enum {
@@ -168,6 +183,8 @@ class Cc1101 : public TestUnit {
          UNKNOWN = 255
       } MainRadioControlState;
 
+      typedef struct { uint8_t pa_power; const char dbm[4]; } PATABLE_INIT_ITEM_t;
+
       typedef enum { NO_ADDR_CHECK = 0, CHECK_NO_BROADCAST = 1, CHECK_WITH_BROADCAST_0 = 2, CHECK_WITH_BROADCAST_0_AND_255 = 3 } ADR_CHK_t;
       typedef enum { FIXED = 0, VARIABLE = 1, INFINITE = 2 } LENGTH_CONFIG_t;
       typedef enum { NORMAL_USE_FIFO = 0, SYNC_SERIAL = 1, RANDOM_TX = 2, ASYNC_SERIAL = 3 } PKT_FORMAT_t;
@@ -196,6 +213,7 @@ class Cc1101 : public TestUnit {
       typedef struct { uint8_t rx_time:3; uint8_t rx_time_qual:1; uint8_t rx_time_rssi:1; uint8_t bit765:3; } MCSM2_t;
       typedef struct { TXOFF_MODE_t txoff_mode:2; RXOFF_MODE_t rxoff_mode:2; CCA_MODE_t cca_mode:2; uint8_t bit76:2; } MCSM1_t;
       typedef struct { uint8_t xosc_force_on:1; uint8_t pin_ctrl_en:1; uint8_t po_timeout:2; FS_AUTOCAL_t fs_autocal:2; uint8_t bit76:2; } MCSM0_t;
+      typedef struct { uint8_t pa_power:3; uint8_t bit3:1; uint8_t lodiv_buf_current:2; uint8_t bit76:2; } FREND0_t;
 
       typedef union {
          uint8_t byte;
@@ -240,7 +258,7 @@ class Cc1101 : public TestUnit {
          uint8_t worevt0;
          uint8_t worctrl;
          uint8_t frend1;
-         uint8_t frend0;
+         FREND0_t frend0;
          uint8_t fscal3;
          uint8_t fscal2;
          uint8_t fscal1;