// PB6 ... MISO
// PB7 ... SCK
- int8_t Cc1101New::run (uint8_t subtest) {
- if (subtest == 0 && mode == Test) {
- while (wait(0) == EOF) {
+ int8_t Cc1101New::runSend (uint8_t subtest) {
+ if (subtest == 0) {
+ bool ok = true;
+ GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET;
+ ok &= writeRegister(0x02, cfg0);
+ return ok;
+ } else if (subtest > 1) {
+ return -1;
+ }
+
+ 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;
}
- } else if (subtest == 0 && mode == Send) {
- uint16_t cnt = 0;
+ 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;
+ }
+
+ int8_t Cc1101New::runReceive (uint8_t subtest) {
+ if (subtest > 0) {
+ return -1;
+ }
+
+ int key = EOF;
+ uint16_t cnt = 0;
+ MainRadioControlState state;
+ while (key == EOF) {
+ printf_P(PSTR("\n [%04x] => start ... "), cnt++);
+ strobe(SRX);
do {
- MainRadioControlState state = UNKNOWN;
- uint8_t data[20];
- printf_P(PSTR("\n [%04x]: state="), cnt++);
+ state = UNKNOWN;
if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
printf_P(PSTR("E1"));
- } else {
- printf_P(PSTR("0x%02x"), state);
+ _delay_ms(500);
+ break;
}
- for (uint8_t i = 0; i < sizeof(data); i++) {
- data[i] = i;
+ if (wait(0) != EOF) {
+ printf_P(PSTR("cancelled"));
+ _delay_ms(500);
+ break;
}
- printf_P(PSTR(" --> send %d bytes ... "), sizeof(data));
- if (!sendData(data, sizeof(data))) {
- flashRedLed(100);
- printf_P(PSTR("E1"));
- continue;
+ if (state == IDLE) {
+ printf_P(PSTR("? (IDLE)"));
+ _delay_ms(500);
+ break;
}
- flashGreenLed(100);
- printf_P(PSTR("OK -> state="));
+
+ } while (state != RX && state != RXFIFO_OVERFLOW);
+
+ if (state != RX && state != RXFIFO_OVERFLOW) {
+ continue;
+ }
+
+ printf_P(PSTR("OK, receive ... "));
+
+ do {
+ uint8_t length;
+ uint8_t data[16];
if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
- printf_P(PSTR("E1"));
- } else {
- printf_P(PSTR("0x%02x"), state);
+ printf_P(PSTR("E2"));
+ _delay_ms(500);
+ continue;
+ }
+ if (wait(0) != EOF) {
+ printf_P(PSTR("cancelled"));
+ _delay_ms(500);
+ continue;
+ }
+ if (receiveData(data, &length, sizeof(data))) {
+ flashGreenLed(100);
+ printf_P(PSTR("OK, %d bytes received: "), length);
+ for (uint8_t i = 0; i < length; i++) {
+ printf_P(PSTR(" 0x%02x"), data[i]);
+ }
+ printf_P(PSTR(" ... "));
}
- } while (wait(2000) == EOF);
- return 0;
+ } while (state == RX || state == RXFIFO_OVERFLOW);
- } else if (subtest == 0 && mode == Receive) {
-
+ printf_P(PSTR("done (state=0x%02x)"), state);
}
return -1;
}
+ int8_t Cc1101New::runTest (uint8_t subtest) {
+ if (subtest > 0) {
+ return -1;
+ }
+ while (wait(0) == EOF) {}
+ return -1;
+ }
+
+
+ int8_t Cc1101New::run (uint8_t subtest) {
+ switch (mode) {
+ case Send: return runSend(subtest);
+ case Receive: return runReceive(subtest);
+ case Test: return runTest(subtest);
+ default: return -1;
+ }
+ }
+
// --------------------------------------------------------
const Cc1101New::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = {
/* 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
+ /* 0x02: iocfg0 0x06 (----) */ { Cc1101New::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,
bool Cc1101New::sendData (uint8_t *buffer, uint8_t length) {
bool ok = true;
+ uint8_t txbytes;
// ok &= writeRegister(0x3f, length);
ok &= writeRegisters(0x3f, buffer, length);
- ok &= strobe(STX); // start sending bytes
- ok &= waitForGD0High();
- ok &= waitForGD0Low();
- ok &= strobe(SFTX); //flush TXfifo
+ ok &= readStatusRegister(TXBYTES, &txbytes);
+ ok &= (txbytes == 20);
+ timer = 10;
+ if (ok) {
+ triggerOn();
+ ok &= strobe(STX); // start sending bytes
+ // ok &= waitForGD0High(); // wait for start of SYNC
+ if (ok) {
+ uint8_t state;
+ do {
+ ok &= readStatusRegister(MARCSTATE, &state);
+ } while (ok && state != 0x13 && timer > 0);
+ ok &= state == 0x13; // check if in state TX
+ }
+ if (ok) {
+ do {
+ ok &= readStatusRegister(TXBYTES, &txbytes);
+ } while (ok && txbytes > 0 && timer > 0);
+ ok &= txbytes == 0;
+ }
+ }
+ if (!ok) {
+ strobe(SFTX); // flush TXfifo
+ }
+ // ok &= waitForGD0Low(); // wait for end of package
+ triggerOff();
+
+ // if (ok) {
+ // printf_P(PSTR(" -> ? %02x %02x %02x %02x? "), state, txbytes[0], txbytes[1], txbytes[2]);
+ // }
+
return ok;
}
+ bool Cc1101New::receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize) {
+ bool ok = true;
+ STATUS_RXBYTES_t status;
+
+ ok &= readStatusRegister(RXBYTES, &status.byte);
+ if (ok && status.rxbytes.num_rxbytes > 0) {
+ uint8_t length = status.rxbytes.num_rxbytes;
+ ok &= readStatusRegister(RXBYTES, &status.byte);
+ if (ok && status.rxbytes.num_rxbytes == length) {
+ // ok &= readRegister(RXFIFO, &length);
+ if (length <= maxBufferSize) {
+ ok &= readRegisters(0xff, buffer, length);
+ } else {
+ ok = false;
+ }
+ ok &= strobe(SFRX);
+ if (ok) {
+ *receivedLength = length;
+ return ok;
+ }
+ }
+ }
+ strobe(SFRX);
+ *receivedLength = 0;
+ return false;
+ }
+
void Cc1101New::printRegisters () {
const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
debugPrint.byte = 0xff; // print all
printRegisters();
- triggerOn();
for (uint8_t addr = 0; ok && addr < sizeof(Register_t); addr++) {
uint8_t regValue;
memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1);
ok &= writeRegister(addr, regValue);
}
- triggerOff();
printRegisters();
debugPrint.print = tmp;
void tick1ms () { if (timer > 0) timer--; };
private:
- typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SFTX = 0x3b, SIDLE = 0x36 } StrobeCommand_t;
+ 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;
private:
+ int8_t runSend (uint8_t subtest);
+ int8_t runReceive (uint8_t subtest);
+ int8_t runTest (uint8_t subtest);
uint8_t sendSpiByte (uint8_t b);
void triggerOn();
void triggerOff();
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);
+ bool receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize);
void printRegisters ();
bool resetCC1101 ();
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 union {
+ uint8_t byte;
+ struct {
+ uint8_t num_rxbytes:7;
+ uint8_t rxfifo_overflow:1;
+ } rxbytes;
+ } STATUS_RXBYTES_t;
+
typedef struct {
IOCFG2_t iocfg2;
IOCFG1_t iocfg1;