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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 #include <ao_cc1200.h>
23 #include <ao_packet.h>
28 static uint8_t cc1201;
30 static uint8_t ao_radio_mutex;
32 static uint8_t ao_radio_wake; /* radio ready. Also used as sleep address */
33 static uint8_t ao_radio_abort; /* radio operation should abort */
35 int8_t ao_radio_rssi; /* Last received RSSI value */
38 #define CC1200_DEBUG 0
41 #ifndef CC1200_LOW_LEVEL_DEBUG
42 #define CC1200_LOW_LEVEL_DEBUG 0
45 #define CC1200_TRACE 0
46 #define CC1200_APRS_TRACE 0
48 extern const uint32_t ao_radio_cal;
51 #define FOSC AO_CC1200_FOSC
56 #define AO_CC1200_SPI_SPEED ao_spi_speed(7700000) /* 7.7MHz max for extended memory reads */
58 #define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_CC1200_SPI_SPEED)
59 #define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS)
60 #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1200_SPI_BUS)
61 #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS)
62 #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1200_SPI_BUS)
63 #define ao_radio_duplex(o,i,l) ao_spi_duplex((o), (i), (l), AO_CC1200_SPI_BUS)
66 ao_radio_reg_read(uint16_t addr)
72 printf("\t\tao_radio_reg_read (%04x): ", addr); flush();
74 if (CC1200_IS_EXTENDED(addr)) {
75 data[0] = ((1 << CC1200_READ) |
78 data[1] = (uint8_t) addr;
81 data[0] = ((1 << CC1200_READ) |
87 ao_radio_spi_send(data, d);
88 ao_radio_spi_recv(data, 1);
91 printf (" %02x\n", data[0]);
97 ao_radio_reg_write(uint16_t addr, uint8_t value)
103 printf("\t\tao_radio_reg_write (%04x): %02x\n", addr, value);
105 if (CC1200_IS_EXTENDED(addr)) {
106 data[0] = ((0 << CC1200_READ) |
107 (0 << CC1200_BURST) |
109 data[1] = (uint8_t) addr;
112 data[0] = ((0 << CC1200_READ) |
113 (0 << CC1200_BURST) |
119 ao_radio_spi_send(data, d+1);
122 (void) ao_radio_reg_read(addr);
127 ao_radio_strobe(uint8_t addr)
132 printf("\t\tao_radio_strobe (%02x): ", addr); flush();
135 ao_radio_duplex(&addr, &in, 1);
138 printf("%02x\n", in); flush();
144 ao_radio_fifo_read(uint8_t *data, uint8_t len)
146 uint8_t addr = ((1 << CC1200_READ) |
147 (1 << CC1200_BURST) |
152 ao_radio_duplex(&addr, &status, 1);
153 ao_radio_spi_recv(data, len);
159 ao_radio_fifo_write_start(void)
161 uint8_t addr = ((0 << CC1200_READ) |
162 (1 << CC1200_BURST) |
167 ao_radio_duplex(&addr, &status, 1);
171 static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) {
177 ao_radio_fifo_write(const uint8_t *data, uint8_t len)
179 uint8_t status = ao_radio_fifo_write_start();
180 ao_radio_spi_send(data, len);
181 return ao_radio_fifo_write_stop(status);
185 ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
187 uint8_t status = ao_radio_fifo_write_start();
188 ao_radio_spi_send_fixed(data, len);
189 return ao_radio_fifo_write_stop(status);
193 ao_radio_int_pin(void)
195 return ao_gpio_get(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
199 ao_radio_status(void)
201 return ao_radio_strobe (CC1200_SNOP);
205 ao_radio_recv_abort(void)
208 ao_wakeup(&ao_radio_wake);
211 #define ao_radio_rdf_value 0x55
217 ao_wakeup(&ao_radio_wake);
221 ao_radio_start_tx(void)
223 ao_radio_strobe(CC1200_STX);
227 ao_radio_start_rx(void)
229 ao_radio_strobe(CC1200_SRX);
236 uint8_t state = (ao_radio_strobe(CC1200_SIDLE) >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
237 if (state == CC1200_STATUS_STATE_IDLE)
239 if (state == CC1200_STATUS_STATE_TX_FIFO_ERROR)
240 ao_radio_strobe(CC1200_SFTX);
241 if (state == CC1200_STATUS_STATE_RX_FIFO_ERROR)
242 ao_radio_strobe(CC1200_SFRX);
244 /* Flush any pending data in the fifos */
245 ao_radio_strobe(CC1200_SFTX);
246 ao_radio_strobe(CC1200_SFRX);
247 /* Make sure the RF calibration is current */
248 ao_radio_strobe(CC1200_SCAL);
254 * fdev = fosc >> 22 * (256 + dev_m) << dev_e
256 * Deviation for 38400 baud should be 20.5kHz:
258 * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 3) = 20523Hz
260 * Deviation for 9600 baud should be 5.125kHz:
262 * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 1) = 5131Hz
264 * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and
265 * cc115l can't do that, so we'll use 1.5kHz instead:
267 * 40e6 / (2 ** 21) * (79) = 1506Hz
270 #define PACKET_DEV_M_384 13
271 #define PACKET_DEV_E_384 3
273 #define PACKET_DEV_M_96 13
274 #define PACKET_DEV_E_96 1
276 #define PACKET_DEV_M_24 79
277 #define PACKET_DEV_E_24 0
280 * For our packet data
282 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
283 * Rdata = -------------------------------------- * fosc
286 * Given the bit period of the baseband, T, the bandwidth of the
287 * baseband signal is B = 1/(2T). The overall bandwidth of the
288 * modulated signal is then Channel bandwidth = 2Δf + 2B.
290 * 38400 -- 2 * 20500 + 38400 = 79.4 kHz
291 * 9600 -- 2 * 5.125 + 9600 = 19.9 kHz
292 * 2400 -- 2 * 1.5 + 2400 = 5.4 khz
294 * Symbol rate 38400 Baud:
296 * DATARATE_M = 1013008
300 * Symbol rate 9600 Baud:
302 * DATARATE_M = 1013008
304 * CHANBW = 26.042 (round to 19.8)
306 * Symbol rate 2400 Baud:
308 * DATARATE_M = 1013008
310 * CHANBW = 5.0 (round to 9.5)
314 #define PACKET_SYMBOL_RATE_M 1013008
315 #define PACKET_SYMBOL_RATE_E_384 8
316 #define PACKET_SYMBOL_RATE_E_96 6
317 #define PACKET_SYMBOL_RATE_E_24 4
321 #define PACKET_SYMBOL_RATE_M 239914
322 #define PACKET_SYMBOL_RATE_E_384 9
323 #define PACKET_SYMBOL_RATE_E_96 7
324 #define PACKET_SYMBOL_RATE_E_24 5
328 #define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
329 (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
332 * CC1201 doesn't support our low bandwidth receive setups, so we use
333 * larger values for that part, leaving the bandwidth at over 50kHz
337 #define PACKET_CHAN_BW_96_CC1200 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
338 (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
340 #define PACKET_CHAN_BW_96_CC1201 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
341 (8 << CC1200_CHAN_BW_BB_CIC_DECFACT))
344 #define PACKET_CHAN_BW_24_CC1200 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
345 (44 << CC1200_CHAN_BW_BB_CIC_DECFACT))
347 #define PACKET_CHAN_BW_24_CC1201 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
348 (8 << CC1200_CHAN_BW_BB_CIC_DECFACT))
350 static const uint16_t packet_setup[] = {
351 CC1200_SYMBOL_RATE1, ((PACKET_SYMBOL_RATE_M >> 8) & 0xff),
352 CC1200_SYMBOL_RATE0, ((PACKET_SYMBOL_RATE_M >> 0) & 0xff),
353 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
354 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
355 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
356 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
357 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
358 ((1 << CC1200_PKT_CFG1_FEC_EN) |
359 (1 << CC1200_PKT_CFG1_WHITE_DATA) |
360 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
361 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
362 (CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES << CC1200_PKT_CFG1_CRC_CFG) |
363 (1 << CC1200_PKT_CFG1_APPEND_STATUS)),
364 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
365 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
368 static const uint16_t packet_setup_384[] = {
369 CC1200_DEVIATION_M, PACKET_DEV_M_384,
370 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
371 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
372 (PACKET_DEV_E_384 << CC1200_MODCFG_DEV_E_DEV_E)),
373 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_384 << CC1200_SYMBOL_RATE2_DATARATE_E) |
374 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
375 CC1200_CHAN_BW, PACKET_CHAN_BW_384,
376 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
377 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
378 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
379 (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
380 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
383 static const uint16_t packet_setup_96[] = {
384 CC1200_DEVIATION_M, PACKET_DEV_M_96,
385 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
386 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
387 (PACKET_DEV_E_96 << CC1200_MODCFG_DEV_E_DEV_E)),
388 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) |
389 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
390 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
391 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
392 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
393 (CC1200_MDMCFG2_UPSAMPLER_P_32 << CC1200_MDMCFG2_UPSAMPLER_P) |
394 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
397 static const uint16_t packet_setup_24[] = {
398 CC1200_DEVIATION_M, PACKET_DEV_M_24,
399 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
400 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
401 (PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)),
402 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) |
403 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
404 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
405 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
406 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
407 (CC1200_MDMCFG2_UPSAMPLER_P_64 << CC1200_MDMCFG2_UPSAMPLER_P) |
408 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
412 * RDF deviation is 3kHz
414 * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
415 * fdev = fosc >> 21 * dev_m dev_e == 0
417 * 40e6 / (2 ** 21) * 157 = 2995Hz
421 #define RDF_DEV_M 157
424 * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone)
426 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
427 * Rdata = -------------------------------------- * fosc
430 * DATARATE_M = 669411
433 * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes
435 #define RDF_SYMBOL_RATE_E 4
436 #define RDF_SYMBOL_RATE_M 669411
437 #define RDF_PACKET_LEN 50
439 static const uint16_t rdf_setup[] = {
440 CC1200_DEVIATION_M, RDF_DEV_M,
441 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
442 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
443 (RDF_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
444 CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
445 (((RDF_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
446 CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff),
447 CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff),
448 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
449 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
450 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
451 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
452 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
453 ((0 << CC1200_PKT_CFG1_FEC_EN) |
454 (0 << CC1200_PKT_CFG1_WHITE_DATA) |
455 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
456 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
457 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
458 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
459 CC1200_PREAMBLE_CFG1,
460 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
461 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
462 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
463 ((0 << CC1200_MDMCFG2_ASK_SHAPE) |
464 (0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
465 (12 << CC1200_MDMCFG2_UPSAMPLER_P) |
466 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
470 * APRS deviation is 3kHz
472 * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
473 * fdev = fosc >> 21 * dev_m dev_e == 0
475 * 40e6 / (2 ** 21) * 157 = 2995Hz
479 #define APRS_DEV_M 157
482 * For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate)
484 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
485 * Rdata = -------------------------------------- * fosc
488 * DATARATE_M = 1013008
491 * Rdata = 9599.998593330383301
494 #define APRS_SYMBOL_RATE_E 6
495 #define APRS_SYMBOL_RATE_M 1013008
496 #define APRS_BUFFER_SIZE 64
498 static const uint16_t aprs_setup[] = {
499 CC1200_DEVIATION_M, APRS_DEV_M,
500 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
501 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
502 (APRS_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
503 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
504 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
505 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
506 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
507 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
508 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
509 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
510 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
511 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
512 ((0 << CC1200_PKT_CFG1_FEC_EN) |
513 (0 << CC1200_PKT_CFG1_WHITE_DATA) |
514 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
515 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
516 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
517 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
518 CC1200_PKT_CFG0, /* Packet Configuration Reg. 0 */
519 ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
520 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
521 (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
522 (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
523 CC1200_PREAMBLE_CFG1,
524 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
525 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
526 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
527 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
528 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
529 (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
530 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
532 ((0 << CC1200_FIFO_CFG_CRC_AUTOFLUSH) |
533 (APRS_BUFFER_SIZE << CC1200_FIFO_CFG_FIFO_THR)),
537 * For Test mode, we want an unmodulated carrier. To do that, we
538 * set the deviation to zero and enable a preamble so that the radio
539 * turns on before we send any data
542 static const uint16_t test_setup[] = {
543 CC1200_DEVIATION_M, 0,
544 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
545 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
546 (0 << CC1200_MODCFG_DEV_E_DEV_E)),
547 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
548 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
549 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
550 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
551 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
552 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
553 CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
554 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
555 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
556 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
557 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
558 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
561 #define AO_PKT_CFG0_INFINITE ((CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
562 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
563 (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
564 (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
566 #define AO_PKT_CFG0_FIXED ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
567 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
568 (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
569 (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
571 static uint16_t ao_radio_mode;
573 #define AO_RADIO_MODE_BITS_PACKET 1
574 #define AO_RADIO_MODE_BITS_TX_BUF 4
575 #define AO_RADIO_MODE_BITS_FINISH 8
576 #define AO_RADIO_MODE_BITS_RDF 32
577 #define AO_RADIO_MODE_BITS_APRS 64
578 #define AO_RADIO_MODE_BITS_TEST 128
579 #define AO_RADIO_MODE_BITS_INFINITE 256
580 #define AO_RADIO_MODE_BITS_FIXED 512
582 #define AO_RADIO_MODE_NONE 0
583 #define AO_RADIO_MODE_PACKET_TX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH)
584 #define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH)
585 #define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH)
586 #define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
587 #define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF)
588 #define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_FINISH)
589 #define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
592 _ao_radio_set_regs(const uint16_t *regs, int nreg)
596 for (i = 0; i < nreg; i++) {
597 ao_radio_reg_write(regs[0], (uint8_t) regs[1]);
602 #define ao_radio_set_regs(setup) _ao_radio_set_regs(setup, (sizeof (setup) / sizeof(setup[0])) >> 1)
605 ao_radio_set_mode(uint16_t new_mode)
609 if (new_mode == ao_radio_mode)
612 changes = (uint16_t) (new_mode & (~ao_radio_mode));
614 if (changes & AO_RADIO_MODE_BITS_PACKET) {
615 ao_radio_set_regs(packet_setup);
617 switch (ao_config.radio_rate) {
619 case AO_RADIO_RATE_38400:
620 ao_radio_set_regs(packet_setup_384);
622 case AO_RADIO_RATE_9600:
623 ao_radio_set_regs(packet_setup_96);
625 ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_96_CC1201);
627 ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_96_CC1200);
629 case AO_RADIO_RATE_2400:
630 ao_radio_set_regs(packet_setup_24);
632 ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_24_CC1201);
634 ao_radio_reg_write(CC1200_CHAN_BW, PACKET_CHAN_BW_24_CC1200);
639 if (changes & AO_RADIO_MODE_BITS_TX_BUF) {
640 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR);
643 if (changes & AO_RADIO_MODE_BITS_FINISH) {
644 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
647 if (changes & AO_RADIO_MODE_BITS_RDF)
648 ao_radio_set_regs(rdf_setup);
650 if (changes & AO_RADIO_MODE_BITS_APRS)
651 ao_radio_set_regs(aprs_setup);
653 if (changes & AO_RADIO_MODE_BITS_TEST)
654 ao_radio_set_regs(test_setup);
656 if (changes & AO_RADIO_MODE_BITS_INFINITE)
657 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_INFINITE);
659 if (changes & AO_RADIO_MODE_BITS_FIXED)
660 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_FIXED);
662 ao_radio_mode = new_mode;
665 static const uint16_t radio_setup[] = {
666 #include "ao_cc1200_CC1200.h"
669 static uint8_t ao_radio_configured = 0;
674 uint8_t partnumber = ao_radio_reg_read(CC1200_PARTNUMBER);
676 if (partnumber == CC1200_PARTNUMBER_CC1201)
679 ao_radio_strobe(CC1200_SRES);
681 ao_radio_set_regs(radio_setup);
689 ao_radio_configured = 1;
693 ao_radio_set_len(uint8_t len)
695 static uint8_t last_len;
697 if (len != last_len) {
698 ao_radio_reg_write(CC1200_PKT_LEN, len);
704 ao_radio_get(uint8_t len)
706 static uint32_t last_radio_setting;
707 static uint8_t last_radio_rate;
708 static uint8_t last_radio_10mw;
710 ao_mutex_get(&ao_radio_mutex);
712 if (!ao_radio_configured)
714 if (ao_config.radio_setting != last_radio_setting) {
715 ao_radio_reg_write(CC1200_FREQ2, (uint8_t) (ao_config.radio_setting >> 16));
716 ao_radio_reg_write(CC1200_FREQ1, (uint8_t) (ao_config.radio_setting >> 8));
717 ao_radio_reg_write(CC1200_FREQ0, (uint8_t) ao_config.radio_setting);
718 last_radio_setting = ao_config.radio_setting;
719 ao_radio_strobe(CC1200_SCAL);
721 if (ao_config.radio_rate != last_radio_rate) {
722 ao_radio_mode &= (uint16_t) ~AO_RADIO_MODE_BITS_PACKET;
723 last_radio_rate = ao_config.radio_rate;
725 if(ao_config.radio_10mw != last_radio_10mw) {
726 last_radio_10mw = ao_config.radio_10mw;
728 * 0x37 "should" be 10dBm, but measurements on TBT
729 * v4.0 show that too hot, so use * 0x32 to make sure
732 if (ao_config.radio_10mw)
733 ao_radio_reg_write(CC1200_PA_CFG1, 0x32);
735 ao_radio_reg_write(CC1200_PA_CFG1, 0x3f);
737 ao_radio_set_len(len);
740 #define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
742 static inline uint8_t
745 return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
750 ao_radio_show_state(char *where)
752 printf("%s: state %d len %d rxbytes %d\n",
753 where, ao_radio_state(),
754 ao_radio_reg_read(CC1200_PKT_LEN),
755 ao_radio_reg_read(CC1200_NUM_RXBYTES));
758 #define ao_radio_show_state(where)
761 /* Wait for the radio to signal an interrupt
764 _ao_radio_wait_isr(AO_TICK_TYPE timeout)
766 while (!ao_radio_wake && !ao_radio_abort)
767 if (ao_sleep_for(&ao_radio_wake, timeout))
772 ao_radio_wait_isr(AO_TICK_TYPE timeout)
774 ao_arch_block_interrupts();
775 _ao_radio_wait_isr(timeout);
776 ao_arch_release_interrupts();
780 ao_rdf_start(uint8_t len)
785 ao_radio_set_mode(AO_RADIO_MODE_RDF);
795 ao_radio_wait_isr(0);
804 ao_rdf_start(AO_RADIO_RDF_LEN);
806 ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
812 ao_radio_continuity(uint8_t c)
817 ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
819 status = ao_radio_fifo_write_start();
820 for (i = 0; i < 3; i++) {
821 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
823 ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
825 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
827 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
828 status = ao_radio_fifo_write_stop(status);
834 ao_radio_rdf_abort(void)
837 ao_wakeup(&ao_radio_wake);
840 static uint8_t radio_on;
843 ao_radio_test_on(void)
847 ao_monitor_disable();
850 ao_packet_slave_stop();
856 ao_radio_set_mode(AO_RADIO_MODE_TEST);
857 ao_radio_strobe(CC1200_STX);
860 for (t = 0; t < 10; t++) {
861 printf ("status: %02x\n", ao_radio_status());
862 ao_delay(AO_MS_TO_TICKS(100));
871 ao_radio_test_off(void)
887 ao_radio_test_cmd(void)
891 if (ao_cmd_lex_c != '\n')
892 mode = (uint8_t) ao_cmd_decimal();
897 printf ("Hit a character to stop..."); flush();
906 ao_radio_send(const void *d, uint8_t size)
909 ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX);
911 ao_radio_fifo_write(d, size);
917 ao_radio_send_aprs(ao_radio_fill_func fill)
919 uint8_t buf[APRS_BUFFER_SIZE];
928 while (!done && !ao_radio_abort) {
929 cnt = (*fill)(buf, sizeof(buf));
936 /* At the last buffer, set the total length */
938 ao_radio_set_len((uint8_t) (total & 0xff));
940 /* Wait for some space in the fifo */
941 ao_arch_block_interrupts();
942 while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) {
944 _ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
946 ao_arch_release_interrupts();
951 ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
953 ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
955 ao_radio_fifo_write(buf, (uint8_t) cnt);
957 ao_radio_strobe(CC1200_STX);
961 /* Wait for the transmitter to go idle */
962 ao_arch_block_interrupts();
963 while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) {
965 _ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
967 ao_arch_release_interrupts();
975 ao_radio_marc_state(void)
977 return ao_radio_reg_read(CC1200_MARCSTATE);
981 ao_radio_modem_status1(void)
983 return ao_radio_reg_read(CC1200_MODEM_STATUS1);
987 ao_radio_modem_status0(void)
989 return ao_radio_reg_read(CC1200_MODEM_STATUS0);
992 struct ao_radio_state {
995 uint8_t marc_status1;
996 uint8_t marc_status0;
997 uint8_t modem_status1;
998 uint8_t modem_status0;
1002 ao_radio_fill_state(char *where, struct ao_radio_state *s)
1004 strcpy(s->where, where);
1005 s->marc_state = ao_radio_marc_state();
1006 s->marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
1007 s->marc_status0 = ao_radio_reg_read(CC1200_MARC_STATUS0);
1008 s->modem_status1 = ao_radio_modem_status1();
1009 s->modem_status0 = ao_radio_modem_status0();
1013 ao_radio_dump_state(struct ao_radio_state *s)
1015 printf ("%s: marc %2x marc1 %2x marc0 %2x modem1 %2x modem0 %2x\n",
1016 s->where, s->marc_state, s->marc_status1, s->marc_status0, s->modem_status1, s->modem_status0);
1021 ao_radio_recv(void *d, uint8_t size, AO_TICK_TYPE timeout)
1023 uint8_t success = 0;
1026 ao_radio_get(size - 2);
1027 ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
1029 ao_radio_start_rx();
1031 while (!ao_radio_abort) {
1032 ao_radio_wait_isr(timeout);
1035 if (ao_radio_wake) {
1036 uint8_t marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
1038 /* Check the receiver status to see what happened
1040 switch (marc_status1) {
1041 case CC1200_MARC_STATUS1_RX_FINISHED:
1042 case CC1200_MARC_STATUS1_ADDRESS:
1043 case CC1200_MARC_STATUS1_CRC:
1044 /* Normal return, go fetch the bytes from the FIFO
1045 * and give them back to the caller
1049 case CC1200_MARC_STATUS1_RX_TIMEOUT:
1050 case CC1200_MARC_STATUS1_RX_TERMINATION:
1051 case CC1200_MARC_STATUS1_EWOR_SYNC_LOST:
1052 case CC1200_MARC_STATUS1_MAXIMUM_LENGTH:
1053 case CC1200_MARC_STATUS1_RX_FIFO_OVERFLOW:
1054 case CC1200_MARC_STATUS1_RX_FIFO_UNDERFLOW:
1055 /* Something weird happened; reset the radio and
1061 /* some other status; go wait for the radio to do something useful
1067 uint8_t modem_status1 = ao_radio_reg_read(CC1200_MODEM_STATUS1);
1069 /* Check to see if the packet header has been seen, in which case we'll
1070 * want to keep waiting for the rest of the packet to appear
1072 if (modem_status1 & (1 << CC1200_MODEM_STATUS1_SYNC_FOUND))
1076 /* Set a timeout based on the packet length so that we make sure to
1077 * wait long enough to receive the whole thing.
1079 * timeout = bits * FEC expansion / rate
1081 switch (ao_config.radio_rate) {
1083 case AO_RADIO_RATE_38400:
1084 timeout = AO_MS_TO_TICKS((AO_TICK_TYPE) size * (8 * 2 * 10) / 384) + 1;
1086 case AO_RADIO_RATE_9600:
1087 timeout = AO_MS_TO_TICKS((AO_TICK_TYPE) size * (8 * 2 * 10) / 96) + 1;
1089 case AO_RADIO_RATE_2400:
1090 timeout = AO_MS_TO_TICKS((AO_TICK_TYPE) size * (8 * 2 * 10) / 24) + 1;
1101 status = ao_radio_fifo_read(d, size);
1103 rssi = ((int8_t *) d)[size - 2];
1104 ao_radio_rssi = rssi;
1106 /* Bound it to the representable range */
1110 /* Write it back to the packet */
1111 ((uint8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi);
1123 static char *cc1200_state_name[] = {
1124 [CC1200_STATUS_STATE_IDLE] = "IDLE",
1125 [CC1200_STATUS_STATE_RX] = "RX",
1126 [CC1200_STATUS_STATE_TX] = "TX",
1127 [CC1200_STATUS_STATE_FSTXON] = "FSTXON",
1128 [CC1200_STATUS_STATE_CALIBRATE] = "CALIBRATE",
1129 [CC1200_STATUS_STATE_SETTLING] = "SETTLING",
1130 [CC1200_STATUS_STATE_RX_FIFO_ERROR] = "RX_FIFO_ERROR",
1131 [CC1200_STATUS_STATE_TX_FIFO_ERROR] = "TX_FIFO_ERROR",
1134 struct ao_cc1200_reg {
1139 static const struct ao_cc1200_reg ao_cc1200_reg[] = {
1140 { .addr = CC1200_IOCFG3, .name = "IOCFG3" },
1141 { .addr = CC1200_IOCFG2, .name = "IOCFG2" },
1142 { .addr = CC1200_IOCFG1, .name = "IOCFG1" },
1143 { .addr = CC1200_IOCFG0, .name = "IOCFG0" },
1144 { .addr = CC1200_SYNC3, .name = "SYNC3" },
1145 { .addr = CC1200_SYNC2, .name = "SYNC2" },
1146 { .addr = CC1200_SYNC1, .name = "SYNC1" },
1147 { .addr = CC1200_SYNC0, .name = "SYNC0" },
1148 { .addr = CC1200_SYNC_CFG1, .name = "SYNC_CFG1" },
1149 { .addr = CC1200_SYNC_CFG0, .name = "SYNC_CFG0" },
1150 { .addr = CC1200_DEVIATION_M, .name = "DEVIATION_M" },
1151 { .addr = CC1200_MODCFG_DEV_E, .name = "MODCFG_DEV_E" },
1152 { .addr = CC1200_DCFILT_CFG, .name = "DCFILT_CFG" },
1153 { .addr = CC1200_PREAMBLE_CFG1, .name = "PREAMBLE_CFG1" },
1154 { .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
1155 { .addr = CC1200_IQIC, .name = "IQIC" },
1156 { .addr = CC1200_CHAN_BW, .name = "CHAN_BW" },
1157 { .addr = CC1200_MDMCFG2, .name = "MDMCFG2" },
1158 { .addr = CC1200_MDMCFG1, .name = "MDMCFG1" },
1159 { .addr = CC1200_MDMCFG0, .name = "MDMCFG0" },
1160 { .addr = CC1200_SYMBOL_RATE2, .name = "SYMBOL_RATE2" },
1161 { .addr = CC1200_SYMBOL_RATE1, .name = "SYMBOL_RATE1" },
1162 { .addr = CC1200_SYMBOL_RATE0, .name = "SYMBOL_RATE0" },
1163 { .addr = CC1200_AGC_REF, .name = "AGC_REF" },
1164 { .addr = CC1200_AGC_CS_THR, .name = "AGC_CS_THR" },
1165 { .addr = CC1200_AGC_GAIN_ADJUST, .name = "AGC_GAIN_ADJUST" },
1166 { .addr = CC1200_AGC_CFG3, .name = "AGC_CFG3" },
1167 { .addr = CC1200_AGC_CFG2, .name = "AGC_CFG2" },
1168 { .addr = CC1200_AGC_CFG1, .name = "AGC_CFG1" },
1169 { .addr = CC1200_AGC_CFG0, .name = "AGC_CFG0" },
1170 { .addr = CC1200_FIFO_CFG, .name = "FIFO_CFG" },
1171 { .addr = CC1200_DEV_ADDR, .name = "DEV_ADDR" },
1172 { .addr = CC1200_SETTLING_CFG, .name = "SETTLING_CFG" },
1173 { .addr = CC1200_FS_CFG, .name = "FS_CFG" },
1174 { .addr = CC1200_WOR_CFG1, .name = "WOR_CFG1" },
1175 { .addr = CC1200_WOR_CFG0, .name = "WOR_CFG0" },
1176 { .addr = CC1200_WOR_EVENT0_MSB, .name = "WOR_EVENT0_MSB" },
1177 { .addr = CC1200_WOR_EVENT0_LSB, .name = "WOR_EVENT0_LSB" },
1178 { .addr = CC1200_RXDCM_TIME, .name = "RXDCM_TIME" },
1179 { .addr = CC1200_PKT_CFG2, .name = "PKT_CFG2" },
1180 { .addr = CC1200_PKT_CFG1, .name = "PKT_CFG1" },
1181 { .addr = CC1200_PKT_CFG0, .name = "PKT_CFG0" },
1182 { .addr = CC1200_RFEND_CFG1, .name = "RFEND_CFG1" },
1183 { .addr = CC1200_RFEND_CFG0, .name = "RFEND_CFG0" },
1184 { .addr = CC1200_PA_CFG1, .name = "PA_CFG1" },
1185 { .addr = CC1200_PA_CFG0, .name = "PA_CFG0" },
1186 { .addr = CC1200_PKT_LEN, .name = "PKT_LEN" },
1187 { .addr = CC1200_IF_MIX_CFG, .name = "IF_MIX_CFG" },
1188 { .addr = CC1200_FREQOFF_CFG, .name = "FREQOFF_CFG" },
1189 { .addr = CC1200_TOC_CFG, .name = "TOC_CFG" },
1190 { .addr = CC1200_MARC_SPARE, .name = "MARC_SPARE" },
1191 { .addr = CC1200_ECG_CFG, .name = "ECG_CFG" },
1192 { .addr = CC1200_EXT_CTRL, .name = "EXT_CTRL" },
1193 { .addr = CC1200_RCCAL_FINE, .name = "RCCAL_FINE" },
1194 { .addr = CC1200_RCCAL_COARSE, .name = "RCCAL_COARSE" },
1195 { .addr = CC1200_RCCAL_OFFSET, .name = "RCCAL_OFFSET" },
1196 { .addr = CC1200_FREQOFF1, .name = "FREQOFF1" },
1197 { .addr = CC1200_FREQOFF0, .name = "FREQOFF0" },
1198 { .addr = CC1200_FREQ2, .name = "FREQ2" },
1199 { .addr = CC1200_FREQ1, .name = "FREQ1" },
1200 { .addr = CC1200_FREQ0, .name = "FREQ0" },
1201 { .addr = CC1200_IF_ADC2, .name = "IF_ADC2" },
1202 { .addr = CC1200_IF_ADC1, .name = "IF_ADC1" },
1203 { .addr = CC1200_IF_ADC0, .name = "IF_ADC0" },
1204 { .addr = CC1200_FS_DIG1, .name = "FS_DIG1" },
1205 { .addr = CC1200_FS_DIG0, .name = "FS_DIG0" },
1206 { .addr = CC1200_FS_CAL3, .name = "FS_CAL3" },
1207 { .addr = CC1200_FS_CAL2, .name = "FS_CAL2" },
1208 { .addr = CC1200_FS_CAL1, .name = "FS_CAL1" },
1209 { .addr = CC1200_FS_CAL0, .name = "FS_CAL0" },
1210 { .addr = CC1200_FS_CHP, .name = "FS_CHP" },
1211 { .addr = CC1200_FS_DIVTWO, .name = "FS_DIVTWO" },
1212 { .addr = CC1200_FS_DSM1, .name = "FS_DSM1" },
1213 { .addr = CC1200_FS_DSM0, .name = "FS_DSM0" },
1214 { .addr = CC1200_FS_DVC1, .name = "FS_DVC1" },
1215 { .addr = CC1200_FS_DVC0, .name = "FS_DVC0" },
1216 { .addr = CC1200_FS_LBI, .name = "FS_LBI" },
1217 { .addr = CC1200_FS_PFD, .name = "FS_PFD" },
1218 { .addr = CC1200_FS_PRE, .name = "FS_PRE" },
1219 { .addr = CC1200_FS_REG_DIV_CML, .name = "FS_REG_DIV_CML" },
1220 { .addr = CC1200_FS_SPARE, .name = "FS_SPARE" },
1221 { .addr = CC1200_FS_VCO4, .name = "FS_VCO4" },
1222 { .addr = CC1200_FS_VCO3, .name = "FS_VCO3" },
1223 { .addr = CC1200_FS_VCO2, .name = "FS_VCO2" },
1224 { .addr = CC1200_FS_VCO1, .name = "FS_VCO1" },
1225 { .addr = CC1200_FS_VCO0, .name = "FS_VCO0" },
1226 { .addr = CC1200_GBIAS6, .name = "GBIAS6" },
1227 { .addr = CC1200_GBIAS5, .name = "GBIAS5" },
1228 { .addr = CC1200_GBIAS4, .name = "GBIAS4" },
1229 { .addr = CC1200_GBIAS3, .name = "GBIAS3" },
1230 { .addr = CC1200_GBIAS2, .name = "GBIAS2" },
1231 { .addr = CC1200_GBIAS1, .name = "GBIAS1" },
1232 { .addr = CC1200_GBIAS0, .name = "GBIAS0" },
1233 { .addr = CC1200_IFAMP, .name = "IFAMP" },
1234 { .addr = CC1200_LNA, .name = "LNA" },
1235 { .addr = CC1200_RXMIX, .name = "RXMIX" },
1236 { .addr = CC1200_XOSC5, .name = "XOSC5" },
1237 { .addr = CC1200_XOSC4, .name = "XOSC4" },
1238 { .addr = CC1200_XOSC3, .name = "XOSC3" },
1239 { .addr = CC1200_XOSC2, .name = "XOSC2" },
1240 { .addr = CC1200_XOSC1, .name = "XOSC1" },
1241 { .addr = CC1200_XOSC0, .name = "XOSC0" },
1242 { .addr = CC1200_ANALOG_SPARE, .name = "ANALOG_SPARE" },
1243 { .addr = CC1200_PA_CFG3, .name = "PA_CFG3" },
1244 { .addr = CC1200_WOR_TIME1, .name = "WOR_TIME1" },
1245 { .addr = CC1200_WOR_TIME0, .name = "WOR_TIME0" },
1246 { .addr = CC1200_WOR_CAPTURE1, .name = "WOR_CAPTURE1" },
1247 { .addr = CC1200_WOR_CAPTURE0, .name = "WOR_CAPTURE0" },
1248 { .addr = CC1200_BIST, .name = "BIST" },
1249 { .addr = CC1200_DCFILTOFFSET_I1, .name = "DCFILTOFFSET_I1" },
1250 { .addr = CC1200_DCFILTOFFSET_I0, .name = "DCFILTOFFSET_I0" },
1251 { .addr = CC1200_DCFILTOFFSET_Q1, .name = "DCFILTOFFSET_Q1" },
1252 { .addr = CC1200_DCFILTOFFSET_Q0, .name = "DCFILTOFFSET_Q0" },
1253 { .addr = CC1200_IQIE_I1, .name = "IQIE_I1" },
1254 { .addr = CC1200_IQIE_I0, .name = "IQIE_I0" },
1255 { .addr = CC1200_IQIE_Q1, .name = "IQIE_Q1" },
1256 { .addr = CC1200_IQIE_Q0, .name = "IQIE_Q0" },
1257 { .addr = CC1200_RSSI1, .name = "RSSI1" },
1258 { .addr = CC1200_RSSI0, .name = "RSSI0" },
1259 { .addr = CC1200_MARCSTATE, .name = "MARCSTATE" },
1260 { .addr = CC1200_LQI_VAL, .name = "LQI_VAL" },
1261 { .addr = CC1200_PQT_SYNC_ERR, .name = "PQT_SYNC_ERR" },
1262 { .addr = CC1200_DEM_STATUS, .name = "DEM_STATUS" },
1263 { .addr = CC1200_FREQOFF_EST1, .name = "FREQOFF_EST1" },
1264 { .addr = CC1200_FREQOFF_EST0, .name = "FREQOFF_EST0" },
1265 { .addr = CC1200_AGC_GAIN3, .name = "AGC_GAIN3" },
1266 { .addr = CC1200_AGC_GAIN2, .name = "AGC_GAIN2" },
1267 { .addr = CC1200_AGC_GAIN1, .name = "AGC_GAIN1" },
1268 { .addr = CC1200_AGC_GAIN0, .name = "AGC_GAIN0" },
1269 { .addr = CC1200_SOFT_RX_DATA_OUT, .name = "SOFT_RX_DATA_OUT" },
1270 { .addr = CC1200_SOFT_TX_DATA_IN, .name = "SOFT_TX_DATA_IN" },
1271 { .addr = CC1200_ASK_SOFT_RX_DATA, .name = "ASK_SOFT_RX_DATA" },
1272 { .addr = CC1200_RNDGEN, .name = "RNDGEN" },
1273 { .addr = CC1200_MAGN2, .name = "MAGN2" },
1274 { .addr = CC1200_MAGN1, .name = "MAGN1" },
1275 { .addr = CC1200_MAGN0, .name = "MAGN0" },
1276 { .addr = CC1200_ANG1, .name = "ANG1" },
1277 { .addr = CC1200_ANG0, .name = "ANG0" },
1278 { .addr = CC1200_CHFILT_I2, .name = "CHFILT_I2" },
1279 { .addr = CC1200_CHFILT_I1, .name = "CHFILT_I1" },
1280 { .addr = CC1200_CHFILT_I0, .name = "CHFILT_I0" },
1281 { .addr = CC1200_CHFILT_Q2, .name = "CHFILT_Q2" },
1282 { .addr = CC1200_CHFILT_Q1, .name = "CHFILT_Q1" },
1283 { .addr = CC1200_CHFILT_Q0, .name = "CHFILT_Q0" },
1284 { .addr = CC1200_GPIO_STATUS, .name = "GPIO_STATUS" },
1285 { .addr = CC1200_FSCAL_CTRL, .name = "FSCAL_CTRL" },
1286 { .addr = CC1200_PHASE_ADJUST, .name = "PHASE_ADJUST" },
1287 { .addr = CC1200_PARTNUMBER, .name = "PARTNUMBER" },
1288 { .addr = CC1200_PARTVERSION, .name = "PARTVERSION" },
1289 { .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" },
1290 { .addr = CC1200_MODEM_STATUS1, .name = "MODEM_STATUS1" },
1291 { .addr = CC1200_MODEM_STATUS0, .name = "MODEM_STATUS0" },
1292 { .addr = CC1200_MARC_STATUS1, .name = "MARC_STATUS1" },
1293 { .addr = CC1200_MARC_STATUS0, .name = "MARC_STATUS0" },
1294 { .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
1295 { .addr = CC1200_FSRF_TEST, .name = "FSRF_TEST" },
1296 { .addr = CC1200_PRE_TEST, .name = "PRE_TEST" },
1297 { .addr = CC1200_PRE_OVR, .name = "PRE_OVR" },
1298 { .addr = CC1200_ADC_TEST, .name = "ADC_TEST" },
1299 { .addr = CC1200_DVC_TEST, .name = "DVC_TEST" },
1300 { .addr = CC1200_ATEST, .name = "ATEST" },
1301 { .addr = CC1200_ATEST_LVDS, .name = "ATEST_LVDS" },
1302 { .addr = CC1200_ATEST_MODE, .name = "ATEST_MODE" },
1303 { .addr = CC1200_XOSC_TEST1, .name = "XOSC_TEST1" },
1304 { .addr = CC1200_XOSC_TEST0, .name = "XOSC_TEST0" },
1305 { .addr = CC1200_RXFIRST, .name = "RXFIRST" },
1306 { .addr = CC1200_TXFIRST, .name = "TXFIRST" },
1307 { .addr = CC1200_RXLAST, .name = "RXLAST" },
1308 { .addr = CC1200_TXLAST, .name = "TXLAST" },
1309 { .addr = CC1200_NUM_TXBYTES, .name = "NUM_TXBYTES" },
1310 { .addr = CC1200_NUM_RXBYTES, .name = "NUM_RXBYTES" },
1311 { .addr = CC1200_FIFO_NUM_TXBYTES, .name = "FIFO_NUM_TXBYTES" },
1312 { .addr = CC1200_FIFO_NUM_RXBYTES, .name = "FIFO_NUM_RXBYTES" },
1315 #define AO_NUM_CC1200_REG (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0])
1318 ao_radio_get_marc_status(void)
1320 return ao_radio_reg_read(CC1200_MARC_STATUS1);
1323 static void ao_radio_show(void) {
1327 ao_mutex_get(&ao_radio_mutex);
1328 status = ao_radio_status();
1329 printf ("Status: %02x\n", status);
1330 printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1);
1331 printf ("STATE: %s\n", cc1200_state_name[(status >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK]);
1332 printf ("MARC: %02x\n", ao_radio_get_marc_status());
1334 for (i = 0; i < AO_NUM_CC1200_REG; i++)
1335 printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1200_reg[i].addr), ao_cc1200_reg[i].name);
1340 static void ao_radio_beep(void) {
1344 static void ao_radio_packet(void) {
1345 static const uint8_t packet[] = {
1347 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1348 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1349 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1350 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1356 ao_radio_send(packet, sizeof (packet));
1360 ao_radio_test_recv(void)
1362 static uint8_t bytes[34];
1365 if (ao_radio_recv(bytes, 34, 0)) {
1366 if (bytes[33] & 0x80)
1370 printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32]));
1371 for (b = 0; b < 32; b++)
1372 printf (" %02x", bytes[b]);
1374 printf (" RSSI %02x LQI %02x", bytes[32], bytes[33]);
1380 #include <ao_aprs.h>
1385 #if PACKET_HAS_SLAVE
1386 ao_packet_slave_stop();
1393 #if CC1200_LOW_LEVEL_DEBUG
1395 ao_radio_strobe_test(void)
1400 addr = ao_cmd_hex();
1401 if (ao_cmd_status != ao_cmd_success)
1403 r = ao_radio_strobe(addr);
1404 printf ("Strobe %02x -> %02x (rdy %d state %d)\n",
1412 ao_radio_write_test(void)
1417 addr = ao_cmd_hex();
1418 if (ao_cmd_status != ao_cmd_success)
1420 data = ao_cmd_hex();
1421 if (ao_cmd_status != ao_cmd_success)
1423 printf ("Write %04x = %02x\n", addr, data);
1424 ao_radio_reg_write(addr, data);
1428 ao_radio_read_test(void)
1433 addr = ao_cmd_hex();
1434 if (ao_cmd_status != ao_cmd_success)
1436 data = ao_radio_reg_read(addr);
1437 printf ("Read %04x = %02x\n", addr, data);
1441 static const struct ao_cmds ao_radio_cmds[] = {
1442 { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
1445 { ao_radio_aprs, "G\0Send APRS packet" },
1447 { ao_radio_show, "R\0Show CC1200 status" },
1448 { ao_radio_beep, "b\0Emit an RDF beacon" },
1449 { ao_radio_packet, "p\0Send a test packet" },
1450 { ao_radio_test_recv, "q\0Recv a test packet" },
1452 #if CC1200_LOW_LEVEL_DEBUG
1453 { ao_radio_strobe_test, "A <value>\0Strobe radio" },
1454 { ao_radio_write_test, "W <addr> <value>\0Write radio reg" },
1455 { ao_radio_read_test, "B <addr>\0Read radio reg" },
1463 ao_radio_configured = 0;
1464 ao_spi_init_cs (AO_CC1200_SPI_CS_PORT, (1 << AO_CC1200_SPI_CS_PIN));
1467 AO_CC1200_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC1200_SPI_CS_PIN));
1468 for (i = 0; i < 10000; i++) {
1469 if ((SPI_2_PORT->idr & (1 << SPI_2_MISO_PIN)) == 0)
1472 AO_CC1200_SPI_CS_PORT->bsrr = (1 << AO_CC1200_SPI_CS_PIN);
1474 ao_panic(AO_PANIC_SELF_TEST_CC1200);
1477 /* Enable the EXTI interrupt for the appropriate pin */
1478 ao_enable_port(AO_CC1200_INT_PORT);
1479 ao_exti_setup(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN,
1480 AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH,
1483 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
1485 ao_cmd_register(&ao_radio_cmds[0]);