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