knx
ETS configurable knx-stack
rf_physical_layer_cc1101.cpp
Go to the documentation of this file.
1 #ifndef DeviceFamily_CC13X0
2 
3 #include "config.h"
4 #ifdef USE_RF
5 
7 #include "rf_data_link_layer.h"
8 
9 #include "bits.h"
10 #include "platform.h"
11 
12 #include <stdio.h>
13 #include <string.h>
14 
15 // Table for encoding 4-bit data into a 8-bit Manchester encoding.
16 const uint8_t RfPhysicalLayerCC1101::manchEncodeTab[16] = {0xAA, // 0x0 Manchester encoded
17  0xA9, // 0x1 Manchester encoded
18  0xA6, // 0x2 Manchester encoded
19  0xA5, // 0x3 Manchester encoded
20  0x9A, // 0x4 Manchester encoded
21  0x99, // 0x5 Manchester encoded
22  0x96, // 0x6 Manchester encoded
23  0x95, // 0x7 Manchester encoded
24  0x6A, // 0x8 Manchester encoded
25  0x69, // 0x9 Manchester encoded
26  0x66, // 0xA Manchester encoded
27  0x65, // 0xB Manchester encoded
28  0x5A, // 0xC Manchester encoded
29  0x59, // 0xD Manchester encoded
30  0x56, // 0xE Manchester encoded
31  0x55
32  }; // 0xF Manchester encoded
33 
34 // Table for decoding 4-bit Manchester encoded data into 2-bit
35 // data. 0xFF indicates invalid Manchester encoding
36 const uint8_t RfPhysicalLayerCC1101::manchDecodeTab[16] = {0xFF, // Manchester encoded 0x0 decoded
37  0xFF, // Manchester encoded 0x1 decoded
38  0xFF, // Manchester encoded 0x2 decoded
39  0xFF, // Manchester encoded 0x3 decoded
40  0xFF, // Manchester encoded 0x4 decoded
41  0x03, // Manchester encoded 0x5 decoded
42  0x02, // Manchester encoded 0x6 decoded
43  0xFF, // Manchester encoded 0x7 decoded
44  0xFF, // Manchester encoded 0x8 decoded
45  0x01, // Manchester encoded 0x9 decoded
46  0x00, // Manchester encoded 0xA decoded
47  0xFF, // Manchester encoded 0xB decoded
48  0xFF, // Manchester encoded 0xC decoded
49  0xFF, // Manchester encoded 0xD decoded
50  0xFF, // Manchester encoded 0xE decoded
51  0xFF
52  };// Manchester encoded 0xF decoded
53 
54 // Product = CC1101
55 // Chip version = A (VERSION = 0x04)
56 // Crystal accuracy = 10 ppm
57 // X-tal frequency = 26 MHz
58 // RF output power = + 10 dBm
59 // RX filterbandwidth = 270 kHz
60 // Deviation = 47 kHz
61 // Datarate = 32.73 kBaud
62 // Modulation = (0) 2-FSK
63 // Manchester enable = (0) Manchester disabled
64 // RF Frequency = 868.299866 MHz
65 // Channel spacing = 199.951172 kHz
66 // Channel number = 0
67 // Optimization = -
68 // Sync mode = (5) 15/16 + carrier-sense above threshold
69 // Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX
70 // CRC operation = (0) CRC disabled for TX and RX
71 // Forward Error Correction = (0) FEC disabled
72 // Length configuration = (0) Fixed length packets, length configured in PKTLEN register.
73 // Packetlength = 255
74 // Preamble count = (2) 4 bytes
75 // Append status = 0
76 // Address check = (0) No address check
77 // FIFO autoflush = 0
78 // Device address = 0
79 // GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet
80 // GDO2 signal selection = ( 0) Asserts when RX FiFO threshold
81 const uint8_t RfPhysicalLayerCC1101::cc1101_2FSK_32_7_kb[CFG_REGISTER] =
82 {
83  0x00, // IOCFG2 GDO2 Output Pin Configuration
84  0x2E, // IOCFG1 GDO1 Output Pin Configuration
85  0x06, // IOCFG0 GDO0 Output Pin Configuration
86  0x40, // FIFOTHR RX FIFO and TX FIFO Thresholds // 4 bytes in RX FIFO (2 bytes manchester encoded)
87  0x76, // SYNC1 Sync Word
88  0x96, // SYNC0 Sync Word
89  0xFF, // PKTLEN Packet Length
90  0x00, // PKTCTRL1 Packet Automation Control
91  0x00, // PKTCTRL0 Packet Automation Control
92  0x00, // ADDR Device Address
93  0x00, // CHANNR Channel Number
94  0x08, // FSCTRL1 Frequency Synthesizer Control
95  0x00, // FSCTRL0 Frequency Synthesizer Control
96  0x21, // FREQ2 Frequency Control Word
97  0x65, // FREQ1 Frequency Control Word
98  0x6A, // FREQ0 Frequency Control Word
99  0x6A, // MDMCFG4 Modem Configuration
100  0x4A, // MDMCFG3 Modem Configuration
101  0x05, // MDMCFG2 Modem Configuration
102  0x22, // MDMCFG1 Modem Configuration
103  0xF8, // MDMCFG0 Modem Configuration
104  0x47, // DEVIATN Modem Deviation Setting
105  0x07, // MCSM2 Main Radio Control State Machine Configuration
106  0x30, // MCSM1 Main Radio Control State Machine Configuration (IDLE after TX and RX)
107  0x18, // MCSM0 Main Radio Control State Machine Configuration
108  0x2E, // FOCCFG Frequency Offset Compensation Configuration
109  0x6D, // BSCFG Bit Synchronization Configuration
110  0x43, // AGCCTRL2 AGC Control 0x04, // AGCCTRL2 magn target 33dB vs 36dB (max LNA+LNA2 gain vs. ) (highest gain cannot be used vs. all gain settings)
111  0x40, // AGCCTRL1 AGC Control 0x09, // AGCCTRL1 carrier sense threshold disabled vs. 7dB below magn target (LNA prio strat. 1 vs 0)
112  0x91, // AGCCTRL0 AGC Control 0xB2, // AGCCTRL0 channel filter samples 16 vs.32
113  0x87, // WOREVT1 High Byte Event0 Timeout
114  0x6B, // WOREVT0 Low Byte Event0 Timeout
115  0xFB, // WORCTRL Wake On Radio Control
116  0xB6, // FREND1 Front End RX Configuration
117  0x10, // FREND0 Front End TX Configuration
118  0xE9, // FSCAL3 Frequency Synthesizer Calibration 0xEA, // FSCAL3
119  0x2A, // FSCAL2 Frequency Synthesizer Calibration
120  0x00, // FSCAL1 Frequency Synthesizer Calibration
121  0x1F, // FSCAL0 Frequency Synthesizer Calibration
122  0x41, // RCCTRL1 RC Oscillator Configuration
123  0x00, // RCCTRL0 RC Oscillator Configuration
124  0x59, // FSTEST Frequency Synthesizer Calibration Control
125  0x7F, // PTEST Production Test
126  0x3F, // AGCTEST AGC Test
127  0x81, // TEST2 Various Test Settings
128  0x35, // TEST1 Various Test Settings
129  0x09 // TEST0 Various Test Settings
130 };
131 
132 //Patable index: -30 -20- -15 -10 0 5 7 10 dBm
133 const uint8_t RfPhysicalLayerCC1101::paTablePower868[8] = {0x03, 0x17, 0x1D, 0x26, 0x50, 0x86, 0xCD, 0xC0};
134 
136  : RfPhysicalLayer(rfDataLinkLayer, platform)
137 {
138 }
139 
140 void RfPhysicalLayerCC1101::manchEncode(uint8_t* uncodedData, uint8_t* encodedData)
141 {
142  uint8_t data0, data1;
143 
144  // - Shift to get 4-bit data values
145  data1 = (((*uncodedData) >> 4) & 0x0F);
146  data0 = ((*uncodedData) & 0x0F);
147 
148  // - Perform Manchester encoding -
149  *encodedData = (manchEncodeTab[data1]);
150  *(encodedData + 1) = manchEncodeTab[data0];
151 }
152 
153 bool RfPhysicalLayerCC1101::manchDecode(uint8_t* encodedData, uint8_t* decodedData)
154 {
155  uint8_t data0, data1, data2, data3;
156 
157  // - Shift to get 4 bit data and decode
158  data3 = ((*encodedData >> 4) & 0x0F);
159  data2 = ( *encodedData & 0x0F);
160  data1 = ((*(encodedData + 1) >> 4) & 0x0F);
161  data0 = ((*(encodedData + 1)) & 0x0F);
162 
163  // Check for invalid Manchester encoding
164  if ( (manchDecodeTab[data3] == 0xFF ) | (manchDecodeTab[data2] == 0xFF ) |
165  (manchDecodeTab[data1] == 0xFF ) | (manchDecodeTab[data0] == 0xFF ) )
166  {
167  return false;
168  }
169 
170  // Shift result into a byte
171  *decodedData = (manchDecodeTab[data3] << 6) | (manchDecodeTab[data2] << 4) |
172  (manchDecodeTab[data1] << 2) | manchDecodeTab[data0];
173 
174  return true;
175 }
176 
177 uint8_t RfPhysicalLayerCC1101::sIdle()
178 {
179  uint8_t marcState;
180  uint32_t timeStart;
181 
182  spiWriteStrobe(SIDLE); //sets to idle first. must be in
183 
184  marcState = 0xFF; //set unknown/dummy state value
185  timeStart = millis();
186 
187  while ((marcState != MARCSTATE_IDLE) && ((millis() - timeStart) < CC1101_TIMEOUT)) //0x01 = sidle
188  {
189  marcState = (spiReadRegister(MARCSTATE) & MARCSTATE_BITMASK); //read out state of cc1101 to be sure in RX
190  }
191 
192  //print("marcstate: 0x");
193  //println(marcState, HEX);
194 
195  if (marcState != MARCSTATE_IDLE)
196  {
197  println("Timeout when trying to set idle state.");
198  return false;
199  }
200 
201  return true;
202 }
203 
204 uint8_t RfPhysicalLayerCC1101::sReceive()
205 {
206  uint8_t marcState;
207  uint32_t timeStart;
208 
209  spiWriteStrobe(SRX); //writes receive strobe (receive mode)
210 
211  marcState = 0xFF; //set unknown/dummy state value
212  timeStart = millis();
213 
214  while ((marcState != MARCSTATE_RX) && ((millis() - timeStart) < CC1101_TIMEOUT)) //0x0D = RX
215  {
216  marcState = (spiReadRegister(MARCSTATE) & MARCSTATE_BITMASK); //read out state of cc1101 to be sure in RX
217  }
218 
219  //print("marcstate: 0x");
220  //println(marcState, HEX);
221 
222  if (marcState != MARCSTATE_RX)
223  {
224  println("Timeout when trying to set receive state.");
225  return false;
226  }
227 
228  return true;
229 }
230 
231 void RfPhysicalLayerCC1101::spiWriteRegister(uint8_t spi_instr, uint8_t value)
232 {
233  uint8_t tbuf[2] = {0};
234  tbuf[0] = spi_instr | WRITE_SINGLE_BYTE;
235  tbuf[1] = value;
236  uint8_t len = 2;
237  digitalWrite(SPI_SS_PIN, LOW);
238  _platform.readWriteSpi(tbuf, len);
239  digitalWrite(SPI_SS_PIN, HIGH);
240 }
241 
242 uint8_t RfPhysicalLayerCC1101::spiReadRegister(uint8_t spi_instr)
243 {
244  uint8_t value;
245  uint8_t rbuf[2] = {0};
246  rbuf[0] = spi_instr | READ_SINGLE_BYTE;
247  uint8_t len = 2;
248  digitalWrite(SPI_SS_PIN, LOW);
249  _platform.readWriteSpi(rbuf, len);
250  digitalWrite(SPI_SS_PIN, HIGH);
251  value = rbuf[1];
252  //printf("SPI_arr_0: 0x%02X\n", rbuf[0]);
253  //printf("SPI_arr_1: 0x%02X\n", rbuf[1]);
254  return value;
255 }
256 
257 uint8_t RfPhysicalLayerCC1101::spiWriteStrobe(uint8_t spi_instr)
258 {
259  uint8_t tbuf[1] = {0};
260  tbuf[0] = spi_instr;
261  //printf("SPI_data: 0x%02X\n", tbuf[0]);
262  digitalWrite(SPI_SS_PIN, LOW);
263  _platform.readWriteSpi(tbuf, 1);
264  digitalWrite(SPI_SS_PIN, HIGH);
265  return tbuf[0];
266 }
267 
268 void RfPhysicalLayerCC1101::spiReadBurst(uint8_t spi_instr, uint8_t* pArr, uint8_t len)
269 {
270  uint8_t rbuf[len + 1];
271  rbuf[0] = spi_instr | READ_BURST;
272  digitalWrite(SPI_SS_PIN, LOW);
273  _platform.readWriteSpi(rbuf, len + 1);
274  digitalWrite(SPI_SS_PIN, HIGH);
275 
276  for (uint8_t i = 0; i < len ; i++ )
277  {
278  pArr[i] = rbuf[i + 1];
279  //printf("SPI_arr_read: 0x%02X\n", pArr[i]);
280  }
281 }
282 
283 void RfPhysicalLayerCC1101::spiWriteBurst(uint8_t spi_instr, const uint8_t* pArr, uint8_t len)
284 {
285  uint8_t tbuf[len + 1];
286  tbuf[0] = spi_instr | WRITE_BURST;
287 
288  for (uint8_t i = 0; i < len ; i++ )
289  {
290  tbuf[i + 1] = pArr[i];
291  //printf("SPI_arr_write: 0x%02X\n", tbuf[i+1]);
292  }
293 
294  digitalWrite(SPI_SS_PIN, LOW);
295  _platform.readWriteSpi(tbuf, len + 1);
296  digitalWrite(SPI_SS_PIN, HIGH);
297 }
298 
299 void RfPhysicalLayerCC1101::powerDownCC1101()
300 {
301  // Set IDLE state first
302  sIdle();
303  delayMicroseconds(100);
304  // CC1101 Power Down
305  spiWriteStrobe(SPWD);
306 }
307 
308 void RfPhysicalLayerCC1101::setOutputPowerLevel(int8_t dBm)
309 {
310  uint8_t pa = 0xC0;
311 
312  if (dBm <= -30)
313  pa = 0x00;
314  else if (dBm <= -20)
315  pa = 0x01;
316  else if (dBm <= -15)
317  pa = 0x02;
318  else if (dBm <= -10)
319  pa = 0x03;
320  else if (dBm <= 0)
321  pa = 0x04;
322  else if (dBm <= 5)
323  pa = 0x05;
324  else if (dBm <= 7)
325  pa = 0x06;
326  else if (dBm <= 10)
327  pa = 0x07;
328 
329  spiWriteRegister(FREND0, pa);
330 }
331 
333 {
334  // Setup SPI and GPIOs
336  pinMode(GPIO_GDO2_PIN, INPUT);
337  pinMode(GPIO_GDO0_PIN, INPUT);
338  pinMode(SPI_SS_PIN, OUTPUT);
339 
340  // Toggle chip select signal as described in CC11xx manual
341  digitalWrite(SPI_SS_PIN, HIGH);
342  delayMicroseconds(30);
343  digitalWrite(SPI_SS_PIN, LOW);
344  delayMicroseconds(30);
345  digitalWrite(SPI_SS_PIN, HIGH);
346  delayMicroseconds(45);
347 
348  // Send SRES command
349  digitalWrite(SPI_SS_PIN, LOW);
350  delay(10); // Normally we would have to poll MISO here: while(_platform.readGpio(SPI_MISO_PIN));
351  spiWriteStrobe(SRES);
352  // Wait for chip to finish internal reset
353  delay(10); // Normally we would have to poll MISO here: while(_platform.readGpio(SPI_MISO_PIN));
354  digitalWrite(SPI_SS_PIN, HIGH);
355 
356  // Flush the FIFOs
357  spiWriteStrobe(SFTX);
358  delayMicroseconds(100);
359  spiWriteStrobe(SFRX);
360  delayMicroseconds(100);
361 
362  uint8_t partnum = spiReadRegister(PARTNUM); //reads CC1101 partnumber;
363  uint8_t version = spiReadRegister(VERSION); //reads CC1101 version number;
364 
365  // Checks if valid chip ID is found. Usually 0x03 or 0x14. if not -> abort
366  if (version == 0x00 || version == 0xFF)
367  {
368  println("No CC11xx found!");
369  stopChip();
370  return false;
371  }
372 
373  print("Partnumber: 0x");
374  println(partnum, HEX);
375  print("Version : 0x");
376  println(version, HEX);
377 
378  // Set modulation mode 2FSK, 32768kbit/s
379  spiWriteBurst(WRITE_BURST, cc1101_2FSK_32_7_kb, CFG_REGISTER);
380 
381  // Set PA table
382  spiWriteBurst(PATABLE_BURST, paTablePower868, 8);
383 
384  // Set ISM band to 868.3MHz
385  spiWriteRegister(FREQ2, 0x21);
386  spiWriteRegister(FREQ1, 0x65);
387  spiWriteRegister(FREQ0, 0x6A);
388 
389  // Set channel 0 in ISM band
390  spiWriteRegister(CHANNR, 0);
391 
392  // Set PA to 0dBm as default
393  setOutputPowerLevel(0);
394 
395  return true;
396 }
397 
399 {
400  powerDownCC1101();
401 
403 }
404 
406 {
407  uint8_t config_reg_verify[CFG_REGISTER];
408  uint8_t Patable_verify[CFG_REGISTER];
409 
410  spiReadBurst(READ_BURST, config_reg_verify, CFG_REGISTER); //reads all 47 config register from cc1101
411  spiReadBurst(PATABLE_BURST, Patable_verify, 8); //reads output power settings from cc1101
412 
413  println("Config Register:");
414  printHex("", config_reg_verify, CFG_REGISTER);
415 
416  println("PaTable:");
417  printHex("", Patable_verify, 8);
418 }
419 
421 {
422  switch (_loopState)
423  {
424  case TX_START:
425  {
426  prevStatusGDO0 = 0;
427  prevStatusGDO2 = 0;
428  // Set sync word in TX mode
429  // The same sync word is used in RX mode, but we use it in different way here:
430  // Important: the TX FIFO must provide the last byte of the
431  // sync word
432  spiWriteRegister(SYNC1, 0x54);
433  spiWriteRegister(SYNC0, 0x76);
434  // Set TX FIFO threshold to 33 bytes
435  spiWriteRegister(FIFOTHR, 0x47);
436  // Set GDO2 to be TX FIFO threshold signal
437  spiWriteRegister(IOCFG2, 0x02);
438  // Set GDO0 to be packet transmitted signal
439  spiWriteRegister(IOCFG0, 0x06);
440  // Flush TX FIFO
441  spiWriteStrobe(SFTX);
442 
443  _rfDataLinkLayer.loadNextTxFrame(&sendBuffer, &sendBufferLength);
444 
445  // Calculate total number of bytes in the KNX RF packet from L-field
446  pktLen = PACKET_SIZE(sendBuffer[0]);
447 
448  // Check for valid length
449  if ((pktLen == 0) || (pktLen > 290))
450  {
451  println("TX packet length error!");
452  break;
453  }
454 
455  // Manchester encoded data takes twice the space plus
456  // 1 byte for postamble and 1 byte (LSB) of the synchronization word
457  bytesLeft = (2 * pktLen) + 2;
458  // Last byte of synchronization word
459  buffer[0] = 0x96;
460 
461  // Manchester encode packet
462  for (int i = 0; i < pktLen; i++)
463  {
464  manchEncode(&sendBuffer[i], &buffer[1 + i * 2]);
465  }
466 
467  // Append the postamble sequence
468  buffer[1 + bytesLeft - 1] = 0x55;
469 
470  // Fill TX FIFO
471  pByteIndex = &buffer[0];
472 
473  // Set fixed packet length mode if less than 256 bytes to transmit
474  if (bytesLeft < 256)
475  {
476  spiWriteRegister(PKTLEN, bytesLeft);
477  spiWriteRegister(PKTCTRL0, 0x00); // Set fixed pktlen mode
478  fixedLengthMode = true;
479  }
480  else // Else set infinite length mode
481  {
482  uint8_t fixedLength = bytesLeft % 256;
483  spiWriteRegister(PKTLEN, fixedLength);
484  spiWriteRegister(PKTCTRL0, 0x02);
485  fixedLengthMode = false;
486  }
487 
488  uint8_t bytesToWrite = MIN(64, bytesLeft);
489  spiWriteBurst(TXFIFO_BURST, pByteIndex, bytesToWrite);
490  pByteIndex += bytesToWrite;
491  bytesLeft -= bytesToWrite;
492 
493  // Enable transmission of packet
494  spiWriteStrobe(STX);
495 
496  _loopState = TX_ACTIVE;
497  }
498 
499  // Fall through
500 
501  case TX_ACTIVE:
502  {
503  // Check if we have an incomplete packet transmission
504  if (syncStart && (millis() - packetStartTime > TX_PACKET_TIMEOUT))
505  {
506  println("TX packet timeout!");
507  // Set transceiver to IDLE (no RX or TX)
508  sIdle();
509  _loopState = TX_END;
510  break;
511  }
512 
513  // Detect falling edge 1->0 on GDO2
514  statusGDO2 = digitalRead(GPIO_GDO2_PIN);
515 
516  if (prevStatusGDO2 != statusGDO2)
517  {
518  prevStatusGDO2 = statusGDO2;
519 
520  // Check if signal GDO2 is de-asserted (TX FIFO is below threshold of 33 bytes, i.e. TX FIFO is half full)
521  if (statusGDO2 == 0)
522  {
523  // - TX FIFO half full detected (< 33 bytes)
524  // Write data fragment to TX FIFO
525  uint8_t bytesToWrite = MIN(64, bytesLeft);
526  spiWriteBurst(TXFIFO_BURST, pByteIndex, bytesToWrite);
527  pByteIndex += bytesToWrite;
528  bytesLeft -= bytesToWrite;
529 
530  // Set fixed length mode if less than 256 left to transmit
531  if ( (bytesLeft < (256 - 64)) && !fixedLengthMode )
532  {
533  spiWriteRegister(PKTCTRL0, 0x00); // Set fixed pktlen mode
534  fixedLengthMode = true;
535  }
536  }
537  }
538 
539  // Detect falling edge 1->0 on GDO0
540  statusGDO0 = digitalRead(GPIO_GDO0_PIN);
541 
542  if (prevStatusGDO0 != statusGDO0)
543  {
544  prevStatusGDO0 = statusGDO0;
545 
546  // If GDO0 is de-asserted: TX packet complete or TX FIFO underflow
547  if (statusGDO0 == 0x00)
548  {
549  // There might be an TX FIFO underflow
550  uint8_t chipStatusBytes = spiWriteStrobe(SNOP);
551 
552  if ((chipStatusBytes & CHIPSTATUS_STATE_BITMASK) == CHIPSTATUS_STATE_TX_UNDERFLOW)
553  {
554  println("TX FIFO underflow!");
555  // Set transceiver to IDLE (no RX or TX)
556  sIdle();
557  }
558 
559  _loopState = TX_END;
560  }
561  else
562  {
563  // GDO0 asserted because sync word was transmitted
564  //println("TX Syncword!");
565  // wait for TX_PACKET_TIMEOUT milliseconds
566  // Complete packet must have been transmitted within this time
567  packetStartTime = millis();
568  syncStart = true;
569  }
570  }
571  }
572  break;
573 
574  case TX_END:
575  {
576  // free buffer
577  delete sendBuffer;
578  // Go back to RX after TX
579  _loopState = RX_START;
580  }
581  break;
582 
583  case RX_START:
584  {
585  prevStatusGDO2 = 0;
586  prevStatusGDO0 = 0;
587  syncStart = false;
588  packetStart = true;
589  fixedLengthMode = false;
590  pByteIndex = buffer;
591  bytesLeft = 0;
592  pktLen = 0;
593  // Set sync word in RX mode
594  // The same sync word is used in TX mode, but we use it in different way
595  spiWriteRegister(SYNC1, 0x76);
596  spiWriteRegister(SYNC0, 0x96);
597  // Set GDO2 to be RX FIFO threshold signal
598  spiWriteRegister(IOCFG2, 0x00);
599  // Set GDO0 to be packet received signal
600  spiWriteRegister(IOCFG0, 0x06);
601  // Set RX FIFO threshold to 4 bytes
602  spiWriteRegister(FIFOTHR, 0x40);
603  // Set infinite pktlen mode
604  spiWriteRegister(PKTCTRL0, 0x02);
605  // Flush RX FIFO
606  spiWriteStrobe(SFRX);
607  // Start RX
608  sReceive();
609  _loopState = RX_ACTIVE;
610  }
611  break;
612 
613  case RX_ACTIVE:
614  {
615  if (!_rfDataLinkLayer.isTxQueueEmpty() && !syncStart)
616  {
617  sIdle();
618  _loopState = TX_START;
619  break;
620  }
621 
622  // Check if we have an incomplete packet reception
623  // This is related to CC1101 errata "Radio stays in RX state instead of entering RXFIFO_OVERFLOW state"
624  if (syncStart && (millis() - packetStartTime > RX_PACKET_TIMEOUT))
625  {
626  println("RX packet timeout!");
627  //uint8_t marcState = (spiReadRegister(MARCSTATE) & MARCSTATE_BITMASK); //read out state of cc1101 to be sure in RX
628  //print("marcstate: 0x");
629  //println(marcState, HEX);
630  sIdle();
631  _loopState = RX_START;
632  break;
633  }
634 
635  // Detect rising edge 0->1 on GDO2
636  statusGDO2 = digitalRead(GPIO_GDO2_PIN);
637 
638  if (prevStatusGDO2 != statusGDO2)
639  {
640  prevStatusGDO2 = statusGDO2;
641 
642  // Check if signal GDO2 is asserted (RX FIFO is equal to or above threshold of 4 bytes)
643  if (statusGDO2 == 1)
644  {
645  if (packetStart)
646  {
647  // - RX FIFO 4 bytes detected -
648  // Calculate the total length of the packet, and set fixed mode if less
649  // than 255 bytes to receive
650 
651  // Read the 2 first bytes
652  spiReadBurst(RXFIFO_BURST, pByteIndex, 2);
653 
654  // Decode the L-field
655  if (!manchDecode(&buffer[0], &packet[0]))
656  {
657  //println("Could not decode L-field: manchester code violation");
658  _loopState = RX_START;
659  break;
660  }
661 
662  // Get bytes to receive from L-field, multiply by 2 because of manchester code
663  pktLen = 2 * PACKET_SIZE(packet[0]);
664 
665  // - Length mode -
666  if (pktLen < 256)
667  {
668  // Set fixed packet length mode is less than 256 bytes
669  spiWriteRegister(PKTLEN, pktLen);
670  spiWriteRegister(PKTCTRL0, 0x00); // Set fixed pktlen mode
671  fixedLengthMode = true;
672  }
673  else
674  {
675  // Infinite packet length mode is more than 255 bytes
676  // Calculate the PKTLEN value
677  uint8_t fixedLength = pktLen % 256;
678  spiWriteRegister(PKTLEN, fixedLength);
679  }
680 
681  pByteIndex += 2;
682  bytesLeft = pktLen - 2;
683 
684  // Set RX FIFO threshold to 32 bytes
685  packetStart = false;
686  spiWriteRegister(FIFOTHR, 0x47);
687  }
688  else
689  {
690  // - RX FIFO Half Full detected -
691  // Read out the RX FIFO and set fixed mode if less
692  // than 255 bytes to receive
693 
694  // - Length mode -
695  // Set fixed packet length mode if less than 256 bytes
696  if ((bytesLeft < 256 ) && !fixedLengthMode)
697  {
698  spiWriteRegister(PKTCTRL0, 0x00); // Set fixed pktlen mode
699  fixedLengthMode = true;
700  }
701 
702  // Read out the RX FIFO
703  // Do not empty the FIFO (See the CC110x or 2500 Errata Note)
704  spiReadBurst(RXFIFO_BURST, pByteIndex, 32 - 1);
705 
706  bytesLeft -= (32 - 1);
707  pByteIndex += (32 - 1);
708  }
709  }
710  }
711 
712  // Detect falling edge 1->0 on GDO0
713  statusGDO0 = digitalRead(GPIO_GDO0_PIN);
714 
715  if (prevStatusGDO0 != statusGDO0)
716  {
717  prevStatusGDO0 = statusGDO0;
718 
719  // If GDO0 is de-asserted: RX packet complete or RX FIFO overflow
720  if (statusGDO0 == 0x00)
721  {
722  // There might be an RX FIFO overflow
723  uint8_t chipStatusBytes = spiWriteStrobe(SNOP);
724 
725  if ((chipStatusBytes & CHIPSTATUS_STATE_BITMASK) == CHIPSTATUS_STATE_RX_OVERFLOW)
726  {
727  println("RX FIFO overflow!");
728  _loopState = RX_START;
729  break;
730  }
731 
732  // Check if we are in the middle of the packet reception
733  if (!packetStart)
734  {
735  // Complete packet received
736  // Read out remaining bytes in the RX FIFO
737  spiReadBurst(RXFIFO_BURST, pByteIndex, bytesLeft);
738  _loopState = RX_END;
739  }
740  }
741  else
742  {
743  // GDO0 asserted because sync word was received and recognized
744  //println("RX Syncword!");
745  // wait for RX_PACKET_TIMEOUT milliseconds
746  // Complete packet must have been received within this time
747  packetStartTime = millis();
748  syncStart = true;
749  }
750  }
751  }
752  break;
753 
754  case RX_END:
755  {
756  uint16_t pLen = PACKET_SIZE(packet[0]);
757  // Decode the first block (always 10 bytes + 2 bytes CRC)
758  bool decodeOk = true;
759 
760  for (uint16_t i = 1; i < pLen; i++)
761  {
762  // Check for manchester violation, abort if there is one
763  if (!manchDecode(&buffer[i * 2], &packet[i]))
764  {
765  println("Could not decode packet: manchester code violation");
766  decodeOk = false;
767  break;
768  }
769  }
770 
771  if (decodeOk)
772  {
773  _rfDataLinkLayer.frameBytesReceived(&packet[0], pLen);
774  }
775 
776  _loopState = RX_START;
777  }
778  break;
779  }
780 }
781 
782 #endif // USE_RF
783 
784 #endif // DeviceFamily_CC13X0
void print(const char *s)
void println(const char *s)
void printHex(const char *suffix, const uint8_t *data, size_t length, bool newline)
Definition: bits.cpp:12
void pinMode(unsigned long pin, unsigned long mode)
void digitalWrite(unsigned long pin, unsigned long value)
void delay(uint32_t ms)
uint32_t millis()
void delayMicroseconds(unsigned int howLong)
uint32_t digitalRead(uint32_t dwPin)
virtual int readWriteSpi(uint8_t *data, size_t len)
Definition: platform.cpp:24
virtual void setupSpi()
Definition: platform.cpp:18
virtual void closeSpi()
Definition: platform.cpp:21
RfPhysicalLayerCC1101(RfDataLinkLayer &rfDataLinkLayer, Platform &platform)
Platform & _platform
RfDataLinkLayer & _rfDataLinkLayer