// 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;
}