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