2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
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.
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.
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.
19 #include <ao_cc1200.h>
22 #include <ao_packet.h>
27 static uint8_t ao_radio_mutex;
29 static uint8_t ao_radio_wake; /* radio ready. Also used as sleep address */
30 static uint8_t ao_radio_abort; /* radio operation should abort */
32 int8_t ao_radio_rssi; /* Last received RSSI value */
35 #define CC1200_DEBUG 0
38 #ifndef CC1200_LOW_LEVEL_DEBUG
39 #define CC1200_LOW_LEVEL_DEBUG 0
42 #define CC1200_TRACE 0
43 #define CC1200_APRS_TRACE 0
45 extern const uint32_t ao_radio_cal;
48 #define FOSC AO_CC1200_FOSC
53 #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)
54 #define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS)
55 #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1200_SPI_BUS)
56 #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS)
57 #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1200_SPI_BUS)
58 #define ao_radio_duplex(o,i,l) ao_spi_duplex((o), (i), (l), AO_CC1200_SPI_BUS)
61 ao_radio_reg_read(uint16_t addr)
67 printf("\t\tao_radio_reg_read (%04x): ", addr); flush();
69 if (CC1200_IS_EXTENDED(addr)) {
70 data[0] = ((1 << CC1200_READ) |
76 data[0] = ((1 << CC1200_READ) |
82 ao_radio_spi_send(data, d);
83 ao_radio_spi_recv(data, 1);
86 printf (" %02x\n", data[0]);
92 ao_radio_reg_write(uint16_t addr, uint8_t value)
98 printf("\t\tao_radio_reg_write (%04x): %02x\n", addr, value);
100 if (CC1200_IS_EXTENDED(addr)) {
101 data[0] = ((0 << CC1200_READ) |
102 (0 << CC1200_BURST) |
107 data[0] = ((0 << CC1200_READ) |
108 (0 << CC1200_BURST) |
114 ao_radio_spi_send(data, d+1);
117 (void) ao_radio_reg_read(addr);
122 ao_radio_strobe(uint8_t addr)
127 printf("\t\tao_radio_strobe (%02x): ", addr); flush();
130 ao_radio_duplex(&addr, &in, 1);
133 printf("%02x\n", in); flush();
139 ao_radio_fifo_read(uint8_t *data, uint8_t len)
141 uint8_t addr = ((1 << CC1200_READ) |
142 (1 << CC1200_BURST) |
147 ao_radio_duplex(&addr, &status, 1);
148 ao_radio_spi_recv(data, len);
154 ao_radio_fifo_write_start(void)
156 uint8_t addr = ((0 << CC1200_READ) |
157 (1 << CC1200_BURST) |
162 ao_radio_duplex(&addr, &status, 1);
166 static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) {
172 ao_radio_fifo_write(const uint8_t *data, uint8_t len)
174 uint8_t status = ao_radio_fifo_write_start();
175 ao_radio_spi_send(data, len);
176 return ao_radio_fifo_write_stop(status);
180 ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
182 uint8_t status = ao_radio_fifo_write_start();
183 ao_radio_spi_send_fixed(data, len);
184 return ao_radio_fifo_write_stop(status);
188 ao_radio_int_pin(void)
190 return ao_gpio_get(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_CC1200_INT);
194 ao_radio_status(void)
196 return ao_radio_strobe (CC1200_SNOP);
200 ao_radio_recv_abort(void)
203 ao_wakeup(&ao_radio_wake);
206 #define ao_radio_rdf_value 0x55
211 ao_exti_disable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
213 ao_wakeup(&ao_radio_wake);
217 ao_radio_start_tx(void)
219 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
220 ao_radio_strobe(CC1200_STX);
224 ao_radio_start_rx(void)
226 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
227 ao_radio_strobe(CC1200_SRX);
234 uint8_t state = (ao_radio_strobe(CC1200_SIDLE) >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
235 if (state == CC1200_STATUS_STATE_IDLE)
237 if (state == CC1200_STATUS_STATE_TX_FIFO_ERROR)
238 ao_radio_strobe(CC1200_SFTX);
239 if (state == CC1200_STATUS_STATE_RX_FIFO_ERROR)
240 ao_radio_strobe(CC1200_SFRX);
242 /* Flush any pending data in the fifos */
243 ao_radio_strobe(CC1200_SFTX);
244 ao_radio_strobe(CC1200_SFRX);
245 /* Make sure the RF calibration is current */
246 ao_radio_strobe(CC1200_SCAL);
252 * fdev = fosc >> 22 * (256 + dev_m) << dev_e
254 * Deviation for 38400 baud should be 20.5kHz:
256 * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 3) = 20523Hz
258 * Deviation for 9600 baud should be 5.125kHz:
260 * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 1) = 5131Hz
262 * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and
263 * cc115l can't do that, so we'll use 1.5kHz instead:
265 * 40e6 / (2 ** 21) * (79) = 1506Hz
268 #define PACKET_DEV_M_384 13
269 #define PACKET_DEV_E_384 3
271 #define PACKET_DEV_M_96 13
272 #define PACKET_DEV_E_96 1
274 #define PACKET_DEV_M_24 79
275 #define PACKET_DEV_E_24 0
278 * For our packet data
280 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
281 * Rdata = -------------------------------------- * fosc
284 * Given the bit period of the baseband, T, the bandwidth of the
285 * baseband signal is B = 1/(2T). The overall bandwidth of the
286 * modulated signal is then Channel bandwidth = 2Δf + 2B.
288 * 38400 -- 2 * 20500 + 38400 = 79.4 kHz
289 * 9600 -- 2 * 5.125 + 9600 = 19.9 kHz
290 * 2400 -- 2 * 1.5 + 2400 = 5.4 khz
292 * Symbol rate 38400 Baud:
294 * DATARATE_M = 1013008
298 * Symbol rate 9600 Baud:
300 * DATARATE_M = 1013008
302 * CHANBW = 26.042 (round to 19.8)
304 * Symbol rate 2400 Baud:
306 * DATARATE_M = 1013008
308 * CHANBW = 5.0 (round to 9.5)
312 #define PACKET_SYMBOL_RATE_M 1013008
313 #define PACKET_SYMBOL_RATE_E_384 8
314 #define PACKET_SYMBOL_RATE_E_96 6
315 #define PACKET_SYMBOL_RATE_E_24 4
319 #define PACKET_SYMBOL_RATE_M 239914
320 #define PACKET_SYMBOL_RATE_E_384 9
321 #define PACKET_SYMBOL_RATE_E_96 7
322 #define PACKET_SYMBOL_RATE_E_24 5
326 #define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
327 (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
330 #define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
331 (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
334 #define PACKET_CHAN_BW_24 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
335 (44 << CC1200_CHAN_BW_BB_CIC_DECFACT))
337 static const uint16_t packet_setup[] = {
338 CC1200_SYMBOL_RATE1, ((PACKET_SYMBOL_RATE_M >> 8) & 0xff),
339 CC1200_SYMBOL_RATE0, ((PACKET_SYMBOL_RATE_M >> 0) & 0xff),
340 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
341 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
342 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
343 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
344 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
345 ((1 << CC1200_PKT_CFG1_FEC_EN) |
346 (1 << CC1200_PKT_CFG1_WHITE_DATA) |
347 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
348 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
349 (CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES << CC1200_PKT_CFG1_CRC_CFG) |
350 (1 << CC1200_PKT_CFG1_APPEND_STATUS)),
351 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
352 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
355 static const uint16_t packet_setup_384[] = {
356 CC1200_DEVIATION_M, PACKET_DEV_M_384,
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_384 << CC1200_MODCFG_DEV_E_DEV_E)),
360 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_384 << 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_384,
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_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
367 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
370 static const uint16_t packet_setup_96[] = {
371 CC1200_DEVIATION_M, PACKET_DEV_M_96,
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_96 << CC1200_MODCFG_DEV_E_DEV_E)),
375 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << 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_96,
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_32 << CC1200_MDMCFG2_UPSAMPLER_P) |
382 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
385 static const uint16_t packet_setup_24[] = {
386 CC1200_DEVIATION_M, PACKET_DEV_M_24,
387 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
388 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
389 (PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)),
390 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) |
391 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
392 CC1200_CHAN_BW, PACKET_CHAN_BW_24,
393 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
394 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
395 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
396 (CC1200_MDMCFG2_UPSAMPLER_P_64 << CC1200_MDMCFG2_UPSAMPLER_P) |
397 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
401 * RDF deviation is 3kHz
403 * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
404 * fdev = fosc >> 21 * dev_m dev_e == 0
406 * 40e6 / (2 ** 21) * 157 = 2995Hz
410 #define RDF_DEV_M 157
413 * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone)
415 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
416 * Rdata = -------------------------------------- * fosc
419 * DATARATE_M = 669411
422 * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes
424 #define RDF_SYMBOL_RATE_E 4
425 #define RDF_SYMBOL_RATE_M 669411
426 #define RDF_PACKET_LEN 50
428 static const uint16_t rdf_setup[] = {
429 CC1200_DEVIATION_M, RDF_DEV_M,
430 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
431 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
432 (RDF_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
433 CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
434 (((RDF_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
435 CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff),
436 CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff),
437 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
438 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
439 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
440 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
441 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
442 ((0 << CC1200_PKT_CFG1_FEC_EN) |
443 (0 << CC1200_PKT_CFG1_WHITE_DATA) |
444 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
445 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
446 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
447 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
448 CC1200_PREAMBLE_CFG1,
449 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
450 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
451 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
452 ((0 << CC1200_MDMCFG2_ASK_SHAPE) |
453 (0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
454 (12 << CC1200_MDMCFG2_UPSAMPLER_P) |
455 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
459 * APRS deviation is 3kHz
461 * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
462 * fdev = fosc >> 21 * dev_m dev_e == 0
464 * 40e6 / (2 ** 21) * 157 = 2995Hz
468 #define APRS_DEV_M 157
471 * For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate)
473 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
474 * Rdata = -------------------------------------- * fosc
477 * DATARATE_M = 1013008
480 * Rdata = 9599.998593330383301
483 #define APRS_SYMBOL_RATE_E 6
484 #define APRS_SYMBOL_RATE_M 1013008
485 #define APRS_BUFFER_SIZE 64
487 static const uint16_t aprs_setup[] = {
488 CC1200_DEVIATION_M, APRS_DEV_M,
489 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
490 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
491 (APRS_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
492 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
493 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
494 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
495 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
496 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
497 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
498 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
499 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
500 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
501 ((0 << CC1200_PKT_CFG1_FEC_EN) |
502 (0 << CC1200_PKT_CFG1_WHITE_DATA) |
503 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
504 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
505 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
506 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
507 CC1200_PKT_CFG0, /* Packet Configuration Reg. 0 */
508 ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
509 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
510 (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
511 (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
512 CC1200_PREAMBLE_CFG1,
513 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
514 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
515 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
516 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
517 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
518 (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
519 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
521 ((0 << CC1200_FIFO_CFG_CRC_AUTOFLUSH) |
522 (APRS_BUFFER_SIZE << CC1200_FIFO_CFG_FIFO_THR)),
526 * For Test mode, we want an unmodulated carrier. To do that, we
527 * set the deviation to zero and enable a preamble so that the radio
528 * turns on before we send any data
531 static const uint16_t test_setup[] = {
532 CC1200_DEVIATION_M, 0,
533 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
534 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
535 (0 << CC1200_MODCFG_DEV_E_DEV_E)),
536 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
537 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
538 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
539 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
540 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
541 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
542 CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
543 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
544 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
545 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
546 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
547 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
550 #define AO_PKT_CFG0_INFINITE ((CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
551 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
552 (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
553 (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
555 #define AO_PKT_CFG0_FIXED ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
556 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
557 (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
558 (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
560 static uint16_t ao_radio_mode;
562 #define AO_RADIO_MODE_BITS_PACKET 1
563 #define AO_RADIO_MODE_BITS_TX_BUF 4
564 #define AO_RADIO_MODE_BITS_TX_FINISH 8
565 #define AO_RADIO_MODE_BITS_RX 16
566 #define AO_RADIO_MODE_BITS_RDF 32
567 #define AO_RADIO_MODE_BITS_APRS 64
568 #define AO_RADIO_MODE_BITS_TEST 128
569 #define AO_RADIO_MODE_BITS_INFINITE 256
570 #define AO_RADIO_MODE_BITS_FIXED 512
572 #define AO_RADIO_MODE_NONE 0
573 #define AO_RADIO_MODE_PACKET_TX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
574 #define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_RX)
575 #define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
576 #define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
577 #define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF)
578 #define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
579 #define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
582 _ao_radio_set_regs(const uint16_t *regs, int nreg)
586 for (i = 0; i < nreg; i++) {
587 ao_radio_reg_write(regs[0], regs[1]);
592 #define ao_radio_set_regs(setup) _ao_radio_set_regs(setup, (sizeof (setup) / sizeof(setup[0])) >> 1)
595 ao_radio_set_mode(uint16_t new_mode)
599 if (new_mode == ao_radio_mode)
602 changes = new_mode & (~ao_radio_mode);
604 if (changes & AO_RADIO_MODE_BITS_PACKET) {
605 ao_radio_set_regs(packet_setup);
607 switch (ao_config.radio_rate) {
609 case AO_RADIO_RATE_38400:
610 ao_radio_set_regs(packet_setup_384);
612 case AO_RADIO_RATE_9600:
613 ao_radio_set_regs(packet_setup_96);
615 case AO_RADIO_RATE_2400:
616 ao_radio_set_regs(packet_setup_24);
621 if (changes & AO_RADIO_MODE_BITS_TX_BUF) {
622 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR);
623 ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
626 if (changes & AO_RADIO_MODE_BITS_TX_FINISH) {
627 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
628 ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
631 if (changes & AO_RADIO_MODE_BITS_RX) {
632 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP);
633 ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH);
636 if (changes & AO_RADIO_MODE_BITS_RDF)
637 ao_radio_set_regs(rdf_setup);
639 if (changes & AO_RADIO_MODE_BITS_APRS)
640 ao_radio_set_regs(aprs_setup);
642 if (changes & AO_RADIO_MODE_BITS_TEST)
643 ao_radio_set_regs(test_setup);
645 if (changes & AO_RADIO_MODE_BITS_INFINITE)
646 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_INFINITE);
648 if (changes & AO_RADIO_MODE_BITS_FIXED)
649 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_FIXED);
651 ao_radio_mode = new_mode;
654 static const uint16_t radio_setup[] = {
655 #include "ao_cc1200_CC1200.h"
658 static uint8_t ao_radio_configured = 0;
663 ao_radio_strobe(CC1200_SRES);
665 ao_radio_set_regs(radio_setup);
673 ao_radio_configured = 1;
677 ao_radio_set_len(uint8_t len)
679 static uint8_t last_len;
681 if (len != last_len) {
682 ao_radio_reg_write(CC1200_PKT_LEN, len);
688 ao_radio_get(uint8_t len)
690 static uint32_t last_radio_setting;
691 static uint8_t last_radio_rate;
693 ao_mutex_get(&ao_radio_mutex);
695 if (!ao_radio_configured)
697 if (ao_config.radio_setting != last_radio_setting) {
698 ao_radio_reg_write(CC1200_FREQ2, ao_config.radio_setting >> 16);
699 ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8);
700 ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting);
701 last_radio_setting = ao_config.radio_setting;
702 ao_radio_strobe(CC1200_SCAL);
704 if (ao_config.radio_rate != last_radio_rate) {
705 ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET;
706 last_radio_rate = ao_config.radio_rate;
708 ao_radio_set_len(len);
711 #define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
713 static inline uint8_t
716 return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
721 ao_radio_show_state(char *where)
723 printf("%s: state %d len %d rxbytes %d\n",
724 where, ao_radio_state(),
725 ao_radio_reg_read(CC1200_PKT_LEN),
726 ao_radio_reg_read(CC1200_NUM_RXBYTES));
729 #define ao_radio_show_state(where)
732 /* Wait for the radio to signal an interrupt
735 ao_radio_wait_isr(uint16_t timeout)
737 ao_arch_block_interrupts();
738 while (!ao_radio_wake && !ao_radio_abort)
739 if (ao_sleep_for(&ao_radio_wake, timeout))
741 ao_arch_release_interrupts();
745 ao_rdf_start(uint8_t len)
750 ao_radio_set_mode(AO_RADIO_MODE_RDF);
760 ao_radio_wait_isr(0);
769 ao_rdf_start(AO_RADIO_RDF_LEN);
771 ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
777 ao_radio_continuity(uint8_t c)
782 ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
784 status = ao_radio_fifo_write_start();
785 for (i = 0; i < 3; i++) {
786 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
788 ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
790 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
792 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
793 status = ao_radio_fifo_write_stop(status);
799 ao_radio_rdf_abort(void)
802 ao_wakeup(&ao_radio_wake);
806 ao_radio_test_cmd(void)
809 static uint8_t radio_on;
811 if (ao_cmd_lex_c != '\n') {
813 mode = (uint8_t) ao_cmd_lex_u32;
816 if ((mode & 2) && !radio_on) {
818 ao_monitor_disable();
821 ao_packet_slave_stop();
827 ao_radio_set_mode(AO_RADIO_MODE_TEST);
828 ao_radio_strobe(CC1200_STX);
831 for (t = 0; t < 10; t++) {
832 printf ("status: %02x\n", ao_radio_status());
833 ao_delay(AO_MS_TO_TICKS(100));
840 printf ("Hit a character to stop..."); flush();
844 if ((mode & 1) && radio_on) {
858 ao_radio_send(const void *d, uint8_t size)
861 ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX);
863 ao_radio_fifo_write(d, size);
869 ao_radio_send_aprs(ao_radio_fill_func fill)
871 uint8_t buf[APRS_BUFFER_SIZE];
880 while (!done && !ao_radio_abort) {
881 cnt = (*fill)(buf, sizeof(buf));
888 /* At the last buffer, set the total length */
890 ao_radio_set_len(total & 0xff);
892 /* Wait for some space in the fifo */
893 while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) {
895 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
896 ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
902 ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
904 ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
906 ao_radio_fifo_write(buf, cnt);
908 ao_radio_strobe(CC1200_STX);
912 /* Wait for the transmitter to go idle */
913 while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) {
915 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
916 ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
925 ao_radio_marc_state(void)
927 return ao_radio_reg_read(CC1200_MARCSTATE);
931 ao_radio_modem_status1(void)
933 return ao_radio_reg_read(CC1200_MODEM_STATUS1);
937 ao_radio_modem_status0(void)
939 return ao_radio_reg_read(CC1200_MODEM_STATUS0);
942 struct ao_radio_state {
945 uint8_t marc_status1;
946 uint8_t marc_status0;
947 uint8_t modem_status1;
948 uint8_t modem_status0;
952 ao_radio_fill_state(char *where, struct ao_radio_state *s)
954 strcpy(s->where, where);
955 s->marc_state = ao_radio_marc_state();
956 s->marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
957 s->marc_status0 = ao_radio_reg_read(CC1200_MARC_STATUS0);
958 s->modem_status1 = ao_radio_modem_status1();
959 s->modem_status0 = ao_radio_modem_status0();
963 ao_radio_dump_state(struct ao_radio_state *s)
965 printf ("%s: marc %2x marc1 %2x marc0 %2x modem1 %2x modem0 %2x\n",
966 s->where, s->marc_state, s->marc_status1, s->marc_status0, s->modem_status1, s->modem_status0);
971 ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
976 ao_radio_get(size - 2);
977 ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
981 while (!ao_radio_abort) {
982 ao_radio_wait_isr(timeout);
984 uint8_t marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
986 /* Check the receiver status to see what happened
988 switch (marc_status1) {
989 case CC1200_MARC_STATUS1_RX_FINISHED:
990 case CC1200_MARC_STATUS1_ADDRESS:
991 case CC1200_MARC_STATUS1_CRC:
992 /* Normal return, go fetch the bytes from the FIFO
993 * and give them back to the caller
997 case CC1200_MARC_STATUS1_RX_TIMEOUT:
998 case CC1200_MARC_STATUS1_RX_TERMINATION:
999 case CC1200_MARC_STATUS1_EWOR_SYNC_LOST:
1000 case CC1200_MARC_STATUS1_MAXIMUM_LENGTH:
1001 case CC1200_MARC_STATUS1_RX_FIFO_OVERFLOW:
1002 case CC1200_MARC_STATUS1_RX_FIFO_UNDERFLOW:
1003 /* Something weird happened; reset the radio and
1009 /* some other status; go wait for the radio to do something useful
1015 uint8_t modem_status1 = ao_radio_reg_read(CC1200_MODEM_STATUS1);
1017 /* Check to see if the packet header has been seen, in which case we'll
1018 * want to keep waiting for the rest of the packet to appear
1020 if (modem_status1 & (1 << CC1200_MODEM_STATUS1_SYNC_FOUND))
1024 /* Set a timeout based on the packet length so that we make sure to
1025 * wait long enough to receive the whole thing.
1027 * timeout = bits * FEC expansion / rate
1029 switch (ao_config.radio_rate) {
1031 case AO_RADIO_RATE_38400:
1032 timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 384) + 1;
1034 case AO_RADIO_RATE_9600:
1035 timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 96) + 1;
1037 case AO_RADIO_RATE_2400:
1038 timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 24) + 1;
1049 status = ao_radio_fifo_read(d, size);
1051 rssi = ((int8_t *) d)[size - 2];
1052 ao_radio_rssi = rssi;
1054 /* Bound it to the representable range */
1058 /* Write it back to the packet */
1059 ((int8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi);
1071 static char *cc1200_state_name[] = {
1072 [CC1200_STATUS_STATE_IDLE] = "IDLE",
1073 [CC1200_STATUS_STATE_RX] = "RX",
1074 [CC1200_STATUS_STATE_TX] = "TX",
1075 [CC1200_STATUS_STATE_FSTXON] = "FSTXON",
1076 [CC1200_STATUS_STATE_CALIBRATE] = "CALIBRATE",
1077 [CC1200_STATUS_STATE_SETTLING] = "SETTLING",
1078 [CC1200_STATUS_STATE_RX_FIFO_ERROR] = "RX_FIFO_ERROR",
1079 [CC1200_STATUS_STATE_TX_FIFO_ERROR] = "TX_FIFO_ERROR",
1082 struct ao_cc1200_reg {
1087 static const struct ao_cc1200_reg ao_cc1200_reg[] = {
1088 { .addr = CC1200_IOCFG3, .name = "IOCFG3" },
1089 { .addr = CC1200_IOCFG2, .name = "IOCFG2" },
1090 { .addr = CC1200_IOCFG1, .name = "IOCFG1" },
1091 { .addr = CC1200_IOCFG0, .name = "IOCFG0" },
1092 { .addr = CC1200_SYNC3, .name = "SYNC3" },
1093 { .addr = CC1200_SYNC2, .name = "SYNC2" },
1094 { .addr = CC1200_SYNC1, .name = "SYNC1" },
1095 { .addr = CC1200_SYNC0, .name = "SYNC0" },
1096 { .addr = CC1200_SYNC_CFG1, .name = "SYNC_CFG1" },
1097 { .addr = CC1200_SYNC_CFG0, .name = "SYNC_CFG0" },
1098 { .addr = CC1200_DEVIATION_M, .name = "DEVIATION_M" },
1099 { .addr = CC1200_MODCFG_DEV_E, .name = "MODCFG_DEV_E" },
1100 { .addr = CC1200_DCFILT_CFG, .name = "DCFILT_CFG" },
1101 { .addr = CC1200_PREAMBLE_CFG1, .name = "PREAMBLE_CFG1" },
1102 { .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
1103 { .addr = CC1200_IQIC, .name = "IQIC" },
1104 { .addr = CC1200_CHAN_BW, .name = "CHAN_BW" },
1105 { .addr = CC1200_MDMCFG2, .name = "MDMCFG2" },
1106 { .addr = CC1200_MDMCFG1, .name = "MDMCFG1" },
1107 { .addr = CC1200_MDMCFG0, .name = "MDMCFG0" },
1108 { .addr = CC1200_SYMBOL_RATE2, .name = "SYMBOL_RATE2" },
1109 { .addr = CC1200_SYMBOL_RATE1, .name = "SYMBOL_RATE1" },
1110 { .addr = CC1200_SYMBOL_RATE0, .name = "SYMBOL_RATE0" },
1111 { .addr = CC1200_AGC_REF, .name = "AGC_REF" },
1112 { .addr = CC1200_AGC_CS_THR, .name = "AGC_CS_THR" },
1113 { .addr = CC1200_AGC_GAIN_ADJUST, .name = "AGC_GAIN_ADJUST" },
1114 { .addr = CC1200_AGC_CFG3, .name = "AGC_CFG3" },
1115 { .addr = CC1200_AGC_CFG2, .name = "AGC_CFG2" },
1116 { .addr = CC1200_AGC_CFG1, .name = "AGC_CFG1" },
1117 { .addr = CC1200_AGC_CFG0, .name = "AGC_CFG0" },
1118 { .addr = CC1200_FIFO_CFG, .name = "FIFO_CFG" },
1119 { .addr = CC1200_DEV_ADDR, .name = "DEV_ADDR" },
1120 { .addr = CC1200_SETTLING_CFG, .name = "SETTLING_CFG" },
1121 { .addr = CC1200_FS_CFG, .name = "FS_CFG" },
1122 { .addr = CC1200_WOR_CFG1, .name = "WOR_CFG1" },
1123 { .addr = CC1200_WOR_CFG0, .name = "WOR_CFG0" },
1124 { .addr = CC1200_WOR_EVENT0_MSB, .name = "WOR_EVENT0_MSB" },
1125 { .addr = CC1200_WOR_EVENT0_LSB, .name = "WOR_EVENT0_LSB" },
1126 { .addr = CC1200_RXDCM_TIME, .name = "RXDCM_TIME" },
1127 { .addr = CC1200_PKT_CFG2, .name = "PKT_CFG2" },
1128 { .addr = CC1200_PKT_CFG1, .name = "PKT_CFG1" },
1129 { .addr = CC1200_PKT_CFG0, .name = "PKT_CFG0" },
1130 { .addr = CC1200_RFEND_CFG1, .name = "RFEND_CFG1" },
1131 { .addr = CC1200_RFEND_CFG0, .name = "RFEND_CFG0" },
1132 { .addr = CC1200_PA_CFG1, .name = "PA_CFG1" },
1133 { .addr = CC1200_PA_CFG0, .name = "PA_CFG0" },
1134 { .addr = CC1200_PKT_LEN, .name = "PKT_LEN" },
1135 { .addr = CC1200_IF_MIX_CFG, .name = "IF_MIX_CFG" },
1136 { .addr = CC1200_FREQOFF_CFG, .name = "FREQOFF_CFG" },
1137 { .addr = CC1200_TOC_CFG, .name = "TOC_CFG" },
1138 { .addr = CC1200_MARC_SPARE, .name = "MARC_SPARE" },
1139 { .addr = CC1200_ECG_CFG, .name = "ECG_CFG" },
1140 { .addr = CC1200_EXT_CTRL, .name = "EXT_CTRL" },
1141 { .addr = CC1200_RCCAL_FINE, .name = "RCCAL_FINE" },
1142 { .addr = CC1200_RCCAL_COARSE, .name = "RCCAL_COARSE" },
1143 { .addr = CC1200_RCCAL_OFFSET, .name = "RCCAL_OFFSET" },
1144 { .addr = CC1200_FREQOFF1, .name = "FREQOFF1" },
1145 { .addr = CC1200_FREQOFF0, .name = "FREQOFF0" },
1146 { .addr = CC1200_FREQ2, .name = "FREQ2" },
1147 { .addr = CC1200_FREQ1, .name = "FREQ1" },
1148 { .addr = CC1200_FREQ0, .name = "FREQ0" },
1149 { .addr = CC1200_IF_ADC2, .name = "IF_ADC2" },
1150 { .addr = CC1200_IF_ADC1, .name = "IF_ADC1" },
1151 { .addr = CC1200_IF_ADC0, .name = "IF_ADC0" },
1152 { .addr = CC1200_FS_DIG1, .name = "FS_DIG1" },
1153 { .addr = CC1200_FS_DIG0, .name = "FS_DIG0" },
1154 { .addr = CC1200_FS_CAL3, .name = "FS_CAL3" },
1155 { .addr = CC1200_FS_CAL2, .name = "FS_CAL2" },
1156 { .addr = CC1200_FS_CAL1, .name = "FS_CAL1" },
1157 { .addr = CC1200_FS_CAL0, .name = "FS_CAL0" },
1158 { .addr = CC1200_FS_CHP, .name = "FS_CHP" },
1159 { .addr = CC1200_FS_DIVTWO, .name = "FS_DIVTWO" },
1160 { .addr = CC1200_FS_DSM1, .name = "FS_DSM1" },
1161 { .addr = CC1200_FS_DSM0, .name = "FS_DSM0" },
1162 { .addr = CC1200_FS_DVC1, .name = "FS_DVC1" },
1163 { .addr = CC1200_FS_DVC0, .name = "FS_DVC0" },
1164 { .addr = CC1200_FS_LBI, .name = "FS_LBI" },
1165 { .addr = CC1200_FS_PFD, .name = "FS_PFD" },
1166 { .addr = CC1200_FS_PRE, .name = "FS_PRE" },
1167 { .addr = CC1200_FS_REG_DIV_CML, .name = "FS_REG_DIV_CML" },
1168 { .addr = CC1200_FS_SPARE, .name = "FS_SPARE" },
1169 { .addr = CC1200_FS_VCO4, .name = "FS_VCO4" },
1170 { .addr = CC1200_FS_VCO3, .name = "FS_VCO3" },
1171 { .addr = CC1200_FS_VCO2, .name = "FS_VCO2" },
1172 { .addr = CC1200_FS_VCO1, .name = "FS_VCO1" },
1173 { .addr = CC1200_FS_VCO0, .name = "FS_VCO0" },
1174 { .addr = CC1200_GBIAS6, .name = "GBIAS6" },
1175 { .addr = CC1200_GBIAS5, .name = "GBIAS5" },
1176 { .addr = CC1200_GBIAS4, .name = "GBIAS4" },
1177 { .addr = CC1200_GBIAS3, .name = "GBIAS3" },
1178 { .addr = CC1200_GBIAS2, .name = "GBIAS2" },
1179 { .addr = CC1200_GBIAS1, .name = "GBIAS1" },
1180 { .addr = CC1200_GBIAS0, .name = "GBIAS0" },
1181 { .addr = CC1200_IFAMP, .name = "IFAMP" },
1182 { .addr = CC1200_LNA, .name = "LNA" },
1183 { .addr = CC1200_RXMIX, .name = "RXMIX" },
1184 { .addr = CC1200_XOSC5, .name = "XOSC5" },
1185 { .addr = CC1200_XOSC4, .name = "XOSC4" },
1186 { .addr = CC1200_XOSC3, .name = "XOSC3" },
1187 { .addr = CC1200_XOSC2, .name = "XOSC2" },
1188 { .addr = CC1200_XOSC1, .name = "XOSC1" },
1189 { .addr = CC1200_XOSC0, .name = "XOSC0" },
1190 { .addr = CC1200_ANALOG_SPARE, .name = "ANALOG_SPARE" },
1191 { .addr = CC1200_PA_CFG3, .name = "PA_CFG3" },
1192 { .addr = CC1200_WOR_TIME1, .name = "WOR_TIME1" },
1193 { .addr = CC1200_WOR_TIME0, .name = "WOR_TIME0" },
1194 { .addr = CC1200_WOR_CAPTURE1, .name = "WOR_CAPTURE1" },
1195 { .addr = CC1200_WOR_CAPTURE0, .name = "WOR_CAPTURE0" },
1196 { .addr = CC1200_BIST, .name = "BIST" },
1197 { .addr = CC1200_DCFILTOFFSET_I1, .name = "DCFILTOFFSET_I1" },
1198 { .addr = CC1200_DCFILTOFFSET_I0, .name = "DCFILTOFFSET_I0" },
1199 { .addr = CC1200_DCFILTOFFSET_Q1, .name = "DCFILTOFFSET_Q1" },
1200 { .addr = CC1200_DCFILTOFFSET_Q0, .name = "DCFILTOFFSET_Q0" },
1201 { .addr = CC1200_IQIE_I1, .name = "IQIE_I1" },
1202 { .addr = CC1200_IQIE_I0, .name = "IQIE_I0" },
1203 { .addr = CC1200_IQIE_Q1, .name = "IQIE_Q1" },
1204 { .addr = CC1200_IQIE_Q0, .name = "IQIE_Q0" },
1205 { .addr = CC1200_RSSI1, .name = "RSSI1" },
1206 { .addr = CC1200_RSSI0, .name = "RSSI0" },
1207 { .addr = CC1200_MARCSTATE, .name = "MARCSTATE" },
1208 { .addr = CC1200_LQI_VAL, .name = "LQI_VAL" },
1209 { .addr = CC1200_PQT_SYNC_ERR, .name = "PQT_SYNC_ERR" },
1210 { .addr = CC1200_DEM_STATUS, .name = "DEM_STATUS" },
1211 { .addr = CC1200_FREQOFF_EST1, .name = "FREQOFF_EST1" },
1212 { .addr = CC1200_FREQOFF_EST0, .name = "FREQOFF_EST0" },
1213 { .addr = CC1200_AGC_GAIN3, .name = "AGC_GAIN3" },
1214 { .addr = CC1200_AGC_GAIN2, .name = "AGC_GAIN2" },
1215 { .addr = CC1200_AGC_GAIN1, .name = "AGC_GAIN1" },
1216 { .addr = CC1200_AGC_GAIN0, .name = "AGC_GAIN0" },
1217 { .addr = CC1200_SOFT_RX_DATA_OUT, .name = "SOFT_RX_DATA_OUT" },
1218 { .addr = CC1200_SOFT_TX_DATA_IN, .name = "SOFT_TX_DATA_IN" },
1219 { .addr = CC1200_ASK_SOFT_RX_DATA, .name = "ASK_SOFT_RX_DATA" },
1220 { .addr = CC1200_RNDGEN, .name = "RNDGEN" },
1221 { .addr = CC1200_MAGN2, .name = "MAGN2" },
1222 { .addr = CC1200_MAGN1, .name = "MAGN1" },
1223 { .addr = CC1200_MAGN0, .name = "MAGN0" },
1224 { .addr = CC1200_ANG1, .name = "ANG1" },
1225 { .addr = CC1200_ANG0, .name = "ANG0" },
1226 { .addr = CC1200_CHFILT_I2, .name = "CHFILT_I2" },
1227 { .addr = CC1200_CHFILT_I1, .name = "CHFILT_I1" },
1228 { .addr = CC1200_CHFILT_I0, .name = "CHFILT_I0" },
1229 { .addr = CC1200_CHFILT_Q2, .name = "CHFILT_Q2" },
1230 { .addr = CC1200_CHFILT_Q1, .name = "CHFILT_Q1" },
1231 { .addr = CC1200_CHFILT_Q0, .name = "CHFILT_Q0" },
1232 { .addr = CC1200_GPIO_STATUS, .name = "GPIO_STATUS" },
1233 { .addr = CC1200_FSCAL_CTRL, .name = "FSCAL_CTRL" },
1234 { .addr = CC1200_PHASE_ADJUST, .name = "PHASE_ADJUST" },
1235 { .addr = CC1200_PARTNUMBER, .name = "PARTNUMBER" },
1236 { .addr = CC1200_PARTVERSION, .name = "PARTVERSION" },
1237 { .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" },
1238 { .addr = CC1200_MODEM_STATUS1, .name = "MODEM_STATUS1" },
1239 { .addr = CC1200_MODEM_STATUS0, .name = "MODEM_STATUS0" },
1240 { .addr = CC1200_MARC_STATUS1, .name = "MARC_STATUS1" },
1241 { .addr = CC1200_MARC_STATUS0, .name = "MARC_STATUS0" },
1242 { .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
1243 { .addr = CC1200_FSRF_TEST, .name = "FSRF_TEST" },
1244 { .addr = CC1200_PRE_TEST, .name = "PRE_TEST" },
1245 { .addr = CC1200_PRE_OVR, .name = "PRE_OVR" },
1246 { .addr = CC1200_ADC_TEST, .name = "ADC_TEST" },
1247 { .addr = CC1200_DVC_TEST, .name = "DVC_TEST" },
1248 { .addr = CC1200_ATEST, .name = "ATEST" },
1249 { .addr = CC1200_ATEST_LVDS, .name = "ATEST_LVDS" },
1250 { .addr = CC1200_ATEST_MODE, .name = "ATEST_MODE" },
1251 { .addr = CC1200_XOSC_TEST1, .name = "XOSC_TEST1" },
1252 { .addr = CC1200_XOSC_TEST0, .name = "XOSC_TEST0" },
1253 { .addr = CC1200_RXFIRST, .name = "RXFIRST" },
1254 { .addr = CC1200_TXFIRST, .name = "TXFIRST" },
1255 { .addr = CC1200_RXLAST, .name = "RXLAST" },
1256 { .addr = CC1200_TXLAST, .name = "TXLAST" },
1257 { .addr = CC1200_NUM_TXBYTES, .name = "NUM_TXBYTES" },
1258 { .addr = CC1200_NUM_RXBYTES, .name = "NUM_RXBYTES" },
1259 { .addr = CC1200_FIFO_NUM_TXBYTES, .name = "FIFO_NUM_TXBYTES" },
1260 { .addr = CC1200_FIFO_NUM_RXBYTES, .name = "FIFO_NUM_RXBYTES" },
1263 #define AO_NUM_CC1200_REG (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0])
1266 ao_radio_get_marc_status(void)
1268 return ao_radio_reg_read(CC1200_MARC_STATUS1);
1271 static void ao_radio_show(void) {
1275 ao_mutex_get(&ao_radio_mutex);
1276 status = ao_radio_status();
1277 printf ("Status: %02x\n", status);
1278 printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1);
1279 printf ("STATE: %s\n", cc1200_state_name[(status >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK]);
1280 printf ("MARC: %02x\n", ao_radio_get_marc_status());
1282 for (i = 0; i < AO_NUM_CC1200_REG; i++)
1283 printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1200_reg[i].addr), ao_cc1200_reg[i].name);
1288 static void ao_radio_beep(void) {
1292 static void ao_radio_packet(void) {
1293 static const uint8_t packet[] = {
1295 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1296 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1297 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1298 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1304 ao_radio_send(packet, sizeof (packet));
1308 ao_radio_test_recv(void)
1313 if (ao_radio_recv(bytes, 34, 0)) {
1314 if (bytes[33] & 0x80)
1318 printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32]));
1319 for (b = 0; b < 32; b++)
1320 printf (" %02x", bytes[b]);
1322 printf (" RSSI %02x LQI %02x", bytes[32], bytes[33]);
1328 #include <ao_aprs.h>
1333 #if PACKET_HAS_SLAVE
1334 ao_packet_slave_stop();
1341 #if CC1200_LOW_LEVEL_DEBUG
1343 ao_radio_strobe_test(void)
1348 if (ao_cmd_status != ao_cmd_success)
1350 r = ao_radio_strobe(ao_cmd_lex_i);
1351 printf ("Strobe %02x -> %02x (rdy %d state %d)\n",
1359 ao_radio_write_test(void)
1365 if (ao_cmd_status != ao_cmd_success)
1367 addr = ao_cmd_lex_i;
1369 if (ao_cmd_status != ao_cmd_success)
1371 data = ao_cmd_lex_i;
1372 printf ("Write %04x = %02x\n", addr, data);
1373 ao_radio_reg_write(addr, data);
1377 ao_radio_read_test(void)
1383 if (ao_cmd_status != ao_cmd_success)
1385 addr = ao_cmd_lex_i;
1386 data = ao_radio_reg_read(addr);
1387 printf ("Read %04x = %02x\n", addr, data);
1391 static const struct ao_cmds ao_radio_cmds[] = {
1392 { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
1395 { ao_radio_aprs, "G\0Send APRS packet" },
1397 { ao_radio_show, "R\0Show CC1200 status" },
1398 { ao_radio_beep, "b\0Emit an RDF beacon" },
1399 { ao_radio_packet, "p\0Send a test packet" },
1400 { ao_radio_test_recv, "q\0Recv a test packet" },
1402 #if CC1200_LOW_LEVEL_DEBUG
1403 { ao_radio_strobe_test, "A <value>\0Strobe radio" },
1404 { ao_radio_write_test, "W <addr> <value>\0Write radio reg" },
1405 { ao_radio_read_test, "B <addr>\0Read radio reg" },
1413 ao_radio_configured = 0;
1414 ao_spi_init_cs (AO_CC1200_SPI_CS_PORT, (1 << AO_CC1200_SPI_CS_PIN));
1417 AO_CC1200_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC1200_SPI_CS_PIN));
1418 for (i = 0; i < 10000; i++) {
1419 if ((SPI_2_PORT->idr & (1 << SPI_2_MISO_PIN)) == 0)
1422 AO_CC1200_SPI_CS_PORT->bsrr = (1 << AO_CC1200_SPI_CS_PIN);
1424 ao_panic(AO_PANIC_SELF_TEST_CC1200);
1427 /* Enable the EXTI interrupt for the appropriate pin */
1428 ao_enable_port(AO_CC1200_INT_PORT);
1429 ao_exti_setup(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN,
1430 AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH,
1433 ao_cmd_register(&ao_radio_cmds[0]);