├── LICENSE ├── README.md ├── Tools ├── eeprom_create.py └── eeprom_write.ino ├── cc1100_arduino.cpp ├── cc1100_arduino.h ├── cc1100_raspi.cpp ├── cc1100_raspi.h └── examples ├── Arduino ├── Rx_demo │ └── Rx_demo.ino ├── Rx_demo_WOR │ └── Rx_demo_WOR.ino └── Tx_demo │ └── Tx_demo.ino └── raspi ├── RX_Demo.cpp ├── RX_Demo_WOR.cpp └── TX_Demo.cpp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 SpaceTeddy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CC1101 2 | ====== 3 | 4 | driver library for Ti CC1100 / CC1101.
5 | Contains Lib for Arduino and Raspberry Pi.
6 | Note: Raspi need wiringPi
7 | 8 | a compatible and tested library for TI MSP430 is provided by abhra0897.
9 | https://github.com/abhra0897/msp430_cc1101_energia_v2
10 | 11 | 12 | Donation 13 | ======== 14 | 15 | If you are happy with the library and you want to 16 | spend me a beer, please feel free to use the following link. ;) 17 | 18 | https://www.paypal.me/bringmichzumschotter 19 | 20 | 21 | Hardware connection 22 | =================== 23 | 24 | check cc1101_arduino.h and/or cc1101_raspi.h for Pin description 25 | 26 | CC1101 Vdd = 3.3V 27 | CC1101 max. digital voltage level = 3.3V (not 5V tolerant) 28 | 29 | ``` 30 | CC1101<->Arduino 31 | 32 | Vdd - 3.3V 33 | SI - MOSI (11) 34 | SO - MISO (12) 35 | CS - SS (10) 36 | SCLK   -    SCK (13) 37 | GDO2 - GPIO ( 3) 38 | GDO0 - not used in this demo 39 | GND - GND 40 | 41 | 42 | CC1101<->Raspi 43 | 44 | Vdd - 3.3V (P1-01) 45 | SI - MOSI (P1-19) 46 | SO - MISO (P1-21) 47 | CS - SS (P1-24) 48 | SCLK   -    SCK (P1-23) 49 | GDO2 - GPIO (P1-22) 50 | GDO0 - not used in this demo 51 | GND - P1-25 52 | ``` 53 | 54 | General description of RF packet 55 | ================================ 56 | 57 | ``` 58 | -> pkt_len [1byte] | rx_addr [1byte] | tx_addr [1byte] | payload data [1..60bytes] 59 | ``` 60 | 61 | pkt_len = count of bytes which shall transfered over air (rx_addr + tx_addr + payload data)
62 | rx_addr = address of device, which shall receive the message (0x00 = broadcast to all devices)
63 | tx_addr = transmitter or my address. the receiver should know who has sent a message.
64 | payload = 1 to 60 bytes payload data.
65 | 66 | TX Bytes example:
67 | -> 0x06 0x03 0x01 0x00 0x01 0x02 0x03
68 | 69 | Basic configuration 70 | =================== 71 | 72 | use **uint8_t CC1100::begin(volatile uint8_t &My_addr)** always as first configuration step. For Arduino devices, this function returns the device address, which was already stored in the Arduino EEPROM. 73 | 74 | Device address 75 | -------------- 76 | you should set a unique device address for the transmitter and a unique device address for the receiver. 77 | This can be done with **void CC1100::set_myaddr(uint8_t addr)**. 78 | 79 | i.E. -> TX = 0x01 ; RX = 0x03 80 | 81 | 82 | Modulation modes 83 | ---------------- 84 | the following modulation modes can be set by **void CC1100::set_mode(uint8_t mode)**. Transmitter and receiver must have the same Mode setting. 85 | 86 | ``` 87 | 1 = GFSK_1_2_kb 88 | 2 = GFSK_38_4_kb 89 | 3 = GFSK_100_kb 90 | 4 = MSK_250_kb 91 | 5 = MSK_500_kb 92 | 6 = OOK_4_8_kb 93 | ``` 94 | 95 | ISM frequency band 96 | ------------------ 97 | you can set a frequency operation band by **void CC1100::set_ISM(uint8_t ism_freq)** to make it compatible with your hardware. 98 | 99 | ``` 100 | 1 = 315 101 | 2 = 433 102 | 3 = 868 103 | 4 = 915 104 | ``` 105 | 106 | Arduino specific 107 | ================ 108 | 109 | CC1101 RF settings must be stored in the Arduino EEPROM to have maximum flexibility with different mode settings and reduced memory usage. 110 | Follow the following steps, how to store the compiled EEPROM file (*.eep) to your Arduino EEPROM. From my experience, you have to repeat this step only, if you have changed the Arduino Version, because the gcc compiler defines the location of the eeprom settings. 111 | 112 | - compile the tx_demo or rx_demo example sketch 113 | - remember the path of your compiled output data (Arduino *.hex file and *.eep file) 114 | - use the python eeprom_create.py to generate the eeprom array for the eeprom_write.ino 115 | This is needed because the compiler can choose the EEPROM position by its own. 116 | - usage: ``` ./eeprom_create.py ``` 117 | - you get an output file with like *.array 118 | - open that file and copy the array content into the eeprom_write.ino sketch at the correct position 119 | - compile the eeprom_write.ino sketch 120 | - upload into to your connected arduino hardware 121 | - open the Arduino Serial console, set the baudrate to 38400 and restart your arduino hardware 122 | - type the character ```w``` to the input field and press the sent button 123 | - wait till eeprom is written 124 | - sent ```r``` to verify that eeprom is written. 125 | - if your EEPROM data is written correct, you can compile and upload the RX_Demo or TX_Demo sketch to that hardware 126 | 127 | 128 | Raspberry Pi 129 | ============ 130 | 131 | How to compile Raspi Demo files 132 | ------------------------------- 133 | 134 | be sure first, that you have already wiringPi installed on your Raspberry Pi hardware. 135 | 136 | copy RX_Demo.cpp, TX_Demo.cpp, cc1100_raspi.cpp, cc1100_raspi.h in the same directory and compile:
137 | 138 | RX_Demo.cpp
139 | ``` 140 | sudo g++ -lwiringPi RX_Demo.cpp cc1100_raspi.cpp -o RX_Demo 141 | sudo chmod 755 RX_Demo 142 | ``` 143 | 144 | TX_Demo.cpp
145 | ``` 146 | sudo g++ -lwiringPi TX_Demo.cpp cc1100_raspi.cpp -o TX_Demo 147 | sudo chmod 755 TX_Demo 148 | ``` 149 | 150 | Command Line parameters 151 | ----------------------- 152 | 153 | TX_Demo:
154 | ``` 155 | CC1100 SW [-h] [-V] [-a My_Addr] [-r RxDemo_Addr] [-i Msg_Interval] [-t tx_retries] [-c channel] [-f frequency] 156 | [-m modulation] 157 | 158 | -h print this help and exit 159 | -V print version and exit 160 | -v set verbose flag 161 | -a my address [1-255] set my address 162 | -r rx address [1-255] set RxDemo receiver address 163 | -i interval ms[1-6000] sets message interval timing 164 | -t tx_retries [0-255] sets message send retries 165 | -c channel [1-255] set transmit channel 166 | -f frequency [315,434,868,915] set ISM band 167 | -m modulation [1,38,100,250,500,4] set modulation 168 | ``` 169 | 170 | Example,
171 | ``` 172 | sudo ./TX_Demo -v -a1 -r3 -i1000 -t5 -c1 -f434 -m100 173 | ``` 174 | 175 | RX_Demo:
176 | ``` 177 | CC1100 SW [-h] [-V] [-v] [-a My_Addr] [-c channel] [-f frequency] [-m modulation] 178 | -h print this help and exit 179 | -V print version and exit 180 | -v set verbose flag 181 | -a my address [1-255] set my address 182 | -c channel [1-255] set transmit channel 183 | -f frequency [315,434,868,915] set ISM band 184 | -m modulation [1,38,100,250,500,4] set modulation 185 | ``` 186 | 187 | Example,
188 | ``` 189 | sudo ./RX_Demo -v -a3 -c1 -f434 -m100 190 | ``` 191 | -------------------------------------------------------------------------------- /Tools/eeprom_create.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding:utf-8 3 | 4 | '''creates an C++ array from an Arduino iHex EEPROM file (*.eep) 5 | usage: ./eeprom_create.py 6 | you get an output file with *.array extension''' 7 | 8 | from sys import argv 9 | 10 | # finds substring in string 11 | def find_all(a_string, sub): 12 | result = [] 13 | k = 0 14 | while k < len(a_string): 15 | k = a_string.find(sub, k) 16 | if k == -1: 17 | return result 18 | else: 19 | result.append(k) 20 | k += 1 #change to k += len(sub) to not search overlapping results 21 | return result 22 | 23 | str_search_start_line = ':' 24 | 25 | script, filename = argv 26 | 27 | txt = open(filename) 28 | 29 | #print ("Here's your file %r:") % filename 30 | txt = txt.read() 31 | file_len = len(txt) 32 | print("File length:" + str(file_len)) 33 | 34 | print(txt) 35 | 36 | f = open(filename + ".array", 'w') 37 | 38 | str_search_start_line = ':' 39 | start = [] 40 | start = find_all(txt,":") 41 | len = len(start) 42 | #print len 43 | #print start 44 | loop = 1 45 | txt_neu = "" 46 | total_bytes = 0 47 | max_length = 0 48 | f.write("Import file: " + filename + "\n") 49 | f.write("\n") 50 | for x in start: 51 | if(txt[x+7] == '0' and txt[x+8] == '1'): 52 | print ("EOF!") 53 | print ("Output array:") 54 | length = txt[x+1] + txt[x+2] 55 | length = int(length, 16) 56 | if(length > max_length): 57 | max_length = length 58 | total_bytes += length 59 | length = (length * 2) - 1 60 | count = 0 61 | loop += + 1 62 | while (count <= length): 63 | txt_neu += "0x" + txt[x+9+count] 64 | count = count + 1 65 | txt_neu += txt[x+9+count] 66 | if(loop == len and count == length): 67 | txt_neu += "};" 68 | else: 69 | txt_neu += "," 70 | count = count + 1 71 | txt_neu = txt_neu + "\n" 72 | 73 | print ("Total Bytes: " + str(total_bytes)) 74 | #print ("#define EEPROM_LEN " + str(total_bytes)) 75 | print ("uint8_t eeprom_cc1101[FULL_EEPROM_LEN] = {") 76 | if(max_length == 16): 77 | print("//00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F") 78 | if(max_length == 32): 79 | print("//00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F") 80 | print (txt_neu) 81 | #f.write("#define EEPROM_LEN " + str(total_bytes) + "\n") 82 | f.write("uint8_t eeprom_cc1101[FULL_EEPROM_LEN] = { \n") 83 | if(max_length == 16): 84 | f.write("//00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" + "\n") 85 | if(max_length == 32): 86 | f.write("//00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" + "\n") 87 | f.write(txt_neu) 88 | f.close() 89 | -------------------------------------------------------------------------------- /Tools/eeprom_write.ino: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------*/ 2 | /* Write eeprom data to internal EEPROM memory /* 3 | /* by Chris /* 4 | /* /* 5 | /*----------------------------------------------------------------------------*/ 6 | 7 | #include 8 | 9 | #define FULL_EEPROM_LEN 512 10 | 11 | #define EEPROM_ADDRESS_CC1100_FREQUENCY 0x1F4 12 | #define EEPROM_ADDRESS_CC1100_MODE 0x1F5 13 | #define EEPROM_ADDRESS_CC1100_MY_ADDR 0x1F6 14 | #define EEPROM_ADDRESS_CC1100_CHANNEL 0x1F7 15 | 16 | #define CC1100_FREQUENCY 0x03 17 | #define CC1100_MODE 0x04 18 | #define CC1100_MY_ADDR 0x03 19 | #define CC1100_CHANNEL 0x01 20 | 21 | 22 | int a = 0; 23 | int value; 24 | 25 | //------------------------------------------------------------------------------ 26 | 27 | //main control 1.6.10 28 | 29 | uint8_t eeprom_cc1101[FULL_EEPROM_LEN] = { 30 | //00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 31 | 0x06,0x2E,0x06,0x47,0xD3,0x91,0xFF,0x04,0x05,0x00,0x00,0x06,0x00,0x21,0x65,0x6A, 32 | 0x87,0x83,0x3B,0x22,0xF8,0x15,0x07,0x30,0x18,0x14,0x6C,0x07,0x00,0x92,0x87,0x6B, 33 | 0xFB,0x56,0x17,0xE9,0x2A,0x00,0x1F,0x41,0x00,0x59,0x7F,0x3F,0x81,0x35,0x09,0x07, 34 | 0x2E,0x80,0x07,0x57,0x43,0x3E,0x0E,0x45,0xFF,0x00,0x0C,0x00,0x21,0x65,0x6A,0x0E, 35 | 0x3B,0x73,0xA0,0xF8,0x00,0x07,0x0C,0x18,0x1D,0x1C,0xC7,0x40,0xB2,0x02,0x26,0x09, 36 | 0xB6,0x17,0xEA,0x0A,0x00,0x19,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E, 37 | 0x80,0x07,0x57,0x43,0x3E,0x0E,0x45,0xFF,0x00,0x0B,0x00,0x21,0x65,0x6A,0x2D,0x3B, 38 | 0x73,0xA0,0xF8,0x00,0x07,0x0C,0x18,0x1D,0x1C,0xC7,0x00,0xB2,0x02,0x26,0x09,0xB6, 39 | 0x17,0xEA,0x0A,0x00,0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E,0x80, 40 | 0x07,0x57,0x43,0x3E,0x0E,0x45,0xFF,0x00,0x08,0x00,0x21,0x65,0x6A,0x5B,0xF8,0x13, 41 | 0xA0,0xF8,0x47,0x07,0x0C,0x18,0x1D,0x1C,0xC7,0x00,0xB2,0x02,0x26,0x09,0xB6,0x17, 42 | 0xEA,0x0A,0x00,0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E,0x80,0x07, 43 | 0x57,0x43,0x3E,0x0E,0x45,0xFF,0x00,0x06,0x00,0x21,0x65,0x6A,0xCA,0x83,0x13,0xA0, 44 | 0xF8,0x34,0x07,0x0C,0x19,0x16,0x6C,0x43,0x40,0x91,0x02,0x26,0x09,0x56,0x17,0xA9, 45 | 0x0A,0x00,0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E,0x80,0x07,0x57, 46 | 0x43,0x3E,0x0E,0x45,0xFF,0x00,0x08,0x00,0x21,0x65,0x6A,0xF5,0x83,0x13,0xA0,0xF8, 47 | 0x15,0x07,0x0C,0x19,0x16,0x6C,0x03,0x40,0x91,0x02,0x26,0x09,0x56,0x17,0xA9,0x0A, 48 | 0x00,0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x0B,0x1B,0x6D,0x67,0x50,0x85, 49 | 0xC9,0xC1,0x03,0x17,0x1D,0x26,0x50,0x86,0xCD,0xC0,0x6C,0x1C,0x06,0x3A,0x51,0x85, 50 | 0xC8,0xC0,0x17,0x1D,0x26,0x69,0x51,0x86,0xCC,0xC3}; 51 | /* 52 | //Remote control 1.6.10 53 | uint8_t eeprom_cc1101[EEPROM_LEN] = { 54 | //00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 55 | 0x06,0x2E,0x06,0x47,0xD3,0x91,0xFF,0x04,0x05,0x00,0x00,0x06,0x00,0x21,0x65,0x6A, 56 | 0x87,0x83,0x3B,0x22,0xF8,0x15,0x07,0x30,0x18,0x14,0x6C,0x07,0x00,0x92,0x87,0x6B, 57 | 0xFB,0x56,0x17,0xE9,0x2A,0x00,0x1F,0x41,0x00,0x59,0x7F,0x3F,0x81,0x35,0x09,0x07, 58 | 0x2E,0x80,0x07,0x57,0x43,0x3E,0x0E,0x45,0xFF,0x00,0x0C,0x00,0x21,0x65,0x6A,0x0E, 59 | 0x3B,0x73,0xA0,0xF8,0x00,0x07,0x0C,0x18,0x1D,0x1C,0xC7,0x40,0xB2,0x02,0x26,0x09, 60 | 0xB6,0x17,0xEA,0x0A,0x00,0x19,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E, 61 | 0x80,0x07,0x57,0x43,0x3E,0x0E,0x45,0xFF,0x00,0x0B,0x00,0x21,0x65,0x6A,0x2D,0x3B, 62 | 0x73,0xA0,0xF8,0x00,0x07,0x0C,0x18,0x1D,0x1C,0xC7,0x00,0xB2,0x02,0x26,0x09,0xB6, 63 | 0x17,0xEA,0x0A,0x00,0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E,0x80, 64 | 0x07,0x57,0x43,0x3E,0x0E,0x45,0xFF,0x00,0x08,0x21,0x65,0x6A,0x5B,0xF8,0x13,0xA0, 65 | 0xF8,0x47,0x07,0x0C,0x18,0x1D,0x1C,0xC7,0x00,0xB2,0x02,0x26,0x09,0xB6,0x17,0xEA, 66 | 0x0A,0x00,0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E,0x80,0x07,0x57, 67 | 0x43,0x3E,0x0E,0x45,0xFF,0x00,0x06,0x00,0x21,0x65,0x6A,0xCA,0x83,0x13,0xA0,0xF8, 68 | 0x34,0x07,0x0C,0x19,0x16,0x6C,0x43,0x40,0x91,0x02,0x26,0x09,0x56,0x17,0xA9,0x0A, 69 | 0x00,0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x07,0x2E,0x80,0x07,0x57,0x43, 70 | 0x3E,0x0E,0x45,0xFF,0x00,0x08,0x00,0x21,0x65,0x6A,0xF5,0x83,0x13,0xA0,0xF8,0x15, 71 | 0x07,0x0C,0x19,0x16,0x6C,0x03,0x40,0x91,0x02,0x26,0x09,0x56,0x17,0xA9,0x0A,0x00, 72 | 0x11,0x41,0x00,0x59,0x7F,0x3F,0x81,0x3F,0x0B,0x0B,0x1B,0x6D,0x67,0x50,0x85,0xC9, 73 | 0xC1,0x03,0x17,0x1D,0x26,0x50,0x86,0xCD,0xC0,0x6C,0x1C,0x06,0x3A,0x51,0x85,0xC8, 74 | 0xC0,0x17,0x1D,0x26,0x69,0x51,0x86,0xCC,0xC3}; 75 | */ 76 | 77 | //------------------------------------------------------------------------------ 78 | void blank_eeprom(void){ 79 | Serial.print(F("erase EEPROM...")); 80 | 81 | uint16_t count = 0; 82 | for (int i = 0; i < FULL_EEPROM_LEN; i++){ 83 | EEPROM.write(i, 0xFF); 84 | count++; 85 | Serial.print(F(".")); 86 | if(count == 16){ 87 | Serial.println(); 88 | count = 0; 89 | } 90 | } 91 | Serial.println(); 92 | Serial.println(F("erase done!"));Serial.println(); 93 | } 94 | 95 | void write_eeprom(void){ 96 | Serial.print(F("write EEPROM...")); 97 | 98 | uint16_t count = 0; 99 | for (int i = 0; i < FULL_EEPROM_LEN; i++){ 100 | EEPROM.write(i, eeprom_cc1101[i]); 101 | count++; 102 | Serial.print(F(".")); 103 | if(count == 16){ 104 | Serial.println(); 105 | count = 0; 106 | } 107 | } 108 | Serial.println(); 109 | Serial.println(F("write done!"));Serial.println(); 110 | } 111 | 112 | void read_eeprom(void){ 113 | Serial.println(F("read EEPROM..."));Serial.println(); 114 | char hex_value[4]; 115 | uint16_t newline; 116 | 117 | newline = 0; 118 | Serial.println(F("uint8_t eeprom = {")); 119 | for (int i = 0; i < FULL_EEPROM_LEN; i++){ 120 | value = EEPROM.read(i); 121 | sprintf(hex_value,"%02x", value); 122 | Serial.print("0x");Serial.print(hex_value); 123 | if(i < FULL_EEPROM_LEN-1){ 124 | Serial.print(F(",")); 125 | } 126 | else{ 127 | Serial.print(F("};")); 128 | } 129 | newline++; 130 | if(newline == 16){ 131 | Serial.println(); 132 | newline = 0; 133 | } 134 | 135 | } 136 | Serial.println();Serial.println(F("read done..."));Serial.println(); 137 | } 138 | 139 | void setup() { 140 | 141 | // put your setup code here, to run once: 142 | Serial.begin(38400); 143 | Serial.println(F("EEPROM write sketch")); 144 | Serial.println(F("===================")); 145 | Serial.println(); 146 | 147 | Serial.println(F("Settings:")); 148 | 149 | //ISM Frequency - default 868MHz 150 | eeprom_cc1101[500] = CC1100_FREQUENCY; 151 | Serial.print(F("ISM Mode: "));Serial.println(eeprom_cc1101[EEPROM_ADDRESS_CC1100_FREQUENCY]); 152 | 153 | //Modulation Mode - default 250 kbit 154 | eeprom_cc1101[501] = CC1100_MODE; 155 | Serial.print(F("Modulation Mode: "));Serial.println(eeprom_cc1101[EEPROM_ADDRESS_CC1100_MODE]); 156 | 157 | //My Address - default address 1 158 | eeprom_cc1101[502] = CC1100_MY_ADDR; 159 | Serial.print(F("My Addr: "));Serial.println(eeprom_cc1101[EEPROM_ADDRESS_CC1100_MY_ADDR]); 160 | 161 | //Channel - default 1 162 | eeprom_cc1101[503] = CC1100_CHANNEL; 163 | Serial.print(F("Channel: "));Serial.println(eeprom_cc1101[EEPROM_ADDRESS_CC1100_CHANNEL]); 164 | Serial.println();Serial.println(); 165 | 166 | 167 | Serial.println(F("*------ Menu -------*")); 168 | Serial.println(F("*press 'w' for write*")); 169 | Serial.println(F("*press 'r' for read *")); 170 | Serial.println(F("*press 'b' for blank*")); 171 | Serial.println(F("=====================")); 172 | Serial.println();Serial.println(); 173 | 174 | } 175 | 176 | void loop() { 177 | if(Serial.available() > 0) { 178 | char c = Serial.read(); 179 | if(c == 'r'){ 180 | read_eeprom(); 181 | } 182 | if(c == 'w'){ 183 | write_eeprom(); 184 | } 185 | if(c == 'b'){ 186 | blank_eeprom(); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /cc1100_arduino.cpp: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------ 2 | ' CC1100 Arduino Library 3 | ' ---------------------- 4 | ' 5 | ' 6 | ' 7 | ' 8 | ' 9 | ' module contains helper code from other people. Thx for that 10 | '-----------------------------------------------------------------------------*/ 11 | #include 12 | 13 | //-------------------[global EEPROM default settings 868 Mhz]------------------- 14 | static uint8_t cc1100_GFSK_1_2_kb[] EEMEM = { 15 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 16 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 17 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 18 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 19 | 0x57, // SYNC1 Sync Word, High Byte 20 | 0x43, // SYNC0 Sync Word, Low Byte 21 | 0x3E, // PKTLEN Packet Length 22 | 0x0E, // PKTCTRL1 Packet Automation Control 23 | 0x45, // PKTCTRL0 Packet Automation Control 24 | 0xFF, // ADDR Device Address 25 | 0x00, // CHANNR Channel Number 26 | 0x08, // FSCTRL1 Frequency Synthesizer Control 27 | 0x00, // FSCTRL0 Frequency Synthesizer Control 28 | 0x21, // FREQ2 Frequency Control Word, High Byte 29 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 30 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 31 | 0xF5, // MDMCFG4 Modem Configuration 32 | 0x83, // MDMCFG3 Modem Configuration 33 | 0x13, // MDMCFG2 Modem Configuration 34 | 0xA0, // MDMCFG1 Modem Configuration 35 | 0xF8, // MDMCFG0 Modem Configuration 36 | 0x15, // DEVIATN Modem Deviation Setting 37 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 38 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 39 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 40 | 0x16, // FOCCFG Frequency Offset Compensation Configuration 41 | 0x6C, // BSCFG Bit Synchronization Configuration 42 | 0x03, // AGCCTRL2 AGC Control 43 | 0x40, // AGCCTRL1 AGC Control 44 | 0x91, // AGCCTRL0 AGC Control 45 | 0x02, // WOREVT1 High Byte Event0 Timeout 46 | 0x26, // WOREVT0 Low Byte Event0 Timeout 47 | 0x09, // WORCTRL Wake On Radio Control 48 | 0x56, // FREND1 Front End RX Configuration 49 | 0x17, // FREND0 Front End TX Configuration 50 | 0xA9, // FSCAL3 Frequency Synthesizer Calibration 51 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 52 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 53 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 54 | 0x41, // RCCTRL1 RC Oscillator Configuration 55 | 0x00, // RCCTRL0 RC Oscillator Configuration 56 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 57 | 0x7F, // PTEST Production Test 58 | 0x3F, // AGCTEST AGC Test 59 | 0x81, // TEST2 Various Test Settings 60 | 0x3F, // TEST1 Various Test Settings 61 | 0x0B // TEST0 Various Test Settings 62 | }; 63 | 64 | static uint8_t cc1100_GFSK_38_4_kb[] EEMEM = { 65 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 66 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 67 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 68 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 69 | 0x57, // SYNC1 Sync Word, High Byte 70 | 0x43, // SYNC0 Sync Word, Low Byte 71 | 0x3E, // PKTLEN Packet Length 72 | 0x0E, // PKTCTRL1 Packet Automation Control 73 | 0x45, // PKTCTRL0 Packet Automation Control 74 | 0xFF, // ADDR Device Address 75 | 0x00, // CHANNR Channel Number 76 | 0x06, // FSCTRL1 Frequency Synthesizer Control 77 | 0x00, // FSCTRL0 Frequency Synthesizer Control 78 | 0x21, // FREQ2 Frequency Control Word, High Byte 79 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 80 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 81 | 0xCA, // MDMCFG4 Modem Configuration 82 | 0x83, // MDMCFG3 Modem Configuration 83 | 0x13, // MDMCFG2 Modem Configuration 84 | 0xA0, // MDMCFG1 Modem Configuration 85 | 0xF8, // MDMCFG0 Modem Configuration 86 | 0x34, // DEVIATN Modem Deviation Setting 87 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 88 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 89 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 90 | 0x16, // FOCCFG Frequency Offset Compensation Configuration 91 | 0x6C, // BSCFG Bit Synchronization Configuration 92 | 0x43, // AGCCTRL2 AGC Control 93 | 0x40, // AGCCTRL1 AGC Control 94 | 0x91, // AGCCTRL0 AGC Control 95 | 0x02, // WOREVT1 High Byte Event0 Timeout 96 | 0x26, // WOREVT0 Low Byte Event0 Timeout 97 | 0x09, // WORCTRL Wake On Radio Control 98 | 0x56, // FREND1 Front End RX Configuration 99 | 0x17, // FREND0 Front End TX Configuration 100 | 0xA9, // FSCAL3 Frequency Synthesizer Calibration 101 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 102 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 103 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 104 | 0x41, // RCCTRL1 RC Oscillator Configuration 105 | 0x00, // RCCTRL0 RC Oscillator Configuration 106 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 107 | 0x7F, // PTEST Production Test 108 | 0x3F, // AGCTEST AGC Test 109 | 0x81, // TEST2 Various Test Settings 110 | 0x3F, // TEST1 Various Test Settings 111 | 0x0B // TEST0 Various Test Settings 112 | }; 113 | 114 | static uint8_t cc1100_GFSK_100_kb[] EEMEM = { 115 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 116 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 117 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 118 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 119 | 0x57, // SYNC1 Sync Word, High Byte 120 | 0x43, // SYNC0 Sync Word, Low Byte 121 | 0x3E, // PKTLEN Packet Length 122 | 0x0E, // PKTCTRL1 Packet Automation Control 123 | 0x45, // PKTCTRL0 Packet Automation Control 124 | 0xFF, // ADDR Device Address 125 | 0x00, // CHANNR Channel Number 126 | 0x08, // FSCTRL1 Frequency Synthesizer Control 127 | 0x00, // FSCTRL0 Frequency Synthesizer Control 128 | 0x21, // FREQ2 Frequency Control Word, High Byte 129 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 130 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 131 | 0x5B, // MDMCFG4 Modem Configuration 132 | 0xF8, // MDMCFG3 Modem Configuration 133 | 0x13, // MDMCFG2 Modem Configuration 134 | 0xA0, // MDMCFG1 Modem Configuration 135 | 0xF8, // MDMCFG0 Modem Configuration 136 | 0x47, // DEVIATN Modem Deviation Setting 137 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 138 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 139 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 140 | 0x1D, // FOCCFG Frequency Offset Compensation Configuration 141 | 0x1C, // BSCFG Bit Synchronization Configuration 142 | 0xC7, // AGCCTRL2 AGC Control 143 | 0x00, // AGCCTRL1 AGC Control 144 | 0xB2, // AGCCTRL0 AGC Control 145 | 0x02, // WOREVT1 High Byte Event0 Timeout 146 | 0x26, // WOREVT0 Low Byte Event0 Timeout 147 | 0x09, // WORCTRL Wake On Radio Control 148 | 0xB6, // FREND1 Front End RX Configuration 149 | 0x17, // FREND0 Front End TX Configuration 150 | 0xEA, // FSCAL3 Frequency Synthesizer Calibration 151 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 152 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 153 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 154 | 0x41, // RCCTRL1 RC Oscillator Configuration 155 | 0x00, // RCCTRL0 RC Oscillator Configuration 156 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 157 | 0x7F, // PTEST Production Test 158 | 0x3F, // AGCTEST AGC Test 159 | 0x81, // TEST2 Various Test Settings 160 | 0x3F, // TEST1 Various Test Settings 161 | 0x0B // TEST0 Various Test Settings 162 | }; 163 | 164 | static uint8_t cc1100_MSK_250_kb[] EEMEM = { 165 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 166 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 167 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 168 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 169 | 0x57, // SYNC1 Sync Word, High Byte 170 | 0x43, // SYNC0 Sync Word, Low Byte 171 | 0x3E, // PKTLEN Packet Length 172 | 0x0E, // PKTCTRL1 Packet Automation Control 173 | 0x45, // PKTCTRL0 Packet Automation Control 174 | 0xFF, // ADDR Device Address 175 | 0x00, // CHANNR Channel Number 176 | 0x0B, // FSCTRL1 Frequency Synthesizer Control 177 | 0x00, // FSCTRL0 Frequency Synthesizer Control 178 | 0x21, // FREQ2 Frequency Control Word, High Byte 179 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 180 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 181 | 0x2D, // MDMCFG4 Modem Configuration 182 | 0x3B, // MDMCFG3 Modem Configuration 183 | 0x73, // MDMCFG2 Modem Configuration 184 | 0xA0, // MDMCFG1 Modem Configuration 185 | 0xF8, // MDMCFG0 Modem Configuration 186 | 0x00, // DEVIATN Modem Deviation Setting 187 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 188 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 189 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 190 | 0x1D, // FOCCFG Frequency Offset Compensation Configuration 191 | 0x1C, // BSCFG Bit Synchronization Configuration 192 | 0xC7, // AGCCTRL2 AGC Control 193 | 0x00, // AGCCTRL1 AGC Control 194 | 0xB2, // AGCCTRL0 AGC Control 195 | 0x02, // WOREVT1 High Byte Event0 Timeout 196 | 0x26, // WOREVT0 Low Byte Event0 Timeout 197 | 0x09, // WORCTRL Wake On Radio Control 198 | 0xB6, // FREND1 Front End RX Configuration 199 | 0x17, // FREND0 Front End TX Configuration 200 | 0xEA, // FSCAL3 Frequency Synthesizer Calibration 201 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 202 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 203 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 204 | 0x41, // RCCTRL1 RC Oscillator Configuration 205 | 0x00, // RCCTRL0 RC Oscillator Configuration 206 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 207 | 0x7F, // PTEST Production Test 208 | 0x3F, // AGCTEST AGC Test 209 | 0x81, // TEST2 Various Test Settings 210 | 0x3F, // TEST1 Various Test Settings 211 | 0x0B // TEST0 Various Test Settings 212 | }; 213 | 214 | static uint8_t cc1100_MSK_500_kb[] EEMEM = { 215 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 216 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 217 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 218 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 219 | 0x57, // SYNC1 Sync Word, High Byte 220 | 0x43, // SYNC0 Sync Word, Low Byte 221 | 0x3E, // PKTLEN Packet Length 222 | 0x0E, // PKTCTRL1 Packet Automation Control 223 | 0x45, // PKTCTRL0 Packet Automation Control 224 | 0xFF, // ADDR Device Address 225 | 0x00, // CHANNR Channel Number 226 | 0x0C, // FSCTRL1 Frequency Synthesizer Control 227 | 0x00, // FSCTRL0 Frequency Synthesizer Control 228 | 0x21, // FREQ2 Frequency Control Word, High Byte 229 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 230 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 231 | 0x0E, // MDMCFG4 Modem Configuration 232 | 0x3B, // MDMCFG3 Modem Configuration 233 | 0x73, // MDMCFG2 Modem Configuration 234 | 0xA0, // MDMCFG1 Modem Configuration 235 | 0xF8, // MDMCFG0 Modem Configuration 236 | 0x00, // DEVIATN Modem Deviation Setting 237 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 238 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 239 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 240 | 0x1D, // FOCCFG Frequency Offset Compensation Configuration 241 | 0x1C, // BSCFG Bit Synchronization Configuration 242 | 0xC7, // AGCCTRL2 AGC Control 243 | 0x40, // AGCCTRL1 AGC Control 244 | 0xB2, // AGCCTRL0 AGC Control 245 | 0x02, // WOREVT1 High Byte Event0 Timeout 246 | 0x26, // WOREVT0 Low Byte Event0 Timeout 247 | 0x09, // WORCTRL Wake On Radio Control 248 | 0xB6, // FREND1 Front End RX Configuration 249 | 0x17, // FREND0 Front End TX Configuration 250 | 0xEA, // FSCAL3 Frequency Synthesizer Calibration 251 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 252 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 253 | 0x19, // FSCAL0 Frequency Synthesizer Calibration 254 | 0x41, // RCCTRL1 RC Oscillator Configuration 255 | 0x00, // RCCTRL0 RC Oscillator Configuration 256 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 257 | 0x7F, // PTEST Production Test 258 | 0x3F, // AGCTEST AGC Test 259 | 0x81, // TEST2 Various Test Settings 260 | 0x3F, // TEST1 Various Test Settings 261 | 0x0B // TEST0 Various Test Settings 262 | }; 263 | 264 | static uint8_t cc1100_OOK_4_8_kb[] EEMEM = { 265 | 0x06, // IOCFG2 GDO2 Output Pin Configuration 266 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 267 | 0x06, // IOCFG0 GDO0 Output Pin Configuration 268 | 0x47, // FIFOTHR RX FIFO and TX FIFO Thresholds 269 | 0x57, // SYNC1 Sync Word, High Byte 270 | 0x43, // SYNC0 Sync Word, Low Byte 271 | 0xFF, // PKTLEN Packet Length 272 | 0x04, // PKTCTRL1 Packet Automation Control 273 | 0x05, // PKTCTRL0 Packet Automation Control 274 | 0x00, // ADDR Device Address 275 | 0x00, // CHANNR Channel Number 276 | 0x06, // FSCTRL1 Frequency Synthesizer Control 277 | 0x00, // FSCTRL0 Frequency Synthesizer Control 278 | 0x21, // FREQ2 Frequency Control Word, High Byte 279 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 280 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 281 | 0x87, // MDMCFG4 Modem Configuration 282 | 0x83, // MDMCFG3 Modem Configuration 283 | 0x3B, // MDMCFG2 Modem Configuration 284 | 0x22, // MDMCFG1 Modem Configuration 285 | 0xF8, // MDMCFG0 Modem Configuration 286 | 0x15, // DEVIATN Modem Deviation Setting 287 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 288 | 0x30, // MCSM1 Main Radio Control State Machine Configuration 289 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 290 | 0x14, // FOCCFG Frequency Offset Compensation Configuration 291 | 0x6C, // BSCFG Bit Synchronization Configuration 292 | 0x07, // AGCCTRL2 AGC Control 293 | 0x00, // AGCCTRL1 AGC Control 294 | 0x92, // AGCCTRL0 AGC Control 295 | 0x87, // WOREVT1 High Byte Event0 Timeout 296 | 0x6B, // WOREVT0 Low Byte Event0 Timeout 297 | 0xFB, // WORCTRL Wake On Radio Control 298 | 0x56, // FREND1 Front End RX Configuration 299 | 0x17, // FREND0 Front End TX Configuration 300 | 0xE9, // FSCAL3 Frequency Synthesizer Calibration 301 | 0x2A, // FSCAL2 Frequency Synthesizer Calibration 302 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 303 | 0x1F, // FSCAL0 Frequency Synthesizer Calibration 304 | 0x41, // RCCTRL1 RC Oscillator Configuration 305 | 0x00, // RCCTRL0 RC Oscillator Configuration 306 | 0x59, // FSTEST Frequency Synthesizer Calibration Control 307 | 0x7F, // PTEST Production Test 308 | 0x3F, // AGCTEST AGC Test 309 | 0x81, // TEST2 Various Test Settings 310 | 0x35, // TEST1 Various Test Settings 311 | 0x09, // TEST0 Various Test Settings 312 | }; 313 | 314 | //Patable index: -30 -20- -15 -10 0 5 7 10 dBm 315 | static uint8_t patable_power_315[] EEMEM = {0x17,0x1D,0x26,0x69,0x51,0x86,0xCC,0xC3}; 316 | static uint8_t patable_power_433[] EEMEM = {0x6C,0x1C,0x06,0x3A,0x51,0x85,0xC8,0xC0}; 317 | static uint8_t patable_power_868[] EEMEM = {0x03,0x17,0x1D,0x26,0x50,0x86,0xCD,0xC0}; 318 | static uint8_t patable_power_915[] EEMEM = {0x0B,0x1B,0x6D,0x67,0x50,0x85,0xC9,0xC1}; 319 | //static uint8_t patable_power_2430[] EEMEM = {0x44,0x84,0x46,0x55,0xC6,0x6E,0x9A,0xFE}; 320 | 321 | //----------------------------------[END]--------------------------------------- 322 | 323 | //-------------------------[CC1100 reset function]------------------------------ 324 | void CC1100::reset(void) // reset defined in cc1100 datasheet 325 | { 326 | digitalWrite(SS_PIN, LOW); 327 | delayMicroseconds(10); 328 | digitalWrite(SS_PIN, HIGH); 329 | delayMicroseconds(40); 330 | 331 | spi_write_strobe(SRES); 332 | delay(1); 333 | } 334 | //-----------------------------[END]-------------------------------------------- 335 | 336 | //------------------------[set Power Down]-------------------------------------- 337 | void CC1100::powerdown(void) 338 | { 339 | sidle(); 340 | spi_write_strobe(SPWD); // CC1100 Power Down 341 | } 342 | //-----------------------------[end]-------------------------------------------- 343 | 344 | //---------------------------[WakeUp]------------------------------------------- 345 | void CC1100::wakeup(void) 346 | { 347 | digitalWrite(SS_PIN, LOW); 348 | delayMicroseconds(10); 349 | digitalWrite(SS_PIN, HIGH); 350 | delayMicroseconds(10); 351 | receive(); // go to RX Mode 352 | } 353 | //-----------------------------[end]-------------------------------------------- 354 | 355 | //---------------------[CC1100 set debug level]--------------------------------- 356 | uint8_t CC1100::set_debug_level(uint8_t set_debug_level = 1) //default ON 357 | { 358 | debug_level = set_debug_level; //set debug level of CC1101 outputs 359 | 360 | return debug_level; 361 | } 362 | //-----------------------------[end]-------------------------------------------- 363 | 364 | //---------------------[CC1100 get debug level]--------------------------------- 365 | uint8_t CC1100::get_debug_level(void) 366 | { 367 | return debug_level; 368 | } 369 | //-----------------------------[end]-------------------------------------------- 370 | 371 | //----------------------[CC1100 init functions]--------------------------------- 372 | uint8_t CC1100::begin(volatile uint8_t &My_addr) 373 | { 374 | uint8_t cc1100_freq_select, cc1100_mode_select, cc1100_channel_select; 375 | uint8_t partnum, version; 376 | 377 | pinMode(GDO0, INPUT); //setup AVR GPIO ports 378 | pinMode(GDO2, INPUT); 379 | 380 | set_debug_level(set_debug_level()); //set debug level of CC1101 outputs 381 | 382 | if(debug_level > 0){ 383 | Serial.println(F("Init CC1100...")); 384 | } 385 | 386 | spi_begin(); //inits SPI Interface 387 | reset(); //CC1100 init reset 388 | 389 | spi_write_strobe(SFTX);delayMicroseconds(100);//flush the TX_fifo content 390 | spi_write_strobe(SFRX);delayMicroseconds(100);//flush the RX_fifo content 391 | 392 | partnum = spi_read_register(PARTNUM); //reads CC1100 partnumber 393 | version = spi_read_register(VERSION); //reads CC1100 version number 394 | 395 | //checks if valid Chip ID is found. Usualy 0x03 or 0x14. if not -> abort 396 | if(version == 0x00 || version == 0xFF){ 397 | if(debug_level > 0){ 398 | Serial.print(F("no CC11xx found!")); 399 | Serial.println(); 400 | } 401 | 402 | return FALSE; 403 | } 404 | 405 | if(debug_level > 0){ 406 | Serial.print(F("Partnumber:")); 407 | uart_puthex_byte(partnum); 408 | Serial.println(); 409 | 410 | Serial.print(F("Version:")); 411 | uart_puthex_byte(version); 412 | Serial.println(); 413 | } 414 | 415 | //reads setting parameters from eeprom 416 | My_addr = eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_MY_ADDR); 417 | cc1100_freq_select = eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_FREQUENCY); 418 | cc1100_mode_select = eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_MODE); 419 | cc1100_channel_select = eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_CHANNEL); 420 | 421 | //if no valid settings are available, CC100 Powerdown and SPI disable 422 | if( My_addr == 0xFF || 423 | cc1100_freq_select == 0xFF || 424 | cc1100_mode_select == 0xFF || 425 | cc1100_channel_select == 0xFF) 426 | { 427 | if(debug_level > 0){ 428 | Serial.print(F("no EEPROM settings...")); 429 | Serial.println(); 430 | } 431 | end(); //CC1100 Powerdown and disable SPI bus 432 | 433 | return FALSE; 434 | } 435 | 436 | //set modulation mode 437 | set_mode(cc1100_mode_select); 438 | 439 | //set ISM band 440 | set_ISM(cc1100_freq_select); 441 | 442 | //set channel 443 | set_channel(cc1100_channel_select); 444 | 445 | //set output power amplifier 446 | set_output_power_level(0); //set PA to 0dBm as default 447 | 448 | //set my receiver address 449 | set_myaddr(My_addr); //My_Addr from EEPROM to global variable 450 | 451 | if(debug_level > 0){ 452 | Serial.println(F("...done")); 453 | } 454 | 455 | receive(); //set CC1100 in receive mode 456 | 457 | return TRUE; 458 | } 459 | //-------------------------------[end]------------------------------------------ 460 | 461 | //-----------------[finish's the CC1100 operation]------------------------------ 462 | void CC1100::end(void) 463 | { 464 | powerdown(); //power down CC1100 465 | spi_end(); //disable SPI Interface 466 | } 467 | //-------------------------------[end]------------------------------------------ 468 | 469 | //-----------------------[show all CC1100 registers]---------------------------- 470 | void CC1100::show_register_settings(void) 471 | { 472 | if(debug_level > 0){ 473 | uint8_t config_reg_verify[CFG_REGISTER],Patable_verify[CFG_REGISTER]; 474 | 475 | spi_read_burst(READ_BURST,config_reg_verify,CFG_REGISTER); //reads all 47 config register 476 | spi_read_burst(PATABLE_BURST,Patable_verify,8); //reads output power settings 477 | 478 | //show_main_settings(); 479 | Serial.println(F("Cfg_reg:")); 480 | 481 | for(uint8_t i = 0 ; i < CFG_REGISTER; i++) //showes rx_buffer for debug 482 | { 483 | uart_puthex_byte(config_reg_verify[i]);Serial.print(F(" ")); 484 | if(i==9 || i==19 || i==29 || i==39) //just for beautiful output style 485 | { 486 | Serial.println(); 487 | } 488 | } 489 | Serial.println(); 490 | Serial.println(F("PaTable:")); 491 | 492 | for(uint8_t i = 0 ; i < 8; i++) //showes rx_buffer for debug 493 | { 494 | uart_puthex_byte(Patable_verify[i]);Serial.print(F(" ")); 495 | } 496 | Serial.println(); 497 | } 498 | } 499 | //-------------------------------[end]------------------------------------------ 500 | 501 | //--------------------------[show settings]------------------------------------- 502 | void CC1100::show_main_settings(void) 503 | { 504 | if(debug_level > 0){ 505 | Serial.print(F("Mode:")); 506 | Serial.print(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_MODE)); 507 | Serial.println(); 508 | 509 | Serial.print(F("Frequency:")); 510 | Serial.print(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_FREQUENCY)); 511 | Serial.println(); 512 | 513 | Serial.print(F("Channel:")); 514 | Serial.print(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_CHANNEL)); 515 | Serial.println(); 516 | 517 | Serial.print(F("My_Addr:")); 518 | Serial.print(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_MY_ADDR)); 519 | Serial.println(); 520 | } 521 | } 522 | //-------------------------------[end]------------------------------------------ 523 | 524 | //----------------------------[idle mode]--------------------------------------- 525 | uint8_t CC1100::sidle(void) 526 | { 527 | uint8_t marcstate; 528 | 529 | spi_write_strobe(SIDLE); //sets to idle first. must be in 530 | 531 | marcstate = 0xFF; //set unknown/dummy state value 532 | 533 | while(marcstate != 0x01) //0x01 = sidle 534 | { 535 | marcstate = (spi_read_register(MARCSTATE) & 0x1F); //read out state of cc1100 to be sure in RX 536 | //uart_puthex_byte(marcstate); 537 | } 538 | //Serial.println(); 539 | delayMicroseconds(100); 540 | return TRUE; 541 | } 542 | //-------------------------------[end]------------------------------------------ 543 | 544 | //---------------------------[transmit mode]------------------------------------ 545 | uint8_t CC1100::transmit(void) 546 | { 547 | uint8_t marcstate; 548 | 549 | sidle(); //sets to idle first. 550 | spi_write_strobe(STX); //sends the data over air 551 | 552 | marcstate = 0xFF; //set unknown/dummy state value 553 | 554 | while(marcstate != 0x01) //0x01 = ILDE after sending data 555 | { 556 | marcstate = (spi_read_register(MARCSTATE) & 0x1F); //read out state of cc1100 to be sure in IDLE and TX is finished 557 | //uart_puthex_byte(marcstate); 558 | } 559 | //Serial.println(); 560 | delayMicroseconds(100); 561 | return TRUE; 562 | } 563 | //-------------------------------[end]------------------------------------------ 564 | 565 | //---------------------------[receive mode]------------------------------------- 566 | uint8_t CC1100::receive(void) 567 | { 568 | uint8_t marcstate; 569 | 570 | sidle(); //sets to idle first. 571 | spi_write_strobe(SRX); //writes receive strobe (receive mode) 572 | 573 | marcstate = 0xFF; //set unknown/dummy state value 574 | 575 | while(marcstate != 0x0D) //0x0D = RX 576 | { 577 | marcstate = (spi_read_register(MARCSTATE) & 0x1F); //read out state of cc1100 to be sure in RX 578 | //uart_puthex_byte(marcstate); 579 | } 580 | //Serial.println(); 581 | delayMicroseconds(100); 582 | return TRUE; 583 | } 584 | //-------------------------------[end]------------------------------------------ 585 | 586 | //------------[enables WOR Mode EVENT0 ~1890ms; rx_timeout ~235ms]-------------------- 587 | void CC1100::wor_enable() 588 | { 589 | /* 590 | EVENT1 = WORCTRL[6:4] -> Datasheet page 88 591 | EVENT0 = (750/Xtal)*(WOREVT1<<8+WOREVT0)*2^(5*WOR_RES) = (750/26Meg)*65407*2^(5*0) = 1.89s 592 | 593 | (WOR_RES=0;RX_TIME=0) -> Datasheet page 80 594 | i.E RX_TIMEOUT = EVENT0* (3.6038) *26/26Meg = 235.8ms 595 | (WOR_RES=0;RX_TIME=1) -> Datasheet page 80 596 | i.E.RX_TIMEOUT = EVENT0* (1.8029) *26/26Meg = 117.9ms 597 | */ 598 | sidle(); 599 | 600 | spi_write_register(MCSM0, 0x18); //FS Autocalibration 601 | spi_write_register(MCSM2, 0x01); //MCSM2.RX_TIME = 1b 602 | 603 | // configure EVENT0 time 604 | spi_write_register(WOREVT1, 0xFF); //High byte Event0 timeout 605 | spi_write_register(WOREVT0, 0x7F); //Low byte Event0 timeout 606 | 607 | // configure EVENT1 time 608 | spi_write_register(WORCTRL, 0x78); //WOR_RES=0b; tEVENT1=0111b=48d -> 48*(750/26MHz)= 1.385ms 609 | 610 | spi_write_strobe(SFRX); //flush RX buffer 611 | spi_write_strobe(SWORRST); //resets the WOR timer to the programmed Event 1 612 | spi_write_strobe(SWOR); //put the radio in WOR mode when CSn is released 613 | 614 | delayMicroseconds(100); 615 | } 616 | //-------------------------------[end]------------------------------------------ 617 | 618 | //------------------------[disable WOR Mode]------------------------------------- 619 | void CC1100::wor_disable() 620 | { 621 | sidle(); //exit WOR Mode 622 | spi_write_register(MCSM2, 0x07); //stay in RX. No RX timeout 623 | } 624 | //-------------------------------[end]------------------------------------------ 625 | 626 | //------------------------[resets WOR Timer]------------------------------------ 627 | void CC1100::wor_reset() 628 | { 629 | sidle(); //go to IDLE 630 | spi_write_register(MCSM2, 0x01); //MCSM2.RX_TIME = 1b 631 | spi_write_strobe(SFRX); //flush RX buffer 632 | spi_write_strobe(SWORRST); //resets the WOR timer to the programmed Event 1 633 | spi_write_strobe(SWOR); //put the radio in WOR mode when CSn is released 634 | 635 | delayMicroseconds(100); 636 | } 637 | //-------------------------------[end]------------------------------------------ 638 | 639 | //-------------------------[tx_payload_burst]----------------------------------- 640 | uint8_t CC1100::tx_payload_burst(uint8_t my_addr, uint8_t rx_addr, 641 | uint8_t *txbuffer, uint8_t length) 642 | { 643 | txbuffer[0] = length-1; 644 | txbuffer[1] = rx_addr; 645 | txbuffer[2] = my_addr; 646 | 647 | spi_write_burst(TXFIFO_BURST,txbuffer,length); //writes TX_Buffer +1 because of pktlen must be also transfered 648 | 649 | if(debug_level > 0){ 650 | Serial.print(F("TX_FIFO:")); 651 | for(uint8_t i = 0 ; i < length; i++) //TX_fifo debug out 652 | { 653 | uart_puthex_byte(txbuffer[i]); 654 | } 655 | Serial.println(); 656 | } 657 | return TRUE; 658 | } 659 | //-------------------------------[end]------------------------------------------ 660 | 661 | //------------------[rx_payload_burst - package received]----------------------- 662 | uint8_t CC1100::rx_payload_burst(uint8_t rxbuffer[], uint8_t &pktlen) 663 | { 664 | uint8_t bytes_in_RXFIFO = 0; 665 | uint8_t res = 0; 666 | 667 | bytes_in_RXFIFO = spi_read_register(RXBYTES); //reads the number of bytes in RXFIFO 668 | 669 | if((bytes_in_RXFIFO & 0x7F) && !(bytes_in_RXFIFO & 0x80)) //if bytes in buffer and no RX Overflow 670 | { 671 | spi_read_burst(RXFIFO_BURST, rxbuffer, bytes_in_RXFIFO); 672 | pktlen = rxbuffer[0]; 673 | res = TRUE; 674 | } 675 | else 676 | { 677 | if(debug_level > 0){ 678 | Serial.print(F("no bytes in RX buffer or RX Overflow!: "));Serial.println(bytes_in_RXFIFO); 679 | } 680 | sidle(); //set to IDLE 681 | spi_write_strobe(SFRX);delayMicroseconds(100); //flush RX Buffer 682 | receive(); //set to receive mode 683 | res = FALSE; 684 | } 685 | 686 | return res; 687 | } 688 | //-------------------------------[end]------------------------------------------ 689 | 690 | //---------------------------[sent packet]-------------------------------------- 691 | uint8_t CC1100::sent_packet(uint8_t my_addr, uint8_t rx_addr, uint8_t *txbuffer, 692 | uint8_t pktlen, uint8_t tx_retries) 693 | { 694 | uint8_t pktlen_ack; //default package len for ACK 695 | uint8_t rxbuffer[FIFOBUFFER]; 696 | uint8_t tx_retries_count = 0; 697 | uint8_t from_sender; 698 | uint16_t ackWaitCounter = 0; 699 | 700 | if(pktlen > (FIFOBUFFER - 1)) //FIFO overflow check 701 | { 702 | printf("ERROR: package size overflow\r\n"); 703 | return FALSE; 704 | } 705 | 706 | do //sent package out with retries 707 | { 708 | tx_payload_burst(my_addr, rx_addr, txbuffer, pktlen); //loads the data in cc1100 buffer 709 | transmit(); //sents data over air 710 | receive(); //receive mode 711 | 712 | if(rx_addr == BROADCAST_ADDRESS){ //no wait acknowledge if sent to broadcast address or tx_retries = 0 713 | return TRUE; //successful sent to BROADCAST_ADDRESS 714 | } 715 | 716 | while (ackWaitCounter < ACK_TIMEOUT ) //wait for an acknowledge 717 | { 718 | if (packet_available() == TRUE) //if RF package received check package acknowge 719 | { 720 | from_sender = rx_addr; //the original message sender address 721 | rx_fifo_erase(rxbuffer); //erase RX software buffer 722 | rx_payload_burst(rxbuffer, pktlen_ack); //reads package in buffer 723 | check_acknowledge(rxbuffer, pktlen_ack, from_sender, my_addr); //check if received message is an acknowledge from client 724 | return TRUE; //package successfully sent 725 | } 726 | else{ 727 | ackWaitCounter++; //increment ACK wait counter 728 | delay(1); //delay to give receiver time 729 | } 730 | } 731 | 732 | ackWaitCounter = 0; //resets the ACK_Timeout 733 | tx_retries_count++; //increase tx retry counter 734 | 735 | if(debug_level > 0){ //debug output messages 736 | Serial.print(F(" #:")); 737 | uart_puthex_byte(tx_retries_count-1); 738 | Serial.println(); 739 | } 740 | }while(tx_retries_count <= tx_retries); //while count of retries is reaches 741 | 742 | return FALSE; //sent failed. too many retries 743 | } 744 | //-------------------------------[end]------------------------------------------ 745 | 746 | //--------------------------[sent ACKNOWLEDGE]------------------------------------ 747 | void CC1100::sent_acknowledge(uint8_t my_addr, uint8_t tx_addr) 748 | { 749 | uint8_t pktlen = 0x06; //complete Pktlen for ACK packet 750 | uint8_t tx_buffer[0x06]; //tx buffer array init 751 | 752 | tx_buffer[3] = 'A'; tx_buffer[4] = 'c'; tx_buffer[5] = 'k'; //fill buffer with ACK Payload 753 | 754 | tx_payload_burst(my_addr, tx_addr, tx_buffer, pktlen); //load payload to CC1100 755 | transmit(); //sent package over the air 756 | receive(); //set CC1100 in receive mode 757 | 758 | if(debug_level > 0){ //debut output 759 | Serial.println(F("Ack_sent!")); 760 | } 761 | } 762 | //-------------------------------[end]------------------------------------------ 763 | //----------------------[check if Packet is received]--------------------------- 764 | uint8_t CC1100::packet_available() 765 | { 766 | if(digitalRead(GDO2) == TRUE) //if RF package received 767 | { 768 | if(spi_read_register(IOCFG2) == 0x06) //if sync word detect mode is used 769 | { 770 | while(digitalRead(GDO2) == TRUE){ //wait till sync word is fully received 771 | Serial.println(F("!")); 772 | } 773 | } 774 | 775 | if(debug_level > 0){ 776 | //Serial.println("Pkt->:"); 777 | } 778 | return TRUE; 779 | } 780 | return FALSE; 781 | } 782 | //-------------------------------[end]------------------------------------------ 783 | 784 | //------------------[check Payload for ACK or Data]----------------------------- 785 | uint8_t CC1100::get_payload(uint8_t rxbuffer[], uint8_t &pktlen, uint8_t &my_addr, 786 | uint8_t &sender, int8_t &rssi_dbm, uint8_t &lqi) 787 | { 788 | uint8_t crc; 789 | 790 | rx_fifo_erase(rxbuffer); //delete rx_fifo bufffer 791 | 792 | if(rx_payload_burst(rxbuffer, pktlen) == FALSE) //read package in buffer 793 | { 794 | rx_fifo_erase(rxbuffer); //delete rx_fifo bufffer 795 | return FALSE; //exit 796 | } 797 | else 798 | { 799 | my_addr = rxbuffer[1]; //set receiver address to my_addr 800 | sender = rxbuffer[2]; 801 | 802 | if(check_acknowledge(rxbuffer, pktlen, sender, my_addr) == TRUE) //acknowlage received? 803 | { 804 | rx_fifo_erase(rxbuffer); //delete rx_fifo bufffer 805 | return FALSE; //Ack received -> finished 806 | } 807 | else //real data, and sent acknowladge 808 | { 809 | rssi_dbm = rssi_convert(rxbuffer[pktlen + 1]); //converts receiver strength to dBm 810 | lqi = lqi_convert(rxbuffer[pktlen + 2]); //get rf quialtiy indicator 811 | crc = check_crc(lqi); //get packet CRC 812 | 813 | if(debug_level > 0){ //debug output messages 814 | if(rxbuffer[1] == BROADCAST_ADDRESS) //if my receiver address is BROADCAST_ADDRESS 815 | { 816 | Serial.println(F("BROADCAST message")); 817 | } 818 | 819 | Serial.print(F("RX_FIFO:")); 820 | for(uint8_t i = 0 ; i < pktlen + 1; i++) //showes rx_buffer for debug 821 | { 822 | uart_puthex_byte(rxbuffer[i]); 823 | } 824 | Serial.print(" |"); 825 | uart_puthex_byte(rxbuffer[pktlen+1]); 826 | uart_puthex_byte(rxbuffer[pktlen+2]); 827 | Serial.print("|"); 828 | Serial.println(); 829 | 830 | Serial.print(F("RSSI:"));uart_puti(rssi_dbm);Serial.print(F(" ")); 831 | Serial.print(F("LQI:"));uart_puthex_byte(lqi);Serial.print(F(" ")); 832 | Serial.print(F("CRC:"));uart_puthex_byte(crc); 833 | Serial.println(); 834 | } 835 | 836 | my_addr = rxbuffer[1]; //set receiver address to my_addr 837 | sender = rxbuffer[2]; //set from_sender address 838 | 839 | if(my_addr != BROADCAST_ADDRESS) //send only ack if no BROADCAST_ADDRESS 840 | { 841 | sent_acknowledge(my_addr, sender); //sending acknowledge to sender! 842 | } 843 | 844 | return TRUE; 845 | } 846 | return FALSE; 847 | } 848 | } 849 | //-------------------------------[end]------------------------------------------ 850 | 851 | //-------------------------[check ACKNOWLEDGE]------------------------------------ 852 | uint8_t CC1100::check_acknowledge(uint8_t *rxbuffer, uint8_t pktlen, uint8_t sender, uint8_t my_addr) 853 | { 854 | int8_t rssi_dbm; 855 | uint8_t crc, lqi; 856 | 857 | if((pktlen == 0x05 && \ 858 | (rxbuffer[1] == my_addr || rxbuffer[1] == BROADCAST_ADDRESS)) && \ 859 | rxbuffer[2] == sender && \ 860 | rxbuffer[3] == 'A' && rxbuffer[4] == 'c' && rxbuffer[5] == 'k') //acknowledge received! 861 | { 862 | if(rxbuffer[1] == BROADCAST_ADDRESS){ //if receiver address BROADCAST_ADDRESS skip acknowledge 863 | if(debug_level > 0){ 864 | Serial.println(F("BROADCAST ACK")); 865 | } 866 | return FALSE; 867 | } 868 | rssi_dbm = rssi_convert(rxbuffer[pktlen + 1]); 869 | lqi = lqi_convert(rxbuffer[pktlen + 2]); 870 | crc = check_crc(lqi); 871 | 872 | if(debug_level > 0){ 873 | //Serial.println(); 874 | Serial.print(F("ACK! ")); 875 | Serial.print(F("RSSI:"));uart_puti(rssi_dbm);Serial.print(F(" ")); 876 | Serial.print(F("LQI:"));uart_puthex_byte(lqi);Serial.print(F(" ")); 877 | Serial.print(F("CRC:"));uart_puthex_byte(crc); 878 | Serial.println(); 879 | } 880 | return TRUE; 881 | } 882 | return FALSE; 883 | } 884 | //-------------------------------[end]------------------------------------------ 885 | 886 | //------------[check if Packet is received within defined time in ms]----------- 887 | uint8_t CC1100::wait_for_packet(uint16_t milliseconds) 888 | { 889 | for(uint16_t i = 0; i < milliseconds; i++) 890 | { 891 | delay(1); //delay till system has data available 892 | if (packet_available()) 893 | { 894 | return TRUE; 895 | } 896 | } 897 | //Serial.println(F("no packet received!")); 898 | return FALSE; 899 | } 900 | //-------------------------------[end]------------------------------------------ 901 | 902 | //--------------------------[tx_fifo_erase]------------------------------------- 903 | void CC1100::tx_fifo_erase(uint8_t *txbuffer) 904 | { 905 | memset(txbuffer, 0, sizeof(FIFOBUFFER)); //erased the TX_fifo array content to "0" 906 | } 907 | //-------------------------------[end]------------------------------------------ 908 | 909 | //--------------------------[rx_fifo_erase]------------------------------------- 910 | void CC1100::rx_fifo_erase(uint8_t *rxbuffer) 911 | { 912 | memset(rxbuffer, 0, sizeof(FIFOBUFFER)); //erased the RX_fifo array content to "0" 913 | } 914 | //-------------------------------[end]------------------------------------------ 915 | 916 | //------------------------[set CC1100 address]---------------------------------- 917 | void CC1100::set_myaddr(uint8_t addr) 918 | { 919 | spi_write_register(ADDR,addr); //stores MyAddr in the CC1100 920 | 921 | if(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_MY_ADDR) != addr) 922 | { 923 | eeprom_write_byte((uint8_t*)EEPROM_ADDRESS_CC1100_MY_ADDR, addr); //writes byte to eeprom 924 | } 925 | } 926 | //-------------------------------[end]------------------------------------------ 927 | 928 | //---------------------------[set channel]-------------------------------------- 929 | void CC1100::set_channel(uint8_t channel) 930 | { 931 | spi_write_register(CHANNR,channel); //stores the new channel # in the CC1100 932 | 933 | if(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_CHANNEL) != channel) 934 | { 935 | eeprom_write_byte((uint8_t*)EEPROM_ADDRESS_CC1100_CHANNEL, channel); //writes byte to eeprom 936 | } 937 | } 938 | //-------------------------------[end]------------------------------------------ 939 | 940 | //-[set modulation mode 1 = GFSK_1_2_kb; 2 = GFSK_38_4_kb; 3 = GFSK_100_kb; 4 = MSK_250_kb; 5 = MSK_500_kb; 6 = OOK_4_8_kb]- 941 | void CC1100::set_mode(uint8_t mode) 942 | { 943 | uint8_t Cfg_reg[CFG_REGISTER]; 944 | 945 | switch (mode) 946 | { 947 | case 0x01: 948 | eeprom_read_block(Cfg_reg,cc1100_GFSK_1_2_kb,CFG_REGISTER); //sets up settings for GFSK 1,2 kbit mode/speed 949 | break; 950 | case 0x02: 951 | eeprom_read_block(Cfg_reg,cc1100_GFSK_38_4_kb,CFG_REGISTER); //sets up settings for GFSK 38,4 kbit mode/speed 952 | break; 953 | case 0x03: 954 | eeprom_read_block(Cfg_reg,cc1100_GFSK_100_kb,CFG_REGISTER); //sets up settings for GFSK 100 kbit mode/speed 955 | break; 956 | case 0x04: 957 | eeprom_read_block(Cfg_reg,cc1100_MSK_250_kb,CFG_REGISTER); //sets up settings for GFSK 38,4 kbit mode/speed 958 | break; 959 | case 0x05: 960 | eeprom_read_block(Cfg_reg,cc1100_MSK_500_kb,CFG_REGISTER); //sets up settings for GFSK 38,4 kbit mode/speed 961 | break; 962 | case 0x06: 963 | eeprom_read_block(Cfg_reg,cc1100_OOK_4_8_kb,CFG_REGISTER); //sets up settings for GFSK 38,4 kbit mode/speed 964 | break; 965 | default: 966 | eeprom_read_block(Cfg_reg,cc1100_GFSK_38_4_kb,CFG_REGISTER); //sets up settings for GFSK 38,4 kbit mode/speed 967 | mode = 0x02; 968 | break; 969 | } 970 | 971 | spi_write_burst(WRITE_BURST,Cfg_reg,CFG_REGISTER); //writes all 47 config register 972 | 973 | if(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_MODE) != mode) 974 | { 975 | eeprom_write_byte((uint8_t*)EEPROM_ADDRESS_CC1100_MODE, mode); //sets the cc1100 frequency 976 | } 977 | } 978 | //-------------------------------[end]------------------------------------------ 979 | 980 | //---------[set ISM Band 1=315MHz; 2=433MHz; 3=868MHz; 4=915MHz]---------------- 981 | void CC1100::set_ISM(uint8_t ism_freq) 982 | { 983 | uint8_t freq2, freq1, freq0; 984 | uint8_t Patable[8]; 985 | 986 | switch (ism_freq) //loads the RF freq which is defined in cc1100_freq_select 987 | { 988 | case 0x01: //315MHz 989 | freq2=0x0C; 990 | freq1=0x1D; 991 | freq0=0x89; 992 | eeprom_read_block(Patable,patable_power_315,8); 993 | break; 994 | case 0x02: //433.92MHz 995 | freq2=0x10; 996 | freq1=0xB0; 997 | freq0=0x71; 998 | eeprom_read_block(Patable,patable_power_433,8); 999 | break; 1000 | case 0x03: //868.3MHz 1001 | freq2=0x21; 1002 | freq1=0x65; 1003 | freq0=0x6A; 1004 | eeprom_read_block(Patable,patable_power_868,8); 1005 | break; 1006 | case 0x04: //915MHz 1007 | freq2=0x23; 1008 | freq1=0x31; 1009 | freq0=0x3B; 1010 | eeprom_read_block(Patable,patable_power_915,8); 1011 | break; 1012 | /* 1013 | case 0x05: //2430MHz 1014 | freq2=0x5D; 1015 | freq1=0x76; 1016 | freq0=0x27; 1017 | eeprom_read_block(Patable,patable_power_2430,8); 1018 | break; 1019 | */ 1020 | default: //default is 868.3MHz 1021 | freq2=0x21; 1022 | freq1=0x65; 1023 | freq0=0x6A; 1024 | eeprom_read_block(Patable,patable_power_868,8); //sets up output power ramp register 1025 | ism_freq = 0x03; 1026 | break; 1027 | } 1028 | 1029 | spi_write_register(FREQ2,freq2); //stores the new freq setting for defined ISM band 1030 | spi_write_register(FREQ1,freq1); 1031 | spi_write_register(FREQ0,freq0); 1032 | 1033 | spi_write_burst(PATABLE_BURST,Patable,8); //writes output power settings to cc1100 1034 | 1035 | if(eeprom_read_byte((const uint8_t*)EEPROM_ADDRESS_CC1100_FREQUENCY) != ism_freq) 1036 | { 1037 | eeprom_write_byte((uint8_t*)EEPROM_ADDRESS_CC1100_FREQUENCY, ism_freq); //selects the cc1100 frequency 1038 | } 1039 | } 1040 | //-------------------------------[end]------------------------------------------ 1041 | 1042 | //--------------------------[set frequency]------------------------------------- 1043 | /* 1044 | void CC1100::set_freq(uint32_t freq) 1045 | { 1046 | 1047 | // this is split into 3 bytes that are written to 3 different registers on the CC1101 1048 | uint32_t reg_freq = freq / (26000000>>16); 1049 | 1050 | uint8_t freq2 = (reg_freq>>16) & 0xFF; // high byte, bits 7..6 are always 0 for this register 1051 | uint8_t freq1 = (reg_freq>>8) & 0xFF; // middle byte 1052 | uint8_t freq0 = reg_freq & 0xFF; // low byte 1053 | 1054 | Serial.print(F("FREQ2:"));Serial.println(freq2); 1055 | Serial.print(F("FREQ1:"));Serial.println(freq1); 1056 | Serial.print(F("FREQ0:"));Serial.println(freq0); 1057 | 1058 | spi_write_register(FREQ2,freq2); //stores the new freq setting for defined ISM band 1059 | spi_write_register(FREQ1,freq1); 1060 | spi_write_register(FREQ0,freq0); 1061 | 1062 | } 1063 | */ 1064 | //-------------------------------[end]------------------------------------------ 1065 | 1066 | //---------------------------[set PATABLE]-------------------------------------- 1067 | void CC1100::set_patable(uint8_t *patable_arr) 1068 | { 1069 | spi_write_burst(PATABLE_BURST,patable_arr,8); //writes output power settings to cc1100 "104us" 1070 | } 1071 | //-------------------------------[end]------------------------------------------ 1072 | 1073 | //-------------------------[set output power]----------------------------------- 1074 | void CC1100::set_output_power_level(int8_t dBm) 1075 | { 1076 | uint8_t pa = 0xC0; 1077 | 1078 | if (dBm <= -30) pa = 0x00; 1079 | else if (dBm <= -20) pa = 0x01; 1080 | else if (dBm <= -15) pa = 0x02; 1081 | else if (dBm <= -10) pa = 0x03; 1082 | else if (dBm <= 0) pa = 0x04; 1083 | else if (dBm <= 5) pa = 0x05; 1084 | else if (dBm <= 7) pa = 0x06; 1085 | else if (dBm <= 10) pa = 0x07; 1086 | 1087 | spi_write_register(FREND0,pa); 1088 | } 1089 | //-------------------------------[end]------------------------------------------ 1090 | 1091 | //-------[set Modulation type 2-FSK=0; GFSK=1; ASK/OOK=3; 4-FSK=4; MSK=7]------ 1092 | void CC1100::set_modulation_type(uint8_t cfg) 1093 | { 1094 | uint8_t data; 1095 | data = spi_read_register(MDMCFG2); 1096 | data = (data & 0x8F) | (((cfg) << 4) & 0x70); 1097 | spi_write_register(MDMCFG2, data); 1098 | //printf("MDMCFG2: 0x%02X\n", data); 1099 | } 1100 | //-------------------------------[end]----------------------------------------- 1101 | 1102 | //------------------------[set preamble Len]----------------------------------- 1103 | void CC1100::set_preamble_len(uint8_t cfg) 1104 | { 1105 | uint8_t data; 1106 | data = spi_read_register(MDMCFG1); 1107 | data = (data & 0x8F) | (((cfg) << 4) & 0x70); 1108 | spi_write_register(MDMCFG1, data); 1109 | //printf("MDMCFG2: 0x%02X\n", data); 1110 | } 1111 | //-------------------------------[end]----------------------------------------- 1112 | 1113 | //-------------------[set modem datarate and deviant]-------------------------- 1114 | void CC1100::set_datarate(uint8_t mdmcfg4, uint8_t mdmcfg3, uint8_t deviant) 1115 | { 1116 | spi_write_register(MDMCFG4, mdmcfg4); 1117 | spi_write_register(MDMCFG3, mdmcfg3); 1118 | spi_write_register(DEVIATN, deviant); 1119 | } 1120 | //-------------------------------[end]----------------------------------------- 1121 | 1122 | //----------------------[set sync mode no sync=0;]----------------------------- 1123 | void CC1100::set_sync_mode(uint8_t cfg) 1124 | { 1125 | uint8_t data; 1126 | data = spi_read_register(MDMCFG2); 1127 | data = (data & 0xF8) | (cfg & 0x07); 1128 | spi_write_register(MDMCFG2, data); 1129 | //printf("MDMCFG2: 0x%02X\n", data); 1130 | } 1131 | //-------------------------------[end]----------------------------------------- 1132 | 1133 | //---------------[set FEC ON=TRUE; OFF=FALSE]---------------------------------- 1134 | void CC1100::set_fec(uint8_t cfg) 1135 | { 1136 | uint8_t data; 1137 | data = spi_read_register(MDMCFG1); 1138 | data = (data & 0x7F) | (((cfg) << 7) & 0x80); 1139 | spi_write_register(MDMCFG1, data); 1140 | printf("MDMCFG1: 0x%02X\n", data); 1141 | } 1142 | //-------------------------------[end]------------------------------------------ 1143 | 1144 | //---------------[set data_whitening ON=TRUE; OFF=FALSE]------------------------ 1145 | void CC1100::set_data_whitening(uint8_t cfg) 1146 | { 1147 | uint8_t data; 1148 | data = spi_read_register(PKTCTRL0); 1149 | data = (data & 0xBF) | (((cfg) << 6) & 0x40); 1150 | spi_write_register(PKTCTRL0, data); 1151 | //printf("PKTCTRL0: 0x%02X\n", data); 1152 | } 1153 | //-------------------------------[end]----------------------------------------- 1154 | 1155 | //------------[set manchester encoding ON=TRUE; OFF=FALSE]--------------------- 1156 | void CC1100::set_manchester_encoding(uint8_t cfg) 1157 | { 1158 | uint8_t data; 1159 | data = spi_read_register(MDMCFG2); 1160 | data = (data & 0xF7) | (((cfg) << 3) & 0x08); 1161 | spi_write_register(MDMCFG2, data); 1162 | //printf("MDMCFG2: 0x%02X\n", data); 1163 | } 1164 | //-------------------------------[end]------------------------------------------ 1165 | 1166 | //--------------------------[rssi_convert]-------------------------------------- 1167 | int8_t CC1100::rssi_convert(uint8_t Rssi_hex) 1168 | { 1169 | int8_t rssi_dbm; 1170 | int16_t Rssi_dec; 1171 | 1172 | Rssi_dec = Rssi_hex; //convert unsigned to signed 1173 | 1174 | if(Rssi_dec >= 128){ 1175 | rssi_dbm=((Rssi_dec-256)/2)-RSSI_OFFSET_868MHZ; 1176 | } 1177 | else{ 1178 | if(Rssi_dec<128){ 1179 | rssi_dbm=((Rssi_dec)/2)-RSSI_OFFSET_868MHZ; 1180 | } 1181 | } 1182 | return rssi_dbm; 1183 | } 1184 | //-------------------------------[end]------------------------------------------ 1185 | 1186 | //----------------------------[lqi convert]------------------------------------- 1187 | uint8_t CC1100::lqi_convert(uint8_t lqi) 1188 | { 1189 | return (lqi & 0x7F); 1190 | } 1191 | //-------------------------------[end]------------------------------------------ 1192 | 1193 | //----------------------------[check crc]--------------------------------------- 1194 | uint8_t CC1100::check_crc(uint8_t lqi) 1195 | { 1196 | return (lqi & 0x80); 1197 | } 1198 | //-------------------------------[end]------------------------------------------ 1199 | 1200 | //----------------------------[get temp]---------------------------------------- 1201 | uint8_t CC1100::get_temp(uint8_t *ptemp_Arr) 1202 | { 1203 | const uint8_t num_samples = 8; 1204 | uint16_t adc_result = 0; 1205 | uint32_t temperature = 0; 1206 | 1207 | sidle(); //sets CC1100 into IDLE 1208 | spi_write_register(PTEST,0xBF); //enable temp sensor 1209 | delay(50); //wait a bit 1210 | 1211 | for(uint8_t i=0;i 0){ 1225 | Serial.print(F("Temp:"));Serial.print(ptemp_Arr[0]);Serial.print(F("."));Serial.println(ptemp_Arr[1]); 1226 | } 1227 | 1228 | spi_write_register(PTEST,0x7F); //writes 0x7F back to PTest (app. note) 1229 | 1230 | receive(); 1231 | return (*ptemp_Arr); 1232 | } 1233 | //-------------------------------[end]------------------------------------------ 1234 | 1235 | //|==================== SPI Initialisation for CC1100 =========================| 1236 | void CC1100::spi_begin(void) 1237 | { 1238 | pinMode(SCK_PIN, OUTPUT); 1239 | pinMode(MOSI_PIN, OUTPUT); 1240 | pinMode(MISO_PIN, INPUT); 1241 | pinMode(SS_PIN, OUTPUT); 1242 | 1243 | //|--- Aktivieren des SPI Master Interfaces, fosc = fclk / x --------| 1244 | /* 1245 | Spi prescaler: 1246 | SPI2X SPR1 SPR0 1247 | 0 0 0 fosc/4 1248 | 0 0 1 fosc/16 1249 | 0 1 0 fosc/64 1250 | 0 1 1 fosc/128 1251 | 1 0 0 fosc/2 1252 | 1 0 1 fosc/8 1253 | 1 1 0 fosc/32 1254 | 1 1 1 fosc/64 1255 | */ 1256 | SPCR = ((1< 1375 | Don't blame P. Fleury if it doesn't work ;-) 1376 | *******************************************************************************/ 1377 | void CC1100::uart_puthex_nibble(const unsigned char b) 1378 | { 1379 | unsigned char c = b & 0x0f; 1380 | if (c>9) c += 'A'-10; 1381 | else c += '0'; 1382 | Serial.write(c); //uart_putc replaced to Serial.write 1383 | } /* uart_puthex_nibble */ 1384 | 1385 | /******************************************************************************* 1386 | Function: uart_puthex_byte() 1387 | Purpose: transmit upper and lower nibble as ASCII-hex to UART 1388 | Input: byte value 1389 | Returns: none 1390 | This functions has been added by Martin Thomas 1391 | Don't blame P. Fleury if it doesn't work ;-) 1392 | *******************************************************************************/ 1393 | void CC1100::uart_puthex_byte(const unsigned char b) 1394 | { 1395 | uart_puthex_nibble(b>>4); 1396 | uart_puthex_nibble(b); 1397 | } /* uart_puthex_byte */ 1398 | 1399 | /******************************************************************************* 1400 | Function: uart_puti() 1401 | Purpose: transmit integer as ASCII to UART 1402 | Input: integer value 1403 | Returns: none 1404 | This functions has been added by Martin Thomas 1405 | Don't blame P. Fleury if it doesn't work ;-) 1406 | *******************************************************************************/ 1407 | void CC1100::uart_puti(const int val) 1408 | { 1409 | char buffer[sizeof(int)*8+1]; 1410 | Serial.print(itoa(val, buffer, 10)); //uart_puts replaced to Serial.print 1411 | 1412 | }/* uart_puti */ 1413 | //|================================= END ======================================| 1414 | -------------------------------------------------------------------------------- /cc1100_arduino.h: -------------------------------------------------------------------------------- 1 | #ifndef cc1100_H 2 | #define cc1100_H 3 | 4 | #include 5 | 6 | /*----------------------------------[standard]--------------------------------*/ 7 | #define TRUE 1 8 | #define FALSE 0 9 | 10 | //|=====================[ setting EEPROM addresses]============================= 11 | #define EEPROM_ADDRESS_CC1100_FREQUENCY 0x1F4 //ISM band 12 | #define EEPROM_ADDRESS_CC1100_MODE 0x1F5 //modulation mode 13 | #define EEPROM_ADDRESS_CC1100_MY_ADDR 0x1F6 //receiver address 14 | #define EEPROM_ADDRESS_CC1100_CHANNEL 0x1F7 //channel number 15 | 16 | //**************************** pins ******************************************// 17 | #define SCK_PIN 13 18 | #define MISO_PIN 12 19 | #define MOSI_PIN 11 20 | #define SS_PIN 10 21 | #define GDO2 3 //2 main, 5 remote, 3 M16 22 | #define GDO0 99 23 | 24 | /*----------------------[CC1100 - misc]---------------------------------------*/ 25 | #define CRYSTAL_FREQUENCY 26000000 26 | #define CFG_REGISTER 0x2F //47 registers 27 | #define FIFOBUFFER 0x42 //size of Fifo Buffer 28 | #define RSSI_OFFSET_868MHZ 0x4E //dec = 74 29 | #define TX_RETRIES_MAX 0x05 //tx_retries_max 30 | #define ACK_TIMEOUT 200 //ACK timeout in ms 31 | #define CC1100_COMPARE_REGISTER 0x00 //register compare 0=no compare 1=compare 32 | #define BROADCAST_ADDRESS 0x00 //broadcast address 33 | #define CC1100_FREQ_315MHZ 0x01 34 | #define CC1100_FREQ_434MHZ 0x02 35 | #define CC1100_FREQ_868MHZ 0x03 36 | #define CC1100_FREQ_915MHZ 0x04 37 | #define CC1100_FREQ_2430MHZ 0x05 38 | #define CC1100_TEMP_ADC_MV 3.225 //3.3V/1023 . mV pro digit 39 | #define CC1100_TEMP_CELS_CO 2.47 //Temperature coefficient 2.47mV per Grad Celsius 40 | 41 | /*---------------------------[CC1100 - R/W offsets]---------------------------*/ 42 | #define WRITE_SINGLE_BYTE 0x00 43 | #define WRITE_BURST 0x40 44 | #define READ_SINGLE_BYTE 0x80 45 | #define READ_BURST 0xC0 46 | /*---------------------------[END R/W offsets]--------------------------------*/ 47 | 48 | /*------------------------[CC1100 - FIFO commands]----------------------------*/ 49 | #define TXFIFO_BURST 0x7F //write burst only 50 | #define TXFIFO_SINGLE_BYTE 0x3F //write single only 51 | #define RXFIFO_BURST 0xFF //read burst only 52 | #define RXFIFO_SINGLE_BYTE 0xBF //read single only 53 | #define PATABLE_BURST 0x7E //power control read/write 54 | #define PATABLE_SINGLE_BYTE 0xFE //power control read/write 55 | /*---------------------------[END FIFO commands]------------------------------*/ 56 | 57 | /*----------------------[CC1100 - config register]----------------------------*/ 58 | #define IOCFG2 0x00 // GDO2 output pin configuration 59 | #define IOCFG1 0x01 // GDO1 output pin configuration 60 | #define IOCFG0 0x02 // GDO0 output pin configuration 61 | #define FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds 62 | #define SYNC1 0x04 // Sync word, high byte 63 | #define SYNC0 0x05 // Sync word, low byte 64 | #define PKTLEN 0x06 // Packet length 65 | #define PKTCTRL1 0x07 // Packet automation control 66 | #define PKTCTRL0 0x08 // Packet automation control 67 | #define ADDR 0x09 // Device address 68 | #define CHANNR 0x0A // Channel number 69 | #define FSCTRL1 0x0B // Frequency synthesizer control 70 | #define FSCTRL0 0x0C // Frequency synthesizer control 71 | #define FREQ2 0x0D // Frequency control word, high byte 72 | #define FREQ1 0x0E // Frequency control word, middle byte 73 | #define FREQ0 0x0F // Frequency control word, low byte 74 | #define MDMCFG4 0x10 // Modem configuration 75 | #define MDMCFG3 0x11 // Modem configuration 76 | #define MDMCFG2 0x12 // Modem configuration 77 | #define MDMCFG1 0x13 // Modem configuration 78 | #define MDMCFG0 0x14 // Modem configuration 79 | #define DEVIATN 0x15 // Modem deviation setting 80 | #define MCSM2 0x16 // Main Radio Cntrl State Machine config 81 | #define MCSM1 0x17 // Main Radio Cntrl State Machine config 82 | #define MCSM0 0x18 // Main Radio Cntrl State Machine config 83 | #define FOCCFG 0x19 // Frequency Offset Compensation config 84 | #define BSCFG 0x1A // Bit Synchronization configuration 85 | #define AGCCTRL2 0x1B // AGC control 86 | #define AGCCTRL1 0x1C // AGC control 87 | #define AGCCTRL0 0x1D // AGC control 88 | #define WOREVT1 0x1E // High byte Event 0 timeout 89 | #define WOREVT0 0x1F // Low byte Event 0 timeout 90 | #define WORCTRL 0x20 // Wake On Radio control 91 | #define FREND1 0x21 // Front end RX configuration 92 | #define FREND0 0x22 // Front end TX configuration 93 | #define FSCAL3 0x23 // Frequency synthesizer calibration 94 | #define FSCAL2 0x24 // Frequency synthesizer calibration 95 | #define FSCAL1 0x25 // Frequency synthesizer calibration 96 | #define FSCAL0 0x26 // Frequency synthesizer calibration 97 | #define RCCTRL1 0x27 // RC oscillator configuration 98 | #define RCCTRL0 0x28 // RC oscillator configuration 99 | #define FSTEST 0x29 // Frequency synthesizer cal control 100 | #define PTEST 0x2A // Production test 101 | #define AGCTEST 0x2B // AGC test 102 | #define TEST2 0x2C // Various test settings 103 | #define TEST1 0x2D // Various test settings 104 | #define TEST0 0x2E // Various test settings 105 | /*-------------------------[END config register]------------------------------*/ 106 | 107 | /*------------------------[CC1100-command strobes]----------------------------*/ 108 | #define SRES 0x30 // Reset chip 109 | #define SFSTXON 0x31 // Enable/calibrate freq synthesizer 110 | #define SXOFF 0x32 // Turn off crystal oscillator. 111 | #define SCAL 0x33 // Calibrate freq synthesizer & disable 112 | #define SRX 0x34 // Enable RX. 113 | #define STX 0x35 // Enable TX. 114 | #define SIDLE 0x36 // Exit RX / TX 115 | #define SAFC 0x37 // AFC adjustment of freq synthesizer 116 | #define SWOR 0x38 // Start automatic RX polling sequence 117 | #define SPWD 0x39 // Enter pwr down mode when CSn goes hi 118 | #define SFRX 0x3A // Flush the RX FIFO buffer. 119 | #define SFTX 0x3B // Flush the TX FIFO buffer. 120 | #define SWORRST 0x3C // Reset real time clock. 121 | #define SNOP 0x3D // No operation. 122 | /*-------------------------[END command strobes]------------------------------*/ 123 | 124 | /*----------------------[CC1100 - status register]----------------------------*/ 125 | #define PARTNUM 0xF0 // Part number 126 | #define VERSION 0xF1 // Current version number 127 | #define FREQEST 0xF2 // Frequency offset estimate 128 | #define LQI 0xF3 // Demodulator estimate for link quality 129 | #define RSSI 0xF4 // Received signal strength indication 130 | #define MARCSTATE 0xF5 // Control state machine state 131 | #define WORTIME1 0xF6 // High byte of WOR timer 132 | #define WORTIME0 0xF7 // Low byte of WOR timer 133 | #define PKTSTATUS 0xF8 // Current GDOx status and packet status 134 | #define VCO_VC_DAC 0xF9 // Current setting from PLL cal module 135 | #define TXBYTES 0xFA // Underflow and # of bytes in TXFIFO 136 | #define RXBYTES 0xFB // Overflow and # of bytes in RXFIFO 137 | #define RCCTRL1_STATUS 0xFC //Last RC Oscillator Calibration Result 138 | #define RCCTRL0_STATUS 0xFD //Last RC Oscillator Calibration Result 139 | //--------------------------[END status register]------------------------------- 140 | 141 | class CC1100 142 | { 143 | private: 144 | 145 | void spi_begin(void); 146 | void spi_end(void); 147 | uint8_t spi_putc(uint8_t data); 148 | 149 | public: 150 | uint8_t debug_level; 151 | 152 | uint8_t set_debug_level(uint8_t set_debug_level); 153 | uint8_t get_debug_level(void); 154 | 155 | uint8_t begin(volatile uint8_t &My_addr); 156 | void end(void); 157 | 158 | void spi_write_strobe(uint8_t spi_instr); 159 | void spi_write_register(uint8_t spi_instr, uint8_t value); 160 | void spi_write_burst(uint8_t spi_instr, uint8_t *pArr, uint8_t length); 161 | void spi_read_burst(uint8_t spi_instr, uint8_t *pArr, uint8_t length); 162 | uint8_t spi_read_register(uint8_t spi_instr); 163 | uint8_t spi_read_status(uint8_t spi_instr); 164 | 165 | void reset(void); 166 | void wakeup(void); 167 | void powerdown(void); 168 | 169 | void wor_enable(void); 170 | void wor_disable(void); 171 | void wor_reset(void); 172 | 173 | uint8_t sidle(void); 174 | uint8_t transmit(void); 175 | uint8_t receive(void); 176 | 177 | void show_register_settings(void); 178 | void show_main_settings(void); 179 | 180 | uint8_t packet_available(); 181 | uint8_t wait_for_packet(uint16_t milliseconds); 182 | 183 | uint8_t get_payload(uint8_t rxbuffer[], uint8_t &pktlen_rx,uint8_t &my_addr, 184 | uint8_t &sender, int8_t &rssi_dbm, uint8_t &lqi); 185 | 186 | uint8_t tx_payload_burst(uint8_t my_addr, uint8_t rx_addr, uint8_t *txbuffer, uint8_t length); 187 | uint8_t rx_payload_burst(uint8_t rxbuffer[], uint8_t &pktlen); 188 | 189 | void rx_fifo_erase(uint8_t *rxbuffer); 190 | void tx_fifo_erase(uint8_t *txbuffer); 191 | 192 | uint8_t sent_packet(uint8_t my_addr, uint8_t rx_addr, uint8_t *txbuffer, uint8_t pktlen, uint8_t tx_retries); 193 | void sent_acknowledge(uint8_t my_addr, uint8_t tx_addr); 194 | 195 | uint8_t check_acknowledge(uint8_t *rxbuffer, uint8_t pktlen, uint8_t sender, uint8_t my_addr); 196 | 197 | int8_t rssi_convert(uint8_t Rssi); 198 | uint8_t check_crc(uint8_t lqi); 199 | uint8_t lqi_convert(uint8_t lqi); 200 | uint8_t get_temp(uint8_t *ptemp_Arr); 201 | 202 | void set_myaddr(uint8_t addr); 203 | void set_channel(uint8_t channel); 204 | void set_ISM(uint8_t ism_freq); 205 | void set_mode(uint8_t mode); 206 | void set_output_power_level(int8_t dbm); 207 | void set_patable(uint8_t *patable_arr); 208 | void set_fec(uint8_t cfg); 209 | void set_data_whitening(uint8_t cfg); 210 | void set_modulation_type(uint8_t cfg); 211 | void set_preamble_len(uint8_t cfg); 212 | void set_manchester_encoding(uint8_t cfg); 213 | void set_sync_mode(uint8_t cfg); 214 | void set_datarate(uint8_t mdmcfg4, uint8_t mdmcfg3, uint8_t deviant); 215 | 216 | void uart_puthex_nibble(const unsigned char b); 217 | void uart_puthex_byte(const unsigned char b); 218 | void uart_puti(const int val); 219 | 220 | }; 221 | //=======================[CC1100 special functions]============================= 222 | 223 | #endif // CC1100_H 224 | -------------------------------------------------------------------------------- /cc1100_raspi.cpp: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------- 2 | ' CC1100 Raspberry Pi Library 3 | ' --------------------------- 4 | ' 5 | ' 6 | ' 7 | ' 8 | ' 9 | ' module contains helper code from other people. Thx for that 10 | '-----------------------------------------------------------------------------*/ 11 | #include "cc1100_raspi.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | extern uint8_t cc1100_debug; 19 | //-------------------[global default settings 868 Mhz]--------------------------------- 20 | 21 | static uint8_t cc1100_GFSK_1_2_kb[CFG_REGISTER] = { 22 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 23 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 24 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 25 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 26 | 0x57, // SYNC1 Sync Word, High Byte 27 | 0x43, // SYNC0 Sync Word, Low Byte 28 | 0x3E, // PKTLEN Packet Length 29 | 0x0E, // PKTCTRL1 Packet Automation Control 30 | 0x45, // PKTCTRL0 Packet Automation Control 31 | 0xFF, // ADDR Device Address 32 | 0x00, // CHANNR Channel Number 33 | 0x08, // FSCTRL1 Frequency Synthesizer Control 34 | 0x00, // FSCTRL0 Frequency Synthesizer Control 35 | 0x21, // FREQ2 Frequency Control Word, High Byte 36 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 37 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 38 | 0xF5, // MDMCFG4 Modem Configuration 39 | 0x83, // MDMCFG3 Modem Configuration 40 | 0x13, // MDMCFG2 Modem Configuration 41 | 0xA0, // MDMCFG1 Modem Configuration 42 | 0xF8, // MDMCFG0 Modem Configuration 43 | 0x15, // DEVIATN Modem Deviation Setting 44 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 45 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 46 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 47 | 0x16, // FOCCFG Frequency Offset Compensation Configuration 48 | 0x6C, // BSCFG Bit Synchronization Configuration 49 | 0x03, // AGCCTRL2 AGC Control 50 | 0x40, // AGCCTRL1 AGC Control 51 | 0x91, // AGCCTRL0 AGC Control 52 | 0x02, // WOREVT1 High Byte Event0 Timeout 53 | 0x26, // WOREVT0 Low Byte Event0 Timeout 54 | 0x09, // WORCTRL Wake On Radio Control 55 | 0x56, // FREND1 Front End RX Configuration 56 | 0x17, // FREND0 Front End TX Configuration 57 | 0xA9, // FSCAL3 Frequency Synthesizer Calibration 58 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 59 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 60 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 61 | 0x41, // RCCTRL1 RC Oscillator Configuration 62 | 0x00, // RCCTRL0 RC Oscillator Configuration 63 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 64 | 0x7F, // PTEST Production Test 65 | 0x3F, // AGCTEST AGC Test 66 | 0x81, // TEST2 Various Test Settings 67 | 0x3F, // TEST1 Various Test Settings 68 | 0x0B // TEST0 Various Test Settings 69 | }; 70 | 71 | static uint8_t cc1100_GFSK_38_4_kb[CFG_REGISTER] = { 72 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 73 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 74 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 75 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 76 | 0x57, // SYNC1 Sync Word, High Byte 77 | 0x43, // SYNC0 Sync Word, Low Byte 78 | 0x3E, // PKTLEN Packet Length 79 | 0x0E, // PKTCTRL1 Packet Automation Control 80 | 0x45, // PKTCTRL0 Packet Automation Control 81 | 0xFF, // ADDR Device Address 82 | 0x00, // CHANNR Channel Number 83 | 0x06, // FSCTRL1 Frequency Synthesizer Control 84 | 0x00, // FSCTRL0 Frequency Synthesizer Control 85 | 0x21, // FREQ2 Frequency Control Word, High Byte 86 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 87 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 88 | 0xCA, // MDMCFG4 Modem Configuration 89 | 0x83, // MDMCFG3 Modem Configuration 90 | 0x13, // MDMCFG2 Modem Configuration 91 | 0xA0, // MDMCFG1 Modem Configuration 92 | 0xF8, // MDMCFG0 Modem Configuration 93 | 0x34, // DEVIATN Modem Deviation Setting 94 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 95 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 96 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 97 | 0x16, // FOCCFG Frequency Offset Compensation Configuration 98 | 0x6C, // BSCFG Bit Synchronization Configuration 99 | 0x43, // AGCCTRL2 AGC Control 100 | 0x40, // AGCCTRL1 AGC Control 101 | 0x91, // AGCCTRL0 AGC Control 102 | 0x02, // WOREVT1 High Byte Event0 Timeout 103 | 0x26, // WOREVT0 Low Byte Event0 Timeout 104 | 0x09, // WORCTRL Wake On Radio Control 105 | 0x56, // FREND1 Front End RX Configuration 106 | 0x17, // FREND0 Front End TX Configuration 107 | 0xA9, // FSCAL3 Frequency Synthesizer Calibration 108 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 109 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 110 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 111 | 0x41, // RCCTRL1 RC Oscillator Configuration 112 | 0x00, // RCCTRL0 RC Oscillator Configuration 113 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 114 | 0x7F, // PTEST Production Test 115 | 0x3F, // AGCTEST AGC Test 116 | 0x81, // TEST2 Various Test Settings 117 | 0x3F, // TEST1 Various Test Settings 118 | 0x0B // TEST0 Various Test Settings 119 | }; 120 | 121 | static uint8_t cc1100_GFSK_100_kb[CFG_REGISTER] = { 122 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 123 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 124 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 125 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 126 | 0x57, // SYNC1 Sync Word, High Byte 127 | 0x43, // SYNC0 Sync Word, Low Byte 128 | 0x3E, // PKTLEN Packet Length 129 | 0x0E, // PKTCTRL1 Packet Automation Control 130 | 0x45, // PKTCTRL0 Packet Automation Control 131 | 0xFF, // ADDR Device Address 132 | 0x00, // CHANNR Channel Number 133 | 0x08, // FSCTRL1 Frequency Synthesizer Control 134 | 0x00, // FSCTRL0 Frequency Synthesizer Control 135 | 0x21, // FREQ2 Frequency Control Word, High Byte 136 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 137 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 138 | 0x5B, // MDMCFG4 Modem Configuration 139 | 0xF8, // MDMCFG3 Modem Configuration 140 | 0x13, // MDMCFG2 Modem Configuration 141 | 0xA0, // MDMCFG1 Modem Configuration 142 | 0xF8, // MDMCFG0 Modem Configuration 143 | 0x47, // DEVIATN Modem Deviation Setting 144 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 145 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 146 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 147 | 0x1D, // FOCCFG Frequency Offset Compensation Configuration 148 | 0x1C, // BSCFG Bit Synchronization Configuration 149 | 0xC7, // AGCCTRL2 AGC Control 150 | 0x00, // AGCCTRL1 AGC Control 151 | 0xB2, // AGCCTRL0 AGC Control 152 | 0x02, // WOREVT1 High Byte Event0 Timeout 153 | 0x26, // WOREVT0 Low Byte Event0 Timeout 154 | 0x09, // WORCTRL Wake On Radio Control 155 | 0xB6, // FREND1 Front End RX Configuration 156 | 0x17, // FREND0 Front End TX Configuration 157 | 0xEA, // FSCAL3 Frequency Synthesizer Calibration 158 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 159 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 160 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 161 | 0x41, // RCCTRL1 RC Oscillator Configuration 162 | 0x00, // RCCTRL0 RC Oscillator Configuration 163 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 164 | 0x7F, // PTEST Production Test 165 | 0x3F, // AGCTEST AGC Test 166 | 0x81, // TEST2 Various Test Settings 167 | 0x3F, // TEST1 Various Test Settings 168 | 0x0B // TEST0 Various Test Settings 169 | }; 170 | 171 | static uint8_t cc1100_MSK_250_kb[CFG_REGISTER] = { 172 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 173 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 174 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 175 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 176 | 0x57, // SYNC1 Sync Word, High Byte 177 | 0x43, // SYNC0 Sync Word, Low Byte 178 | 0x3E, // PKTLEN Packet Length 179 | 0x0E, // PKTCTRL1 Packet Automation Control 180 | 0x45, // PKTCTRL0 Packet Automation Control 181 | 0xFF, // ADDR Device Address 182 | 0x00, // CHANNR Channel Number 183 | 0x0B, // FSCTRL1 Frequency Synthesizer Control 184 | 0x00, // FSCTRL0 Frequency Synthesizer Control 185 | 0x21, // FREQ2 Frequency Control Word, High Byte 186 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 187 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 188 | 0x2D, // MDMCFG4 Modem Configuration 189 | 0x3B, // MDMCFG3 Modem Configuration 190 | 0x73, // MDMCFG2 Modem Configuration 191 | 0xA0, // MDMCFG1 Modem Configuration 192 | 0xF8, // MDMCFG0 Modem Configuration 193 | 0x00, // DEVIATN Modem Deviation Setting 194 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 195 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 196 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 197 | 0x1D, // FOCCFG Frequency Offset Compensation Configuration 198 | 0x1C, // BSCFG Bit Synchronization Configuration 199 | 0xC7, // AGCCTRL2 AGC Control 200 | 0x00, // AGCCTRL1 AGC Control 201 | 0xB2, // AGCCTRL0 AGC Control 202 | 0x02, // WOREVT1 High Byte Event0 Timeout 203 | 0x26, // WOREVT0 Low Byte Event0 Timeout 204 | 0x09, // WORCTRL Wake On Radio Control 205 | 0xB6, // FREND1 Front End RX Configuration 206 | 0x17, // FREND0 Front End TX Configuration 207 | 0xEA, // FSCAL3 Frequency Synthesizer Calibration 208 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 209 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 210 | 0x11, // FSCAL0 Frequency Synthesizer Calibration 211 | 0x41, // RCCTRL1 RC Oscillator Configuration 212 | 0x00, // RCCTRL0 RC Oscillator Configuration 213 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 214 | 0x7F, // PTEST Production Test 215 | 0x3F, // AGCTEST AGC Test 216 | 0x81, // TEST2 Various Test Settings 217 | 0x3F, // TEST1 Various Test Settings 218 | 0x0B // TEST0 Various Test Settings 219 | }; 220 | 221 | static uint8_t cc1100_MSK_500_kb[CFG_REGISTER] = { 222 | 0x07, // IOCFG2 GDO2 Output Pin Configuration 223 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 224 | 0x80, // IOCFG0 GDO0 Output Pin Configuration 225 | 0x07, // FIFOTHR RX FIFO and TX FIFO Thresholds 226 | 0x57, // SYNC1 Sync Word, High Byte 227 | 0x43, // SYNC0 Sync Word, Low Byte 228 | 0x3E, // PKTLEN Packet Length 229 | 0x0E, // PKTCTRL1 Packet Automation Control 230 | 0x45, // PKTCTRL0 Packet Automation Control 231 | 0xFF, // ADDR Device Address 232 | 0x00, // CHANNR Channel Number 233 | 0x0C, // FSCTRL1 Frequency Synthesizer Control 234 | 0x00, // FSCTRL0 Frequency Synthesizer Control 235 | 0x21, // FREQ2 Frequency Control Word, High Byte 236 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 237 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 238 | 0x0E, // MDMCFG4 Modem Configuration 239 | 0x3B, // MDMCFG3 Modem Configuration 240 | 0x73, // MDMCFG2 Modem Configuration 241 | 0xA0, // MDMCFG1 Modem Configuration 242 | 0xF8, // MDMCFG0 Modem Configuration 243 | 0x00, // DEVIATN Modem Deviation Setting 244 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 245 | 0x0C, // MCSM1 Main Radio Control State Machine Configuration 246 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 247 | 0x1D, // FOCCFG Frequency Offset Compensation Configuration 248 | 0x1C, // BSCFG Bit Synchronization Configuration 249 | 0xC7, // AGCCTRL2 AGC Control 250 | 0x40, // AGCCTRL1 AGC Control 251 | 0xB2, // AGCCTRL0 AGC Control 252 | 0x02, // WOREVT1 High Byte Event0 Timeout 253 | 0x26, // WOREVT0 Low Byte Event0 Timeout 254 | 0x09, // WORCTRL Wake On Radio Control 255 | 0xB6, // FREND1 Front End RX Configuration 256 | 0x17, // FREND0 Front End TX Configuration 257 | 0xEA, // FSCAL3 Frequency Synthesizer Calibration 258 | 0x0A, // FSCAL2 Frequency Synthesizer Calibration 259 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 260 | 0x19, // FSCAL0 Frequency Synthesizer Calibration 261 | 0x41, // RCCTRL1 RC Oscillator Configuration 262 | 0x00, // RCCTRL0 RC Oscillator Configuration 263 | 0x59, // FSTEST Frequency Synthesizer Calibration Control, 264 | 0x7F, // PTEST Production Test 265 | 0x3F, // AGCTEST AGC Test 266 | 0x81, // TEST2 Various Test Settings 267 | 0x3F, // TEST1 Various Test Settings 268 | 0x0B // TEST0 Various Test Settings 269 | }; 270 | 271 | static uint8_t cc1100_OOK_4_8_kb[CFG_REGISTER] = { 272 | 0x06, // IOCFG2 GDO2 Output Pin Configuration 273 | 0x2E, // IOCFG1 GDO1 Output Pin Configuration 274 | 0x06, // IOCFG0 GDO0 Output Pin Configuration 275 | 0x47, // FIFOTHR RX FIFO and TX FIFO Thresholds 276 | 0x57, // SYNC1 Sync Word, High Byte 277 | 0x43, // SYNC0 Sync Word, Low Byte 278 | 0xFF, // PKTLEN Packet Length 279 | 0x04, // PKTCTRL1 Packet Automation Control 280 | 0x05, // PKTCTRL0 Packet Automation Control 281 | 0x00, // ADDR Device Address 282 | 0x00, // CHANNR Channel Number 283 | 0x06, // FSCTRL1 Frequency Synthesizer Control 284 | 0x00, // FSCTRL0 Frequency Synthesizer Control 285 | 0x21, // FREQ2 Frequency Control Word, High Byte 286 | 0x65, // FREQ1 Frequency Control Word, Middle Byte 287 | 0x6A, // FREQ0 Frequency Control Word, Low Byte 288 | 0x87, // MDMCFG4 Modem Configuration 289 | 0x83, // MDMCFG3 Modem Configuration 290 | 0x3B, // MDMCFG2 Modem Configuration 291 | 0x22, // MDMCFG1 Modem Configuration 292 | 0xF8, // MDMCFG0 Modem Configuration 293 | 0x15, // DEVIATN Modem Deviation Setting 294 | 0x07, // MCSM2 Main Radio Control State Machine Configuration 295 | 0x30, // MCSM1 Main Radio Control State Machine Configuration 296 | 0x18, // MCSM0 Main Radio Control State Machine Configuration 297 | 0x14, // FOCCFG Frequency Offset Compensation Configuration 298 | 0x6C, // BSCFG Bit Synchronization Configuration 299 | 0x07, // AGCCTRL2 AGC Control 300 | 0x00, // AGCCTRL1 AGC Control 301 | 0x92, // AGCCTRL0 AGC Control 302 | 0x87, // WOREVT1 High Byte Event0 Timeout 303 | 0x6B, // WOREVT0 Low Byte Event0 Timeout 304 | 0xFB, // WORCTRL Wake On Radio Control 305 | 0x56, // FREND1 Front End RX Configuration 306 | 0x17, // FREND0 Front End TX Configuration 307 | 0xE9, // FSCAL3 Frequency Synthesizer Calibration 308 | 0x2A, // FSCAL2 Frequency Synthesizer Calibration 309 | 0x00, // FSCAL1 Frequency Synthesizer Calibration 310 | 0x1F, // FSCAL0 Frequency Synthesizer Calibration 311 | 0x41, // RCCTRL1 RC Oscillator Configuration 312 | 0x00, // RCCTRL0 RC Oscillator Configuration 313 | 0x59, // FSTEST Frequency Synthesizer Calibration Control 314 | 0x7F, // PTEST Production Test 315 | 0x3F, // AGCTEST AGC Test 316 | 0x81, // TEST2 Various Test Settings 317 | 0x35, // TEST1 Various Test Settings 318 | 0x09, // TEST0 Various Test Settings 319 | }; 320 | 321 | //Patable index: -30 -20- -15 -10 0 5 7 10 dBm 322 | static uint8_t patable_power_315[8] = {0x17,0x1D,0x26,0x69,0x51,0x86,0xCC,0xC3}; 323 | static uint8_t patable_power_433[8] = {0x6C,0x1C,0x06,0x3A,0x51,0x85,0xC8,0xC0}; 324 | static uint8_t patable_power_868[8] = {0x03,0x17,0x1D,0x26,0x50,0x86,0xCD,0xC0}; 325 | static uint8_t patable_power_915[8] = {0x0B,0x1B,0x6D,0x67,0x50,0x85,0xC9,0xC1}; 326 | //static uint8_t patable_power_2430[8] = {0x44,0x84,0x46,0x55,0xC6,0x6E,0x9A,0xFE}; 327 | 328 | //----------------------------------[END]--------------------------------------- 329 | 330 | //-------------------------[CC1100 reset function]------------------------------ 331 | void CC1100::reset(void) // reset defined in cc1100 datasheet 332 | { 333 | digitalWrite(SS_PIN, LOW); 334 | delayMicroseconds(10); 335 | digitalWrite(SS_PIN, HIGH); 336 | delayMicroseconds(40); 337 | 338 | spi_write_strobe(SRES); 339 | delay(1); 340 | } 341 | //-----------------------------[END]-------------------------------------------- 342 | 343 | //------------------------[set Power Down]-------------------------------------- 344 | void CC1100::powerdown(void) 345 | { 346 | sidle(); 347 | spi_write_strobe(SPWD); // CC1100 Power Down 348 | } 349 | //-----------------------------[end]-------------------------------------------- 350 | 351 | //---------------------------[WakeUp]------------------------------------------- 352 | void CC1100::wakeup(void) 353 | { 354 | digitalWrite(SS_PIN, LOW); 355 | delayMicroseconds(10); 356 | digitalWrite(SS_PIN, HIGH); 357 | delayMicroseconds(10); 358 | receive(); // go to RX Mode 359 | } 360 | //-----------------------------[end]-------------------------------------------- 361 | 362 | //---------------------[CC1100 set debug level]--------------------------------- 363 | uint8_t CC1100::set_debug_level(uint8_t set_debug_level = 1) //default ON 364 | { 365 | debug_level = set_debug_level; //set debug level of CC1101 outputs 366 | 367 | return debug_level; 368 | } 369 | //-----------------------------[end]-------------------------------------------- 370 | 371 | //---------------------[CC1100 get debug level]--------------------------------- 372 | uint8_t CC1100::get_debug_level(void) 373 | { 374 | return debug_level; 375 | } 376 | //-----------------------------[end]-------------------------------------------- 377 | 378 | //----------------------[CC1100 init functions]--------------------------------- 379 | uint8_t CC1100::begin(volatile uint8_t &My_addr) 380 | { 381 | uint8_t partnum, version; 382 | extern int cc1100_freq_select, cc1100_mode_select, cc1100_channel_select; 383 | 384 | pinMode(GDO0, INPUT); //setup AVR GPIO ports 385 | pinMode(GDO2, INPUT); 386 | 387 | set_debug_level(set_debug_level()); //set debug level of CC1101 outputs 388 | 389 | if(debug_level > 0){ 390 | printf("Init CC1100...\r\n"); 391 | } 392 | 393 | spi_begin(); //inits SPI Interface 394 | reset(); //CC1100 init reset 395 | 396 | spi_write_strobe(SFTX);delayMicroseconds(100);//flush the TX_fifo content 397 | spi_write_strobe(SFRX);delayMicroseconds(100);//flush the RX_fifo content 398 | 399 | partnum = spi_read_register(PARTNUM); //reads CC1100 partnumber 400 | version = spi_read_register(VERSION); //reads CC1100 version number 401 | 402 | //checks if valid Chip ID is found. Usualy 0x03 or 0x14. if not -> abort 403 | if(version == 0x00 || version == 0xFF){ 404 | if(debug_level > 0){ 405 | printf("no CC11xx found!\r\n"); 406 | } 407 | return FALSE; 408 | } 409 | 410 | if(debug_level > 0){ 411 | printf("Partnumber: 0x%02X\r\n", partnum); 412 | printf("Version : 0x%02X\r\n", version); 413 | } 414 | 415 | 416 | 417 | 418 | //set modulation mode 419 | set_mode(cc1100_mode_select); 420 | 421 | //set ISM band 422 | set_ISM(cc1100_freq_select); 423 | 424 | //set channel 425 | set_channel(cc1100_channel_select); 426 | 427 | //set output power amplifier 428 | set_output_power_level(0); //set PA to 0dBm as default 429 | 430 | //set my receiver address 431 | set_myaddr(My_addr); //My_Addr from EEPROM to global variable 432 | 433 | if(debug_level > 0){ 434 | printf("...done!\r\n"); 435 | } 436 | 437 | receive(); //set CC1100 in receive mode 438 | 439 | return TRUE; 440 | } 441 | //-------------------------------[end]------------------------------------------ 442 | 443 | //-----------------[finish's the CC1100 operation]------------------------------ 444 | void CC1100::end(void) 445 | { 446 | powerdown(); //power down CC1100 447 | } 448 | //-------------------------------[end]------------------------------------------ 449 | 450 | //-----------------------[show all CC1100 registers]---------------------------- 451 | void CC1100::show_register_settings(void) 452 | { 453 | if(debug_level > 0){ 454 | uint8_t config_reg_verify[CFG_REGISTER],Patable_verify[CFG_REGISTER]; 455 | 456 | spi_read_burst(READ_BURST,config_reg_verify,CFG_REGISTER); //reads all 47 config register from cc1100 457 | spi_read_burst(PATABLE_BURST,Patable_verify,8); //reads output power settings from cc1100 458 | 459 | //show_main_settings(); 460 | printf("Config Register:\r\n"); 461 | 462 | for(uint8_t i = 0 ; i < CFG_REGISTER; i++) //showes rx_buffer for debug 463 | { 464 | printf("0x%02X ", config_reg_verify[i]); 465 | if(i==9 || i==19 || i==29 || i==39) //just for beautiful output style 466 | { 467 | printf("\r\n"); 468 | } 469 | } 470 | printf("\r\n"); 471 | printf("PaTable:\r\n"); 472 | 473 | for(uint8_t i = 0 ; i < 8; i++) //showes rx_buffer for debug 474 | { 475 | printf("0x%02X ", Patable_verify[i]); 476 | } 477 | printf("\r\n"); 478 | } 479 | } 480 | //-------------------------------[end]------------------------------------------ 481 | 482 | //--------------------------[show settings]------------------------------------- 483 | void CC1100::show_main_settings(void) 484 | { 485 | extern volatile uint8_t My_addr; 486 | extern int cc1100_mode_select, cc1100_freq_select, cc1100_channel_select; 487 | 488 | printf("Mode: %d\r\n", cc1100_mode_select); 489 | printf("Frequency: %d\r\n", cc1100_freq_select); 490 | printf("Channel: %d\r\n", cc1100_channel_select); 491 | printf("My_Addr: %d\r\n", My_addr); 492 | } 493 | //-------------------------------[end]------------------------------------------ 494 | 495 | //----------------------------[idle mode]--------------------------------------- 496 | uint8_t CC1100::sidle(void) 497 | { 498 | uint8_t marcstate; 499 | 500 | spi_write_strobe(SIDLE); //sets to idle first. must be in 501 | 502 | marcstate = 0xFF; //set unknown/dummy state value 503 | 504 | while(marcstate != 0x01) //0x01 = sidle 505 | { 506 | marcstate = (spi_read_register(MARCSTATE) & 0x1F); //read out state of cc1100 to be sure in RX 507 | //printf("marcstate_rx: 0x%02X\r", marcstate); 508 | } 509 | //Serial.println(); 510 | delayMicroseconds(100); 511 | return TRUE; 512 | } 513 | //-------------------------------[end]------------------------------------------ 514 | 515 | //---------------------------[transmit mode]------------------------------------ 516 | uint8_t CC1100::transmit(void) 517 | { 518 | uint8_t marcstate; 519 | 520 | sidle(); //sets to idle first. 521 | spi_write_strobe(STX); //sends the data over air 522 | 523 | marcstate = 0xFF; //set unknown/dummy state value 524 | 525 | while(marcstate != 0x01) //0x01 = ILDE after sending data 526 | { 527 | marcstate = (spi_read_register(MARCSTATE) & 0x1F); //read out state of cc1100 to be sure in IDLE and TX is finished 528 | //printf("marcstate_tx: 0x%02X ",marcstate); 529 | } 530 | //printf("\r\n"); 531 | delayMicroseconds(100); 532 | return TRUE; 533 | } 534 | ///-------------------------------[end]------------------------------------------ 535 | 536 | //---------------------------[receive mode]------------------------------------- 537 | uint8_t CC1100::receive(void) 538 | { 539 | uint8_t marcstate; 540 | 541 | sidle(); //sets to idle first. 542 | spi_write_strobe(SRX); //writes receive strobe (receive mode) 543 | 544 | marcstate = 0xFF; //set unknown/dummy state value 545 | 546 | while(marcstate != 0x0D) //0x0D = RX 547 | { 548 | marcstate = (spi_read_register(MARCSTATE) & 0x1F); //read out state of cc1100 to be sure in RX 549 | //printf("marcstate_rx: 0x%02X\r", marcstate); 550 | } 551 | //printf("\r\n"); 552 | delayMicroseconds(100); 553 | return TRUE; 554 | } 555 | //-------------------------------[end]------------------------------------------ 556 | 557 | //------------[enables WOR Mode EVENT0 ~1890ms; rx_timeout ~235ms]-------------------- 558 | void CC1100::wor_enable() 559 | { 560 | /* 561 | EVENT1 = WORCTRL[6:4] -> Datasheet page 88 562 | EVENT0 = (750/Xtal)*(WOREVT1<<8+WOREVT0)*2^(5*WOR_RES) = (750/26Meg)*65407*2^(5*0) = 1.89s 563 | 564 | (WOR_RES=0;RX_TIME=0) -> Datasheet page 80 565 | i.E RX_TIMEOUT = EVENT0* (3.6038) *26/26Meg = 235.8ms 566 | (WOR_RES=0;RX_TIME=1) -> Datasheet page 80 567 | i.E.RX_TIMEOUT = EVENT0* (1.8029) *26/26Meg = 117.9ms 568 | */ 569 | sidle(); 570 | 571 | spi_write_register(MCSM0, 0x18); //FS Autocalibration 572 | spi_write_register(MCSM2, 0x01); //MCSM2.RX_TIME = 1b 573 | 574 | // configure EVENT0 time 575 | spi_write_register(WOREVT1, 0xFF); //High byte Event0 timeout 576 | spi_write_register(WOREVT0, 0x7F); //Low byte Event0 timeout 577 | 578 | // configure EVENT1 time 579 | spi_write_register(WORCTRL, 0x78); //WOR_RES=0b; tEVENT1=0111b=48d -> 48*(750/26MHz)= 1.385ms 580 | 581 | spi_write_strobe(SFRX); //flush RX buffer 582 | spi_write_strobe(SWORRST); //resets the WOR timer to the programmed Event 1 583 | spi_write_strobe(SWOR); //put the radio in WOR mode when CSn is released 584 | 585 | delayMicroseconds(100); 586 | } 587 | //-------------------------------[end]------------------------------------------ 588 | 589 | //------------------------[disable WOR Mode]------------------------------------- 590 | void CC1100::wor_disable() 591 | { 592 | sidle(); //exit WOR Mode 593 | spi_write_register(MCSM2, 0x07); //stay in RX. No RX timeout 594 | } 595 | //-------------------------------[end]------------------------------------------ 596 | 597 | //------------------------[resets WOR Timer]------------------------------------ 598 | void CC1100::wor_reset() 599 | { 600 | sidle(); //go to IDLE 601 | spi_write_register(MCSM2, 0x01); //MCSM2.RX_TIME = 1b 602 | spi_write_strobe(SFRX); //flush RX buffer 603 | spi_write_strobe(SWORRST); //resets the WOR timer to the programmed Event 1 604 | spi_write_strobe(SWOR); //put the radio in WOR mode when CSn is released 605 | 606 | delayMicroseconds(100); 607 | } 608 | //-------------------------------[end]------------------------------------------ 609 | 610 | //-------------------------[tx_payload_burst]----------------------------------- 611 | uint8_t CC1100::tx_payload_burst(uint8_t my_addr, uint8_t rx_addr, 612 | uint8_t *txbuffer, uint8_t length) 613 | { 614 | txbuffer[0] = length-1; 615 | txbuffer[1] = rx_addr; 616 | txbuffer[2] = my_addr; 617 | 618 | spi_write_burst(TXFIFO_BURST,txbuffer,length); //writes TX_Buffer +1 because of pktlen must be also transfered 619 | 620 | if(debug_level > 0){ 621 | printf("TX_FIFO: "); 622 | for(uint8_t i = 0 ; i < length; i++) //TX_fifo debug out 623 | { 624 | printf("0x%02X ", txbuffer[i]); 625 | } 626 | printf("\r\n"); 627 | } 628 | return TRUE; 629 | } 630 | //-------------------------------[end]------------------------------------------ 631 | 632 | //------------------[rx_payload_burst - package received]----------------------- 633 | uint8_t CC1100::rx_payload_burst(uint8_t rxbuffer[], uint8_t &pktlen) 634 | { 635 | uint8_t bytes_in_RXFIFO = 0; 636 | uint8_t res = 0; 637 | 638 | bytes_in_RXFIFO = spi_read_register(RXBYTES); //reads the number of bytes in RXFIFO 639 | 640 | if((bytes_in_RXFIFO & 0x7F) && !(bytes_in_RXFIFO & 0x80)) //if bytes in buffer and no RX Overflow 641 | { 642 | spi_read_burst(RXFIFO_BURST, rxbuffer, bytes_in_RXFIFO); 643 | pktlen = rxbuffer[0]; 644 | res = TRUE; 645 | } 646 | else 647 | { 648 | if(debug_level > 0){ 649 | printf("no bytes in RX buffer or RX Overflow!: ");printf("0x%02X \r\n", bytes_in_RXFIFO); 650 | } 651 | sidle(); //set to IDLE 652 | spi_write_strobe(SFRX);delayMicroseconds(100); //flush RX Buffer 653 | receive(); //set to receive mode 654 | res = FALSE; 655 | } 656 | 657 | return res; 658 | } 659 | //-------------------------------[end]------------------------------------------ 660 | 661 | //---------------------------[sent packet]-------------------------------------- 662 | uint8_t CC1100::sent_packet(uint8_t my_addr, uint8_t rx_addr, uint8_t *txbuffer, 663 | uint8_t pktlen, uint8_t tx_retries) 664 | { 665 | uint8_t pktlen_ack, rssi, lqi; //default package len for ACK 666 | uint8_t rxbuffer[FIFOBUFFER]; 667 | uint8_t tx_retries_count = 0; 668 | uint8_t from_sender; 669 | uint16_t ackWaitCounter = 0; 670 | 671 | if(pktlen > (FIFOBUFFER - 1)) 672 | { 673 | printf("ERROR: package size overflow\r\n"); 674 | return FALSE; 675 | } 676 | 677 | do //sent package out with retries 678 | { 679 | tx_payload_burst(my_addr, rx_addr, txbuffer, pktlen); //loads the data in cc1100 buffer 680 | transmit(); //sents data over air 681 | receive(); //receive mode 682 | 683 | if(rx_addr == BROADCAST_ADDRESS){ //no wait acknowledge if sent to broadcast address or tx_retries = 0 684 | return TRUE; //successful sent to BROADCAST_ADDRESS 685 | } 686 | 687 | while (ackWaitCounter < ACK_TIMEOUT ) //wait for an acknowledge 688 | { 689 | if (packet_available() == TRUE) //if RF package received check package acknowge 690 | { 691 | from_sender = rx_addr; //the original message sender address 692 | rx_fifo_erase(rxbuffer); //erase RX software buffer 693 | rx_payload_burst(rxbuffer, pktlen_ack); //reads package in buffer 694 | check_acknowledge(rxbuffer, pktlen_ack, from_sender, my_addr); //check if received message is an acknowledge from client 695 | return TRUE; //package successfully sent 696 | } 697 | else{ 698 | ackWaitCounter++; //increment ACK wait counter 699 | delay(1); //delay to give receiver time 700 | } 701 | } 702 | 703 | ackWaitCounter = 0; //resets the ACK_Timeout 704 | tx_retries_count++; //increase tx retry counter 705 | 706 | if(debug_level > 0){ //debug output messages 707 | printf(" #:"); 708 | printf("0x%02X \r\n", tx_retries_count); 709 | } 710 | }while(tx_retries_count <= tx_retries); //while count of retries is reaches 711 | 712 | return FALSE; //sent failed. too many retries 713 | } 714 | //-------------------------------[end]------------------------------------------ 715 | 716 | //--------------------------[sent ACKNOWLEDGE]------------------------------------ 717 | void CC1100::sent_acknowledge(uint8_t my_addr, uint8_t tx_addr) 718 | { 719 | uint8_t pktlen = 0x06; //complete Pktlen for ACK packet 720 | uint8_t tx_buffer[0x06]; //tx buffer array init 721 | 722 | tx_buffer[3] = 'A'; tx_buffer[4] = 'c'; tx_buffer[5] = 'k'; //fill buffer with ACK Payload 723 | 724 | tx_payload_burst(my_addr, tx_addr, tx_buffer, pktlen); //load payload to CC1100 725 | transmit(); //sent package over the air 726 | receive(); //set CC1100 in receive mode 727 | 728 | if(debug_level > 0){ //debut output 729 | printf("Ack_sent!\r\n"); 730 | } 731 | } 732 | //-------------------------------[end]------------------------------------------ 733 | //----------------------[check if Packet is received]--------------------------- 734 | uint8_t CC1100::packet_available() 735 | { 736 | if(digitalRead(GDO2) == TRUE) //if RF package received 737 | { 738 | if(spi_read_register(IOCFG2) == 0x06) //if sync word detect mode is used 739 | { 740 | while(digitalRead(GDO2) == TRUE){ //wait till sync word is fully received 741 | printf("!\r\n"); 742 | } //for sync word receive 743 | } 744 | 745 | if(debug_level > 0){ 746 | //printf("Pkt->:\r\n"); 747 | } 748 | 749 | return TRUE; 750 | } 751 | return FALSE; 752 | } 753 | //-------------------------------[end]------------------------------------------ 754 | 755 | //------------------[check Payload for ACK or Data]----------------------------- 756 | uint8_t CC1100::get_payload(uint8_t rxbuffer[], uint8_t &pktlen, uint8_t &my_addr, 757 | uint8_t &sender, int8_t &rssi_dbm, uint8_t &lqi) 758 | { 759 | uint8_t crc; 760 | 761 | rx_fifo_erase(rxbuffer); //delete rx_fifo bufffer 762 | 763 | if(rx_payload_burst(rxbuffer, pktlen) == FALSE) //read package in buffer 764 | { 765 | rx_fifo_erase(rxbuffer); //delete rx_fifo bufffer 766 | return FALSE; //exit 767 | } 768 | else 769 | { 770 | my_addr = rxbuffer[1]; //set receiver address to my_addr 771 | sender = rxbuffer[2]; 772 | 773 | if(check_acknowledge(rxbuffer, pktlen, sender, my_addr) == TRUE) //acknowlage received? 774 | { 775 | rx_fifo_erase(rxbuffer); //delete rx_fifo bufffer 776 | return FALSE; //Ack received -> finished 777 | } 778 | else //real data, and sent acknowladge 779 | { 780 | rssi_dbm = rssi_convert(rxbuffer[pktlen + 1]); //converts receiver strength to dBm 781 | lqi = lqi_convert(rxbuffer[pktlen + 2]); //get rf quialtiy indicator 782 | crc = check_crc(lqi); //get packet CRC 783 | 784 | if(debug_level > 0){ //debug output messages 785 | if(rxbuffer[1] == BROADCAST_ADDRESS) //if my receiver address is BROADCAST_ADDRESS 786 | { 787 | printf("BROADCAST message\r\n"); 788 | } 789 | 790 | printf("RX_FIFO:"); 791 | for(uint8_t i = 0 ; i < pktlen + 1; i++) //showes rx_buffer for debug 792 | { 793 | printf("0x%02X ", rxbuffer[i]); 794 | } 795 | printf("| 0x%02X 0x%02X |", rxbuffer[pktlen+1], rxbuffer[pktlen+2]); 796 | printf("\r\n"); 797 | 798 | printf("RSSI:%d ", rssi_dbm); 799 | printf("LQI:");printf("0x%02X ", lqi); 800 | printf("CRC:");printf("0x%02X ", crc); 801 | printf("\r\n"); 802 | } 803 | 804 | my_addr = rxbuffer[1]; //set receiver address to my_addr 805 | sender = rxbuffer[2]; //set from_sender address 806 | 807 | if(my_addr != BROADCAST_ADDRESS) //send only ack if no BROADCAST_ADDRESS 808 | { 809 | sent_acknowledge(my_addr, sender); //sending acknowlage to sender! 810 | } 811 | 812 | return TRUE; 813 | } 814 | return FALSE; 815 | } 816 | } 817 | //-------------------------------[end]------------------------------------------ 818 | 819 | //-------------------------[check ACKNOWLEDGE]------------------------------------ 820 | uint8_t CC1100::check_acknowledge(uint8_t *rxbuffer, uint8_t pktlen, uint8_t sender, uint8_t my_addr) 821 | { 822 | int8_t rssi_dbm; 823 | uint8_t crc, lqi; 824 | 825 | if((pktlen == 0x05 && \ 826 | rxbuffer[1] == my_addr || rxbuffer[1] == BROADCAST_ADDRESS) && \ 827 | rxbuffer[2] == sender && \ 828 | rxbuffer[3] == 'A' && rxbuffer[4] == 'c' && rxbuffer[5] == 'k') //acknowledge received! 829 | { 830 | if(rxbuffer[1] == BROADCAST_ADDRESS){ //if receiver address BROADCAST_ADDRESS skip acknowledge 831 | if(debug_level > 0){ 832 | printf("BROADCAST ACK\r\n"); 833 | } 834 | return FALSE; 835 | } 836 | rssi_dbm = rssi_convert(rxbuffer[pktlen + 1]); 837 | lqi = lqi_convert(rxbuffer[pktlen + 2]); 838 | crc = check_crc(lqi); 839 | 840 | if(debug_level > 0){ 841 | printf("ACK! "); 842 | printf("RSSI:%i ",rssi_dbm); 843 | printf("LQI:0x%02X ",lqi); 844 | printf("CRC:0x%02X\r\n",crc); 845 | } 846 | return TRUE; 847 | } 848 | return FALSE; 849 | } 850 | //-------------------------------[end]------------------------------------------ 851 | 852 | //------------[check if Packet is received within defined time in ms]----------- 853 | uint8_t CC1100::wait_for_packet(uint16_t milliseconds) 854 | { 855 | for(uint16_t i = 0; i < milliseconds; i++) 856 | { 857 | delay(1); //delay till system has data available 858 | if (packet_available()) 859 | { 860 | return TRUE; 861 | } 862 | } 863 | return FALSE; 864 | } 865 | //-------------------------------[end]------------------------------------------ 866 | 867 | //--------------------------[tx_fifo_erase]------------------------------------- 868 | void CC1100::tx_fifo_erase(uint8_t *txbuffer) 869 | { 870 | memset(txbuffer, 0, sizeof(FIFOBUFFER)); //erased the TX_fifo array content to "0" 871 | } 872 | //-------------------------------[end]------------------------------------------ 873 | 874 | //--------------------------[rx_fifo_erase]------------------------------------- 875 | void CC1100::rx_fifo_erase(uint8_t *rxbuffer) 876 | { 877 | memset(rxbuffer, 0, sizeof(FIFOBUFFER)); //erased the RX_fifo array content to "0" 878 | } 879 | //-------------------------------[end]------------------------------------------ 880 | 881 | //------------------------[set CC1100 address]---------------------------------- 882 | void CC1100::set_myaddr(uint8_t addr) 883 | { 884 | spi_write_register(ADDR,addr); //stores MyAddr in the CC1100 885 | } 886 | //-------------------------------[end]------------------------------------------ 887 | 888 | //---------------------------[set channel]-------------------------------------- 889 | void CC1100::set_channel(uint8_t channel) 890 | { 891 | spi_write_register(CHANNR,channel); //stores the new channel # in the CC1100 892 | 893 | return; 894 | } 895 | //-------------------------------[end]------------------------------------------ 896 | 897 | //-[set modulation mode 1 = GFSK_1_2_kb; 2 = GFSK_38_4_kb; 3 = GFSK_100_kb; 4 = MSK_250_kb; 5 = MSK_500_kb; 6 = OOK_4_8_kb]- 898 | void CC1100::set_mode(uint8_t mode) 899 | { 900 | 901 | switch (mode) 902 | { 903 | case 0x01: 904 | spi_write_burst(WRITE_BURST,cc1100_GFSK_1_2_kb,CFG_REGISTER); 905 | break; 906 | case 0x02: 907 | spi_write_burst(WRITE_BURST,cc1100_GFSK_38_4_kb,CFG_REGISTER); 908 | break; 909 | case 0x03: 910 | spi_write_burst(WRITE_BURST,cc1100_GFSK_100_kb,CFG_REGISTER); 911 | break; 912 | case 0x04: 913 | spi_write_burst(WRITE_BURST,cc1100_MSK_250_kb,CFG_REGISTER); 914 | break; 915 | case 0x05: 916 | spi_write_burst(WRITE_BURST,cc1100_MSK_500_kb,CFG_REGISTER); 917 | break; 918 | case 0x06: 919 | spi_write_burst(WRITE_BURST,cc1100_OOK_4_8_kb,CFG_REGISTER); 920 | break; 921 | default: 922 | spi_write_burst(WRITE_BURST,cc1100_GFSK_100_kb,CFG_REGISTER); 923 | break; 924 | } 925 | return; 926 | } 927 | //------------------------------------------end]----------------------------------- 928 | 929 | //---------[set ISM Band 1=315MHz; 2=433MHz; 3=868MHz; 4=915MHz]---------------- 930 | void CC1100::set_ISM(uint8_t ism_freq) 931 | { 932 | uint8_t freq2, freq1, freq0; 933 | 934 | switch (ism_freq) //loads the RF freq which is defined in cc1100_freq_select 935 | { 936 | case 0x01: //315MHz 937 | freq2=0x0C; 938 | freq1=0x1D; 939 | freq0=0x89; 940 | spi_write_burst(PATABLE_BURST,patable_power_315,8); 941 | break; 942 | case 0x02: //433.92MHz 943 | freq2=0x10; 944 | freq1=0xB0; 945 | freq0=0x71; 946 | spi_write_burst(PATABLE_BURST,patable_power_433,8); 947 | break; 948 | case 0x03: //868.3MHz 949 | freq2=0x21; 950 | freq1=0x65; 951 | freq0=0x6A; 952 | spi_write_burst(PATABLE_BURST,patable_power_868,8); 953 | break; 954 | case 0x04: //915MHz 955 | freq2=0x23; 956 | freq1=0x31; 957 | freq0=0x3B; 958 | spi_write_burst(PATABLE_BURST,patable_power_915,8); 959 | break; 960 | /* 961 | case 0x05: //2430MHz 962 | freq2=0x5D; 963 | freq1=0x76; 964 | freq0=0x27; 965 | spi_write_burst(PATABLE_BURST,patable_power_2430,8); 966 | break; 967 | */ 968 | default: //default is 868.3MHz 969 | freq2=0x21; 970 | freq1=0x65; 971 | freq0=0x6A; 972 | spi_write_burst(PATABLE_BURST,patable_power_868,8); //sets up output power ramp register 973 | break; 974 | } 975 | 976 | spi_write_register(FREQ2,freq2); //stores the new freq setting for defined ISM band 977 | spi_write_register(FREQ1,freq1); 978 | spi_write_register(FREQ0,freq0); 979 | 980 | return; 981 | } 982 | //-------------------------------[end]------------------------------------------ 983 | 984 | //--------------------------[set frequency]------------------------------------- 985 | void CC1100::set_patable(uint8_t *patable_arr) 986 | { 987 | spi_write_burst(PATABLE_BURST,patable_arr,8); //writes output power settings to cc1100 "104us" 988 | } 989 | //-------------------------------[end]------------------------------------------ 990 | 991 | //-------------------------[set output power]----------------------------------- 992 | void CC1100::set_output_power_level(int8_t dBm) 993 | { 994 | uint8_t pa = 0xC0; 995 | 996 | if (dBm <= -30) pa = 0x00; 997 | else if (dBm <= -20) pa = 0x01; 998 | else if (dBm <= -15) pa = 0x02; 999 | else if (dBm <= -10) pa = 0x03; 1000 | else if (dBm <= 0) pa = 0x04; 1001 | else if (dBm <= 5) pa = 0x05; 1002 | else if (dBm <= 7) pa = 0x06; 1003 | else if (dBm <= 10) pa = 0x07; 1004 | 1005 | spi_write_register(FREND0,pa); 1006 | } 1007 | //-------------------------------[end]------------------------------------------ 1008 | 1009 | //-------[set Modulation type 2-FSK=0; GFSK=1; ASK/OOK=3; 4-FSK=4; MSK=7]------ 1010 | void CC1100::set_modulation_type(uint8_t cfg) 1011 | { 1012 | uint8_t data; 1013 | data = spi_read_register(MDMCFG2); 1014 | data = (data & 0x8F) | (((cfg) << 4) & 0x70); 1015 | spi_write_register(MDMCFG2, data); 1016 | //printf("MDMCFG2: 0x%02X\n", data); 1017 | } 1018 | //-------------------------------[end]----------------------------------------- 1019 | 1020 | //------------------------[set preamble Len]----------------------------------- 1021 | void CC1100::set_preamble_len(uint8_t cfg) 1022 | { 1023 | uint8_t data; 1024 | data = spi_read_register(MDMCFG1); 1025 | data = (data & 0x8F) | (((cfg) << 4) & 0x70); 1026 | spi_write_register(MDMCFG1, data); 1027 | //printf("MDMCFG2: 0x%02X\n", data); 1028 | } 1029 | //-------------------------------[end]----------------------------------------- 1030 | 1031 | //-------------------[set modem datarate and deviant]-------------------------- 1032 | void CC1100::set_datarate(uint8_t mdmcfg4, uint8_t mdmcfg3, uint8_t deviant) 1033 | { 1034 | spi_write_register(MDMCFG4, mdmcfg4); 1035 | spi_write_register(MDMCFG3, mdmcfg3); 1036 | spi_write_register(DEVIATN, deviant); 1037 | } 1038 | //-------------------------------[end]----------------------------------------- 1039 | 1040 | //----------------------[set sync mode no sync=0;]----------------------------- 1041 | void CC1100::set_sync_mode(uint8_t cfg) // 0=no sync word; 1,2 = 16bit sync word, 3= 32bit sync word 1042 | { 1043 | uint8_t data; 1044 | data = spi_read_register(MDMCFG2); 1045 | data = (data & 0xF8) | (cfg & 0x07); 1046 | spi_write_register(MDMCFG2, data); 1047 | //printf("MDMCFG2: 0x%02X\n", data); 1048 | } 1049 | //-------------------------------[end]----------------------------------------- 1050 | 1051 | //---------------[set FEC ON=TRUE; OFF=FALSE]---------------------------------- 1052 | void CC1100::set_fec(uint8_t cfg) 1053 | { 1054 | uint8_t data; 1055 | data = spi_read_register(MDMCFG1); 1056 | data = (data & 0x7F) | (((cfg) << 7) & 0x80); 1057 | spi_write_register(MDMCFG1, data); 1058 | printf("MDMCFG1: 0x%02X\n", data); 1059 | } 1060 | //-------------------------------[end]------------------------------------------ 1061 | 1062 | //---------------[set data_whitening ON=TRUE; OFF=FALSE]------------------------ 1063 | void CC1100::set_data_whitening(uint8_t cfg) 1064 | { 1065 | uint8_t data; 1066 | data = spi_read_register(PKTCTRL0); 1067 | data = (data & 0xBF) | (((cfg) << 6) & 0x40); 1068 | spi_write_register(PKTCTRL0, data); 1069 | //printf("PKTCTRL0: 0x%02X\n", data); 1070 | } 1071 | //-------------------------------[end]----------------------------------------- 1072 | 1073 | //------------[set manchester encoding ON=TRUE; OFF=FALSE]--------------------- 1074 | void CC1100::set_manchester_encoding(uint8_t cfg) 1075 | { 1076 | uint8_t data; 1077 | data = spi_read_register(MDMCFG2); 1078 | data = (data & 0xF7) | (((cfg) << 3) & 0x08); 1079 | spi_write_register(MDMCFG2, data); 1080 | //printf("MDMCFG2: 0x%02X\n", data); 1081 | } 1082 | //-------------------------------[end]------------------------------------------ 1083 | 1084 | //--------------------------[rssi_convert]-------------------------------------- 1085 | int8_t CC1100::rssi_convert(uint8_t Rssi_hex) 1086 | { 1087 | int8_t rssi_dbm; 1088 | int16_t Rssi_dec; 1089 | 1090 | Rssi_dec = Rssi_hex; //convert unsigned to signed 1091 | 1092 | if(Rssi_dec >= 128){ 1093 | rssi_dbm=((Rssi_dec-256)/2)-RSSI_OFFSET_868MHZ; 1094 | } 1095 | else{ 1096 | if(Rssi_dec<128){ 1097 | rssi_dbm=((Rssi_dec)/2)-RSSI_OFFSET_868MHZ; 1098 | } 1099 | } 1100 | return rssi_dbm; 1101 | } 1102 | //-------------------------------[end]------------------------------------------ 1103 | 1104 | //----------------------------[lqi convert]------------------------------------- 1105 | uint8_t CC1100::lqi_convert(uint8_t lqi) 1106 | { 1107 | return (lqi & 0x7F); 1108 | } 1109 | //-------------------------------[end]------------------------------------------ 1110 | 1111 | //----------------------------[check crc]--------------------------------------- 1112 | uint8_t CC1100::check_crc(uint8_t lqi) 1113 | { 1114 | return (lqi & 0x80); 1115 | } 1116 | //-------------------------------[end]------------------------------------------ 1117 | 1118 | /* 1119 | //----------------------------[get temp]---------------------------------------- 1120 | uint8_t CC1100::get_temp(uint8_t *ptemp_Arr) 1121 | { 1122 | const uint8_t num_samples = 8; 1123 | uint16_t adc_result = 0; 1124 | uint32_t temperature = 0; 1125 | 1126 | sidle(); //sets CC1100 into IDLE 1127 | spi_write_register(PTEST,0xBF); //enable temp sensor 1128 | delay(50); //wait a bit 1129 | 1130 | for(uint8_t i=0;i 0){ 1144 | Serial.print(F("Temp:"));Serial.print(ptemp_Arr[0]);Serial.print(F("."));Serial.println(ptemp_Arr[1]); 1145 | } 1146 | 1147 | spi_write_register(PTEST,0x7F); //writes 0x7F back to PTest (app. note) 1148 | 1149 | receive(); 1150 | return (*ptemp_Arr); 1151 | } 1152 | */ 1153 | //-------------------------------[end]------------------------------------------ 1154 | 1155 | //|==================== SPI Initialisation for CC1100 =========================| 1156 | void CC1100::spi_begin(void) 1157 | { 1158 | int x = 0; 1159 | //printf ("init SPI bus... "); 1160 | if ((x = wiringPiSPISetup (0, 8000000)) < 0) //4MHz SPI speed 1161 | { 1162 | if(debug_level > 0){ 1163 | printf ("ERROR: wiringPiSPISetup failed!\r\n"); 1164 | } 1165 | } 1166 | else{ 1167 | //printf ("wiringSPI is up\r\n"); 1168 | } 1169 | } 1170 | //------------------[write register]-------------------------------- 1171 | void CC1100::spi_write_register(uint8_t spi_instr, uint8_t value) 1172 | { 1173 | uint8_t tbuf[2] = {0}; 1174 | tbuf[0] = spi_instr | WRITE_SINGLE_BYTE; 1175 | tbuf[1] = value; 1176 | uint8_t len = 2; 1177 | wiringPiSPIDataRW (0, tbuf, len) ; 1178 | 1179 | return; 1180 | } 1181 | //|============================ Ein Register lesen ============================| 1182 | uint8_t CC1100::spi_read_register(uint8_t spi_instr) 1183 | { 1184 | uint8_t value; 1185 | uint8_t rbuf[2] = {0}; 1186 | rbuf[0] = spi_instr | READ_SINGLE_BYTE; 1187 | uint8_t len = 2; 1188 | wiringPiSPIDataRW (0, rbuf, len) ; 1189 | value = rbuf[1]; 1190 | //printf("SPI_arr_0: 0x%02X\n", rbuf[0]); 1191 | //printf("SPI_arr_1: 0x%02X\n", rbuf[1]); 1192 | return value; 1193 | } 1194 | //|========================= ein Kommando schreiben ========================| 1195 | void CC1100::spi_write_strobe(uint8_t spi_instr) 1196 | { 1197 | uint8_t tbuf[1] = {0}; 1198 | tbuf[0] = spi_instr; 1199 | //printf("SPI_data: 0x%02X\n", tbuf[0]); 1200 | wiringPiSPIDataRW (0, tbuf, 1) ; 1201 | } 1202 | //|======= Mehrere hintereinanderliegende Register auf einmal lesen =======| 1203 | void CC1100::spi_read_burst(uint8_t spi_instr, uint8_t *pArr, uint8_t len) 1204 | { 1205 | uint8_t rbuf[len + 1]; 1206 | rbuf[0] = spi_instr | READ_BURST; 1207 | wiringPiSPIDataRW (0, rbuf, len + 1) ; 1208 | for (uint8_t i=0; i 5 | 6 | 7 | /*----------------------------------[standard]--------------------------------*/ 8 | #define TRUE (1==1) 9 | #define FALSE (!TRUE) 10 | 11 | 12 | //**************************** pins ******************************************// 13 | #define SS_PIN 10 14 | #define GDO2 6 15 | #define GDO0 99 16 | 17 | /*----------------------[CC1100 - misc]---------------------------------------*/ 18 | #define CRYSTAL_FREQUENCY 26000000 19 | #define CFG_REGISTER 0x2F //47 registers 20 | #define FIFOBUFFER 0x42 //size of Fifo Buffer +2 for rssi and lqi 21 | #define RSSI_OFFSET_868MHZ 0x4E //dec = 74 22 | #define TX_RETRIES_MAX 0x05 //tx_retries_max 23 | #define ACK_TIMEOUT 250 //ACK timeout in ms 24 | #define CC1100_COMPARE_REGISTER 0x00 //register compare 0=no compare 1=compare 25 | #define BROADCAST_ADDRESS 0x00 //broadcast address 26 | #define CC1100_FREQ_315MHZ 0x01 27 | #define CC1100_FREQ_434MHZ 0x02 28 | #define CC1100_FREQ_868MHZ 0x03 29 | #define CC1100_FREQ_915MHZ 0x04 30 | //#define CC1100_FREQ_2430MHZ 0x05 31 | #define CC1100_TEMP_ADC_MV 3.225 //3.3V/1023 . mV pro digit 32 | #define CC1100_TEMP_CELS_CO 2.47 //Temperature coefficient 2.47mV per Grad Celsius 33 | 34 | /*---------------------------[CC1100 - R/W offsets]---------------------------*/ 35 | #define WRITE_SINGLE_BYTE 0x00 36 | #define WRITE_BURST 0x40 37 | #define READ_SINGLE_BYTE 0x80 38 | #define READ_BURST 0xC0 39 | /*---------------------------[END R/W offsets]--------------------------------*/ 40 | 41 | /*------------------------[CC1100 - FIFO commands]----------------------------*/ 42 | #define TXFIFO_BURST 0x7F //write burst only 43 | #define TXFIFO_SINGLE_BYTE 0x3F //write single only 44 | #define RXFIFO_BURST 0xFF //read burst only 45 | #define RXFIFO_SINGLE_BYTE 0xBF //read single only 46 | #define PATABLE_BURST 0x7E //power control read/write 47 | #define PATABLE_SINGLE_BYTE 0xFE //power control read/write 48 | /*---------------------------[END FIFO commands]------------------------------*/ 49 | 50 | /*----------------------[CC1100 - config register]----------------------------*/ 51 | #define IOCFG2 0x00 // GDO2 output pin configuration 52 | #define IOCFG1 0x01 // GDO1 output pin configuration 53 | #define IOCFG0 0x02 // GDO0 output pin configuration 54 | #define FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds 55 | #define SYNC1 0x04 // Sync word, high byte 56 | #define SYNC0 0x05 // Sync word, low byte 57 | #define PKTLEN 0x06 // Packet length 58 | #define PKTCTRL1 0x07 // Packet automation control 59 | #define PKTCTRL0 0x08 // Packet automation control 60 | #define ADDR 0x09 // Device address 61 | #define CHANNR 0x0A // Channel number 62 | #define FSCTRL1 0x0B // Frequency synthesizer control 63 | #define FSCTRL0 0x0C // Frequency synthesizer control 64 | #define FREQ2 0x0D // Frequency control word, high byte 65 | #define FREQ1 0x0E // Frequency control word, middle byte 66 | #define FREQ0 0x0F // Frequency control word, low byte 67 | #define MDMCFG4 0x10 // Modem configuration 68 | #define MDMCFG3 0x11 // Modem configuration 69 | #define MDMCFG2 0x12 // Modem configuration 70 | #define MDMCFG1 0x13 // Modem configuration 71 | #define MDMCFG0 0x14 // Modem configuration 72 | #define DEVIATN 0x15 // Modem deviation setting 73 | #define MCSM2 0x16 // Main Radio Cntrl State Machine config 74 | #define MCSM1 0x17 // Main Radio Cntrl State Machine config 75 | #define MCSM0 0x18 // Main Radio Cntrl State Machine config 76 | #define FOCCFG 0x19 // Frequency Offset Compensation config 77 | #define BSCFG 0x1A // Bit Synchronization configuration 78 | #define AGCCTRL2 0x1B // AGC control 79 | #define AGCCTRL1 0x1C // AGC control 80 | #define AGCCTRL0 0x1D // AGC control 81 | #define WOREVT1 0x1E // High byte Event 0 timeout 82 | #define WOREVT0 0x1F // Low byte Event 0 timeout 83 | #define WORCTRL 0x20 // Wake On Radio control 84 | #define FREND1 0x21 // Front end RX configuration 85 | #define FREND0 0x22 // Front end TX configuration 86 | #define FSCAL3 0x23 // Frequency synthesizer calibration 87 | #define FSCAL2 0x24 // Frequency synthesizer calibration 88 | #define FSCAL1 0x25 // Frequency synthesizer calibration 89 | #define FSCAL0 0x26 // Frequency synthesizer calibration 90 | #define RCCTRL1 0x27 // RC oscillator configuration 91 | #define RCCTRL0 0x28 // RC oscillator configuration 92 | #define FSTEST 0x29 // Frequency synthesizer cal control 93 | #define PTEST 0x2A // Production test 94 | #define AGCTEST 0x2B // AGC test 95 | #define TEST2 0x2C // Various test settings 96 | #define TEST1 0x2D // Various test settings 97 | #define TEST0 0x2E // Various test settings 98 | /*-------------------------[END config register]------------------------------*/ 99 | 100 | /*------------------------[CC1100-command strobes]----------------------------*/ 101 | #define SRES 0x30 // Reset chip 102 | #define SFSTXON 0x31 // Enable/calibrate freq synthesizer 103 | #define SXOFF 0x32 // Turn off crystal oscillator. 104 | #define SCAL 0x33 // Calibrate freq synthesizer & disable 105 | #define SRX 0x34 // Enable RX. 106 | #define STX 0x35 // Enable TX. 107 | #define SIDLE 0x36 // Exit RX / TX 108 | #define SAFC 0x37 // AFC adjustment of freq synthesizer 109 | #define SWOR 0x38 // Start automatic RX polling sequence 110 | #define SPWD 0x39 // Enter pwr down mode when CSn goes hi 111 | #define SFRX 0x3A // Flush the RX FIFO buffer. 112 | #define SFTX 0x3B // Flush the TX FIFO buffer. 113 | #define SWORRST 0x3C // Reset real time clock. 114 | #define SNOP 0x3D // No operation. 115 | /*-------------------------[END command strobes]------------------------------*/ 116 | 117 | /*----------------------[CC1100 - status register]----------------------------*/ 118 | #define PARTNUM 0xF0 // Part number 119 | #define VERSION 0xF1 // Current version number 120 | #define FREQEST 0xF2 // Frequency offset estimate 121 | #define LQI 0xF3 // Demodulator estimate for link quality 122 | #define RSSI 0xF4 // Received signal strength indication 123 | #define MARCSTATE 0xF5 // Control state machine state 124 | #define WORTIME1 0xF6 // High byte of WOR timer 125 | #define WORTIME0 0xF7 // Low byte of WOR timer 126 | #define PKTSTATUS 0xF8 // Current GDOx status and packet status 127 | #define VCO_VC_DAC 0xF9 // Current setting from PLL cal module 128 | #define TXBYTES 0xFA // Underflow and # of bytes in TXFIFO 129 | #define RXBYTES 0xFB // Overflow and # of bytes in RXFIFO 130 | #define RCCTRL1_STATUS 0xFC //Last RC Oscillator Calibration Result 131 | #define RCCTRL0_STATUS 0xFD //Last RC Oscillator Calibration Result 132 | //--------------------------[END status register]------------------------------- 133 | 134 | class CC1100 135 | { 136 | private: 137 | 138 | void spi_begin(void); 139 | void spi_end(void); 140 | uint8_t spi_putc(uint8_t data); 141 | 142 | public: 143 | uint8_t debug_level; 144 | 145 | uint8_t set_debug_level(uint8_t set_debug_level); 146 | uint8_t get_debug_level(void); 147 | 148 | uint8_t begin(volatile uint8_t &My_addr); 149 | void end(void); 150 | 151 | void spi_write_strobe(uint8_t spi_instr); 152 | void spi_write_register(uint8_t spi_instr, uint8_t value); 153 | void spi_write_burst(uint8_t spi_instr, uint8_t *pArr, uint8_t length); 154 | void spi_read_burst(uint8_t spi_instr, uint8_t *pArr, uint8_t length); 155 | uint8_t spi_read_register(uint8_t spi_instr); 156 | uint8_t spi_read_status(uint8_t spi_instr); 157 | 158 | void reset(void); 159 | void wakeup(void); 160 | void powerdown(void); 161 | 162 | void wor_enable(void); 163 | void wor_disable(void); 164 | void wor_reset(void); 165 | 166 | uint8_t sidle(void); 167 | uint8_t transmit(void); 168 | uint8_t receive(void); 169 | 170 | void show_register_settings(void); 171 | void show_main_settings(void); 172 | 173 | uint8_t packet_available(); 174 | uint8_t wait_for_packet(uint16_t milliseconds); 175 | 176 | uint8_t get_payload(uint8_t rxbuffer[], uint8_t &pktlen_rx,uint8_t &my_addr, 177 | uint8_t &sender, int8_t &rssi_dbm, uint8_t &lqi); 178 | 179 | uint8_t tx_payload_burst(uint8_t my_addr, uint8_t rx_addr, uint8_t *txbuffer, uint8_t length); 180 | uint8_t rx_payload_burst(uint8_t rxbuffer[], uint8_t &pktlen); 181 | 182 | void rx_fifo_erase(uint8_t *rxbuffer); 183 | void tx_fifo_erase(uint8_t *txbuffer); 184 | 185 | uint8_t sent_packet(uint8_t my_addr, uint8_t rx_addr, uint8_t *txbuffer, uint8_t pktlen, uint8_t tx_retries); 186 | void sent_acknowledge(uint8_t my_addr, uint8_t tx_addr); 187 | 188 | uint8_t check_acknowledge(uint8_t *rxbuffer, uint8_t pktlen, uint8_t sender, uint8_t my_addr); 189 | 190 | int8_t rssi_convert(uint8_t Rssi); 191 | uint8_t check_crc(uint8_t lqi); 192 | uint8_t lqi_convert(uint8_t lqi); 193 | uint8_t get_temp(uint8_t *ptemp_Arr); 194 | 195 | void set_myaddr(uint8_t addr); 196 | void set_channel(uint8_t channel); 197 | void set_ISM(uint8_t ism_freq); 198 | void set_mode(uint8_t mode); 199 | void set_output_power_level(int8_t dbm); 200 | void set_patable(uint8_t *patable_arr); 201 | void set_fec(uint8_t cfg); 202 | void set_data_whitening(uint8_t cfg); 203 | void set_modulation_type(uint8_t cfg); 204 | void set_preamble_len(uint8_t cfg); 205 | void set_manchester_encoding(uint8_t cfg); 206 | void set_sync_mode(uint8_t cfg); 207 | void set_datarate(uint8_t mdmcfg4, uint8_t mdmcfg3, uint8_t deviant); 208 | }; 209 | 210 | 211 | 212 | //=======================[CC1100 special functions]============================= 213 | 214 | 215 | #endif // CC1100_H 216 | -------------------------------------------------------------------------------- /examples/Arduino/Rx_demo/Rx_demo.ino: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | ' RX_DEMO 3 | ' ------- 4 | ' - needs EnableInterrupt (former PinChangeInt) library 5 | ' - *.eep file must flashed to Arduino first -> use eeprom Tool 6 | ' - install cc1100_arduino.h and cc1100_arduino.cpp as a library (create subdirectory "cc1100" 7 | ' in your existing sketchbook/libraries directory and copy cc1100_arduino.* into the cc1100 8 | ' directory) 9 | ' 10 | '-----------------------------------------------------------------------------*/ 11 | #include 12 | #include 13 | #include 14 | 15 | //---------------------------=[Global variables]=---------------------------- 16 | volatile int sleep_enable = 0; 17 | uint32_t rf_timecode = 0; 18 | uint32_t rf_timecode_backup = 0; 19 | //--------------------------[Global Task variables]-------------------------- 20 | 21 | //--------------------------[Global CC1100 variables]------------------------ 22 | uint8_t Tx_fifo[FIFOBUFFER], Rx_fifo[FIFOBUFFER]; 23 | uint8_t My_addr, Tx_addr, Rx_addr, Pktlen, pktlen, Lqi, Rssi; 24 | uint8_t rx_addr,sender,lqi; 25 | int8_t rssi_dbm; 26 | volatile uint8_t cc1101_packet_available; 27 | 28 | //--------------------------[class constructors]----------------------------- 29 | //init CC1100 constructor 30 | CC1100 cc1100; 31 | 32 | //---------------------------------[SETUP]----------------------------------- 33 | void setup() 34 | { 35 | // init serial Port for debugging 36 | Serial.begin(115200);Serial.println(); 37 | 38 | // init CC1101 RF-module and get My_address from EEPROM 39 | cc1100.begin(My_addr); //inits RF module with main default settings 40 | 41 | cc1100.sidle(); //set to ILDE first 42 | 43 | cc1100.set_mode(0x04); //set modulation mode 1 = GFSK_1_2_kb; 2 = GFSK_38_4_kb; 3 = GFSK_100_kb; 4 = MSK_250_kb; 5 = MSK_500_kb; 6 = OOK_4_8_kb 44 | cc1100.set_ISM(0x02); //set ISM Band 1=315MHz; 2=433MHz; 3=868MHz; 4=915MHz 45 | cc1100.set_channel(0x01); //set channel 46 | cc1100.set_output_power_level(0); //set PA level in dbm 47 | cc1100.set_myaddr(0x03); //set my own address 48 | 49 | //cc1100.spi_write_register(IOCFG0, 0x24); //set module in sync mode detection mode 50 | cc1100.spi_write_register(IOCFG2,0x06); 51 | 52 | cc1100.show_main_settings(); //shows setting debug messages to UART 53 | cc1100.show_register_settings(); //shows current CC1101 register values 54 | 55 | cc1100.receive(); //set to RECEIVE mode 56 | 57 | // init interrrupt function for available packet 58 | enableInterrupt(GDO2, rf_available_int, RISING); 59 | 60 | Serial.println(F("CC1101 RX Demo")); //welcome message 61 | } 62 | 63 | //---------------------------------[LOOP]----------------------------------- 64 | void loop() 65 | { 66 | //if valid package is received 67 | if(cc1101_packet_available == TRUE){ 68 | rf_timecode = ((uint32_t)Rx_fifo[3] << 24) + 69 | ((uint32_t)Rx_fifo[4] << 16) + 70 | ((uint16_t)Rx_fifo[5] << 8) + 71 | Rx_fifo[6]; 72 | Serial.print(F("TX_Timecode: "));Serial.print(rf_timecode);Serial.println(F("ms\n")); 73 | 74 | rf_timecode_backup = millis(); 75 | 76 | cc1101_packet_available = FALSE; 77 | } 78 | 79 | //set Arduino in sleep mode if no package is received within 5 sec. 80 | if(millis() - rf_timecode_backup > 5000){ 81 | rf_timecode_backup = millis(); 82 | 83 | sleep_enable = 1; 84 | Serial.println(F("...sleep MCU")); //welcome message 85 | delay(100); 86 | set_sleep_mode(SLEEP_MODE_STANDBY); 87 | cli(); 88 | sleep_enable(); 89 | sei(); 90 | sleep_cpu(); 91 | sleep_disable(); 92 | 93 | enableInterrupt(GDO2, rf_available_int, RISING); 94 | } 95 | 96 | } 97 | //--------------------------[end loop]---------------------------- 98 | 99 | //---------------------[ check incomming RF packet ]----------------------- 100 | void rf_available_int(void) 101 | { 102 | disableInterrupt(GDO2); 103 | sei(); //for millis() 104 | uint32_t time_stamp = millis(); //generate time stamp 105 | 106 | sleep_disable(); 107 | sleep_enable = 0; 108 | 109 | if(cc1100.packet_available() == TRUE) 110 | { 111 | if(cc1100.get_payload(Rx_fifo, pktlen, rx_addr, sender, rssi_dbm, lqi) == TRUE) //stores the payload data to Rx_fifo 112 | { 113 | cc1101_packet_available = TRUE; //set flag that a package is in RX buffer 114 | Serial.print(F("rx_time: "));Serial.print(millis()-time_stamp);Serial.println(F("ms")); 115 | } 116 | else 117 | { 118 | cc1101_packet_available = FALSE; //set flag that an package is corrupted 119 | } 120 | } 121 | 122 | enableInterrupt(GDO2, rf_available_int, RISING); 123 | } 124 | -------------------------------------------------------------------------------- /examples/Arduino/Rx_demo_WOR/Rx_demo_WOR.ino: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | ' CC1101_RX_Demo_WOR 3 | ' ------------------ 4 | ' 5 | ' - needs EnableInterrupt (former PinChangeInt) library 6 | ' - *.eep file must flashed to Arduino first -> use eeprom Tool 7 | ' - install cc1100_arduino.h and cc1100_arduino.cpp as a library (create subdirectory "cc1100" 8 | ' in your existing sketchbook/libraries directory and copy cc1100_arduino.* into the cc1100 9 | ' directory) 10 | ' 11 | '-----------------------------------------------------------------------------*/ 12 | #include 13 | #include 14 | #include 15 | 16 | //---------------------------=[Global variables]=---------------------------- 17 | volatile int mcu_sleep_enable = 0; 18 | volatile int cc1100_wor_enable_flag = 0; 19 | uint32_t rf_timecode = 0; 20 | uint32_t rf_timecode_backup = 0; 21 | //--------------------------[Global Task variables]-------------------------- 22 | 23 | //--------------------------[Global CC1100 variables]------------------------ 24 | uint8_t Tx_fifo[FIFOBUFFER], Rx_fifo[FIFOBUFFER], Patable[8]; 25 | uint8_t My_addr, Tx_addr, Rx_addr, Pktlen, pktlen, Lqi, Rssi; 26 | uint8_t rx_addr,sender,lqi; 27 | int8_t rssi_dbm; 28 | 29 | volatile uint8_t cc1101_packet_available; 30 | 31 | //--------------------------[class constructors]----------------------------- 32 | //init CC1100 constructor 33 | CC1100 cc1100; 34 | 35 | //---------------------------------[SETUP]----------------------------------- 36 | void setup() 37 | { 38 | // init serial Port for debugging 39 | Serial.begin(115200);Serial.println(); 40 | 41 | // init CC1101 RF-module and get My_address from EEPROM 42 | cc1100.begin(My_addr); //inits RF module with main default settings. returns My_addr from Arduino EEPROM setting 43 | 44 | cc1100.sidle(); //set to IDLE first 45 | 46 | cc1100.set_mode(0x04); //set modulation mode 1 = GFSK_1_2_kb; 2 = GFSK_38_4_kb; 3 = GFSK_100_kb; 4 = MSK_250_kb; 5 = MSK_500_kb; 6 = OOK_4_8_kb 47 | cc1100.set_ISM(0x02); //set ISM Band 1=315MHz; 2=433MHz; 3=868MHz; 4=915MHz 48 | cc1100.set_channel(0x01); //set channel 49 | cc1100.set_myaddr(0x03); //overwrites my own address 50 | 51 | cc1100.spi_read_burst(PATABLE_BURST, Patable, 8); //backup selected PA Table settings 52 | cc1100.set_output_power_level(0); //set PA level in dbm 53 | 54 | cc1100.spi_write_register(IOCFG2,0x06); 55 | 56 | cc1100.show_main_settings(); //shows setting debug messages to UART 57 | cc1100.show_register_settings(); //shows current CC1101 register values 58 | 59 | cc1100.set_debug_level(1); //enable/disable debug outputs 60 | 61 | cc1100.wor_enable(); //enable WOR mode 62 | cc1100_wor_enable_flag = 1; //set WOR enable flag 63 | //cc1100.receive(); 64 | 65 | // init interrrupt function for available packet 66 | enableInterrupt(GDO2, rf_available_int, RISING); 67 | 68 | Serial.println(F("CC1101 RX Demo WOR")); //welcome message 69 | } 70 | 71 | //---------------------------------[LOOP]----------------------------------- 72 | void loop() 73 | { 74 | //if valid package is received 75 | if(cc1101_packet_available == TRUE){ 76 | rf_timecode = ((uint32_t)Rx_fifo[3] << 24) + 77 | ((uint32_t)Rx_fifo[4] << 16) + 78 | ((uint16_t)Rx_fifo[5] << 8) + 79 | Rx_fifo[6]; 80 | Serial.print(F("TX_Timecode: "));Serial.print(rf_timecode);Serial.println(F("ms\n")); 81 | 82 | rf_timecode_backup = millis(); 83 | 84 | cc1101_packet_available = FALSE; //resets packet available flag 85 | } 86 | 87 | //enable CC1101 WOR mode and set Arduino in standby mode after 1 sec. 88 | if(millis() - rf_timecode_backup > 1000){ 89 | rf_timecode_backup = millis(); 90 | 91 | if(cc1100_wor_enable_flag == 0){ //enable WOR mode after 5 seconds if WOR is not enabled 92 | cc1100.wor_reset(); 93 | cc1100_wor_enable_flag = 1; //set WOR flag 94 | Serial.println(F("...CC1101 WOR enabled")); 95 | } 96 | 97 | mcu_sleep_enable = 1; //set Arduino in sleep mode till incomming packet interrupt 98 | Serial.println(F("...sleep MCU")); Serial.println(); 99 | delay(100); 100 | set_sleep_mode(SLEEP_MODE_STANDBY); //important to be in STANDBY Mode 101 | cli(); 102 | sleep_enable(); 103 | sei(); 104 | sleep_cpu(); 105 | sleep_disable(); //restart MCU after standby mode 106 | 107 | enableInterrupt(GDO2, rf_available_int, RISING); 108 | } 109 | 110 | } 111 | //--------------------------[end loop]---------------------------- 112 | 113 | //---------------------[ check incomming RF packet ]----------------------- 114 | void rf_available_int(void) 115 | { 116 | disableInterrupt(GDO2); 117 | sei(); //for millis() 118 | uint32_t rf_time_stamp = millis(); //generate time stamp 119 | mcu_sleep_enable = 0; 120 | 121 | 122 | if(cc1100.packet_available() == TRUE){ //checks packet available flag 123 | 124 | if(cc1100_wor_enable_flag == 1){ //only disable and update PA Table if CC1101 is in WOR mode 125 | cc1100.wor_disable(); 126 | cc1100_wor_enable_flag = 0; 127 | cc1100.spi_write_burst(PATABLE_BURST, Patable, 8); //bugfix, CC1101 PA Table is lost after SLEEP mode 128 | } 129 | if(cc1100.get_payload(Rx_fifo, pktlen, rx_addr, sender, rssi_dbm, lqi) == TRUE) //stores the payload data to Rx_fifo 130 | { 131 | cc1101_packet_available = TRUE; //set flag that a package is in RX buffer 132 | Serial.print(F("rx_time: "));Serial.print(millis()-rf_time_stamp);Serial.println(F("ms")); 133 | } 134 | else 135 | { 136 | cc1101_packet_available = FALSE; //set flag that an package is corrupted 137 | } 138 | } 139 | 140 | enableInterrupt(GDO2, rf_available_int, RISING); 141 | } 142 | 143 | //----------------------------------------------------------------------------------- 144 | -------------------------------------------------------------------------------- /examples/Arduino/Tx_demo/Tx_demo.ino: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | ' TX_DEMO 3 | ' ------- 4 | ' - needs EnableInterrupt (former PinChangeInt) library 5 | ' - *.eep file must flashed to Arduino first -> use eeprom Tool 6 | ' - install cc1100_arduino.h and cc1100_arduino.cpp as a library (create subdirectory "cc1100" 7 | ' in your existing sketchbook/libraries directory and copy cc1100_arduino.* into the cc1100 8 | ' directory) 9 | ' 10 | '-----------------------------------------------------------------------------*/ 11 | #include 12 | #include 13 | #include 14 | 15 | //---------------------------=[Global variables]=---------------------------- 16 | 17 | //--------------------------[Global Task variables]-------------------------- 18 | uint32_t prev_millis_1s_timer = 0; 19 | 20 | const uint16_t INTERVAL_1S_TIMER = 1000; // interval at which to blink (milliseconds) 21 | 22 | //--------------------------[Global CC1100 variables]------------------------ 23 | uint8_t Tx_fifo[FIFOBUFFER], Rx_fifo[FIFOBUFFER]; 24 | uint8_t My_addr, Tx_addr, Rx_addr, Pktlen, pktlen, Lqi, Rssi; 25 | uint8_t rx_addr,sender,lqi; 26 | int8_t rssi_dbm; 27 | 28 | volatile uint8_t cc1101_packet_available; 29 | 30 | //--------------------------[class constructors]----------------------------- 31 | //init CC1100 constructor 32 | CC1100 cc1100; 33 | 34 | //---------------------------------[SETUP]----------------------------------- 35 | void setup() 36 | { 37 | // init serial Port for debugging 38 | Serial.begin(115200);Serial.println(); 39 | 40 | // init CC1101 RF-module and get My_address from EEPROM 41 | cc1100.begin(My_addr); //inits RF module with main default settings 42 | 43 | cc1100.sidle(); //set to ILDE first 44 | cc1100.set_mode(0x04); //set modulation mode 1 = GFSK_1_2_kb; 2 = GFSK_38_4_kb; 3 = GFSK_100_kb; 4 = MSK_250_kb; 5 = MSK_500_kb; 6 = OOK_4_8_kb 45 | cc1100.set_ISM(0x02); //set frequency 1=315MHz; 2=433MHz; 3=868MHz; 4=915MHz 46 | cc1100.set_channel(0x01); //set channel 47 | cc1100.set_output_power_level(0); //set PA level in dbm 48 | cc1100.set_myaddr(0x01); //set my own address 49 | 50 | //cc1100.spi_write_register(IOCFG2, 0x06); //set module in sync mode detection mode 51 | //cc1100.set_modulation_type(7); //set Modulation type 2-FSK=0; GFSK=1; ASK/OOK=3; 4-FSK=4; MSK=7 52 | //cc1100.set_datarate(0x8b, 0xf8, 0x44); //set datarate parameters, calculated by python tool 53 | 54 | cc1100.show_main_settings(); //shows setting debug messages to UART 55 | cc1100.show_register_settings(); //shows current CC1101 register values 56 | cc1100.receive(); //set to RECEIVE mode 57 | 58 | // init interrrupt function for available packet 59 | enableInterrupt(GDO2, rf_available_int, RISING); 60 | 61 | Serial.println(F("CC1101 TX Demo")); //welcome message 62 | } 63 | //---------------------------------[LOOP]----------------------------------- 64 | void loop() 65 | { 66 | 67 | // one second update timer 68 | if (millis() - prev_millis_1s_timer >= INTERVAL_1S_TIMER) 69 | { 70 | Rx_addr = 0x03; //receiver address 71 | 72 | uint32_t time_stamp = millis(); //generate time stamp 73 | 74 | Tx_fifo[3] = (uint8_t)(time_stamp >> 24); //split 32-Bit timestamp to 4 byte array 75 | Tx_fifo[4] = (uint8_t)(time_stamp >> 16); 76 | Tx_fifo[5] = (uint8_t)(time_stamp >> 8); 77 | Tx_fifo[6] = (uint8_t)(time_stamp); 78 | 79 | Pktlen = 0x07; //set packet len to 0x13 80 | 81 | detachPinChangeInterrupt(GDO2); //disable pin change interrupt 82 | cc1100.sent_packet(My_addr, Rx_addr, Tx_fifo, Pktlen, 40); //sents package over air. ACK is received via GPIO polling 83 | attachPinChangeInterrupt(GDO2, rf_available_int, RISING); //enable pin change interrupt 84 | 85 | Serial.print(F("tx_time: "));Serial.print(millis()-time_stamp);Serial.println(F("ms")); 86 | prev_millis_1s_timer = millis(); 87 | } 88 | 89 | } 90 | //--------------------------[end loop]---------------------------- 91 | 92 | //-----interrrupt function not needed for this demo 93 | //---------------------[ check incomming RF packet ]----------------------- 94 | void rf_available_int(void) 95 | { 96 | disableInterrupt(GDO2); 97 | 98 | if(cc1100.packet_available() == TRUE){ 99 | if(cc1100.get_payload(Rx_fifo, pktlen, rx_addr, sender, rssi_dbm, lqi) == TRUE) //stores the payload data to Rx_fifo 100 | { 101 | cc1101_packet_available = TRUE; //set flag that a package is in RX buffer 102 | } 103 | else 104 | { 105 | cc1101_packet_available = FALSE; //set flag that an package is corrupted 106 | } 107 | } 108 | 109 | enableInterrupt(GDO2, rf_available_int, RISING); 110 | } 111 | -------------------------------------------------------------------------------- /examples/raspi/RX_Demo.cpp: -------------------------------------------------------------------------------- 1 | #include "cc1100_raspi.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define PACKAGE "CC1100 SW" 14 | #define VERSION_SW "0.9.1" 15 | 16 | //--------------------------[Global CC1100 variables]-------------------------- 17 | uint8_t Tx_fifo[FIFOBUFFER], Rx_fifo[FIFOBUFFER]; 18 | uint8_t My_addr, Tx_addr, Rx_addr, Pktlen, pktlen, Lqi, Rssi; 19 | uint8_t rx_addr,sender,lqi; 20 | int8_t rssi_dbm; 21 | 22 | 23 | int cc1100_freq_select, cc1100_mode_select, cc1100_channel_select; 24 | uint8_t cc1100_debug = 0; //set CC1100 lib in no-debug output mode 25 | 26 | CC1100 cc1100; 27 | 28 | //-------------------------- [End] -------------------------- 29 | 30 | void print_help(int exval) { 31 | printf("%s,%s by CW\r\n", PACKAGE, VERSION_SW); 32 | printf("%s [-h] [-V] [-v] [-a My_Addr] [-c channel] [-f frequency] \r\n", PACKAGE); 33 | printf(" [-m modulation]\n\r\n\r"); 34 | printf(" -h print this help and exit\r\n"); 35 | printf(" -V print version and exit\r\n\r\n"); 36 | printf(" -v set verbose flag\r\n"); 37 | printf(" -a my address [1-255] set my address\r\n\r\n"); 38 | printf(" -c channel [1-255] set transmit channel\r\n"); 39 | printf(" -f frequency [315,434,868,915] set ISM band\r\n\r\n"); 40 | printf(" -m modulation [1,38,100,250,500,4] set modulation\r\n\r\n"); 41 | 42 | exit(exval); 43 | } 44 | 45 | 46 | //|============================ Main ============================| 47 | int main(int argc, char *argv[]) { 48 | //------------- command line option parser ------------------- 49 | int opt; 50 | // no arguments given 51 | if(argc == 1) { 52 | fprintf(stderr, "This program needs arguments....\n\r\n\r"); 53 | print_help(1); 54 | } 55 | 56 | while((opt = getopt(argc, argv, "hVva:c:f:m:")) != -1) { 57 | switch(opt) { 58 | case 'h': 59 | print_help(0); 60 | break; 61 | case 'V': 62 | printf("%s %s\n\n", PACKAGE, VERSION_SW); 63 | exit(0); 64 | break; 65 | case 'v': 66 | printf("%s: Verbose option is set `%c'\n", PACKAGE, optopt); 67 | cc1100_debug = 1; 68 | break; 69 | case 'a': 70 | My_addr = atoi (optarg); 71 | break; 72 | case 'c': 73 | cc1100_channel_select = atoi (optarg); 74 | break; 75 | case 'f': 76 | cc1100_freq_select = atoi (optarg); 77 | switch(cc1100_freq_select){ 78 | case 315: 79 | cc1100_freq_select = 1; 80 | break; 81 | case 434: 82 | cc1100_freq_select = 2; 83 | break; 84 | case 868: 85 | cc1100_freq_select = 3; 86 | break; 87 | case 915: 88 | cc1100_freq_select = 4; 89 | break; 90 | } 91 | break; 92 | case 'm': 93 | cc1100_mode_select = atoi (optarg); 94 | 95 | switch(cc1100_mode_select){ 96 | case 1: 97 | cc1100_mode_select = 1; 98 | break; 99 | case 38: 100 | cc1100_mode_select = 2; 101 | break; 102 | 103 | case 100: 104 | cc1100_mode_select = 3; 105 | break; 106 | case 250: 107 | cc1100_mode_select = 4; 108 | break; 109 | case 500: 110 | cc1100_mode_select = 5; 111 | break; 112 | case 4: 113 | cc1100_mode_select = 6; 114 | break; 115 | } 116 | break; 117 | case ':': 118 | fprintf(stderr, "%s: Error - Option `%c' needs a value\n\n", PACKAGE, optopt); 119 | print_help(1); 120 | break; 121 | case '?': 122 | fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt); 123 | print_help(1); 124 | } 125 | } 126 | 127 | // print all remaining options 128 | for(; optind < argc; optind++) 129 | printf("argument: %s\n", argv[optind]); 130 | 131 | //------------- welcome message ------------------------ 132 | printf("Raspberry CC1101 SPI Library test\n"); 133 | 134 | //------------- hardware setup ------------------------ 135 | 136 | wiringPiSetup(); //setup wiringPi library 137 | 138 | cc1100.begin(My_addr); //setup cc1000 RF IC 139 | cc1100.sidle(); 140 | //cc1100.set_mode(0x03); //set modulation mode 1 = GFSK_1_2_kb; 2 = GFSK_38_4_kb; 3 = GFSK_100_kb; 4 = MSK_250_kb; 5 = MSK_500_kb; 6 = OOK_4_8_kb 141 | //cc1100.set_ISM(0x02); //set ISM Band 1=315MHz; 2=433MHz; 3=868MHz; 4=915MHz 142 | //cc1100.set_channel(0x01); //set channel 143 | cc1100.set_output_power_level(0); //set PA level 144 | //cc1100.set_myaddr(0x03); 145 | 146 | cc1100.show_main_settings(); //shows setting debug messages to UART 147 | cc1100.show_register_settings(); 148 | 149 | cc1100.receive(); 150 | //------------------------- Main Loop ------------------------ 151 | for (;;) { 152 | delay(1); //delay to reduce system load 153 | 154 | if (cc1100.packet_available()) //checks if a packed is available 155 | { 156 | cc1100.get_payload(Rx_fifo, pktlen, rx_addr, sender, rssi_dbm, lqi); //stores the payload data to Rx_fifo 157 | } 158 | } 159 | return 0; 160 | } 161 | //-------------------- END OF MAIN -------------------------------- 162 | -------------------------------------------------------------------------------- /examples/raspi/RX_Demo_WOR.cpp: -------------------------------------------------------------------------------- 1 | #include "cc1100_raspi.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define PACKAGE "CC1100 SW" 14 | #define VERSION_SW "0.9.0" 15 | 16 | //--------------------------[Global CC1100 variables]-------------------------- 17 | uint8_t Tx_fifo[FIFOBUFFER], Rx_fifo[FIFOBUFFER], Patable[8]; 18 | uint8_t My_addr, Tx_addr, Rx_addr, Pktlen, pktlen, Lqi, Rssi; 19 | uint8_t rx_addr,sender,lqi; 20 | int8_t rssi_dbm; 21 | 22 | 23 | int cc1100_freq_select, cc1100_mode_select, cc1100_channel_select; 24 | uint8_t cc1100_debug = 0; //set CC1100 lib in no-debug output mode 25 | uint8_t cc1100_wor_enable_flag = 0; 26 | 27 | CC1100 cc1100; 28 | 29 | //-------------------------- [End] -------------------------- 30 | 31 | void print_help(int exval) { 32 | printf("%s,%s by CW\r\n", PACKAGE, VERSION_SW); 33 | printf("%s [-h] [-V] [-v] [-a My_Addr] [-c channel] [-f frequency] \r\n", PACKAGE); 34 | printf(" [-m modulation]\n\r\n\r"); 35 | printf(" -h print this help and exit\r\n"); 36 | printf(" -V print version and exit\r\n\r\n"); 37 | printf(" -v set verbose flag\r\n"); 38 | printf(" -a my address [1-255] set my address\r\n\r\n"); 39 | printf(" -c channel [1-255] set transmit channel\r\n"); 40 | printf(" -f frequency [315,434,868,915] set ISM band\r\n\r\n"); 41 | printf(" -m modulation [1,38,100,250,500,4] set modulation\r\n\r\n"); 42 | 43 | exit(exval); 44 | } 45 | 46 | 47 | //|============================ Main ============================| 48 | int main(int argc, char *argv[]) { 49 | //------------- command line option parser ------------------- 50 | int opt; 51 | // no arguments given 52 | if(argc == 1) { 53 | fprintf(stderr, "This program needs arguments....\n\r\n\r"); 54 | print_help(1); 55 | } 56 | 57 | while((opt = getopt(argc, argv, "hVva:c:f:m:")) != -1) { 58 | switch(opt) { 59 | case 'h': 60 | print_help(0); 61 | break; 62 | case 'V': 63 | printf("%s %s\n\n", PACKAGE, VERSION_SW); 64 | exit(0); 65 | break; 66 | case 'v': 67 | printf("%s: Verbose option is set `%c'\n", PACKAGE, optopt); 68 | cc1100_debug = 1; 69 | break; 70 | case 'a': 71 | My_addr = atoi (optarg); 72 | break; 73 | case 'c': 74 | cc1100_channel_select = atoi (optarg); 75 | break; 76 | case 'f': 77 | cc1100_freq_select = atoi (optarg); 78 | switch(cc1100_freq_select){ 79 | case 315: 80 | cc1100_freq_select = 1; 81 | break; 82 | case 434: 83 | cc1100_freq_select = 2; 84 | break; 85 | case 868: 86 | cc1100_freq_select = 3; 87 | break; 88 | case 915: 89 | cc1100_freq_select = 4; 90 | break; 91 | } 92 | break; 93 | case 'm': 94 | cc1100_mode_select = atoi (optarg); 95 | switch(cc1100_mode_select){ 96 | case 1: 97 | cc1100_mode_select = 1; 98 | break; 99 | case 38: 100 | cc1100_mode_select = 2; 101 | break; 102 | 103 | case 100: 104 | cc1100_mode_select = 3; 105 | break; 106 | case 250: 107 | cc1100_mode_select = 4; 108 | break; 109 | case 500: 110 | cc1100_mode_select = 5; 111 | break; 112 | case 4: 113 | cc1100_mode_select = 6; 114 | break; 115 | } 116 | break; 117 | case ':': 118 | fprintf(stderr, "%s: Error - Option `%c' needs a value\n\n", PACKAGE, optopt); 119 | print_help(1); 120 | break; 121 | case '?': 122 | fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt); 123 | print_help(1); 124 | } 125 | } 126 | 127 | // print all remaining options 128 | for(; optind < argc; optind++) 129 | printf("argument: %s\n", argv[optind]); 130 | 131 | //------------- welcome message ------------------------ 132 | printf("Raspberry CC1101 SPI Library test\n"); 133 | 134 | //------------- hardware setup ------------------------ 135 | 136 | wiringPiSetup(); //setup wiringPi library 137 | 138 | cc1100.begin(My_addr); //setup cc1000 RF IC 139 | cc1100.sidle(); 140 | cc1100.set_output_power_level(0); //set PA level 141 | 142 | cc1100.spi_read_burst(PATABLE_BURST, Patable, 8); //backup selected PA Table settings 143 | 144 | cc1100.show_main_settings(); //shows setting debug messages to UART 145 | cc1100.show_register_settings(); 146 | 147 | cc1100.wor_enable(); //enable WOR mode 148 | cc1100_wor_enable_flag = 1; //set WOR enable flag 149 | //------------------------- Main Loop ------------------------ 150 | for (;;) { 151 | delay(1); //delay to reduce system load 152 | 153 | if (cc1100.packet_available() == TRUE) //checks if a packed is available 154 | { 155 | if(cc1100_wor_enable_flag == 1){ //only disable and update PA Table if CC1101 is in WOR mode 156 | //Serial.println(F("update PA_Table: ")); 157 | cc1100_wor_enable_flag = 0; 158 | cc1100.spi_write_burst(PATABLE_BURST, Patable, 8); //bugfix, CC1101 PA Table is lost after SLEEP mode 159 | } 160 | 161 | cc1100.get_payload(Rx_fifo, pktlen, rx_addr, sender, rssi_dbm, lqi); //stores the payload data to Rx_fifo 162 | cc1100.wor_reset(); 163 | cc1100_wor_enable_flag = 1; 164 | } 165 | } 166 | return 0; 167 | } 168 | //-------------------- END OF MAIN -------------------------------- 169 | -------------------------------------------------------------------------------- /examples/raspi/TX_Demo.cpp: -------------------------------------------------------------------------------- 1 | #include "cc1100_raspi.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #define PACKAGE "CC1100 SW" 13 | #define VERSION_SW "0.9.6" 14 | 15 | #define INTERVAL_1S_TIMER 1000 16 | 17 | 18 | //--------------------------[Global CC1100 variables]-------------------------- 19 | uint8_t Tx_fifo[FIFOBUFFER], Rx_fifo[FIFOBUFFER]; 20 | uint8_t My_addr, Tx_addr, Rx_addr, Pktlen, pktlen, Lqi, Rssi; 21 | uint8_t rx_addr,sender,lqi; 22 | int8_t rssi_dbm; 23 | 24 | int cc1100_freq_select, cc1100_mode_select, cc1100_channel_select; 25 | 26 | uint32_t prev_millis_1s_timer = 0; 27 | 28 | uint8_t cc1100_debug = 0; //set CC1100 lib in no-debug output mode 29 | uint8_t tx_retries = 1; 30 | uint8_t rx_demo_addr = 3; 31 | int interval = 1000; 32 | 33 | CC1100 cc1100; 34 | 35 | //-------------------------- [End] -------------------------- 36 | 37 | void print_help(int exval) { 38 | printf("%s,%s by CW\r\n", PACKAGE, VERSION_SW); 39 | printf("%s [-h] [-V] [-a My_Addr] [-r RxDemo_Addr] [-i Msg_Interval] [-t tx_retries] [-c channel] [-f frequency]\r\n", PACKAGE); 40 | printf(" [-m modulation]\n\r\n\r"); 41 | printf(" -h print this help and exit\r\n"); 42 | printf(" -V print version and exit\r\n\r\n"); 43 | printf(" -v set verbose flag\r\n"); 44 | printf(" -a my address [1-255] set my address\r\n\r\n"); 45 | printf(" -r rx address [1-255] set RxDemo receiver address\r\n\r\n"); 46 | printf(" -i interval ms[1-6000] sets message interval timing\r\n\r\n"); 47 | printf(" -t tx_retries [0-255] sets message send retries\r\n\r\n"); 48 | printf(" -c channel [1-255] set transmit channel\r\n"); 49 | printf(" -f frequency [315,434,868,915] set ISM band\r\n\r\n"); 50 | printf(" -m modulation [1,38,100,250,500,4] set modulation\r\n\r\n"); 51 | 52 | exit(exval); 53 | } 54 | 55 | 56 | //|============================ Main ============================| 57 | int main(int argc, char *argv[]) { 58 | //------------- command line option parser ------------------- 59 | int opt; 60 | // no arguments given 61 | if(argc == 1) { 62 | fprintf(stderr, "This program needs arguments....\n\r\n\r"); 63 | print_help(1); 64 | } 65 | 66 | while((opt = getopt(argc, argv, "hVva:r:i:t:c:f:m:")) != -1) { 67 | switch(opt) { 68 | case 'h': 69 | print_help(0); 70 | break; 71 | case 'V': 72 | printf("%s %s\n\n", PACKAGE, VERSION_SW); 73 | exit(0); 74 | break; 75 | case 'v': 76 | printf("%s: Verbose option is set `%c'\n", PACKAGE, optopt); 77 | cc1100_debug = 1; 78 | break; 79 | case 'a': 80 | My_addr = atoi (optarg); 81 | break; 82 | case 'r': 83 | rx_demo_addr = atoi (optarg); 84 | break; 85 | case 'i': 86 | interval = atoi (optarg); 87 | break; 88 | case 't': 89 | tx_retries = atoi (optarg); 90 | break; 91 | case 'c': 92 | cc1100_channel_select = atoi (optarg); 93 | break; 94 | case 'f': 95 | cc1100_freq_select = atoi (optarg); 96 | switch(cc1100_freq_select){ 97 | case 315: 98 | cc1100_freq_select = 1; 99 | break; 100 | case 434: 101 | cc1100_freq_select = 2; 102 | break; 103 | case 868: 104 | cc1100_freq_select = 3; 105 | break; 106 | case 915: 107 | cc1100_freq_select = 4; 108 | break; 109 | } 110 | break; 111 | case 'm': 112 | cc1100_mode_select = atoi (optarg); 113 | 114 | switch(cc1100_mode_select){ 115 | case 1: 116 | cc1100_mode_select = 1; 117 | break; 118 | case 38: 119 | cc1100_mode_select = 2; 120 | break; 121 | 122 | case 100: 123 | cc1100_mode_select = 3; 124 | break; 125 | case 250: 126 | cc1100_mode_select = 4; 127 | break; 128 | case 500: 129 | cc1100_mode_select = 5; 130 | break; 131 | case 4: 132 | cc1100_mode_select = 6; 133 | break; 134 | } 135 | break; 136 | case ':': 137 | fprintf(stderr, "%s: Error - Option `%c' needs a value\n\n", PACKAGE, optopt); 138 | print_help(1); 139 | break; 140 | case '?': 141 | fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt); 142 | print_help(1); 143 | } 144 | } 145 | 146 | // print all remaining options 147 | for(; optind < argc; optind++) 148 | printf("argument: %s\n", argv[optind]); 149 | 150 | //------------- welcome message ------------------------ 151 | printf("Raspberry CC1101 SPI Library test\n"); 152 | 153 | //------------- hardware setup ------------------------ 154 | 155 | wiringPiSetup(); //setup wiringPi library 156 | 157 | cc1100.begin(My_addr); //setup cc1000 RF IC 158 | cc1100.sidle(); 159 | //cc1100.set_mode(0x04); //set modulation mode 1 = GFSK_1_2_kb; 2 = GFSK_38_4_kb; 3 = GFSK_100_kb; 4 = MSK_250_kb; 5 = MSK_500_kb; 6 = OOK_4_8_kb 160 | //cc1100.set_ISM(0x03); //set ISM Band 1=315MHz; 2=433MHz; 3=868MHz; 4=915MHz 161 | //cc1100.set_channel(0x01); //set channel 162 | cc1100.set_output_power_level(0); //set PA level 163 | //cc1100.set_myaddr(0x05); 164 | 165 | cc1100.receive(); 166 | 167 | cc1100.show_main_settings(); //shows setting debug messages to UART 168 | cc1100.show_register_settings(); 169 | //------------------------- Main Loop ------------------------ 170 | for (;;) 171 | { 172 | delay(1); //delay to reduce system load 173 | 174 | if (millis() - prev_millis_1s_timer >= interval) // one second update timer 175 | { 176 | Rx_addr = rx_demo_addr; //receiver address 177 | 178 | uint32_t time_stamp = millis(); //generate time stamp 179 | 180 | Tx_fifo[3] = (uint8_t)(time_stamp >> 24); //split 32-Bit timestamp to 4 byte array 181 | Tx_fifo[4] = (uint8_t)(time_stamp >> 16); 182 | Tx_fifo[5] = (uint8_t)(time_stamp >> 8); 183 | Tx_fifo[6] = (uint8_t)(time_stamp); 184 | 185 | Pktlen = 0x07; //set packet len to 0x13 186 | 187 | uint8_t res = cc1100.sent_packet(My_addr, Rx_addr, Tx_fifo, Pktlen, tx_retries); 188 | 189 | if( res == 1) //sents package over air. ACK is received via GPIO polling 190 | { 191 | printf("transmitted tx_timestamp: %ums \r\n\r\n", time_stamp); 192 | } 193 | prev_millis_1s_timer = millis(); 194 | } 195 | 196 | } 197 | printf("finished!\n"); 198 | return 0; 199 | } 200 | //-------------------- END OF MAIN -------------------------------- 201 | --------------------------------------------------------------------------------