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