├── 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 |
--------------------------------------------------------------------------------