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