Commit e0a934fa2c1888096524c127312af195b53f589c
receivedMon, 12. Aug 2024, 18:58:17 (by user sx)
Mon, 12 Aug 2024 16:58:17 +0000 (18:58 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Mon, 12 Aug 2024 16:58:09 +0000 (18:58 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Mon, 12 Aug 2024 16:58:09 +0000 (18:58 +0200)
3 files changed:
software/nano-644/test_2024-07-23/src/main.cpp
software/nano-644/test_2024-07-23/src/units/cc1101new.cpp
software/nano-644/test_2024-07-23/src/units/cc1101new.hpp

index d64616fc3c6d08fda85db09d69e2d4bfaf292c9d..75a111323e3677833dcec85ab11b0c19fa8a4dfa 100644 (file)
@@ -127,7 +127,9 @@ extern "C" {
    Rtc8563 rtc8563;
    Cc1101 cc1101Send(Cc1101::Send);
    Cc1101 cc1101Receive(Cc1101::Receive);
-   Cc1101New cc1101New(Cc1101New::Test);
+   Cc1101New cc1101NewSend(Cc1101New::Send);
+   Cc1101New cc1101NewReceive(Cc1101New::Receive);
+   Cc1101New cc1101NewTest(Cc1101New::Test);
 
 }
 
@@ -184,7 +186,7 @@ int main () {
    #ifdef __AVR_ATmega644P__
       TestUnit *unit[] = {
          &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &portExp, &lcd, &uart1, &modbus, &ieee485,
-         &i2cMaster, &i2cSlave, &i2cSparkfun, &rtc8563, &cc1101Send, &cc1101Receive, &cc1101New
+         &i2cMaster, &i2cSlave, &i2cSparkfun, &rtc8563, &cc1101Send, &cc1101Receive, &cc1101NewSend, &cc1101NewReceive, &cc1101NewTest
       };
    #endif
 
@@ -304,7 +306,9 @@ ISR (TIMER2_COMPA_vect) { // every 100us
       i2cSparkfun.tick1ms();
       cc1101Send.tick1ms();
       cc1101Receive.tick1ms();
-      cc1101New.tick1ms();
+      cc1101NewSend.tick1ms();
+      cc1101NewReceive.tick1ms();
+      cc1101NewTest.tick1ms();
       #ifdef __AVR_ATmega644P__
          if (timerFlashRedLed > 0) {
             if (--timerFlashRedLed < 128) {
index 4e10b87da7a0ea6140401149d2c1acb6584dc0ea..6a7121fe8a434f4a92073cf4921b86d231dedcab 100644 (file)
    // PB7 ... SCK
 
    int8_t Cc1101New::run (uint8_t subtest) {
-      while (wait(0) == EOF) {
+      if (subtest == 0 && mode == Test) {
+         while (wait(0) == EOF) {
+         }
+      } else if (subtest == 0 && mode == Send) {
+         uint16_t cnt = 0;
+         do {
+            MainRadioControlState state = UNKNOWN;
+            uint8_t data[20];
+            printf_P(PSTR("\n [%04x]: state="), cnt++);
+            if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
+               printf_P(PSTR("E1"));
+            } else {
+               printf_P(PSTR("0x%02x"), state);
+            }
+            for (uint8_t i = 0; i < sizeof(data); i++) {
+               data[i] = i;
+            }
+            printf_P(PSTR(" --> send %d bytes ... "), sizeof(data));
+            if (!sendData(data, sizeof(data))) {
+               flashRedLed(100);
+               printf_P(PSTR("E1"));
+               continue;
+            }
+            flashGreenLed(100);
+            printf_P(PSTR("OK -> state="));
+            if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
+               printf_P(PSTR("E1"));
+            } else {
+               printf_P(PSTR("0x%02x"), state);
+            }
+         } while (wait(2000) == EOF);
+         return 0;
+
+
+      } else if (subtest == 0 && mode == Receive) {
+         
       }
       return -1;
    }
    // --------------------------------------------------------
 
    const Cc1101New::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = { 
-      /* iocfg2    0x0b (----) */ { Cc1101New::CHIP_NOT_READY, 0, 0 }, // GDO2
-      /* iocfg1    0x2e (----) */ { Cc1101New::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // GDO1/MISO
-      /* iocfg0    0x06 (----) */ { Cc1101New::CLK_XOSC_DIV_128, 0, 0 },  // GDO0
-      /* fifothr   0x47 (0x07) */ { 7, 0, 1, 0 }, // fifo_thr = 0b111, close_in_rx=0, adc_retention = 1, (bit7=0)
-      /* sync1     0x7a (0xd3) */ 0x7a,
-      /* sync0     0x0e (0x91) */ 0x0e,
-      /* pktlen    0x14 (0x3d) */ 0x14,
-      /* pktctrl1  0x04 (----) */ { Cc1101New::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000
-      /* pktctrl0  0x05 (----) */ { Cc1101New::FIXED, 1, 0, Cc1101New::NORMAL_USE_FIFO, 0, 0 }, // length_config=0b01, crc_en=1, (bit3=0), pkt_format=0b00, white_data=0, (bit7=0)
-      /* addr      0x00 (----) */ 0x00,
-      /* channr    0x00 (----) */ 0x00,
-      /* fsctrl1   0x06 (0x08) */ { 6, 0, 0 }, // frqu_if=6, (bit5=0), (bit76=0b00)
-      /* fsctrl0   0x00 (----) */ { 0 }, // freqoff = 0
-      /* frequ2    0x21 (----) */ 0x21,
-      /* frequ1    0x62 (----) */ 0x62,
-      /* frequ0    0x76 (----) */ 0x76,
-      /* mdmcfg4   0xca (0x5b) */ { 0x0a, 0, 3 }, // drate_e=0x0a, chanbw_m=0, chanbw_e=3
-      /* mdmcfg3   0xf8 (----) */ { 0xf8 }, // drate_m=0xf8
-      /* mdmcfg2   0x16 (0x03) */ { Cc1101New::SYNC_16_16_CARRIER_SENSE, 0, Cc1101New::GFSK, 0}, // sync_mode=0b110, manchester_en=0, mod_format=0b001, dem_dcfilt_off=0
-      /* mdmcfg1   0x22 (----) */ { 2, 0, Cc1101New::FOUR, 0 }, // chanspc_e=0b10, bit32=0, num_preamble=0b010, fec_en=0
-      /* mdmcfg0   0xf8 (----) */ { 0xf8 }, // chanspc_m = 0x08
-      /* deviatn   0x40 (0x47) */ { 0, 0, 4, 0 }, // deviation_m=0, (bit3=0), deviation_e=4, (bit7=0)
-      /* mcsm2     0x07 (----) */ { 7, 0, 0, 0 }, // rx_time=7 (NA), rx_time_qual=0, rx_time_rssi=0, (bit76=0b00)
-      /* mcsm1     0x30 (----) */ { Cc1101New::TXOFF_IDLE, Cc1101New::RXOFF_IDLE, Cc1101New::RSSI_BELOW_THRESHOLD__UNLESS_RECEIVE_PACKET, 0 }, // mcsm1 (txoff_mode=0b00, rxoff_mode=0b00, cca_mode=0b11, (bit76=0b00) )
-      /* mcsm0     0x18 (----) */ { 0, 0, 2, Cc1101New::IDLE_TO_RX_OR_TX, 0 }, // xosc_force_on=0, pin_ctrl_en=0, po_timeout=2 (149-155us), fs_autocal=0b01, (bit76=0b00)
-      /* foccfg    0x16 (0x1d) */ 0x16,
-      /* bscfg     0x6c (0x1c) */ 0x6c,
-      /* agcctrl2  0x43 (0xc7) */ 0x43,
-      /* agcctrl1  0x49 (0x00) */ 0x49,
-      /* agcctrl0  0x91 (0xb2) */ 0x91,
-      /* worevt1   0x87 (----) */ 0x87,
-      /* worevt0   0x6b (----) */ 0x6b,
-      /* worctrl   0xfb (0xf8) */ 0xfb,
-      /* frend1    0x56 (0xb6) */ 0x56,
-      /* frend0    0x10 (----) */ 0x10,
-      /* fscal3    0xe9 (0xea) */ 0xe9,
-      /* fscal2    0x2a (----) */ 0x2a,
-      /* fscal1    0x00 (----) */ 0x00,
-      /* fscal0    0x1f (0x11) */ 0x1f,
-      /* rcctrl1   0x41 (----) */ 0x41,
-      /* rcctrl0   0x00 (----) */ 0x00,
-      /* fstest    0x59 (----) */ 0x59,
-      /* ptest     0x7f (----) */ 0x7f,
-      /* agctest   0x3f (----) */ 0x3f,
-      /* test2     0x81 (0x88) */ 0x81,
-      /* test1     0x35 (0x31) */ 0x35,
-      /* test0     0x09 (0x0b) */ 0x09
-
+      /* 0x00: iocfg2    0x0b (----) */ { Cc1101New::CHIP_NOT_READY, 0, 0 }, // GDO2
+      /* 0x01: iocfg1    0x2e (----) */ { Cc1101New::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // GDO1/MISO
+      /* 0x02: iocfg0    0x06 (----) */ { Cc1101New::CLK_XOSC_DIV_128, 0, 0 },  // GDO0
+      /* 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) */ 0x14,
+      /* 0x07: pktctrl1  0x04 (----) */ { Cc1101New::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000
+      /* 0x08: pktctrl0  0x05 (----) */ { Cc1101New::FIXED, 1, 0, Cc1101New::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) */ { Cc1101New::SYNC_16_16_CARRIER_SENSE, 0, Cc1101New::GFSK, 0}, // sync_mode=0b110, manchester_en=0, mod_format=0b001, dem_dcfilt_off=0
+      /* 0x13: mdmcfg1   0x22 (----) */ { 2, 0, Cc1101New::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 (----) */ { Cc1101New::TXOFF_IDLE, Cc1101New::RXOFF_IDLE, Cc1101New::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, Cc1101New::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
    };
 
-
-// const uint8_t PMEM_CC1101_INIT[] PROGMEM = { 
-//    CC1101_MDMCFG4,  0x5B, // modem config 4 -> ADC decimation rate, symbol rate exponent
-//    CC1101_MDMCFG3,  0xF8, // modem config 3 -> symbol rate mantissa
-//    CC1101_MDMCFG2,  0x03, // modem config 2 -> DC blocking filter, modulation type, manchaster enoding, sync-mode, 
-//    CC1101_MDMCFG1,  0x22, // modem config 1 -> forw error correction, min number of preamble bytes, channel spacing exponent
-//    CC1101_MDMCFG0,  0xF8, // modem config 0 -> channel spacing mantissa
-//    CC1101_CHANNR,   0x00, // channel number
-//    CC1101_DEVIATN,  0x47, // modem deviation setting
-//    CC1101_FREND1,   0xB6, // front end RX configuration
-//    CC1101_FREND0,   0x10, // front end TX configuration
-//    CC1101_MCSM0 ,   0x18, // Main Radio Control State Machine Configuration
-//    CC1101_FOCCFG,   0x1D, // Frequency Offset Compensation Configuration
-//    CC1101_BSCFG,    0x1C, // Bit Synchronization Configuration
-//    CC1101_AGCCTRL2, 0xC7, // AGC Control
-//    CC1101_AGCCTRL1, 0x00, // AGC Control
-//    CC1101_AGCCTRL0, 0xB2, // AGC Control
-//    CC1101_FSCAL3,   0xEA, // Frequency Synthesizer Calibration
-//    CC1101_FSCAL2,   0x2A, // Frequency Synthesizer Calibration
-//    CC1101_FSCAL1,   0x00, // Frequency Synthesizer Calibration
-//    CC1101_FSCAL0,   0x11, // Frequency Synthesizer Calibration
-//     CC1101_FSTEST,   0x59, // Frequency Synthesizer Calibration Control
-//     CC1101_TEST2,    0x81, // Various Test Settings
-//     CC1101_TEST1,    0x35, // Various Test Settings
-//     CC1101_TEST0,    0x09, // Various Test Settings
-//    CC1101_IOCFG2,   0x0B, // GDO2 Output Pin Configuration -> Serial Clock. Synchronous to the data in synchronous serial mode.
-//    CC1101_IOCFG0,   0x06, // GDO0 Output Pin Configuration -> Asserts when sync word has been sent / received, and de-asserts at the end of the packet.
-//    CC1101_PKTCTRL1, 0x04, // Packet Automation Control
-//    CC1101_PKTCTRL0, 0x05, // serial clock.synchronous to the data in synchronous serial mode
-//    CC1101_ADDR,     0x00, // asserts when sync word has been sent/received, and de-asserts at the end of the packet 
-//    CC1101_PKTLEN,   0x3D  // two status bytes will be appended to the payload of the packet,including RSSI LQI and CRC OK
-// };
-
    uint8_t Cc1101New::sendSpiByte (uint8_t b) {
       SPDR = b;
       while (!(SPSR & (1<<SPIF))) {}
 
    PGM_P Cc1101New::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-?");
       }
       return true;
    }
 
+   bool Cc1101New::waitForGD0High () {
+      timer = 100;
+      while (!isGd0High()) {
+         if (timer == 0) {
+            return false;
+         }
+      }
+      return true;
+   }
+
+   bool Cc1101New::waitForGD0Low () {
+      timer = 100;
+      while (isGd0High()) {
+         if (timer == 0) {
+            return false;
+         }
+      }
+      return true;
+   }
+
    bool Cc1101New::strobe (StrobeCommand_t command) {
           bool ok = true;
       setChipEnableLow();
       status.byte = sendSpiByte(value);
       setChipEnableHigh();
       
-      printf_P(PSTR("\n [writeRegister(0x%02x, 0x%02x) -> "), addr, value);
-      if (ok) {
-         printf_P(PSTR("status=0x%02x]"), status.byte);
-      } else {
-         printf_P(PSTR("ERR]"));
+      if (debugPrint.print.writeRegister) {
+         printf_P(PSTR("\n [writeRegister(0x%02x, 0x%02x) -> "), addr, value);
+         if (ok) {
+            printf_P(PSTR("status=0x%02x]"), status.byte);
+         } else {
+            printf_P(PSTR("ERR]"));
+         }
       }
 
       return ok;
    }
 
+   bool Cc1101New::writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
+      bool ok = true;
+      uint8_t l = length;
+      uint8_t *p = buffer;
+
+      addr = (addr & 0x3f) | 0x40; // write burst
+      setChipEnableLow();
+      ok &= waitForMisoLow();
+      sendSpiByte(addr);
+      while (length-- > 0) {
+         sendSpiByte(*buffer++);
+      }
+      setChipEnableHigh();
+
+      if (debugPrint.print.writeRegisters) {
+         printf_P(PSTR("\n [writeRegisters(0x%02x): "), addr & 0x3f);
+         while (l-- > 0) {
+            printf_P(PSTR(" 0x%02x"), *p++);
+         }
+         printf_P(PSTR(" -> "));
+         if (ok) {
+            printf_P(PSTR("status=0x%02x]"), status.byte);
+         } else {
+            printf_P(PSTR("ERR]"));
+         }
+      }
+      
+      return ok;
+   }
+
+
    bool Cc1101New::readRegister (uint8_t addr, uint8_t *value) {
       bool ok = true;
       addr = (addr & 0x3f) | 0x80;
       *value = sendSpiByte(0);
       setChipEnableHigh();
 
-      printf_P(PSTR("\n [readRegister(0x%02x) -> "), addr & 0x3f);
-      if (ok) {
-         printf_P(PSTR("0x%02x,status=0x%02x]"), *value, status.byte);
-      } else {
-         printf_P(PSTR("ERR]"));
+      if (debugPrint.print.readRegister) {
+         printf_P(PSTR("\n [readRegister(0x%02x) -> "), addr & 0x3f);
+         if (ok) {
+            printf_P(PSTR("0x%02x,status=0x%02x]"), *value, status.byte);
+         } else {
+            printf_P(PSTR("ERR]"));
+         }
       }
       return ok;
    }
    
+   bool Cc1101New::readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
+      bool ok = true;
+
+      uint8_t l = length;
+      uint8_t *p = buffer;
+
+      addr |= 0xc0; // read burst
+      setChipEnableLow();
+      ok &= waitForMisoLow();
+      sendSpiByte(addr);
+      while (length-- > 0) {
+         *buffer++ = sendSpiByte(0);
+      }
+      setChipEnableHigh();
+      
+      if (debugPrint.print.readRegisters) {
+         printf_P(PSTR("\n [readRegisters(0x%02x, ..., %d)] -> "), addr & 0x3f, l);
+         if (ok) {
+            while (l-- > 0) {
+               printf_P(PSTR(" 0x%02x"), *p++);
+            }
+            printf_P(PSTR("]"));
+         } else {
+            printf_P(PSTR("ERR]"));
+         }
+      }
+      
+      return ok;
+   }
+
+   bool Cc1101New::readStatusRegister (StatusAddress_t addr, uint8_t *value) {
+       if (addr < 0x30 || addr > 0x3d) {
+         return false;
+      } else {
+         return readRegisters(addr, value, 1);
+      }
+   }
+
+   bool Cc1101New::sendData (uint8_t *buffer, uint8_t length) {
+      bool ok = true;
+      // ok &= writeRegister(0x3f, length);
+      ok &= writeRegisters(0x3f, buffer, length);
+      ok &= strobe(STX);       // start sending bytes
+      ok &= waitForGD0High();
+      ok &= waitForGD0Low();
+      ok &= strobe(SFTX); //flush TXfifo
+      return ok;
+   }
+
+
    void Cc1101New::printRegisters () {
       const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
       printf_P(PSTR("\n"));
          ok &= readRegister(addr, &value);
          if (value != regValue) { printf_P(PSTR(" != 0x%02x"), regValue); }
       }
-      printf_P(PSTR("\n"));
+      uint8_t data[8];
+      for (uint8_t addr = 0x30; addr <= 0x3d; addr++) {
+         readStatusRegister((StatusAddress_t)addr, data);
+      }
+      readRegisters(0x3e, data, 8); // PATABLE
    }
 
    bool Cc1101New::resetCC1101 () {
    bool Cc1101New::initRegister () {
       const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
       bool ok = true;
-
+      DebugPrint_t tmp = debugPrint.print;
+      debugPrint.byte = 0xff; // print all
       printRegisters();
 
       triggerOn();
       triggerOff();
 
       printRegisters();
+      debugPrint.print = tmp;
       return ok;
    }
 
index 6afc8c4d43453627df4eb9883c896662e19568db..53dc65bccdf791776b86ec0a97df29ac56066d00 100644 (file)
@@ -7,9 +7,8 @@
 
 class Cc1101New : public TestUnit {
    public:
-      typedef enum { MHZ915, MHZ433, MHZ868 } InitFrequency;
-      typedef enum { Test } Cc1101Mode;
-      typedef enum { IDLE = 0, RX = 1, TX = 2, FSTXON = 3, CALIBRATE = 4, SETTLING = 5, RXFIFO_OVFL = 6, TXFIFO_UNFL = 7 } StatusState_t;
+      typedef enum { Test, Send, Receive  } Cc1101Mode;
+      typedef enum { _IDLE = 0, _RX = 1, _TX = 2, _FSTXON = 3, _CALIBRATE = 4, _SETTLING = 5, _RXFIFO_OVFL = 6, _TXFIFO_UNFL = 7 } StatusState_t;
       typedef struct { uint8_t fifoBytes:4; StatusState_t state:3; uint8_t chipNotReady:1; } Status_t;
       union {
          Status_t status;
@@ -17,7 +16,7 @@ class Cc1101New : public TestUnit {
       } status;
 
    public:
-      Cc1101New (Cc1101Mode mode) { timer = 0; this->mode = mode; status.byte = 0x80; }
+      Cc1101New (Cc1101Mode mode) { timer = 0; this->mode = mode; status.byte = 0x80; debugPrint.byte = 0; }
       virtual void init ();
       virtual void cleanup ();
       virtual int8_t run (uint8_t subtest);
@@ -27,7 +26,9 @@ class Cc1101New : public TestUnit {
       void tick1ms () { if (timer > 0) timer--; };
 
    private:
-      typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SIDLE = 0x36 } StrobeCommand_t;
+      typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, 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;
 
    private:
       uint8_t sendSpiByte (uint8_t b);
@@ -38,9 +39,15 @@ class Cc1101New : public TestUnit {
       bool isMisoHigh ();
       bool isGd0High ();
       bool waitForMisoLow ();
+      bool waitForGD0High ();
+      bool waitForGD0Low ();
       bool strobe (StrobeCommand_t strobe);
       bool writeRegister (uint8_t addr, uint8_t value);
+      bool writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length);
       bool readRegister (uint8_t addr, uint8_t *value);
+      bool readRegisters (uint8_t addr, uint8_t *buffer, uint8_t length);
+      bool readStatusRegister (StatusAddress_t addr, uint8_t *value);
+      bool sendData (uint8_t *buffer, uint8_t length);
       void printRegisters ();
 
       bool resetCC1101 ();
@@ -50,6 +57,11 @@ class Cc1101New : public TestUnit {
    private:
       Cc1101Mode mode;
       uint8_t timer;
+      union {
+         DebugPrint_t print;
+         uint8_t byte;
+      } debugPrint;
+      
 
    public:
       typedef enum {
@@ -108,6 +120,33 @@ class Cc1101New : public TestUnit {
          CLK_XOSC_DIV_192 = 0x3f
       } GDOx_CFG_t;
 
+      typedef enum { 
+         SLEEP = 0,
+         IDLE = 1,
+         XOFF = 2,
+         MANCAL_VCOON = 3,
+         MANCAL_REGON = 4,
+         MANCAL = 5,
+         FS_WAKEUP_VCOON = 6,
+         FS_WAKEUP_REGON = 7,
+         CALIBRATE_START = 8,
+         SETTLING_BWBOOST = 9,
+         SETTLING_FS_LOCK = 10,
+         SETTLIN_IFADCON = 11,
+         CALIBRATE_END = 12,
+         RX = 13,
+         RX_END = 14,
+         RX_RST = 15,
+         TXRX_SETTLING = 16,
+         RXFIFO_OVERFLOW = 17,
+         FXTXON = 18,
+         TX = 19,
+         TX_END = 20,
+         RXTX_SETTLING = 21,
+         TXFIFO_UNDERFLOW = 22,
+         UNKNOWN = 255
+      } MainRadioControlState;
+
       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;