altos: Complete cc1200 driver
[fw/altos] / src / drivers / ao_cc1200.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include <ao.h>
19 #include <ao_cc1200.h>
20 #include <ao_exti.h>
21 #include <ao_fec.h>
22 #include <ao_packet.h>
23
24 static uint8_t ao_radio_mutex;
25
26 static uint8_t ao_radio_wake;           /* radio ready. Also used as sleep address */
27 static uint8_t ao_radio_abort;          /* radio operation should abort */
28
29 int8_t  ao_radio_rssi;                  /* Last received RSSI value */
30
31 #define CC1200_DEBUG            0
32 #define CC1200_LOW_LEVEL_DEBUG  0
33 #define CC1200_TRACE            0
34 #define CC1200_APRS_TRACE       0
35
36 extern const uint32_t   ao_radio_cal;
37
38 #define FOSC    40000000
39
40 #define ao_radio_select()       ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_125kHz)
41 #define ao_radio_deselect()     ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS)
42 #define ao_radio_spi_send(d,l)  ao_spi_send((d), (l), AO_CC1200_SPI_BUS)
43 #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS)
44 #define ao_radio_spi_recv(d,l)  ao_spi_recv((d), (l), AO_CC1200_SPI_BUS)
45 #define ao_radio_duplex(o,i,l)  ao_spi_duplex((o), (i), (l), AO_CC1200_SPI_BUS)
46
47 static uint8_t
48 ao_radio_reg_read(uint16_t addr)
49 {
50         uint8_t data[2];
51         uint8_t d;
52
53 #if CC1200_TRACE
54         printf("\t\tao_radio_reg_read (%04x): ", addr); flush();
55 #endif
56         if (CC1200_IS_EXTENDED(addr)) {
57                 data[0] = ((1 << CC1200_READ)  |
58                            (0 << CC1200_BURST) |
59                            CC1200_EXTENDED);
60                 data[1] = addr;
61                 d = 2;
62         } else {
63                 data[0] = ((1 << CC1200_READ)  |
64                            (0 << CC1200_BURST) |
65                            addr);
66                 d = 1;
67         }
68         ao_radio_select();
69         ao_radio_spi_send(data, d);
70         ao_radio_spi_recv(data, 1);
71         ao_radio_deselect();
72 #if CC1200_TRACE
73         printf (" %02x\n", data[0]);
74 #endif
75         return data[0];
76 }
77
78 static void
79 ao_radio_reg_write(uint16_t addr, uint8_t value)
80 {
81         uint8_t data[3];
82         uint8_t d;
83
84 #if CC1200_TRACE
85         printf("\t\tao_radio_reg_write (%04x): %02x\n", addr, value);
86 #endif
87         if (CC1200_IS_EXTENDED(addr)) {
88                 data[0] = ((0 << CC1200_READ)  |
89                            (0 << CC1200_BURST) |
90                            CC1200_EXTENDED);
91                 data[1] = addr;
92                 d = 2;
93         } else {
94                 data[0] = ((0 << CC1200_READ)  |
95                            (0 << CC1200_BURST) |
96                            addr);
97                 d = 1;
98         }
99         data[d] = value;
100         ao_radio_select();
101         ao_radio_spi_send(data, d+1);
102         ao_radio_deselect();
103 #if CC1200_TRACE
104         (void) ao_radio_reg_read(addr);
105 #endif
106 }
107
108 static uint8_t
109 ao_radio_strobe(uint8_t addr)
110 {
111         uint8_t in;
112
113 #if CC1200_TRACE
114         printf("\t\tao_radio_strobe (%02x): ", addr); flush();
115 #endif
116         ao_radio_select();
117         ao_radio_duplex(&addr, &in, 1);
118         ao_radio_deselect();
119 #if CC1200_TRACE
120         printf("%02x\n", in); flush();
121 #endif
122         return in;
123 }
124
125 static uint8_t
126 ao_radio_fifo_read(uint8_t *data, uint8_t len)
127 {
128         uint8_t addr = ((1 << CC1200_READ)  |
129                         (1 << CC1200_BURST) |
130                         CC1200_FIFO);
131         uint8_t status;
132
133         ao_radio_select();
134         ao_radio_duplex(&addr, &status, 1);
135         ao_radio_spi_recv(data, len);
136         ao_radio_deselect();
137         return status;
138 }
139
140 static uint8_t
141 ao_radio_fifo_write_start(void)
142 {
143         uint8_t addr = ((0 << CC1200_READ)  |
144                         (1 << CC1200_BURST) |
145                         CC1200_FIFO);
146         uint8_t status;
147
148         ao_radio_select();
149         ao_radio_duplex(&addr, &status, 1);
150         return status;
151 }
152
153 static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) {
154         ao_radio_deselect();
155         return status;
156 }
157
158 static uint8_t
159 ao_radio_fifo_write(const uint8_t *data, uint8_t len)
160 {
161         uint8_t status = ao_radio_fifo_write_start();
162         ao_radio_spi_send(data, len);
163         return ao_radio_fifo_write_stop(status);
164 }
165
166 static uint8_t
167 ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
168 {
169         uint8_t status = ao_radio_fifo_write_start();
170         ao_radio_spi_send_fixed(data, len);
171         return ao_radio_fifo_write_stop(status);
172 }
173
174 static uint8_t
175 ao_radio_tx_fifo_space(void)
176 {
177         return CC1200_FIFO_SIZE - ao_radio_reg_read(CC1200_NUM_TXBYTES);
178 }
179
180 static uint8_t
181 ao_radio_status(void)
182 {
183         return ao_radio_strobe (CC1200_SNOP);
184 }
185
186 void
187 ao_radio_recv_abort(void)
188 {
189         ao_radio_abort = 1;
190         ao_wakeup(&ao_radio_wake);
191 }
192
193 #define ao_radio_rdf_value 0x55
194
195 static void
196 ao_radio_isr(void)
197 {
198         ao_exti_disable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
199         ao_radio_wake = 1;
200         ao_wakeup(&ao_radio_wake);
201 }
202
203 static void
204 ao_radio_start_tx(void)
205 {
206         ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
207         ao_radio_strobe(CC1200_STX);
208 }
209
210 static void
211 ao_radio_start_rx(void)
212 {
213         ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
214         ao_radio_strobe(CC1200_SRX);
215 }
216
217 static void
218 ao_radio_idle(void)
219 {
220         for (;;) {
221                 uint8_t state = (ao_radio_strobe(CC1200_SIDLE) >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
222                 if (state == CC1200_STATUS_STATE_IDLE) {
223                         ao_radio_strobe(CC1200_SFTX);
224                         ao_radio_strobe(CC1200_SFRX);
225                         break;
226                 }
227                 if (state == CC1200_STATUS_STATE_TX_FIFO_ERROR)
228                         ao_radio_strobe(CC1200_SFTX);
229                 if (state == CC1200_STATUS_STATE_RX_FIFO_ERROR)
230                         ao_radio_strobe(CC1200_SFRX);
231         }
232         /* Flush any pending TX bytes */
233         ao_radio_strobe(CC1200_SFTX);
234 }
235
236 /*
237  * Packet deviation
238  *
239  *      fdev = fosc >> 22 * (256 + dev_m) << dev_e
240  *
241  * Deviation for 38400 baud should be 20.5kHz:
242  *
243  *      40e6 / (2 ** 22) * (256 + 13) * (2 ** 3) = 20523Hz
244  *
245  * Deviation for 9600 baud should be 5.125kHz:
246  *
247  *      40e6 / (2 ** 22) * (256 + 13) * (2 ** 1) = 5131Hz
248  *
249  * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and
250  * cc115l can't do that, so we'll use 1.5kHz instead:
251  *
252  *      40e6 / (2 ** 21) * (79) = 1506Hz
253  */
254
255 #define PACKET_DEV_M_384        13
256 #define PACKET_DEV_E_384        3
257
258 #define PACKET_DEV_M_96         13
259 #define PACKET_DEV_E_96         1
260
261 #define PACKET_DEV_M_24         79
262 #define PACKET_DEV_E_24         0
263
264 /*
265  * For our packet data
266  *
267  *              (2**20 + DATARATE_M) * 2 ** DATARATE_E
268  *      Rdata = -------------------------------------- * fosc
269  *                           2 ** 39
270  *
271  * Given the bit period of the baseband, T, the bandwidth of the
272  * baseband signal is B = 1/(2T).  The overall bandwidth of the
273  * modulated signal is then Channel bandwidth = 2Δf + 2B.
274  *
275  * 38400 -- 2 * 20500 + 38400 = 79.4 kHz
276  *  9600 -- 2 * 5.125 +  9600 = 19.9 kHz
277  *  2400 -- 2 * 1.5   +  2400 =  5.4 khz
278  *
279  * Symbol rate 38400 Baud:
280  *
281  *      DATARATE_M = 1013008
282  *      DATARATE_E = 8
283  *      CHANBW = 104.16667
284  *
285  * Symbol rate 9600 Baud:
286  *
287  *      DATARATE_M = 1013008
288  *      DATARATE_E = 6
289  *      CHANBW = 26.042 (round to 19.8)
290  *
291  * Symbol rate 2400 Baud:
292  *
293  *      DATARATE_M = 1013008
294  *      DATARATE_E = 4
295  *      CHANBW = 5.0 (round to 9.5)
296  */
297
298 #define PACKET_SYMBOL_RATE_M            1013008
299
300 #define PACKET_SYMBOL_RATE_E_384        8
301
302 /* 200 / 2 = 100 */
303 #define PACKET_CHAN_BW_384      ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
304                                  (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
305
306 #define PACKET_SYMBOL_RATE_E_96         6
307 /* 200 / 10 = 20 */
308 #define PACKET_CHAN_BW_96       ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
309                                  (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
310
311 #define PACKET_SYMBOL_RATE_E_24         4
312 /* 200 / 25 = 8 */
313 #define PACKET_CHAN_BW_24       ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
314                                  (44 << CC1200_CHAN_BW_BB_CIC_DECFACT))
315
316 static const uint16_t packet_setup[] = {
317         CC1200_SYMBOL_RATE1,            ((PACKET_SYMBOL_RATE_M >> 8) & 0xff),
318         CC1200_SYMBOL_RATE0,            ((PACKET_SYMBOL_RATE_M >> 0) & 0xff),
319         CC1200_PKT_CFG2,                                 /* Packet Configuration Reg. 2 */
320                 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
321                  (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
322                  (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
323         CC1200_PKT_CFG1,                                 /* Packet Configuration Reg. 1 */
324                 ((1 << CC1200_PKT_CFG1_FEC_EN) |
325                  (1 << CC1200_PKT_CFG1_WHITE_DATA) |
326                  (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
327                  (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
328                  (CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES << CC1200_PKT_CFG1_CRC_CFG) |
329                  (1 << CC1200_PKT_CFG1_APPEND_STATUS)),
330         CC1200_PREAMBLE_CFG1,   ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
331                                  (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
332 };
333
334 static const uint16_t packet_setup_384[] = {
335         CC1200_DEVIATION_M,     PACKET_DEV_M_384,
336         CC1200_MODCFG_DEV_E,    ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
337                                  (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
338                                  (PACKET_DEV_E_384 << CC1200_MODCFG_DEV_E_DEV_E)),
339         CC1200_SYMBOL_RATE2,    ((PACKET_SYMBOL_RATE_E_384 << CC1200_SYMBOL_RATE2_DATARATE_E) |
340                                  (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
341         CC1200_CHAN_BW,         PACKET_CHAN_BW_384,
342         CC1200_MDMCFG2,                                  /* General Modem Parameter Configuration Reg. 2 */
343                 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
344                  (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
345                  (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
346                  (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
347 };
348
349 static const uint16_t packet_setup_96[] = {
350         CC1200_DEVIATION_M,     PACKET_DEV_M_96,
351         CC1200_MODCFG_DEV_E,    ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
352                                  (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
353                                  (PACKET_DEV_E_96 << CC1200_MODCFG_DEV_E_DEV_E)),
354         CC1200_SYMBOL_RATE2,    ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) |
355                                  (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
356         CC1200_CHAN_BW,         PACKET_CHAN_BW_96,
357         CC1200_MDMCFG2,                                  /* General Modem Parameter Configuration Reg. 2 */
358                 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
359                  (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
360                  (CC1200_MDMCFG2_UPSAMPLER_P_32 << CC1200_MDMCFG2_UPSAMPLER_P) |
361                  (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
362 };
363
364 static const uint16_t packet_setup_24[] = {
365         CC1200_DEVIATION_M,     PACKET_DEV_M_24,
366         CC1200_MODCFG_DEV_E,    ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
367                                  (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
368                                  (PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)),
369         CC1200_SYMBOL_RATE2,    ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) |
370                                  (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
371         CC1200_CHAN_BW,         PACKET_CHAN_BW_24,
372         CC1200_MDMCFG2,                                  /* General Modem Parameter Configuration Reg. 2 */
373                 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
374                  (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
375                  (CC1200_MDMCFG2_UPSAMPLER_P_64 << CC1200_MDMCFG2_UPSAMPLER_P) |
376                  (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
377 };
378
379 /*
380  * RDF deviation is 3kHz
381  *
382  *      fdev = fosc >> 22 * (256 + dev_m) << dev_e      dev_e != 0
383  *      fdev = fosc >> 21 * dev_m                       dev_e == 0
384  *
385  *      40e6 / (2 ** 21) * 157 = 2995Hz
386  */
387
388 #define RDF_DEV_E       0
389 #define RDF_DEV_M       157
390
391 /*
392  * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone)
393  *
394  *              (2**20 + DATARATE_M) * 2 ** DATARATE_E
395  *      Rdata = -------------------------------------- * fosc
396  *                           2 ** 39
397  *
398  *      DATARATE_M = 669411
399  *      DATARATE_E = 4
400  *
401  * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes
402  */
403 #define RDF_SYMBOL_RATE_E       4
404 #define RDF_SYMBOL_RATE_M       669411
405 #define RDF_PACKET_LEN  50
406
407 static const uint16_t rdf_setup[] = {
408         CC1200_DEVIATION_M,     RDF_DEV_M,
409         CC1200_MODCFG_DEV_E,    ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
410                                  (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
411                                  (RDF_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
412         CC1200_SYMBOL_RATE2,    ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
413                                  (((RDF_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
414         CC1200_SYMBOL_RATE1,    ((RDF_SYMBOL_RATE_M >> 8) & 0xff),
415         CC1200_SYMBOL_RATE0,    ((RDF_SYMBOL_RATE_M >> 0) & 0xff),
416         CC1200_PKT_CFG2,                                 /* Packet Configuration Reg. 2 */
417                 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
418                  (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
419                  (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
420         CC1200_PKT_CFG1,                                 /* Packet Configuration Reg. 1 */
421                 ((0 << CC1200_PKT_CFG1_FEC_EN) |
422                  (0 << CC1200_PKT_CFG1_WHITE_DATA) |
423                  (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
424                  (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
425                  (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
426                  (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
427         CC1200_PREAMBLE_CFG1,
428                 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
429                  (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
430         CC1200_MDMCFG2,                                  /* General Modem Parameter Configuration Reg. 2 */
431                 ((0 << CC1200_MDMCFG2_ASK_SHAPE) |
432                  (0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
433                  (12 << CC1200_MDMCFG2_UPSAMPLER_P) |
434                  (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
435 };
436
437 /*
438  * APRS deviation is 3kHz
439  *
440  *      fdev = fosc >> 22 * (256 + dev_m) << dev_e      dev_e != 0
441  *      fdev = fosc >> 21 * dev_m                       dev_e == 0
442  *
443  *      40e6 / (2 ** 21) * 157 = 2995Hz
444  */
445
446 #define APRS_DEV_E      0
447 #define APRS_DEV_M      157
448
449 /*
450  * For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate)
451  *
452  *              (2**20 + DATARATE_M) * 2 ** DATARATE_E
453  *      Rdata = -------------------------------------- * fosc
454  *                           2 ** 39
455  *
456  *      DATARATE_M = 1013008
457  *      DATARATE_E = 6
458  *
459  *      Rdata = 9599.998593330383301
460  *
461  */
462 #define APRS_SYMBOL_RATE_E      6
463 #define APRS_SYMBOL_RATE_M      1013008
464
465 static const uint16_t aprs_setup[] = {
466         CC1200_DEVIATION_M,     APRS_DEV_M,
467         CC1200_MODCFG_DEV_E,    ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
468                                  (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
469                                  (APRS_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
470         CC1200_SYMBOL_RATE2,    ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
471                                  (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
472         CC1200_SYMBOL_RATE1,    ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
473         CC1200_SYMBOL_RATE0,    ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
474         CC1200_PKT_CFG2,                                 /* Packet Configuration Reg. 2 */
475                 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
476                  (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
477                  (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
478         CC1200_PKT_CFG1,                                 /* Packet Configuration Reg. 1 */
479                 ((0 << CC1200_PKT_CFG1_FEC_EN) |
480                  (0 << CC1200_PKT_CFG1_WHITE_DATA) |
481                  (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
482                  (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
483                  (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
484                  (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
485         CC1200_PKT_CFG0,                                 /* Packet Configuration Reg. 0 */
486                 ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
487                  (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
488                  (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
489                  (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
490         CC1200_PREAMBLE_CFG1,
491                 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
492                  (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
493         CC1200_MDMCFG2,                                  /* General Modem Parameter Configuration Reg. 2 */
494                 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
495                  (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
496                  (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
497                  (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
498 };
499
500 /*
501  * For Test mode, we want an unmodulated carrier. To do that, we
502  * set the deviation to zero and enable a preamble so that the radio
503  * turns on before we send any data
504  */
505
506 static const uint16_t test_setup[] = {
507         CC1200_DEVIATION_M,     0,
508         CC1200_MODCFG_DEV_E,    ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
509                                  (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
510                                  (0 << CC1200_MODCFG_DEV_E_DEV_E)),
511         CC1200_SYMBOL_RATE2,            ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
512                                  (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
513         CC1200_SYMBOL_RATE1,            ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
514         CC1200_SYMBOL_RATE0,            ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
515         CC1200_PKT_CFG2,        ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
516                                  (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
517         CC1200_PKT_CFG1,        ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
518                                  (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
519                                  (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
520                                  (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
521         CC1200_PREAMBLE_CFG1,   ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
522                                  (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
523 };
524
525 #define AO_PKT_CFG0_INFINITE ((CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
526                               (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |      \
527                               (0 << CC1200_PKT_CFG0_UART_MODE_EN) |     \
528                               (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
529
530 #define AO_PKT_CFG0_FIXED ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
531                            (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |         \
532                            (0 << CC1200_PKT_CFG0_UART_MODE_EN) |        \
533                            (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
534
535 static uint16_t ao_radio_mode;
536
537 #define AO_RADIO_MODE_BITS_PACKET       1
538 #define AO_RADIO_MODE_BITS_TX_BUF       4
539 #define AO_RADIO_MODE_BITS_TX_FINISH    8
540 #define AO_RADIO_MODE_BITS_RX           16
541 #define AO_RADIO_MODE_BITS_RDF          32
542 #define AO_RADIO_MODE_BITS_APRS         64
543 #define AO_RADIO_MODE_BITS_TEST         128
544 #define AO_RADIO_MODE_BITS_INFINITE     256
545 #define AO_RADIO_MODE_BITS_FIXED        512
546
547 #define AO_RADIO_MODE_NONE              0
548 #define AO_RADIO_MODE_PACKET_TX         (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED    | AO_RADIO_MODE_BITS_TX_FINISH)
549 #define AO_RADIO_MODE_PACKET_RX         (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED    | AO_RADIO_MODE_BITS_RX)
550 #define AO_RADIO_MODE_RDF               (AO_RADIO_MODE_BITS_RDF    | AO_RADIO_MODE_BITS_FIXED    | AO_RADIO_MODE_BITS_TX_FINISH)
551 #define AO_RADIO_MODE_APRS_BUF          (AO_RADIO_MODE_BITS_APRS   | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
552 #define AO_RADIO_MODE_APRS_LAST_BUF     (AO_RADIO_MODE_BITS_APRS   | AO_RADIO_MODE_BITS_FIXED    | AO_RADIO_MODE_BITS_TX_BUF)
553 #define AO_RADIO_MODE_APRS_FINISH       (AO_RADIO_MODE_BITS_APRS   | AO_RADIO_MODE_BITS_FIXED    | AO_RADIO_MODE_BITS_TX_FINISH)
554 #define AO_RADIO_MODE_TEST              (AO_RADIO_MODE_BITS_TEST   | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
555
556 static void
557 _ao_radio_set_regs(const uint16_t *regs, int nreg)
558 {
559         int i;
560
561         for (i = 0; i < nreg; i++) {
562                 ao_radio_reg_write(regs[0], regs[1]);
563                 regs += 2;
564         }
565 }
566
567 #define ao_radio_set_regs(setup) _ao_radio_set_regs(setup, (sizeof (setup) / sizeof(setup[0])) >> 1)
568
569 static void
570 ao_radio_set_mode(uint16_t new_mode)
571 {
572         uint16_t changes;
573
574         if (new_mode == ao_radio_mode)
575                 return;
576
577         changes = new_mode & (~ao_radio_mode);
578
579         if (changes & AO_RADIO_MODE_BITS_PACKET) {
580                 ao_radio_set_regs(packet_setup);
581
582                 switch (ao_config.radio_rate) {
583                 default:
584                 case AO_RADIO_RATE_38400:
585                         ao_radio_set_regs(packet_setup_384);
586                         break;
587                 case AO_RADIO_RATE_9600:
588                         ao_radio_set_regs(packet_setup_96);
589                         break;
590                 case AO_RADIO_RATE_2400:
591                         ao_radio_set_regs(packet_setup_24);
592                         break;
593                 }
594         }
595
596         if (changes & AO_RADIO_MODE_BITS_TX_BUF)
597                 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR);
598
599         if (changes & AO_RADIO_MODE_BITS_TX_FINISH)
600                 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
601
602         if (changes & AO_RADIO_MODE_BITS_RX)
603                 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
604
605         if (changes & AO_RADIO_MODE_BITS_RDF)
606                 ao_radio_set_regs(rdf_setup);
607
608         if (changes & AO_RADIO_MODE_BITS_APRS)
609                 ao_radio_set_regs(aprs_setup);
610
611         if (changes & AO_RADIO_MODE_BITS_TEST)
612                 ao_radio_set_regs(test_setup);
613
614         if (changes & AO_RADIO_MODE_BITS_INFINITE)
615                 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_INFINITE);
616
617         if (changes & AO_RADIO_MODE_BITS_FIXED)
618                 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_FIXED);
619
620         ao_radio_mode = new_mode;
621 }
622
623 static const uint16_t radio_setup[] = {
624 #include "ao_cc1200_CC1200.h"
625 };
626
627 static uint8_t  ao_radio_configured = 0;
628
629 static void
630 ao_radio_setup(void)
631 {
632         ao_radio_strobe(CC1200_SRES);
633
634         ao_radio_set_regs(radio_setup);
635
636         ao_radio_mode = 0;
637
638         ao_config_get();
639
640         ao_radio_configured = 1;
641 }
642
643 static void
644 ao_radio_set_len(uint8_t len)
645 {
646         static uint8_t  last_len;
647
648         if (len != last_len) {
649                 ao_radio_reg_write(CC1200_PKT_LEN, len);
650                 last_len = len;
651         }
652 }
653
654 static void
655 ao_radio_get(uint8_t len)
656 {
657         static uint32_t last_radio_setting;
658         static uint8_t  last_radio_rate;
659
660         ao_mutex_get(&ao_radio_mutex);
661
662         if (!ao_radio_configured)
663                 ao_radio_setup();
664         if (ao_config.radio_setting != last_radio_setting) {
665                 ao_radio_reg_write(CC1200_FREQ2, ao_config.radio_setting >> 16);
666                 ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8);
667                 ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting);
668                 last_radio_setting = ao_config.radio_setting;
669         }
670         if (ao_config.radio_rate != last_radio_rate) {
671                 ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET;
672                 last_radio_rate = ao_config.radio_rate;
673         }
674         ao_radio_set_len(len);
675 }
676
677 #define ao_radio_put()  ao_mutex_put(&ao_radio_mutex)
678
679 static inline uint8_t
680 ao_radio_state(void)
681 {
682         return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
683 }
684
685 #if CC1200_DEBUG
686 void
687 ao_radio_show_state(char *where)
688 {
689         printf("%s: state %d len %d rxbytes %d\n",
690                where, ao_radio_state(),
691                ao_radio_reg_read(CC1200_PKT_LEN),
692                ao_radio_reg_read(CC1200_NUM_RXBYTES));
693 }
694 #else
695 #define ao_radio_show_state(where)
696 #endif
697
698 /* Wait for the radio to signal an interrupt
699  */
700 static void
701 ao_radio_wait_isr(uint16_t timeout)
702 {
703         uint8_t state;
704
705         state = ao_radio_state();
706         switch (state) {
707         case CC1200_STATUS_STATE_IDLE:
708         case CC1200_STATUS_STATE_RX_FIFO_ERROR:
709         case CC1200_STATUS_STATE_TX_FIFO_ERROR:
710 #if CC1200_LOW_LEVEL_DEBUG
711                 printf("before wait, state %d\n", state); flush();
712 #endif
713                 ao_radio_abort = 1;
714                 return;
715         }
716
717         if (timeout)
718                 ao_alarm(timeout);
719
720         ao_arch_block_interrupts();
721         while (!ao_radio_wake && !ao_radio_abort)
722                 if (ao_sleep(&ao_radio_wake))
723                         ao_radio_abort = 1;
724         ao_arch_release_interrupts();
725         if (timeout)
726                 ao_clear_alarm();
727 }
728
729 static void
730 ao_rdf_start(uint8_t len)
731 {
732         ao_radio_abort = 0;
733         ao_radio_get(len);
734
735         ao_radio_set_mode(AO_RADIO_MODE_RDF);
736         ao_radio_wake = 0;
737 }
738
739 static void
740 ao_radio_run(void)
741 {
742         ao_radio_start_tx();
743         ao_radio_wait_isr(0);
744         if (!ao_radio_wake)
745                 ao_radio_idle();
746         ao_radio_put();
747 }
748
749 void
750 ao_radio_rdf(void)
751 {
752         ao_rdf_start(AO_RADIO_RDF_LEN);
753
754         ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
755
756         ao_radio_run();
757 }
758
759 void
760 ao_radio_continuity(uint8_t c)
761 {
762         uint8_t i;
763         uint8_t status;
764
765         ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
766
767         status = ao_radio_fifo_write_start();
768         for (i = 0; i < 3; i++) {
769                 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
770                 if (i < c)
771                         ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
772                 else
773                         ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
774         }
775         ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
776         status = ao_radio_fifo_write_stop(status);
777         (void) status;
778         ao_radio_run();
779 }
780
781 void
782 ao_radio_rdf_abort(void)
783 {
784         ao_radio_abort = 1;
785         ao_wakeup(&ao_radio_wake);
786 }
787
788 static void
789 ao_radio_test_cmd(void)
790 {
791         uint8_t mode = 2;
792         static uint8_t radio_on;
793         ao_cmd_white();
794         if (ao_cmd_lex_c != '\n') {
795                 ao_cmd_decimal();
796                 mode = (uint8_t) ao_cmd_lex_u32;
797         }
798         mode++;
799         if ((mode & 2) && !radio_on) {
800 #if HAS_MONITOR
801                 ao_monitor_disable();
802 #endif
803 #if PACKET_HAS_SLAVE
804                 ao_packet_slave_stop();
805 #endif
806                 ao_radio_get(0xff);
807                 ao_radio_set_mode(AO_RADIO_MODE_TEST);
808                 ao_radio_strobe(CC1200_STX);
809 #if CC1200_TRACE
810                 { int t;
811                         for (t = 0; t < 10; t++) {
812                                 printf ("status: %02x\n", ao_radio_status());
813                                 ao_delay(AO_MS_TO_TICKS(100));
814                         }
815                 }
816 #endif
817                 radio_on = 1;
818         }
819         if (mode == 3) {
820                 printf ("Hit a character to stop..."); flush();
821                 getchar();
822                 putchar('\n');
823         }
824         if ((mode & 1) && radio_on) {
825                 ao_radio_idle();
826                 ao_radio_put();
827                 radio_on = 0;
828 #if HAS_MONITOR
829                 ao_monitor_enable();
830 #endif
831         }
832 }
833
834 void
835 ao_radio_send(const void *d, uint8_t size)
836 {
837         ao_radio_get(size);
838         ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX);
839
840         ao_radio_fifo_write(d, size);
841
842         ao_radio_run();
843 }
844
845
846 #define AO_RADIO_LOTS   64
847
848 void
849 ao_radio_send_aprs(ao_radio_fill_func fill)
850 {
851         uint8_t buf[AO_RADIO_LOTS], *b;
852         int     cnt;
853         int     total = 0;
854         uint8_t done = 0;
855         uint8_t started = 0;
856         uint8_t fifo_space;
857
858         ao_radio_get(0xff);
859         fifo_space = CC1200_FIFO_SIZE;
860         while (!done) {
861                 cnt = (*fill)(buf, sizeof(buf));
862                 if (cnt < 0) {
863                         done = 1;
864                         cnt = -cnt;
865                 }
866 #if CC1200_APRS_TRACE
867                 printf("APRS fill %d bytes done %d\n", cnt, done);
868 #endif
869                 total += cnt;
870
871                 /* At the last buffer, set the total length */
872                 if (done)
873                         ao_radio_set_len(total & 0xff);
874
875                 b = buf;
876                 while (cnt) {
877                         uint8_t this_len = cnt;
878
879                         /* Wait for some space in the fifo */
880                         while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) {
881 #if CC1200_APRS_TRACE
882                                 printf("APRS space %d cnt %d\n", fifo_space, cnt); flush();
883 #endif
884                                 ao_radio_wake = 0;
885                                 ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
886                         }
887                         if (ao_radio_abort)
888                                 break;
889                         if (this_len > fifo_space)
890                                 this_len = fifo_space;
891
892                         cnt -= this_len;
893
894                         if (done) {
895                                 if (cnt)
896                                         ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF);
897                                 else
898                                         ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
899                         } else
900                                 ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
901
902                         ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
903
904                         ao_radio_fifo_write(b, this_len);
905                         b += this_len;
906 #if CC1200_APRS_TRACE
907                         printf("APRS write fifo %d space now %d\n", this_len, ao_radio_tx_fifo_space());
908 #endif
909                         if (!started) {
910 #if CC1200_APRS_TRACE
911                                 printf("APRS start\n");
912 #endif
913                                 ao_radio_strobe(CC1200_STX);
914 #if CC1200_APRS_TRACE
915                                 { int t;
916                                         for (t = 0; t < 20; t++) {
917                                                 uint8_t status = ao_radio_status();
918                                                 uint8_t space = ao_radio_tx_fifo_space();
919                                                 printf ("status: %02x fifo %d\n", status, space);
920                                                 if ((status >> 4) == 2)
921                                                         break;
922                                                 ao_delay(AO_MS_TO_TICKS(0));
923                                         }
924                                 }
925 #endif
926                                 started = 1;
927                         }
928                 }
929                 if (ao_radio_abort) {
930                         ao_radio_idle();
931                         break;
932                 }
933         }
934         /* Wait for the transmitter to go idle */
935         ao_radio_wake = 0;
936 #if CC1200_APRS_TRACE
937         printf("APRS wait idle\n"); flush();
938 #endif
939         ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
940 #if CC1200_APRS_TRACE
941         printf("APRS abort %d\n", ao_radio_abort);
942 #endif
943         ao_radio_put();
944 }
945
946 #if 0
947 static uint8_t
948 ao_radio_marc_state(void)
949 {
950         return ao_radio_reg_read(CC1200_MARCSTATE);
951 }
952
953 static uint8_t
954 ao_radio_modem_status1(void)
955 {
956         return ao_radio_reg_read(CC1200_MODEM_STATUS1);
957 }
958
959 static uint8_t
960 ao_radio_modem_status0(void)
961 {
962         return ao_radio_reg_read(CC1200_MODEM_STATUS0);
963 }
964
965 struct ao_radio_state {
966         char    where[4];
967         uint8_t marc_state;
968         uint8_t marc_status1;
969         uint8_t marc_status0;
970         uint8_t modem_status1;
971         uint8_t modem_status0;
972 };
973
974 static void
975 ao_radio_fill_state(char *where, struct ao_radio_state *s)
976 {
977         strcpy(s->where, where);
978         s->marc_state = ao_radio_marc_state();
979         s->marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
980         s->marc_status0 = ao_radio_reg_read(CC1200_MARC_STATUS0);
981         s->modem_status1 = ao_radio_modem_status1();
982         s->modem_status0 = ao_radio_modem_status0();
983 }
984
985 static void
986 ao_radio_dump_state(struct ao_radio_state *s)
987 {
988         printf ("%s: marc %2x marc1 %2x marc0 %2x modem1 %2x modem0 %2x\n",
989                 s->where, s->marc_state, s->marc_status1, s->marc_status0, s->modem_status1, s->modem_status0);
990 }
991 #endif
992
993 uint8_t
994 ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
995 {
996         ao_radio_abort = 0;
997         ao_radio_wake = 0;
998         ao_radio_get(size - 2);
999         ao_radio_idle();
1000         ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
1001         ao_radio_wake = 0;
1002         ao_radio_start_rx();
1003         ao_radio_wait_isr(timeout);
1004         if (ao_radio_wake) {
1005                 int8_t  rssi;
1006                 uint8_t status;
1007
1008                 status = ao_radio_fifo_read(d, size);
1009                 (void) status;
1010                 rssi = ((int8_t *) d)[size - 2];
1011                 ao_radio_rssi = rssi;
1012
1013                 /* Bound it to the representable range */
1014                 if (rssi > -11)
1015                         rssi = -11;
1016
1017                 /* Write it back to the packet */
1018                 ((int8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi);
1019         } else {
1020                 ao_radio_idle();
1021                 ao_radio_rssi = 0;
1022         }
1023
1024         ao_radio_put();
1025         return ao_radio_wake;
1026 }
1027
1028
1029 #if CC1200_DEBUG
1030 static char *cc1200_state_name[] = {
1031         [CC1200_STATUS_STATE_IDLE] = "IDLE",
1032         [CC1200_STATUS_STATE_RX] = "RX",
1033         [CC1200_STATUS_STATE_TX] = "TX",
1034         [CC1200_STATUS_STATE_FSTXON] = "FSTXON",
1035         [CC1200_STATUS_STATE_CALIBRATE] = "CALIBRATE",
1036         [CC1200_STATUS_STATE_SETTLING] = "SETTLING",
1037         [CC1200_STATUS_STATE_RX_FIFO_ERROR] = "RX_FIFO_ERROR",
1038         [CC1200_STATUS_STATE_TX_FIFO_ERROR] = "TX_FIFO_ERROR",
1039 };
1040
1041 struct ao_cc1200_reg {
1042         uint16_t        addr;
1043         char            *name;
1044 };
1045
1046 static const struct ao_cc1200_reg ao_cc1200_reg[] = {
1047         { .addr = CC1200_IOCFG3,        .name = "IOCFG3" },
1048         { .addr = CC1200_IOCFG2,        .name = "IOCFG2" },
1049         { .addr = CC1200_IOCFG1,        .name = "IOCFG1" },
1050         { .addr = CC1200_IOCFG0,        .name = "IOCFG0" },
1051         { .addr = CC1200_SYNC3, .name = "SYNC3" },
1052         { .addr = CC1200_SYNC2, .name = "SYNC2" },
1053         { .addr = CC1200_SYNC1, .name = "SYNC1" },
1054         { .addr = CC1200_SYNC0, .name = "SYNC0" },
1055         { .addr = CC1200_SYNC_CFG1,     .name = "SYNC_CFG1" },
1056         { .addr = CC1200_SYNC_CFG0,     .name = "SYNC_CFG0" },
1057         { .addr = CC1200_DEVIATION_M,   .name = "DEVIATION_M" },
1058         { .addr = CC1200_MODCFG_DEV_E,  .name = "MODCFG_DEV_E" },
1059         { .addr = CC1200_DCFILT_CFG,    .name = "DCFILT_CFG" },
1060         { .addr = CC1200_PREAMBLE_CFG1, .name = "PREAMBLE_CFG1" },
1061         { .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
1062         { .addr = CC1200_IQIC,  .name = "IQIC" },
1063         { .addr = CC1200_CHAN_BW,       .name = "CHAN_BW" },
1064         { .addr = CC1200_MDMCFG2,       .name = "MDMCFG2" },
1065         { .addr = CC1200_MDMCFG1,       .name = "MDMCFG1" },
1066         { .addr = CC1200_MDMCFG0,       .name = "MDMCFG0" },
1067         { .addr = CC1200_SYMBOL_RATE2,  .name = "SYMBOL_RATE2" },
1068         { .addr = CC1200_SYMBOL_RATE1,  .name = "SYMBOL_RATE1" },
1069         { .addr = CC1200_SYMBOL_RATE0,  .name = "SYMBOL_RATE0" },
1070         { .addr = CC1200_AGC_REF,       .name = "AGC_REF" },
1071         { .addr = CC1200_AGC_CS_THR,    .name = "AGC_CS_THR" },
1072         { .addr = CC1200_AGC_GAIN_ADJUST,       .name = "AGC_GAIN_ADJUST" },
1073         { .addr = CC1200_AGC_CFG3,      .name = "AGC_CFG3" },
1074         { .addr = CC1200_AGC_CFG2,      .name = "AGC_CFG2" },
1075         { .addr = CC1200_AGC_CFG1,      .name = "AGC_CFG1" },
1076         { .addr = CC1200_AGC_CFG0,      .name = "AGC_CFG0" },
1077         { .addr = CC1200_FIFO_CFG,      .name = "FIFO_CFG" },
1078         { .addr = CC1200_DEV_ADDR,      .name = "DEV_ADDR" },
1079         { .addr = CC1200_SETTLING_CFG,  .name = "SETTLING_CFG" },
1080         { .addr = CC1200_FS_CFG,        .name = "FS_CFG" },
1081         { .addr = CC1200_WOR_CFG1,      .name = "WOR_CFG1" },
1082         { .addr = CC1200_WOR_CFG0,      .name = "WOR_CFG0" },
1083         { .addr = CC1200_WOR_EVENT0_MSB,        .name = "WOR_EVENT0_MSB" },
1084         { .addr = CC1200_WOR_EVENT0_LSB,        .name = "WOR_EVENT0_LSB" },
1085         { .addr = CC1200_RXDCM_TIME,            .name = "RXDCM_TIME" },
1086         { .addr = CC1200_PKT_CFG2,      .name = "PKT_CFG2" },
1087         { .addr = CC1200_PKT_CFG1,      .name = "PKT_CFG1" },
1088         { .addr = CC1200_PKT_CFG0,      .name = "PKT_CFG0" },
1089         { .addr = CC1200_RFEND_CFG1,    .name = "RFEND_CFG1" },
1090         { .addr = CC1200_RFEND_CFG0,    .name = "RFEND_CFG0" },
1091         { .addr = CC1200_PA_CFG1,       .name = "PA_CFG1" },
1092         { .addr = CC1200_PA_CFG0,       .name = "PA_CFG0" },
1093         { .addr = CC1200_PKT_LEN,       .name = "PKT_LEN" },
1094         { .addr = CC1200_IF_MIX_CFG,    .name = "IF_MIX_CFG" },
1095         { .addr = CC1200_FREQOFF_CFG,   .name = "FREQOFF_CFG" },
1096         { .addr = CC1200_TOC_CFG,       .name = "TOC_CFG" },
1097         { .addr = CC1200_MARC_SPARE,    .name = "MARC_SPARE" },
1098         { .addr = CC1200_ECG_CFG,       .name = "ECG_CFG" },
1099         { .addr = CC1200_EXT_CTRL,      .name = "EXT_CTRL" },
1100         { .addr = CC1200_RCCAL_FINE,    .name = "RCCAL_FINE" },
1101         { .addr = CC1200_RCCAL_COARSE,  .name = "RCCAL_COARSE" },
1102         { .addr = CC1200_RCCAL_OFFSET,  .name = "RCCAL_OFFSET" },
1103         { .addr = CC1200_FREQOFF1,      .name = "FREQOFF1" },
1104         { .addr = CC1200_FREQOFF0,      .name = "FREQOFF0" },
1105         { .addr = CC1200_FREQ2, .name = "FREQ2" },
1106         { .addr = CC1200_FREQ1, .name = "FREQ1" },
1107         { .addr = CC1200_FREQ0, .name = "FREQ0" },
1108         { .addr = CC1200_IF_ADC2,       .name = "IF_ADC2" },
1109         { .addr = CC1200_IF_ADC1,       .name = "IF_ADC1" },
1110         { .addr = CC1200_IF_ADC0,       .name = "IF_ADC0" },
1111         { .addr = CC1200_FS_DIG1,       .name = "FS_DIG1" },
1112         { .addr = CC1200_FS_DIG0,       .name = "FS_DIG0" },
1113         { .addr = CC1200_FS_CAL3,       .name = "FS_CAL3" },
1114         { .addr = CC1200_FS_CAL2,       .name = "FS_CAL2" },
1115         { .addr = CC1200_FS_CAL1,       .name = "FS_CAL1" },
1116         { .addr = CC1200_FS_CAL0,       .name = "FS_CAL0" },
1117         { .addr = CC1200_FS_CHP,        .name = "FS_CHP" },
1118         { .addr = CC1200_FS_DIVTWO,     .name = "FS_DIVTWO" },
1119         { .addr = CC1200_FS_DSM1,       .name = "FS_DSM1" },
1120         { .addr = CC1200_FS_DSM0,       .name = "FS_DSM0" },
1121         { .addr = CC1200_FS_DVC1,       .name = "FS_DVC1" },
1122         { .addr = CC1200_FS_DVC0,       .name = "FS_DVC0" },
1123         { .addr = CC1200_FS_LBI,        .name = "FS_LBI" },
1124         { .addr = CC1200_FS_PFD,        .name = "FS_PFD" },
1125         { .addr = CC1200_FS_PRE,        .name = "FS_PRE" },
1126         { .addr = CC1200_FS_REG_DIV_CML,        .name = "FS_REG_DIV_CML" },
1127         { .addr = CC1200_FS_SPARE,      .name = "FS_SPARE" },
1128         { .addr = CC1200_FS_VCO4,       .name = "FS_VCO4" },
1129         { .addr = CC1200_FS_VCO3,       .name = "FS_VCO3" },
1130         { .addr = CC1200_FS_VCO2,       .name = "FS_VCO2" },
1131         { .addr = CC1200_FS_VCO1,       .name = "FS_VCO1" },
1132         { .addr = CC1200_FS_VCO0,       .name = "FS_VCO0" },
1133         { .addr = CC1200_GBIAS6,        .name = "GBIAS6" },
1134         { .addr = CC1200_GBIAS5,        .name = "GBIAS5" },
1135         { .addr = CC1200_GBIAS4,        .name = "GBIAS4" },
1136         { .addr = CC1200_GBIAS3,        .name = "GBIAS3" },
1137         { .addr = CC1200_GBIAS2,        .name = "GBIAS2" },
1138         { .addr = CC1200_GBIAS1,        .name = "GBIAS1" },
1139         { .addr = CC1200_GBIAS0,        .name = "GBIAS0" },
1140         { .addr = CC1200_IFAMP, .name = "IFAMP" },
1141         { .addr = CC1200_LNA,   .name = "LNA" },
1142         { .addr = CC1200_RXMIX, .name = "RXMIX" },
1143         { .addr = CC1200_XOSC5, .name = "XOSC5" },
1144         { .addr = CC1200_XOSC4, .name = "XOSC4" },
1145         { .addr = CC1200_XOSC3, .name = "XOSC3" },
1146         { .addr = CC1200_XOSC2, .name = "XOSC2" },
1147         { .addr = CC1200_XOSC1, .name = "XOSC1" },
1148         { .addr = CC1200_XOSC0, .name = "XOSC0" },
1149         { .addr = CC1200_ANALOG_SPARE,  .name = "ANALOG_SPARE" },
1150         { .addr = CC1200_PA_CFG3,       .name = "PA_CFG3" },
1151         { .addr = CC1200_WOR_TIME1,     .name = "WOR_TIME1" },
1152         { .addr = CC1200_WOR_TIME0,     .name = "WOR_TIME0" },
1153         { .addr = CC1200_WOR_CAPTURE1,  .name = "WOR_CAPTURE1" },
1154         { .addr = CC1200_WOR_CAPTURE0,  .name = "WOR_CAPTURE0" },
1155         { .addr = CC1200_BIST,  .name = "BIST" },
1156         { .addr = CC1200_DCFILTOFFSET_I1,       .name = "DCFILTOFFSET_I1" },
1157         { .addr = CC1200_DCFILTOFFSET_I0,       .name = "DCFILTOFFSET_I0" },
1158         { .addr = CC1200_DCFILTOFFSET_Q1,       .name = "DCFILTOFFSET_Q1" },
1159         { .addr = CC1200_DCFILTOFFSET_Q0,       .name = "DCFILTOFFSET_Q0" },
1160         { .addr = CC1200_IQIE_I1,       .name = "IQIE_I1" },
1161         { .addr = CC1200_IQIE_I0,       .name = "IQIE_I0" },
1162         { .addr = CC1200_IQIE_Q1,       .name = "IQIE_Q1" },
1163         { .addr = CC1200_IQIE_Q0,       .name = "IQIE_Q0" },
1164         { .addr = CC1200_RSSI1, .name = "RSSI1" },
1165         { .addr = CC1200_RSSI0, .name = "RSSI0" },
1166         { .addr = CC1200_MARCSTATE,     .name = "MARCSTATE" },
1167         { .addr = CC1200_LQI_VAL,       .name = "LQI_VAL" },
1168         { .addr = CC1200_PQT_SYNC_ERR,  .name = "PQT_SYNC_ERR" },
1169         { .addr = CC1200_DEM_STATUS,    .name = "DEM_STATUS" },
1170         { .addr = CC1200_FREQOFF_EST1,  .name = "FREQOFF_EST1" },
1171         { .addr = CC1200_FREQOFF_EST0,  .name = "FREQOFF_EST0" },
1172         { .addr = CC1200_AGC_GAIN3,     .name = "AGC_GAIN3" },
1173         { .addr = CC1200_AGC_GAIN2,     .name = "AGC_GAIN2" },
1174         { .addr = CC1200_AGC_GAIN1,     .name = "AGC_GAIN1" },
1175         { .addr = CC1200_AGC_GAIN0,     .name = "AGC_GAIN0" },
1176         { .addr = CC1200_SOFT_RX_DATA_OUT,      .name = "SOFT_RX_DATA_OUT" },
1177         { .addr = CC1200_SOFT_TX_DATA_IN,       .name = "SOFT_TX_DATA_IN" },
1178         { .addr = CC1200_ASK_SOFT_RX_DATA,      .name = "ASK_SOFT_RX_DATA" },
1179         { .addr = CC1200_RNDGEN,        .name = "RNDGEN" },
1180         { .addr = CC1200_MAGN2, .name = "MAGN2" },
1181         { .addr = CC1200_MAGN1, .name = "MAGN1" },
1182         { .addr = CC1200_MAGN0, .name = "MAGN0" },
1183         { .addr = CC1200_ANG1,  .name = "ANG1" },
1184         { .addr = CC1200_ANG0,  .name = "ANG0" },
1185         { .addr = CC1200_CHFILT_I2,     .name = "CHFILT_I2" },
1186         { .addr = CC1200_CHFILT_I1,     .name = "CHFILT_I1" },
1187         { .addr = CC1200_CHFILT_I0,     .name = "CHFILT_I0" },
1188         { .addr = CC1200_CHFILT_Q2,     .name = "CHFILT_Q2" },
1189         { .addr = CC1200_CHFILT_Q1,     .name = "CHFILT_Q1" },
1190         { .addr = CC1200_CHFILT_Q0,     .name = "CHFILT_Q0" },
1191         { .addr = CC1200_GPIO_STATUS,   .name = "GPIO_STATUS" },
1192         { .addr = CC1200_FSCAL_CTRL,    .name = "FSCAL_CTRL" },
1193         { .addr = CC1200_PHASE_ADJUST,  .name = "PHASE_ADJUST" },
1194         { .addr = CC1200_PARTNUMBER,    .name = "PARTNUMBER" },
1195         { .addr = CC1200_PARTVERSION,   .name = "PARTVERSION" },
1196         { .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" },
1197         { .addr = CC1200_MODEM_STATUS1, .name = "MODEM_STATUS1" },
1198         { .addr = CC1200_MODEM_STATUS0, .name = "MODEM_STATUS0" },
1199         { .addr = CC1200_MARC_STATUS1,  .name = "MARC_STATUS1" },
1200         { .addr = CC1200_MARC_STATUS0,  .name = "MARC_STATUS0" },
1201         { .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
1202         { .addr = CC1200_FSRF_TEST,     .name = "FSRF_TEST" },
1203         { .addr = CC1200_PRE_TEST,      .name = "PRE_TEST" },
1204         { .addr = CC1200_PRE_OVR,       .name = "PRE_OVR" },
1205         { .addr = CC1200_ADC_TEST,      .name = "ADC_TEST" },
1206         { .addr = CC1200_DVC_TEST,      .name = "DVC_TEST" },
1207         { .addr = CC1200_ATEST, .name = "ATEST" },
1208         { .addr = CC1200_ATEST_LVDS,    .name = "ATEST_LVDS" },
1209         { .addr = CC1200_ATEST_MODE,    .name = "ATEST_MODE" },
1210         { .addr = CC1200_XOSC_TEST1,    .name = "XOSC_TEST1" },
1211         { .addr = CC1200_XOSC_TEST0,    .name = "XOSC_TEST0" },
1212         { .addr = CC1200_RXFIRST,       .name = "RXFIRST" },
1213         { .addr = CC1200_TXFIRST,       .name = "TXFIRST" },
1214         { .addr = CC1200_RXLAST,        .name = "RXLAST" },
1215         { .addr = CC1200_TXLAST,        .name = "TXLAST" },
1216         { .addr = CC1200_NUM_TXBYTES,   .name = "NUM_TXBYTES" },
1217         { .addr = CC1200_NUM_RXBYTES,   .name = "NUM_RXBYTES" },
1218         { .addr = CC1200_FIFO_NUM_TXBYTES,      .name = "FIFO_NUM_TXBYTES" },
1219         { .addr = CC1200_FIFO_NUM_RXBYTES,      .name = "FIFO_NUM_RXBYTES" },
1220 };
1221
1222 #define AO_NUM_CC1200_REG       (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0])
1223
1224 static uint8_t
1225 ao_radio_get_marc_status(void)
1226 {
1227         return ao_radio_reg_read(CC1200_MARC_STATUS1);
1228 }
1229
1230 static void ao_radio_show(void) {
1231         uint8_t status;
1232         unsigned int    i;
1233
1234         ao_mutex_get(&ao_radio_mutex);
1235         status = ao_radio_status();
1236         printf ("Status:   %02x\n", status);
1237         printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1);
1238         printf ("STATE:    %s\n", cc1200_state_name[(status >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK]);
1239         printf ("MARC:     %02x\n", ao_radio_get_marc_status());
1240
1241         for (i = 0; i < AO_NUM_CC1200_REG; i++)
1242                 printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1200_reg[i].addr), ao_cc1200_reg[i].name);
1243
1244         ao_radio_put();
1245 }
1246
1247 static void ao_radio_beep(void) {
1248         ao_radio_rdf();
1249 }
1250
1251 static void ao_radio_packet(void) {
1252         static const uint8_t packet[] = {
1253 #if 1
1254                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1255                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1256                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1257                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1258 #else
1259                 3, 1, 2, 3
1260 #endif
1261         };
1262
1263         ao_radio_send(packet, sizeof (packet));
1264 }
1265
1266 void
1267 ao_radio_test_recv(void)
1268 {
1269         uint8_t bytes[34];
1270         uint8_t b;
1271
1272         if (ao_radio_recv(bytes, 34, 0)) {
1273                 if (bytes[33] & 0x80)
1274                         printf ("CRC OK");
1275                 else
1276                         printf ("CRC BAD");
1277                 printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32]));
1278                 for (b = 0; b < 32; b++)
1279                         printf (" %02x", bytes[b]);
1280
1281                 printf (" RSSI %02x LQI %02x", bytes[32], bytes[33]);
1282                 printf ("\n");
1283         }
1284 }
1285
1286 #if HAS_APRS
1287 #include <ao_aprs.h>
1288
1289 static void
1290 ao_radio_aprs(void)
1291 {
1292 #if PACKET_HAS_SLAVE
1293         ao_packet_slave_stop();
1294 #endif
1295         ao_aprs_send();
1296 }
1297 #endif
1298 #endif
1299
1300 #if CC1200_LOW_LEVEL_DEBUG
1301 static void
1302 ao_radio_strobe_test(void)
1303 {
1304         uint8_t r;
1305
1306         ao_cmd_hex();
1307         if (ao_cmd_status != ao_cmd_success)
1308                 return;
1309         r = ao_radio_strobe(ao_cmd_lex_i);
1310         printf ("Strobe %02x -> %02x (rdy %d state %d)\n",
1311                 ao_cmd_lex_i,
1312                 r,
1313                 r >> 7,
1314                 (r >> 4) & 0x7);
1315 }
1316
1317 static void
1318 ao_radio_write_test(void)
1319 {
1320         uint16_t        addr;
1321         uint8_t         data;
1322
1323         ao_cmd_hex();
1324         if (ao_cmd_status != ao_cmd_success)
1325                 return;
1326         addr = ao_cmd_lex_i;
1327         ao_cmd_hex();
1328         if (ao_cmd_status != ao_cmd_success)
1329                 return;
1330         data = ao_cmd_lex_i;
1331         printf ("Write %04x = %02x\n", addr, data);
1332         ao_radio_reg_write(addr, data);
1333 }
1334
1335 static void
1336 ao_radio_read_test(void)
1337 {
1338         uint16_t        addr;
1339         uint8_t         data;
1340
1341         ao_cmd_hex();
1342         if (ao_cmd_status != ao_cmd_success)
1343                 return;
1344         addr = ao_cmd_lex_i;
1345         data = ao_radio_reg_read(addr);
1346         printf ("Read %04x = %02x\n", addr, data);
1347 }
1348 #endif
1349
1350 static const struct ao_cmds ao_radio_cmds[] = {
1351         { ao_radio_test_cmd,    "C <1 start, 0 stop, none both>\0Radio carrier test" },
1352 #if CC1200_DEBUG
1353 #if HAS_APRS
1354         { ao_radio_aprs,        "G\0Send APRS packet" },
1355 #endif
1356         { ao_radio_show,        "R\0Show CC1200 status" },
1357         { ao_radio_beep,        "b\0Emit an RDF beacon" },
1358         { ao_radio_packet,      "p\0Send a test packet" },
1359         { ao_radio_test_recv,   "q\0Recv a test packet" },
1360 #endif
1361 #if CC1200_LOW_LEVEL_DEBUG
1362         { ao_radio_strobe_test, "A <value>\0Strobe radio" },
1363         { ao_radio_write_test,  "W <addr> <value>\0Write radio reg" },
1364         { ao_radio_read_test,   "B <addr>\0Read radio reg" },
1365 #endif
1366         { 0, NULL }
1367 };
1368
1369 void
1370 ao_radio_init(void)
1371 {
1372         ao_radio_configured = 0;
1373         ao_spi_init_cs (AO_CC1200_SPI_CS_PORT, (1 << AO_CC1200_SPI_CS_PIN));
1374
1375 #if 0
1376         AO_CC1200_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC1200_SPI_CS_PIN));
1377         for (i = 0; i < 10000; i++) {
1378                 if ((SPI_2_PORT->idr & (1 << SPI_2_MISO_PIN)) == 0)
1379                         break;
1380         }
1381         AO_CC1200_SPI_CS_PORT->bsrr = (1 << AO_CC1200_SPI_CS_PIN);
1382         if (i == 10000)
1383                 ao_panic(AO_PANIC_SELF_TEST_CC1200);
1384 #endif
1385
1386         /* Enable the EXTI interrupt for the appropriate pin */
1387         ao_enable_port(AO_CC1200_INT_PORT);
1388         ao_exti_setup(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN,
1389                       AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH,
1390                       ao_radio_isr);
1391
1392         ao_cmd_register(&ao_radio_cmds[0]);
1393 }