Traxxas TQ 1st gen: try 5
[DIY-Multiprotocol-TX-Module.git] / Multiprotocol / CC2500_SPI.ino
blob4006e0e86d7a42b638dee1f2d239602d9e3054e8
2 /*
3  This project is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 3 of the License, or
6  (at your option) any later version.
8  Multiprotocol is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  GNU General Public License for more details.
13  You should have received a copy of the GNU General Public License
14  along with Multiprotocol.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 //-------------------------------
17 //-------------------------------
18 //CC2500 SPI routines
19 //-------------------------------
20 //-------------------------------
21 #ifdef CC2500_INSTALLED
22 #include "iface_cc2500.h"
24 //----------------------------
25 void CC2500_WriteReg(uint8_t address, uint8_t data)
27         CC25_CSN_off;
28         SPI_Write(address); 
29         NOP();
30         SPI_Write(data);
31         CC25_CSN_on;
32
34 //----------------------
35 static void CC2500_ReadRegisterMulti(uint8_t address, uint8_t data[], uint8_t length)
37         CC25_CSN_off;
38         SPI_Write(CC2500_READ_BURST | address);
39         for(uint8_t i = 0; i < length; i++)
40                 data[i] = SPI_Read();
41         CC25_CSN_on;
44 //--------------------------------------------
45 static uint8_t CC2500_ReadReg(uint8_t address)
46
47         uint8_t result;
48         CC25_CSN_off;
49         SPI_Write(CC2500_READ_SINGLE | address);
50         result = SPI_Read();  
51         CC25_CSN_on;
52         return(result); 
53
55 //------------------------
56 void CC2500_ReadData(uint8_t *dpbuffer, uint8_t len)
58         CC2500_ReadRegisterMulti(CC2500_3F_RXFIFO, dpbuffer, len);
61 //*********************************************
62 void CC2500_Strobe(uint8_t state)
64         CC25_CSN_off;
65         SPI_Write(state);
66         CC25_CSN_on;
69 static void CC2500_WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t length)
71         CC25_CSN_off;
72         SPI_Write(CC2500_WRITE_BURST | address);
73         for(uint8_t i = 0; i < length; i++)
74                 SPI_Write(data[i]);
75         CC25_CSN_on;
78 void CC2500_WriteData(uint8_t *dpbuffer, uint8_t len)
80         CC2500_Strobe(CC2500_SFTX);
81         CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, dpbuffer, len);
82         CC2500_Strobe(CC2500_STX);
85 void CC2500_SetTxRxMode(uint8_t mode)
87         if(mode == TX_EN)
88         {//from deviation firmware
89                 CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F);
90                 CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F | 0x40);
91         }
92         else
93                 if (mode == RX_EN)
94                 {
95                         CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F);
96                         CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F | 0x40);
97                 }
98                 else
99                 {
100                         CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F);
101                         CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F);
102                 }
105 //------------------------
106 /*static void cc2500_resetChip(void)
108         // Toggle chip select signal
109         CC25_CSN_on;
110         delayMicroseconds(30);
111         CC25_CSN_off;
112         delayMicroseconds(30);
113         CC25_CSN_on;
114         delayMicroseconds(45);
115         CC2500_Strobe(CC2500_SRES);
116         _delay_ms(100);
119 uint8_t CC2500_Reset()
121         CC2500_Strobe(CC2500_SRES);
122         delayMilliseconds(1);
123         CC2500_SetTxRxMode(TXRX_OFF);
124         return CC2500_ReadReg(CC2500_0E_FREQ1) == 0xC4;//check if reset
127 static void CC2500_SetPower_Value(uint8_t power)
129         const unsigned char patable[8]= {
130                 0xC5,  // -12dbm
131                 0x97, // -10dbm
132                 0x6E, // -8dbm
133                 0x7F, // -6dbm
134                 0xA9, // -4dbm
135                 0xBB, // -2dbm
136                 0xFE, // 0dbm
137                 0xFF // 1.5dbm
138         };
139         if (power > 7)
140                 power = 7;
141         CC2500_WriteReg(CC2500_3E_PATABLE,  patable[power]);
144 void CC2500_SetPower()
146         uint8_t power=CC2500_BIND_POWER;
147         if(IS_BIND_DONE)
148                 #ifdef CC2500_ENABLE_LOW_POWER
149                         power=IS_POWER_FLAG_on?CC2500_HIGH_POWER:CC2500_LOW_POWER;
150                 #else
151                         power=CC2500_HIGH_POWER;
152                 #endif
153         if(IS_LBT_POWER_on)
154         {
155                 power=CC2500_LBT_POWER;
156                 LBT_POWER_off;                  // Only accept once
157         }
158         if(IS_RANGE_FLAG_on)
159                 power=CC2500_RANGE_POWER;
160         if(prev_power != power)
161         {
162                 CC2500_WriteReg(CC2500_3E_PATABLE, power);
163                 prev_power=power;
164         }
167 void __attribute__((unused)) CC2500_SetFreqOffset()
169         if(prev_option != option)
170         {
171                 prev_option = option;
172                 CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
173         }
176 void __attribute__((unused)) CC2500_250K_Init()
178         CC2500_Strobe(CC2500_SIDLE);
180         // Address Config = No address check
181         // Base Frequency = 2400
182         // CRC Autoflush = false
183         // CRC Enable = false
184         // Channel Spacing = 333.251953
185         // Data Format = Normal mode
186         // Data Rate = 249.939
187         // Deviation = 126.953125
188         // Device Address = 0
189         // Manchester Enable = false
190         // Modulated = true
191         // Modulation Format = GFSK
192         // Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
193         // RX Filter BW = 203.125000
194         // Sync Word Qualifier Mode = No preamble/sync
195         // TX Power = 0
196         // Whitening = false
197         // Fast Frequency Hopping - no PLL auto calibration
198 /*      //Previous config
199         CC2500_WriteReg(CC2500_08_PKTCTRL0,     0x01);   // Packet Automation Control
200         CC2500_WriteReg(CC2500_0B_FSCTRL1,      0x0A);   // Frequency Synthesizer Control
201         CC2500_WriteReg(CC2500_0C_FSCTRL0, option);  // Frequency offset hack 
202         CC2500_WriteReg(CC2500_0D_FREQ2,        0x5C);   // Frequency Control Word, High Byte
203         CC2500_WriteReg(CC2500_0E_FREQ1,        0x4E);   // Frequency Control Word, Middle Byte
204         CC2500_WriteReg(CC2500_0F_FREQ0,        0xC3);   // Frequency Control Word, Low Byte
205         CC2500_WriteReg(CC2500_10_MDMCFG4,      0x8D);   // Modem Configuration
206         CC2500_WriteReg(CC2500_11_MDMCFG3,      0x3B);   // Modem Configuration
207         CC2500_WriteReg(CC2500_12_MDMCFG2,      0x10);   // Modem Configuration
208         CC2500_WriteReg(CC2500_13_MDMCFG1,      0x23);   // Modem Configuration
209         CC2500_WriteReg(CC2500_14_MDMCFG0,      0xA4);   // Modem Configuration
210         CC2500_WriteReg(CC2500_15_DEVIATN,      0x62);   // Modem Deviation Setting
211         CC2500_WriteReg(CC2500_18_MCSM0,        0x08);   // Main Radio Control State Machine Configuration
212         CC2500_WriteReg(CC2500_19_FOCCFG,       0x1D);   // Frequency Offset Compensation Configuration
213         CC2500_WriteReg(CC2500_1A_BSCFG,        0x1C);   // Bit Synchronization Configuration
214         CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xC7);   // AGC Control
215         CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00);   // AGC Control
216         CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xB0);   // AGC Control
217         CC2500_WriteReg(CC2500_21_FREND1,       0xB6);   // Front End RX Configuration
218         CC2500_WriteReg(CC2500_23_FSCAL3,       0xEA);   // Frequency Synthesizer Calibration
219         CC2500_WriteReg(CC2500_25_FSCAL1,       0x00);   // Frequency Synthesizer Calibration
220         CC2500_WriteReg(CC2500_26_FSCAL0,       0x11);   // Frequency Synthesizer Calibration
222         CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);   // Packet Automation Control, address check true auto append RSSI & LQI
223         CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x00);   // Packet Automation Control, fixed packet len
224         CC2500_WriteReg(CC2500_0B_FSCTRL1,  0x0A);   // Frequency Synthesizer Control (IF Frequency)
225         CC2500_WriteReg(CC2500_0C_FSCTRL0,  0x00);   // Frequency Synthesizer Control
226         CC2500_WriteReg(CC2500_0D_FREQ2,    0x5C);   // Frequency Control Word, High Byte
227         CC2500_WriteReg(CC2500_0E_FREQ1,    0x4E);   // Frequency Control Word, Middle Byte
228         CC2500_WriteReg(CC2500_0F_FREQ0,    0xC5);   // Frequency Control Word, Low Byte
229         CC2500_WriteReg(CC2500_10_MDMCFG4,  0x3D);   // Modem Configuration  Set to 406kHz BW filter
230         CC2500_WriteReg(CC2500_11_MDMCFG3,  0x3B);   // Modem Configuration
231         CC2500_WriteReg(CC2500_12_MDMCFG2,      0x10);   // Modem Configuration, GFSK, no preambule and no sync word -> TX by default
232         CC2500_WriteReg(CC2500_13_MDMCFG1,  0x03);   // Modem Configuration, 2 bytes of preamble
233         CC2500_WriteReg(CC2500_14_MDMCFG0,  0xA4);   // Modem Configuration
234         CC2500_WriteReg(CC2500_15_DEVIATN,  0x62);   // Modem Deviation Setting
235         CC2500_WriteReg(CC2500_18_MCSM0,    0x08);   // Main Radio Control State Machine Configuration
236         CC2500_WriteReg(CC2500_19_FOCCFG,   0x1D);   // Frequency Offset Compensation Configuration
237         CC2500_WriteReg(CC2500_1A_BSCFG,    0x1C);   // Bit Synchronization Configuration
238         CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xC7);   // AGC Control
239         CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00);   // AGC Control
240         CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xB0);   // AGC Control
241         CC2500_WriteReg(CC2500_21_FREND1,   0xB6);   // Front End RX Configuration
242         CC2500_WriteReg(CC2500_23_FSCAL3,   0xEA);   // Frequency Synthesizer Calibration
243         CC2500_WriteReg(CC2500_25_FSCAL1,   0x00);   // Frequency Synthesizer Calibration
244         CC2500_WriteReg(CC2500_26_FSCAL0,   0x11);   // Frequency Synthesizer Calibration
245         
246         //Prep RX
247         // Set first 3 bytes of rx addr in [0]->SYNC1, [1]->SYNC0 and [2]->ADDR
248         // CC2500_WriteReg(CC2500_04_SYNC1,    [0]);   // Sync word, high byte
249         // CC2500_WriteReg(CC2500_05_SYNC0,    [1]);   // Sync word, low byte
250         // CC2500_WriteReg(CC2500_09_ADDR,     [2]);   // Set addr
251         //RX
252         // CC2500_WriteReg(CC2500_12_MDMCFG2,  0x12);  // Modem Configuration, GFSK, 16/16 Sync Word TX&RX
253         //TX
254         // CC2500_WriteReg(CC2500_12_MDMCFG2,   0x10); // Modem Configuration, GFSK, no preambule and no sync word
255         // need to set packet length before sending/receiving
256         // CC2500_WriteReg(CC2500_06_PKTLEN,   cc2500_packet_len);  // Packet len, fix packet len
258         CC2500_SetTxRxMode(TX_EN);
259         CC2500_SetPower();
261 void __attribute__((unused)) CC2500_250K_HoppingCalib(uint8_t num_freq)
263         for (uint8_t i = 0; i < num_freq; i++)
264         {
265                 CC2500_Strobe(CC2500_SIDLE);
266                 // spacing is 333.25 kHz, must multiply channel by 3
267                 CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[i]*3);
268                 // calibrate
269                 CC2500_Strobe(CC2500_SCAL);
270                 delayMicroseconds(900);
271                 calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
272         }
274 void __attribute__((unused)) CC2500_250K_Hopping(uint8_t index)
276         // spacing is 333.25 kHz, must multiply channel by 3
277         CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
278         // set PLL calibration
279         CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]);
281 void __attribute__((unused)) CC2500_250K_RFChannel(uint8_t number)
283         CC2500_Strobe(CC2500_SIDLE);
284         // spacing is 333.25 kHz, must multiply channel by 3
285         CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
286         // calibrate
287         CC2500_Strobe(CC2500_SCAL);
288         delayMicroseconds(900);
290 #endif