AskSin++
Radio.h
1 //- -----------------------------------------------------------------------------------------------------------------------
2 // AskSin driver implementation
3 // 2013-08-03 <trilu@gmx.de> Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
4 //- -----------------------------------------------------------------------------------------------------------------------
5 //- AskSin cc1101 functions -----------------------------------------------------------------------------------------------
6 //- with a lot of copy and paste from culfw firmware
7 //- -----------------------------------------------------------------------------------------------------------------------
8 //- -----------------------------------------------------------------------------------------------------------------------
9 // AskSin++
10 // 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
11 // 2019-03-31 stan23 Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
12 //- -----------------------------------------------------------------------------------------------------------------------
13 
14 #ifndef _CC_H
15 #define _CC_H
16 
17 #include "Message.h"
18 #include "AlarmClock.h"
19 
20 #if defined ARDUINO_ARCH_AVR && !defined Adafruit_SPIDevice_h
21  #include <util/delay.h>
22  typedef uint8_t BitOrder;
23 #endif
24 
25 #ifndef Adafruit_SPIDevice_h
26  #define SPI_BITORDER_MSBFIRST MSBFIRST
27  #define SPI_BITORDER_LSBFIRST LSBFIRST
28 #endif
29 
30 // #define USE_CCA
31 
32 #ifndef USE_OTA_BOOTLOADER
33  // we can not reuse the frequency if the ota bootloader
34  #undef USE_OTA_BOOTLOADER_FREQUENCY
35 #endif
36 
37 namespace as {
38 
39 // CC1101 config register // Reset Description
40 #define CC1101_IOCFG2 0x00 // (0x29) GDO2 Output Pin Configuration
41 #define CC1101_IOCFG1 0x01 // (0x2E) GDO1 Output Pin Configuration
42 #define CC1101_IOCFG0 0x02 // (0x3F) GDO0 Output Pin Configuration
43 #define CC1101_FIFOTHR 0x03 // (0x07) RX FIFO and TX FIFO Thresholds
44 #define CC1101_SYNC1 0x04 // (0xD3) Sync Word, High Byte
45 #define CC1101_SYNC0 0x05 // (0x91) Sync Word, Low Byte
46 #define CC1101_PKTLEN 0x06 // (0xFF) Packet Length
47 #define CC1101_PKTCTRL1 0x07 // (0x04) Packet Automation Control
48 #define CC1101_PKTCTRL0 0x08 // (0x45) Packet Automation Control
49 #define CC1101_ADDR 0x09 // (0x00) Device Address
50 #define CC1101_CHANNR 0x0A // (0x00) Channel Number
51 #define CC1101_FSCTRL1 0x0B // (0x0F) Frequency Synthesizer Control
52 #define CC1101_FSCTRL0 0x0C // (0x00) Frequency Synthesizer Control
53 #define CC1101_FREQ2 0x0D // (0x1E) Frequency Control Word, High Byte
54 #define CC1101_FREQ1 0x0E // (0xC4) Frequency Control Word, Middle Byte
55 #define CC1101_FREQ0 0x0F // (0xEC) Frequency Control Word, Low Byte
56 #define CC1101_MDMCFG4 0x10 // (0x8C) Modem Configuration
57 #define CC1101_MDMCFG3 0x11 // (0x22) Modem Configuration
58 #define CC1101_MDMCFG2 0x12 // (0x02) Modem Configuration
59 #define CC1101_MDMCFG1 0x13 // (0x22) Modem Configuration
60 #define CC1101_MDMCFG0 0x14 // (0xF8) Modem Configuration
61 #define CC1101_DEVIATN 0x15 // (0x47) Modem Deviation Setting
62 #define CC1101_MCSM2 0x16 // (0x07) Main Radio Control State Machine Configuration
63 #define CC1101_MCSM1 0x17 // (0x30) Main Radio Control State Machine Configuration
64 #define CC1101_MCSM0 0x18 // (0x04) Main Radio Control State Machine Configuration
65 #define CC1101_FOCCFG 0x19 // (0x36) Frequency Offset Compensation Configuration
66 #define CC1101_BSCFG 0x1A // (0x6C) Bit Synchronization Configuration
67 #define CC1101_AGCCTRL2 0x1B // (0x03) AGC Control
68 #define CC1101_AGCCTRL1 0x1C // (0x40) AGC Control
69 #define CC1101_AGCCTRL0 0x1D // (0x91) AGC Control
70 #define CC1101_WOREVT1 0x1E // (0x87) High Byte Event0 Timeout
71 #define CC1101_WOREVT0 0x1F // (0x6B) Low Byte Event0 Timeout
72 #define CC1101_WORCTRL 0x20 // (0xF8) Wake On Radio Control
73 #define CC1101_FREND1 0x21 // (0x56) Front End RX Configuration
74 #define CC1101_FREND0 0x22 // (0x10) Front End RX Configuration
75 #define CC1101_FSCAL3 0x23 // (0xA9) Frequency Synthesizer Calibration
76 #define CC1101_FSCAL2 0x24 // (0x0A) Frequency Synthesizer Calibration
77 #define CC1101_FSCAL1 0x25 // (0x20) Frequency Synthesizer Calibration
78 #define CC1101_FSCAL0 0x26 // (0x0D) Frequency Synthesizer Calibration
79 #define CC1101_RCCTRL1 0x27 // (0x41) RC Oscillator Configuration
80 #define CC1101_RCCTRL2 0x28 // (0x00) RC Oscillator Configuration
81 #define CC1101_FSTEST 0x29 // (0x59) Frequency Synthesizer Calibration Control
82 #define CC1101_PTEST 0x2A // (0x7F) Production Test
83 #define CC1101_AGCTEST 0x2B // (0x3F) AGC Test
84 #define CC1101_TEST2 0x2C // (0x88) Various Test Settings
85 #define CC1101_TEST1 0x2D // (0x31) Various Test Settings
86 #define CC1101_TEST0 0x2E // (0x0B) Various Test Settings
87 
88 #define CC1101_PARTNUM 0x30 // (0x00) Readonly: Chip ID
89 #define CC1101_VERSION 0x31 // (0x04) Readonly: Chip ID
90 #define CC1101_FREQEST 0x32 // (0x00) Readonly: Frequency Offset Estimate from Demodulator
91 #define CC1101_LQI 0x33 // (0x00) Readonly: Demodulator Estimate for Link Quality
92 #define CC1101_RSSI 0x34 // (0x00) Readonly: Received Signal Strength Indication
93 #define CC1101_MARCSTATE 0x35 // (0x00) Readonly: Main Radio Control State Machine State
94 #define CC1101_WORTIME1 0x36 // (0x00) Readonly: High Byte of WOR Time
95 #define CC1101_WORTIME0 0x37 // (0x00) Readonly: Low Byte of WOR Time
96 #define CC1101_PKTSTATUS 0x38 // (0x00) Readonly: Current GDOx Status and Packet Status
97 #define CC1101_VCO_VC_DAC 0x39 // (0x00) Readonly: Current Setting from PLL Calibration Module
98 #define CC1101_TXBYTES 0x3A // (0x00) Readonly: Underflow and Number of Bytes
99 #define CC1101_RXBYTES 0x3B // (0x00) Readonly: Overflow and Number of Bytes
100 #define CC1101_RCCTRL1_STATUS 0x3C // (0x00) Readonly: Last RC Oscillator Calibration Result
101 #define CC1101_RCCTRL0_STATUS 0x3D // (0x00) Readonly: Last RC Oscillator Calibration Result
102 
103 #define CC1101_PATABLE 0x3E // PATABLE address
104 #define CC1101_TXFIFO 0x3F // TX FIFO address
105 #define CC1101_RXFIFO 0x3F // RX FIFO address
106 
107 #define CC1101_PA_TABLE0 0x40 // (0x00) PA table, entry 0
108 #define CC1101_PA_TABLE1 0x41 // (0x00) PA table, entry 1
109 #define CC1101_PA_TABLE2 0x42 // (0x00) PA table, entry 2
110 #define CC1101_PA_TABLE3 0x43 // (0x00) PA table, entry 3
111 #define CC1101_PA_TABLE4 0x44 // (0x00) PA table, entry 4
112 #define CC1101_PA_TABLE5 0x45 // (0x00) PA table, entry 5
113 #define CC1101_PA_TABLE6 0x46 // (0x00) PA table, entry 6
114 #define CC1101_PA_TABLE7 0x47 // (0x00) PA table, entry 7
115 
116 // some register definitions for TRX868 communication
117 #define READ_SINGLE 0x80 // type of transfers
118 #define READ_BURST 0xC0
119 #define WRITE_BURST 0x40
120 
121 #define CC1101_CONFIG 0x80 // type of register
122 #define CC1101_STATUS 0xC0
123 
124 #define CC1101_SRES 0x30 // reset CC1101 chip
125 #define CC1101_SFSTXON 0x31 // enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). if in RX (with CCA): Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround).
126 #define CC1101_SXOFF 0x32 // turn off crystal oscillator
127 #define CC1101_SCAL 0x33 // calibrate frequency synthesizer and turn it off. SCAL can be strobed from IDLE mode without setting manual calibration mode (MCSM0.FS_AUTOCAL=0)
128 #define CC1101_SRX 0x34 // enable RX. perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1
129 #define CC1101_STX 0x35 // in IDLE state: enable TX. perform calibration first if MCSM0.FS_AUTOCAL=1. if in RX state and CCA is enabled: only go to TX if channel is clear
130 #define CC1101_SIDLE 0x36 // exit RX / TX, turn off frequency synthesizer and exit Wake-On-Radio mode if applicable
131 #define CC1101_SWOR 0x38 // start automatic RX polling sequence (Wake-on-Radio) as described in Section 19.5 if WORCTRL.RC_PD=0
132 #define CC1101_SPWD 0x39 // enter power down mode when CSn goes high
133 #define CC1101_SFRX 0x3A // flush the RX FIFO buffer. only issue SFRX in IDLE or RXFIFO_OVERFLOW states
134 #define CC1101_SFTX 0x3B // flush the TX FIFO buffer. only issue SFTX in IDLE or TXFIFO_UNDERFLOW states
135 #define CC1101_SWORRST 0x3C // reset real time clock to Event1 value
136 #define CC1101_SNOP 0x3D // no operation. may be used to get access to the chip status byte
137 
138 #define MARCSTATE_SLEEP 0x00
139 #define MARCSTATE_IDLE 0x01
140 #define MARCSTATE_XOFF 0x02
141 #define MARCSTATE_VCOON_MC 0x03
142 #define MARCSTATE_REGON_MC 0x04
143 #define MARCSTATE_MANCAL 0x05
144 #define MARCSTATE_VCOON 0x06
145 #define MARCSTATE_REGON 0x07
146 #define MARCSTATE_STARTCAL 0x08
147 #define MARCSTATE_BWBOOST 0x09
148 #define MARCSTATE_FS_LOCK 0x0A
149 #define MARCSTATE_IFADCON 0x0B
150 #define MARCSTATE_ENDCAL 0x0C
151 #define MARCSTATE_RX 0x0D
152 #define MARCSTATE_RX_END 0x0E
153 #define MARCSTATE_RX_RST 0x0F
154 #define MARCSTATE_TXRX_SWITCH 0x10
155 #define MARCSTATE_RXFIFO_OFLOW 0x11
156 #define MARCSTATE_FSTXON 0x12
157 #define MARCSTATE_TX 0x13
158 #define MARCSTATE_TX_END 0x14
159 #define MARCSTATE_RXTX_SWITCH 0x15
160 #define MARCSTATE_TXFIFO_UFLOW 0x16
161 
162 #define PA_LowPower 0x03 // PATABLE values
163 #define PA_Normal 0x50 // PATABLE values
164 #define PA_MaxPower 0xC0
165 
166 
167 
168 #ifdef ARDUINO_ARCH_AVR
169 
170 template <uint8_t CS,uint8_t MOSI,uint8_t MISO,uint8_t SCLK, class PINTYPE=ArduinoPins>
171 class AvrSPI {
172 
173 public:
174  uint8_t send (uint8_t data) {
175  SPDR = data; // send byte
176  while (!(SPSR & _BV(SPIF))); // wait until transfer finished
177  return SPDR;
178  }
179 
180  void waitMiso () {
181  while(PINTYPE::getState(MISO));
182  }
183 
184  void init () {
185  PINTYPE::setOutput(CS);
186  PINTYPE::setOutput(MOSI);
187  PINTYPE::setInput(MISO);
188  PINTYPE::setOutput(SCLK);
189  // SPI enable, master, speed = CLK/4
190  SPCR = _BV(SPE) | _BV(MSTR);
191  PINTYPE::setHigh(CS);
192  // Set SCLK = 1 and SI = 0, to avoid potential problems with pin control mode
193  PINTYPE::setHigh(SCLK);
194  PINTYPE::setLow(MOSI);
195  }
196 
197  void select () {
198  PINTYPE::setLow(CS);
199  }
200 
201  void deselect () {
202  PINTYPE::setHigh(CS);
203  }
204 
205  void ping () {
206  select(); // wake up the communication module
207  waitMiso();
208  deselect();
209  }
210 
211  uint8_t strobe(uint8_t cmd) {
212  select(); // select CC1101
213  waitMiso(); // wait until MISO goes low
214  uint8_t ret = send(cmd); // send strobe command
215  deselect(); // deselect CC1101
216  return ret;
217  }
218 
219  void readBurst(uint8_t * buf, uint8_t regAddr, uint8_t len) {
220  select(); // select CC1101
221  waitMiso(); // wait until MISO goes low
222  send(regAddr | READ_BURST); // send register address
223  for(uint8_t i=0 ; i<len ; i++) {
224  buf[i] = send(0x00); // read result byte by byte
225  //dbg << i << ":" << buf[i] << '\n';
226  }
227  deselect(); // deselect CC1101
228  }
229 
230  void writeBurst(uint8_t regAddr, uint8_t* buf, uint8_t len) {
231  select(); // select CC1101
232  waitMiso(); // wait until MISO goes low
233  send(regAddr | WRITE_BURST); // send register address
234  for(uint8_t i=0 ; i<len ; i++)
235  send(buf[i]); // send value
236  deselect(); // deselect CC1101
237  }
238 
239  uint8_t readReg(uint8_t regAddr, uint8_t regType) {
240  select(); // select CC1101
241  waitMiso(); // wait until MISO goes low
242  send(regAddr | regType); // send register address
243  uint8_t val = send(0x00); // read result
244  deselect(); // deselect CC1101
245  return val;
246  }
247 
248  void writeReg(uint8_t regAddr, uint8_t val) {
249  select(); // select CC1101
250  waitMiso(); // wait until MISO goes low
251  send(regAddr); // send register address
252  send(val); // send value
253  deselect(); // deselect CC1101
254  }
255 
256 };
257 
258 #endif
259 
260 
261 #ifdef SPI_MODE0
262 
263 template <uint8_t CS,uint32_t CLOCK=2000000, BitOrder BITORDER=SPI_BITORDER_MSBFIRST, uint8_t MODE=SPI_MODE0>
264 class LibSPI {
265 
266 public:
267  LibSPI () {}
268  void init () {
269  pinMode(CS,OUTPUT);
270  SPI.begin();
271  }
272 
273  void select () {
274  digitalWrite(CS,LOW);
275  }
276 
277  void deselect () {
278  digitalWrite(CS,HIGH);
279  }
280 
281  void ping () {
282  SPI.beginTransaction(SPISettings(CLOCK,BITORDER,MODE));
283  select(); // wake up the communication module
284  SPI.transfer(0); // ????
285  deselect();
286  SPI.endTransaction();
287  }
288 
289  void waitMiso () {
290 #ifdef ARDUINO_ARCH_STM32F1
291  while(digitalRead(SPI.misoPin()));
292 #elif defined (PIN_SPI_MISO)
293  while(digitalRead(PIN_SPI_MISO));
294 #else
295  _delay_us(10);
296 #endif
297  }
298 
299  uint8_t send (uint8_t data) {
300  SPI.beginTransaction(SPISettings(CLOCK,BITORDER,MODE));
301  uint8_t ret = SPI.transfer(data);
302  SPI.endTransaction();
303  return ret;
304  }
305 
306  uint8_t strobe(uint8_t cmd) {
307  SPI.beginTransaction(SPISettings(CLOCK,BITORDER,MODE));
308  select(); // select CC1101
309  uint8_t ret = SPI.transfer(cmd);
310  deselect(); // deselect CC1101
311  SPI.endTransaction();
312  return ret;
313  }
314 
315  void readBurst(uint8_t * buf, uint8_t regAddr, uint8_t len) {
316  SPI.beginTransaction(SPISettings(CLOCK,BITORDER,MODE));
317  select(); // select CC1101
318  SPI.transfer(regAddr | READ_BURST); // send register address
319  for(uint8_t i=0 ; i<len ; i++) {
320  buf[i] = SPI.transfer(0x00); // read result byte by byte
321  //dbg << i << ":" << buf[i] << '\n';
322  }
323  deselect(); // deselect CC1101
324  SPI.endTransaction();
325  }
326 
327  void writeBurst(uint8_t regAddr, uint8_t* buf, uint8_t len) {
328  SPI.beginTransaction(SPISettings(CLOCK,BITORDER,MODE));
329  select(); // select CC1101
330  SPI.transfer(regAddr | WRITE_BURST); // send register address
331  for(uint8_t i=0 ; i<len ; i++)
332  SPI.transfer(buf[i]); // send value
333  deselect(); // deselect CC1101
334  SPI.endTransaction();
335  }
336 
337  uint8_t readReg(uint8_t regAddr, uint8_t regType) {
338  SPI.beginTransaction(SPISettings(CLOCK,BITORDER,MODE));
339  select(); // select CC1101
340  SPI.transfer(regAddr | regType); // send register address
341  uint8_t val = SPI.transfer(0x00); // read result
342  deselect(); // deselect CC1101
343  SPI.endTransaction();
344  return val;
345  }
346 
347  void writeReg(uint8_t regAddr, uint8_t val) {
348  SPI.beginTransaction(SPISettings(CLOCK,BITORDER,MODE));
349  select(); // select CC1101
350  SPI.transfer(regAddr); // send register address
351  SPI.transfer(val); // send value
352  deselect(); // deselect CC1101
353  SPI.endTransaction();
354  }
355 
356 };
357 #endif
358 
359 
360 extern void* __gb_radio;
361 
362 class NoRadio {
363 public:
364  NoRadio () {}
365 
366  bool detectBurst () { return false; }
367  void disable () {};
368  void enable () {}
369  void flushrx() {}
370  uint8_t getGDO0 () { return 0; }
371  bool init () { return true; }
372  bool isIdle () { return true; }
373  uint8_t read (__attribute__ ((unused)) Message& msg) { return 0; }
374  uint8_t reset () { return 0; }
375  uint8_t rssi () { return 0; }
376  void setIdle () {}
377  void setSendTimeout (__attribute__ ((unused)) uint16_t timeout=0) {}
378  void waitTimeout (__attribute__ ((unused)) uint16_t timeout) {}
379  void wakeup () {}
380  void initReg(__attribute__ ((unused)) uint8_t val0, __attribute__ ((unused)) uint8_t val1) {}
381  bool write (__attribute__ ((unused)) const Message& msg, __attribute__ ((unused)) uint8_t burst) { return false; }
382 };
383 
384 template <class SPIType>
385 class CC1101 {
386 protected:
387  SPIType spi;
388  uint8_t rss; // signal strength
389 #ifdef USE_OTA_BOOTLOADER_FREQUENCY
390  uint8_t f1,f0; // storage for frequency values from boot loader
391 #endif
392 
393 public:
394  CC1101 () : rss(0)
395 #ifdef USE_OTA_BOOTLOADER_FREQUENCY
396  , f1(0x65), f0(0x6A) // set to defaults
397 #endif
398  {}
399 
400  void setIdle () {
401  //DPRINTLN("CC enter powerdown");
402  uint8_t cnt = 0xff;
403  while(cnt-- && (spi.strobe(CC1101_SIDLE) & 0x70) != 0) {
404  _delay_us(10);
405  }
406  spi.strobe(CC1101_SFRX);
407 
408 #ifdef USE_WOR
409  // init
410  spi.writeReg(CC1101_PKTCTRL1, 0x4C); // preamble quality estimator threshold=2
411  spi.writeReg(CC1101_MCSM2, 0x1c); // RX_TIME_RSSI=1, RX_TIME_QUAL=1, RX_TIME=4
412  //start
413  spi.strobe(CC1101_SWORRST);
414  spi.strobe(CC1101_SWOR);
415 #else
416  spi.strobe(CC1101_SPWD); // enter power down state
417 #endif
418  }
419 
420  void wakeup (bool flush) {
421  spi.ping();
422  if( flush==true ) {
423  flushrx();
424  }
425 #ifdef USE_WOR
426  // ToDo: is this the right position?
427  spi.writeReg(CC1101_PKTCTRL1, 0x0C); // preamble quality estimator threshold=0
428  spi.writeReg(CC1101_MCSM2, 0x07); // RX_TIME_RSSI=0, RX_TIME_QUAL=0, RX_TIME=7
429 #endif
430  spi.strobe(CC1101_SRX);
431  }
432 
433  uint8_t reset() {
434 
435  // Strobe CSn low / high
436  spi.select();
437 
438  // Automatic POR
439  // If the chip has had sufficient time for the crystal oscillator to stabilize after the power-on-reset the SO pin
440  // will go low immediately after taking CSn low. If CSn is taken low before reset is completed the
441  // SO pin will first go high, indicating that the crystal oscillator is not stabilized, before going low
442  spi.waitMiso();
443  spi.deselect();
444 
445  // Hold CSn high for at least 40μs relative to pulling CSn low
446  _delay_us(50);
447 
448  // Pull CSn low and wait for SO to go low (CHIP_RDYn).
449  spi.select();
450  spi.waitMiso();
451 
452  // Issue the SRES strobe on the SI line
453  uint8_t ret = spi.send(CC1101_SRES);
454 
455  // When SO goes low again, reset is complete and the chip is in the IDLE state.
456  spi.waitMiso();
457  spi.deselect();
458 
459  return ret;
460  }
461 
462 
463  bool init () {
464  spi.init(); // init the hardware to get access to the RF modul
465 
466 #ifdef USE_OTA_BOOTLOADER_FREQUENCY
467  // before we reset the CC1101 - store frequency settings from bootloader
468  f1 = spi.readReg(CC1101_FREQ1, CC1101_CONFIG);
469  f0 = spi.readReg(CC1101_FREQ0, CC1101_CONFIG);
470  DPRINT(F("Boot Loader Freq: 0x21"));DHEX(f1);DHEXLN(f0);
471 #endif
472  reset();
473 
474 #ifdef SIMPLE_CC1101_INIT
475  static const uint8_t initVal[] PROGMEM = {
476  /* register value reset explanation of delta to reset value */
477  /* CC1101_IOCFG2 */ 0x2E, // 0x29 high impedance tri state (pin not used)
478  /* CC1101_IOCFG1 */ 0x2E, // 0x2E high impedance tri state (pin not used)
479  /* CC1101_IOCFG0,*/ 0x06, // 0x3F Asserts when sync word has been sent / received, and de-asserts at the end of the packet. In RX, the pin will also deassert when a packet is discarded due to address or maximum length filtering or when the radio enters RXFIFO_OVERFLOW state. In TX the pin will de-assert if the TX FIFO underflows.
480  /* CC1101_FIFOTHR,*/ 0x0D, // 0x07 TX FIFO = 9, RX FIFO = 56 byte
481  /* CC1101_SYNC1, */ 0xE9, // 0xD3 Sync word MSB
482  /* CC1101_SYNC0, */ 0xCA, // 0x91 Sync word LSB
483  /* CC1101_PKTLEN,*/ 0xFF, // 0xFF
484  /* CC1101_PKTCTRL1,*/0x0C, // 0x04 CRC auto flush = 1, append status = 1,
485  /* CC1101_PKTCTRL0,*/0x45, // 0x45
486  /* CC1101_ADDR, */ 0x00, // 0x00
487  /* CC1101_CHANNR,*/ 0x00, // 0x00
488  /* CC1101_FSCTRL1,*/ 0x06, // 0x0F frequency synthesizer control
489  /* CC1101_FSCTRL0,*/ 0x00, // 0x00
490  /* CC1101_FREQ2, */ 0x21, // 0x1E
491  /* CC1101_FREQ1, */ 0x65, // 0xC4
492  /* CC1101_FREQ0, */ 0x6A, // 0xEC
493  /* CC1101_MDMCFG4,*/ 0xC8, // 0x8C channel bandwidth
494  /* CC1101_MDMCFG3,*/ 0x93, // 0x22 symbol data rate
495  /* CC1101_MDMCFG2,*/ 0x03, // 0x02 30 of 32 bits of sync word need to match
496  /* CC1101_MDMCFG1,*/ 0x22, // 0x22
497  /* CC1101_MDMCFG0,*/ 0xF8, // 0xF8
498  /* CC1101_DEVIATN,*/ 0x34, // 0x47 deviation = 19.042969 kHz
499  /* CC1101_MCSM2, */ 0x07, // 0x07
500 #ifdef USE_CCA
501  /* CC1101_MCSM1,*/ 0x33, // 0x30 CCA, RX after TX
502 #else
503  /* CC1101_MCSM1,*/ 0x03, // 0x30 always clear channel indication, RX after TX
504 #endif
505  /* CC1101_MCSM0,*/ 0x18, // 0x04 auto cal when going from IDLE to RX/TX, XOSC stable count = 64
506  /* CC1101_FOCCFG,*/ 0x16, // 0x36 don't freeze freq offset compensation
507  /* CC1101_BSCFG,*/ 0x6C, // 0x6C
508  /* CC1101_AGCCTRL2,*/0x43, // 0x03 forbid highest gain setting for DVGA
509  /* CC1101_AGCCTRL1,*/0x40, // 0x40
510  /* CC1101_AGCCTRL0,*/0x91, // 0x91
511  /* CC1101_WOREVT1,*/ 0x2f, // 0x87 see next line
512  /* CC1101_WOREVT0,*/ 0x65, // 0x6B t_Event0 = 350ms
513  /* CC1101_WORCTRL,*/ 0x78, // 0xF8 RC_PD=0
514  /* CC1101_FREND1,*/ 0x56, // 0x56
515  /* CC1101_FREND0,*/ 0x10, // 0x10
516  /* CC1101_FSCAL3,*/ 0xE9, // 0xA9 charge pump calib stage
517  /* CC1101_FSCAL2,*/ 0x2A, // 0x0A high VCO
518  /* CC1101_FSCAL1,*/ 0x1F, // 0x20 freq synthesizer calib result
519  /* CC1101_FSCAL0,*/ 0x11, // 0x0D freq synthesizer calib control
520  //CC1101_RCCTRL1, 0x41, // 0x41
521  //CC1101_RCCTRL0, 0x00, // 0x00
522  //CC1101_FSTEST, 0x59, // 0x59
523  //CC1101_PTEST, 0x7f, // 0x7f
524  //CC1101_AGCTEST, 0x3f, // 0x3f
525  //CC1101_TEST2, 0x88, // 0x88
526  //CC1101_TEST1, 0x31, // 0x31
527  //CC1101_TEST0, 0x0b, // 0x0b
528  // CC1101_PATABLE, 0x03, // NA
529  };
530  bool initOK = true;
531  for (uint8_t i=0; i<sizeof(initVal); ++i) { // write init value to TRX868
532  bool initres = initReg(i, pgm_read_byte(&initVal[i]));
533  //if any initReg fails, initOK has to be false
534  if (initres == false) initOK = false;
535  }
536 #else
537  // define init settings for CC1101
538  static const uint8_t initVal[] PROGMEM = {
539  /*register value reset explanation of delta to reset value */
540  CC1101_IOCFG2, 0x2E, // 0x29 high impedance tri state (pin not used)
541  //CC1101_IOCFG2, 0x24, // 0x29 Debug: WOR_EVT0
542 
543  //CC1101_IOCFG1, 0x2E, // 0x2E high impedance tri state (pin not used)
544  //CC1101_IOCFG1, 0x25, // 0x2E Debug: WOR_EVT1
545  //CC1101_IOCFG1, 0x0E, // 0x2E Debug: Carrier sense
546  //CC1101_IOCFG1, 0x0F, // 0x2E Debug: CRC_OK
547 
548  CC1101_IOCFG0, 0x06, // 0x3F Asserts when sync word has been sent / received, and de-asserts at the end of the packet. In RX, the pin will also deassert when a packet is discarded due to address or maximum length filtering or when the radio enters RXFIFO_OVERFLOW state. In TX the pin will de-assert if the TX FIFO underflows.
549  CC1101_FIFOTHR, 0x0D, // 0x07 TX FIFO = 9, RX FIFO = 56 byte
550  CC1101_SYNC1, 0xE9, // 0xD3 Sync word MSB
551  CC1101_SYNC0, 0xCA, // 0x91 Sync word LSB
552  //CC1101_PKTLEN, 0xFF, // 0xFF
553  CC1101_PKTCTRL1, 0x0C, // 0x04 CRC auto flush = 1, append status = 1,
554  //CC1101_PKTCTRL0, 0x45, // 0x45
555  //CC1101_ADDR, 0x00, // 0x00
556  //CC1101_CHANNR, 0x00, // 0x00
557  CC1101_FSCTRL1, 0x06, // 0x0F frequency synthesizer control
558  //CC1101_FSCTRL0, 0x00, // 0x00
559 
560 #ifndef USE_OTA_BOOTLOADER_FREQUENCY
561  // 868.299866 MHz - if other values are found in EEPROM, these are overwritten later
562  CC1101_FREQ2, 0x21, // 0x1E
563  CC1101_FREQ1, 0x65, // 0xC4
564  CC1101_FREQ0, 0x6A, // 0xEC
565 #endif
566 
567  CC1101_MDMCFG4, 0xC8, // 0x8C channel bandwidth
568  CC1101_MDMCFG3, 0x93, // 0x22 symbol data rate
569  CC1101_MDMCFG2, 0x03, // 0x02 30 of 32 bits of sync word need to match
570  //CC1101_MDMCFG1, 0x22, // 0x22
571  //CC1101_MDMCFG0, 0xF8, // 0xF8
572  CC1101_DEVIATN, 0x34, // 0x47 deviation = 19.042969 kHz
573  //CC1101_MCSM2, 0x07, // 0x07
574 #ifdef USE_CCA
575  CC1101_MCSM1, 0x33, // 0x30 CCA, RX after TX
576 #else
577  CC1101_MCSM1, 0x03, // 0x30 always clear channel indication, RX after TX
578 #endif
579  CC1101_MCSM0, 0x18, // 0x04 auto cal when going from IDLE to RX/TX, XOSC stable count = 64
580  CC1101_FOCCFG, 0x16, // 0x36 don't freeze freq offset compensation
581  //CC1101_BSCFG, 0x6C, // 0x6C
582  CC1101_AGCCTRL2, 0x43, // 0x03 forbid highest gain setting for DVGA
583  //CC1101_AGCCTRL1, 0x40, // 0x40
584  //CC1101_AGCCTRL0, 0x91, // 0x91
585  CC1101_WOREVT1, 0x2f, // 0x87 see next line
586  CC1101_WOREVT0, 0x65, // 0x6B t_Event0 = 350ms
587  CC1101_WORCTRL, 0x78, // 0xF8 RC_PD=0
588  //CC1101_FREND1, 0x56, // 0x56
589  //CC1101_FREND0, 0x10, // 0x10
590  CC1101_FSCAL3, 0xE9, // 0xA9 charge pump calib stage
591  CC1101_FSCAL2, 0x2A, // 0x0A high VCO
592  CC1101_FSCAL1, 0x1F, // 0x20 freq synthesizer calib result
593  CC1101_FSCAL0, 0x11, // 0x0D freq synthesizer calib control
594  //CC1101_RCCTRL1, 0x41, // 0x41
595  //CC1101_RCCTRL0, 0x00, // 0x00
596  //CC1101_FSTEST, 0x59, // 0x59
597  //CC1101_PTEST, 0x7f, // 0x7f
598  //CC1101_AGCTEST, 0x3f, // 0x3f
599  //CC1101_TEST2, 0x88, // 0x88
600  //CC1101_TEST1, 0x31, // 0x31
601  //CC1101_TEST0, 0x0b, // 0x0b
602  CC1101_PATABLE, 0x03, // NA
603  };
604 
605  bool initOK = true;
606  for (uint8_t i=0; i<sizeof(initVal); i+=2) { // write init value to TRX868
607  bool initres = initReg(pgm_read_byte(&initVal[i]), pgm_read_byte(&initVal[i+1]));
608  //if any initReg fails, initOK has to be false
609  if (initres == false) initOK = false;
610  }
611 #endif
612 
613 
614 #ifdef USE_OTA_BOOTLOADER_FREQUENCY
615  // set frequency from bootloader again
616  initReg(CC1101_FREQ2, 0x21);
617  initReg(CC1101_FREQ1, f1);
618  initReg(CC1101_FREQ0, f0);
619 #endif
620 
621  // Settings that ELV sets
622  DPRINT(F("CC Version: ")); DHEXLN(spi.readReg(CC1101_VERSION, CC1101_STATUS));
623 
624  spi.strobe(CC1101_SCAL); // calibrate frequency synthesizer and turn it off
625 
626  _delay_ms(23);
627 
628  initReg(CC1101_PATABLE, PA_MaxPower); // configure PATABLE
629 
630  DPRINTLN(F(" - ready"));
631  return initOK;
632  }
633 
634 #ifdef SIMPLE_CC1101_INIT
635  bool initReg (uint8_t regAddr, uint8_t val) {
636  spi.writeReg(regAddr, val);
637  return true;
638  }
639 #else
640  bool initReg (uint8_t regAddr, uint8_t val, uint8_t retries=3) {
641  spi.writeReg(regAddr, val);
642  uint8_t val_read = spi.readReg(regAddr, CC1101_CONFIG);
643  bool initResult = true;
644  if( val_read != val ) {
645  if( retries > 0 ) {
646  initResult = initReg(regAddr, val, --retries);
647  _delay_ms(1);
648  }
649  else {
650  DPRINT(F("Error at ")); DHEX(regAddr);
651  DPRINT(F(" expected: ")); DHEX(val); DPRINT(F(" read: ")); DHEXLN(val_read);
652  return false;
653  }
654  }
655  return initResult;
656  }
657 #endif
658 
659  uint8_t rssi () const {
660  return rss;
661  }
662 
663  void flushrx () {
664  spi.strobe(CC1101_SIDLE);
665  spi.strobe(CC1101_SNOP);
666  spi.strobe(CC1101_SFRX);
667  }
668 
669  bool detectBurst () {
670  uint8_t state = spi.readReg(CC1101_PKTSTATUS, CC1101_STATUS);
671  // DHEXLN(state);
672  return (state & 0x01<<6) == (0x01<<6);
673  }
674 
675  void pollRSSI() {
676  calculateRSSI(spi.readReg(CC1101_RSSI, CC1101_STATUS)); // read RSSI from STATUS register
677  }
678 
679 protected:
680 
681  void calculateRSSI(uint8_t rsshex) {
682  rss = -1 * ((((int16_t)rsshex-((int16_t)rsshex >= 128 ? 256 : 0))/2)-74);
683  }
684 
685  uint8_t sndData(uint8_t *buf, uint8_t size, uint8_t burst) {
686  // Going from RX to TX does not work if there was a reception less than 0.5
687  // sec ago. Due to CCA? Using IDLE helps to shorten this period(?)
688  spi.strobe(CC1101_SIDLE); // go to idle mode
689  spi.strobe(CC1101_SFTX ); // flush TX buffer
690 
691  uint8_t i=200;
692  do {
693  spi.strobe(CC1101_STX);
694  _delay_us(100);
695  if( --i == 0 ) {
696  // can not enter TX state - reset fifo
697  spi.strobe(CC1101_SIDLE );
698  spi.strobe(CC1101_SFTX );
699  spi.strobe(CC1101_SNOP );
700  // back to RX mode
701  do { spi.strobe(CC1101_SRX);
702  } while (spi.readReg(CC1101_MARCSTATE, CC1101_STATUS) != MARCSTATE_RX);
703  return false;
704  }
705  }
706  while(spi.readReg(CC1101_MARCSTATE, CC1101_STATUS) != MARCSTATE_TX);
707 
708  _delay_ms(10);
709  if (burst) { // BURST-bit set?
710  _delay_ms(350); // according to ELV, devices get activated every 300ms, so send burst for 360ms
711  }
712 
713  spi.writeReg(CC1101_TXFIFO, size);
714  spi.writeBurst(CC1101_TXFIFO, buf, size); // write in TX FIFO
715 
716  for(uint8_t i = 0; i < 200; i++) { // after sending out all bytes the chip should go automatically in RX mode
717  if( spi.readReg(CC1101_MARCSTATE, CC1101_STATUS) == MARCSTATE_RX)
718  break; //now in RX mode, good
719  _delay_us(100);
720  }
721  return true;
722  }
723 
724  uint8_t rcvData(uint8_t *buf, uint8_t size) {
725  //DPRINTLN(" rcvData");
726 
727  uint8_t packetBytes = 0;
728  uint8_t rxBytes = 0;
729  uint8_t fifoBytes = spi.readReg(CC1101_RXBYTES, CC1101_STATUS); // how many bytes are in the buffer
730  //DPRINT(" RX FIFO: ");DHEXLN(fifoBytes);
731  // overflow detected - flush the FIFO
732  if( fifoBytes > 0 && (fifoBytes & 0x80) != 0x80 ) {
733  packetBytes = spi.readReg(CC1101_RXFIFO, CC1101_CONFIG); // read packet length
734  //DPRINT(" Start Packet: ");DHEXLN(packetBytes);
735  // check that packet fits into the buffer
736  if (packetBytes <= size) {
737  spi.readBurst(buf, CC1101_RXFIFO, packetBytes); // read data packet
738  calculateRSSI(spi.readReg(CC1101_RXFIFO, CC1101_CONFIG)); // read RSSI from RXFIFO
739  uint8_t val = spi.readReg(CC1101_RXFIFO, CC1101_CONFIG); // read LQI and CRC_OK
740  // lqi = val & 0x7F;
741  if( (val & 0x80) == 0x80 ) { // check crc_ok
742  // DPRINTLN("CRC OK");
743  rxBytes = packetBytes;
744  }
745  else {
746  DPRINTLN(F("CRC Failed"));
747  }
748  }
749  else {
750  DPRINT(F("Packet too big: "));DDECLN(packetBytes);
751  }
752  }
753  //DPRINT(F("-> "));
754  //DHEXLN(buf,rxBytes);
755  spi.strobe(CC1101_SFRX);
756  _delay_us(190);
757  flushrx();
758  spi.strobe(CC1101_SRX);
759  //DHEXLN(spi.readReg(CC1101_MARCSTATE, CC1101_STATUS));
760 
761  return rxBytes; // return number of byte in buffer
762  }
763 
764 };
765 
766 template <class SPIType ,uint8_t GDO0,int SENDDELAY=100,class HWRADIO=CC1101<SPIType> >
767 class Radio : public HWRADIO {
768 
769  static void isr () {
770  ((Radio<SPIType,GDO0,SENDDELAY,HWRADIO>*)__gb_radio)->handleInt();
771  }
772 
773  class MinSendTimeout : public Alarm {
774  volatile bool wait;
775  public:
776  MinSendTimeout () : Alarm(0), wait(false) { async(true); }
777  virtual ~MinSendTimeout () {}
778  void waitTimeout () {
779  // wait until time out over
780  while( wait==true ) {
781  // if( sysclock.runwait() == false ) {
782  _delay_ms(1);
783  // }
784  }
785  if( SENDDELAY > 0) {
786  set(millis2ticks(SENDDELAY));
787  // signal new wait cycle
788  wait = true;
789  // add to system clock
790  sysclock.add(*this);
791  }
792  }
793 
794  void setTimeout (uint16_t millis=SENDDELAY) {
795  // cancel possible old timeout
796  sysclock.cancel(*this);
797  // set to 100ms
798  set(millis2ticks(millis));
799  // signal new wait cycle
800  wait = true;
801  // add to system clock
802  sysclock.add(*this);
803  }
804 
805  virtual void trigger(__attribute__ ((unused)) AlarmClock& clock) {
806  // signal wait cycle over
807  wait = false;
808  }
809  } timeout;
810 
811 public:
812  // this will delay next send by given millis
813  void setSendTimeout(uint16_t millis=SENDDELAY) {
814  timeout.setTimeout(millis);
815  }
816  // use the radio timer to wait given millis
817  void waitTimeout (uint16_t millis) {
818  timeout.setTimeout(millis);
819  timeout.waitTimeout();
820  }
821 
822 private:
823  volatile uint8_t intread;
824  volatile uint8_t sending;
825  volatile bool idle;
826  Message buffer;
827 
828 public: //---------------------------------------------------------------------------------------------------------
829  Radio () : intread(0), sending(0), idle(false) {}
830 
831  bool init () {
832  // ensure ISR if off before we start to init CC1101
833  // OTA boot loader may leave it on
834  disable();
835  __gb_radio = this;
836  DPRINT(F("CC init"));
837  pinMode(GDO0,INPUT);
838 
839  DPRINTLN(F("1"));
840 
841  bool initOK = HWRADIO::init();
842  if (initOK) HWRADIO::wakeup(true);
843  //DPRINT(F("CC init "));DPRINTLN(initOK ? F("OK"):F("FAIL"));
844  return initOK;
845  }
846 
847  void setIdle () {
848  if( idle == false ) {
849  HWRADIO::setIdle();
850  idle = true;
851  }
852  }
853 
854  void wakeup (bool flush=true) {
855  if( idle == true ) {
856  HWRADIO::wakeup(flush);
857  idle = false;
858  }
859  }
860 
861  bool isIdle () {
862  return idle;
863  }
864 
865  void handleInt () {
866  if( sending == 0 ) {
867 // DPRINT(" * "); DPRINTLN(millis());
868  intread = 1;
869  }
870  }
871 
872  bool detectBurst () {
873  if( isIdle() == true ) {
874  wakeup();
875  // let radio some time to get carrier signal
876  _delay_ms(3);
877  }
878  return HWRADIO::detectBurst();
879  }
880 
881  uint8_t getGDO0 () {
882  return digitalRead(GDO0);
883  }
884 
885 void enable () {
886 #ifdef EnableInterrupt_h
887  if( digitalPinToInterrupt(GDO0) == NOT_AN_INTERRUPT )
888  enableInterrupt(GDO0,isr,FALLING);
889  else
890 #endif
891  attachInterrupt(digitalPinToInterrupt(GDO0),isr,FALLING);
892 }
893 void disable () {
894 #ifdef EnableInterrupt_h
895  if( digitalPinToInterrupt(GDO0) == NOT_AN_INTERRUPT )
896  disableInterrupt(GDO0);
897  else
898 #endif
899  detachInterrupt(digitalPinToInterrupt(GDO0));
900 }
901 
902  // read the message form the internal buffer, if any
903  uint8_t read (Message& msg) {
904  if( intread == 0 )
905  return 0;
906 
907  intread = 0;
908  uint8_t len = this->rcvData(buffer.buffer(),buffer.buffersize());
909  if( len > 0 ) {
910  buffer.length(len);
911  // decode the message
912  buffer.decode();
913  // copy buffer to message
914  memcpy(msg.buffer(),buffer.buffer(),len);
915  }
916 
917  msg.length(len);
918  // reset buffer
919  buffer.clear();
920  wakeup(false);
921  return msg.length();
922  }
923 
924  // try to read a message - not longer than timeout millis
925  uint8_t read (Message& msg, uint32_t timeout) {
926  uint8_t num = 0;
927  uint32_t time=0;
928  do {
929  num = read(msg);
930  if( num == 0 ) {
931  _delay_ms(50); // wait 50ms
932  time += 50;
933  }
934  }
935  while( num == 0 && time < timeout );
936  return num;
937  }
938 
939  // simple send the message
940  bool write (const Message& msg, uint8_t burst) {
941  memcpy(buffer.buffer(),msg.buffer(),msg.length());
942  buffer.length(msg.length());
943  buffer.encode();
944  return sndData(buffer.buffer(),buffer.length(),burst);
945  }
946 /*
947  bool readAck (const Message& msg) {
948  if( intread == 0 )
949  return false;
950 
951  intread = 0;
952  idle = false;
953  bool ack=false;
954  uint8_t len = this->rcvData(buffer.buffer(),buffer.buffersize());
955  if( len > 0 ) {
956  buffer.length(len);
957  // decode the message
958  buffer.decode();
959  ack = buffer.isAck() &&
960  (buffer.from() == msg.to()) &&
961  (buffer.to() == msg.from()) &&
962  (buffer.count() == msg.count());
963  // reset buffer
964  buffer.clear();
965  }
966  return ack;
967  }
968 */
969  uint8_t sndData(uint8_t *buf, uint8_t size, uint8_t burst) {
970  timeout.waitTimeout();
971  this->wakeup();
972  sending = 1;
973  uint8_t result = HWRADIO::sndData(buf,size,burst);
974  sending = 0;
975  return result;
976  }
977 
978 };
979 
980 }
981 
982 #endif
as::Alarm
Definition: Alarm.h:15
as::CC1101
Definition: Radio.h:385
as::Message
Definition: Message.h:51
as::AlarmClock
Definition: AlarmClock.h:32
as::Radio
Definition: Radio.h:767
as::AvrSPI
Definition: Radio.h:171
as::NoRadio
Definition: Radio.h:362
as::LibSPI
Definition: Radio.h:264