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>
24 #define AO_RADIO_MAX_RECV sizeof(struct ao_packet)
25 #define AO_RADIO_MAX_SEND sizeof(struct ao_packet)
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 */
31 static uint8_t ao_radio_mcu_wake; /* MARC status change */
32 static uint8_t ao_radio_marc_status; /* Last read MARC status value */
33 static uint8_t ao_radio_tx_finished; /* MARC status indicates TX finished */
35 int8_t ao_radio_rssi; /* Last received RSSI value */
37 #define CC1200_DEBUG 1
38 #define CC1200_TRACE 1
40 extern const uint32_t ao_radio_cal;
44 #define ao_radio_try_select(task_id) ao_spi_try_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_125kHz, task_id)
45 #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_125kHz)
46 #define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS)
47 #define ao_radio_spi_send_sync(d,l) ao_spi_send_sync((d), (l), AO_CC1200_SPI_BUS)
48 #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1200_SPI_BUS)
49 #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS)
50 #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1200_SPI_BUS)
51 #define ao_radio_duplex(o,i,l) ao_spi_duplex((o), (i), (l), AO_CC1200_SPI_BUS)
54 ao_radio_reg_read(uint16_t addr)
60 printf("\t\tao_radio_reg_read (%04x): ", addr); flush();
62 if (CC1200_IS_EXTENDED(addr)) {
63 data[0] = ((1 << CC1200_READ) |
69 data[0] = ((1 << CC1200_READ) |
75 ao_radio_spi_send(data, d);
76 ao_radio_spi_recv(data, 1);
79 printf (" %02x\n", data[0]);
85 ao_radio_reg_write(uint16_t addr, uint8_t value)
91 printf("\t\tao_radio_reg_write (%04x): %02x\n", addr, value);
93 if (CC1200_IS_EXTENDED(addr)) {
94 data[0] = ((0 << CC1200_READ) |
100 data[0] = ((0 << CC1200_READ) |
101 (0 << CC1200_BURST) |
107 ao_radio_spi_send(data, d+1);
110 (void) ao_radio_reg_read(addr);
115 ao_radio_strobe(uint8_t addr)
120 printf("\t\tao_radio_strobe (%02x): ", addr); flush();
123 ao_radio_duplex(&addr, &in, 1);
126 printf("%02x\n", in); flush();
133 ao_radio_fifo_read(uint8_t *data, uint8_t len)
135 uint8_t addr = ((1 << CC1200_READ) |
136 (1 << CC1200_BURST) |
141 ao_radio_duplex(&addr, &status, 1);
142 ao_radio_spi_recv(data, len);
149 ao_radio_fifo_write_start(void)
151 uint8_t addr = ((0 << CC1200_READ) |
152 (1 << CC1200_BURST) |
157 ao_radio_duplex(&addr, &status, 1);
161 static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) {
167 ao_radio_fifo_write(uint8_t *data, uint8_t len)
169 uint8_t status = ao_radio_fifo_write_start();
170 ao_radio_spi_send(data, len);
171 return ao_radio_fifo_write_stop(status);
175 ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
177 uint8_t status = ao_radio_fifo_write_start();
178 ao_radio_spi_send_fixed(data, len);
179 return ao_radio_fifo_write_stop(status);
183 ao_radio_tx_fifo_space(void)
185 return CC1200_FIFO_SIZE - ao_radio_reg_read(CC1200_NUM_TXBYTES);
188 #if CC1200_DEBUG || CC1200_TRACE
190 ao_radio_status(void)
192 return ao_radio_strobe (CC1200_SNOP);
197 ao_radio_recv_abort(void)
200 ao_wakeup(&ao_radio_wake);
203 #define ao_radio_rdf_value 0x55
206 ao_radio_get_marc_status(void)
208 return ao_radio_reg_read(CC1200_MARC_STATUS1);
212 ao_radio_check_marc_status(void)
214 ao_radio_mcu_wake = 0;
215 ao_radio_marc_status = ao_radio_get_marc_status();
217 /* Anyt other than 'tx/rx finished' means an error occurred */
218 if (ao_radio_marc_status & ~(CC1200_MARC_STATUS1_TX_FINISHED|CC1200_MARC_STATUS1_RX_FINISHED))
220 if (ao_radio_marc_status & (CC1200_MARC_STATUS1_TX_FINISHED))
221 ao_radio_tx_finished = 1;
227 ao_exti_disable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
229 ao_wakeup(&ao_radio_wake);
233 ao_radio_start_tx(void)
235 ao_exti_set_callback(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, ao_radio_isr);
236 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
237 ao_radio_tx_finished = 0;
238 ao_radio_strobe(CC1200_STX);
245 uint8_t state = (ao_radio_strobe(CC1200_SIDLE) >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
246 if (state == CC1200_STATUS_STATE_IDLE)
248 if (state == CC1200_STATUS_STATE_TX_FIFO_ERROR)
249 ao_radio_strobe(CC1200_SFTX);
250 if (state == CC1200_STATUS_STATE_RX_FIFO_ERROR)
251 ao_radio_strobe(CC1200_SFRX);
253 /* Flush any pending TX bytes */
254 ao_radio_strobe(CC1200_SFTX);
260 * fdev = fosc >> 24 * (256 + dev_m) << dev_e
262 * Deviation for 38400 baud should be 20.5kHz:
264 * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 5) = 20508Hz
266 * Deviation for 9600 baud should be 5.125kHz:
268 * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 3) = 5127Hz
270 * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and
271 * cc115l can't do that, so we'll use 1.5kHz instead:
273 * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 1) = 1499Hz
276 #define PACKET_DEV_M_384 80
277 #define PACKET_DEV_E_384 5
279 #define PACKET_DEV_M_96 80
280 #define PACKET_DEV_E_96 3
282 #define PACKET_DEV_M_24 137
283 #define PACKET_DEV_E_24 1
286 * For our packet data
288 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
289 * Rdata = -------------------------------------- * fosc
292 * Given the bit period of the baseband, T, the bandwidth of the
293 * baseband signal is B = 1/(2T). The overall bandwidth of the
294 * modulated signal is then Channel bandwidth = 2Δf + 2B.
296 * 38400 -- 2 * 20500 + 38400 = 79.4 kHz
297 * 9600 -- 2 * 5.125 + 9600 = 19.9 kHz
298 * 2400 -- 2 * 1.5 + 2400 = 5.4 khz
300 * Symbol rate 38400 Baud:
302 * DATARATE_M = 239914
304 * CHANBW = 79.4 (79.4)
306 * Symbol rate 9600 Baud:
308 * DATARATE_M = 239914
310 * CHANBW = 19.9 (round to 19.8)
312 * Symbol rate 2400 Baud:
314 * DATARATE_M = 239914
316 * CHANBW = 5.0 (round to 9.5)
319 #define PACKET_SYMBOL_RATE_M 239914
321 #define PACKET_SYMBOL_RATE_E_384 9
324 #define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
325 (21 << CC1200_CHAN_BW_BB_CIC_DECFACT))
327 #define PACKET_SYMBOL_RATE_E_96 7
329 #define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
330 (21 << CC1200_CHAN_BW_BB_CIC_DECFACT))
332 #define PACKET_SYMBOL_RATE_E_24 5
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, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
341 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
342 CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
343 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
344 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
345 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
346 CC1200_PKT_CFG0, ((0 << CC1200_PKT_CFG0_RESERVED7) |
347 (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
348 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
349 (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
350 (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
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_PA_CFG0, 0x7b,
366 static const uint16_t packet_setup_96[] = {
367 CC1200_DEVIATION_M, PACKET_DEV_M_96,
368 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
369 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
370 (PACKET_DEV_E_96 << CC1200_MODCFG_DEV_E_DEV_E)),
371 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) |
372 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
373 CC1200_CHAN_BW, PACKET_CHAN_BW_96,
374 CC1200_PA_CFG0, 0x7d,
377 static const uint16_t packet_setup_24[] = {
378 CC1200_DEVIATION_M, PACKET_DEV_M_24,
379 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
380 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
381 (PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)),
382 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) |
383 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
384 CC1200_CHAN_BW, PACKET_CHAN_BW_24,
385 CC1200_PA_CFG0, 0x7e,
388 static const uint16_t packet_tx_setup[] = {
389 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
390 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
391 AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_RX0TX1_CFG,
394 static const uint16_t packet_rx_setup[] = {
395 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
396 (CC1200_PKT_CFG2_PKT_FORMAT_SYNCHRONOUS_SERIAL << CC1200_PKT_CFG2_PKT_FORMAT)),
397 AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_CLKEN_SOFT,
401 * RDF deviation is 5kHz
403 * fdev = fosc >> 24 * (256 + dev_m) << dev_e
405 * 32e6Hz / (2 ** 24) * (256 + 71) * (2 ** 3) = 4989
412 * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone)
414 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
415 * Rdata = -------------------------------------- * fosc
421 * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes
423 #define RDF_SYMBOL_RATE_E 5
424 #define RDF_SYMBOL_RATE_M 25166
425 #define RDF_PACKET_LEN 50
427 static const uint16_t rdf_setup[] = {
428 CC1200_DEVIATION_M, RDF_DEV_M,
429 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
430 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
431 (RDF_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
432 CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
433 (((RDF_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
434 CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff),
435 CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff),
436 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
437 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
438 CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
439 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
440 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
441 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
442 CC1200_PKT_CFG0, ((0 << CC1200_PKT_CFG0_RESERVED7) |
443 (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
444 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
445 (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
446 (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
447 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
448 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
449 CC1200_PA_CFG0, 0x7e,
453 * APRS deviation is 3kHz
455 * fdev = fosc >> 24 * (256 + dev_m) << dev_e
457 * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 2) = 2998Hz
461 #define APRS_DEV_M 137
464 * For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate)
466 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
467 * Rdata = -------------------------------------- * fosc
470 * DATARATE_M = 239914
473 * Rdata = 9599.998593330383301
476 #define APRS_SYMBOL_RATE_E 7
477 #define APRS_SYMBOL_RATE_M 239914
479 static const uint16_t aprs_setup[] = {
480 CC1200_DEVIATION_M, APRS_DEV_M,
481 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
482 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
483 (APRS_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
484 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
485 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
486 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
487 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
488 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
489 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
490 CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
491 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
492 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
493 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
494 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
495 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
496 CC1200_PA_CFG0, 0x7d,
500 * For Test mode, we want an unmodulated carrier. To do that, we
501 * set the deviation to zero and enable a preamble so that the radio
502 * turns on before we send any data
505 static const uint16_t test_setup[] = {
506 CC1200_DEVIATION_M, 0,
507 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
508 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
509 (0 << CC1200_MODCFG_DEV_E_DEV_E)),
510 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
511 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
512 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
513 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
514 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
515 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
516 CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
517 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
518 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
519 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
520 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
521 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
524 #define AO_PKT_CFG0_INFINITE ((0 << CC1200_PKT_CFG0_RESERVED7) | \
525 (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))
530 #define AO_PKT_CFG0_FIXED ((0 << CC1200_PKT_CFG0_RESERVED7) | \
531 (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
532 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
533 (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
534 (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
536 static uint16_t ao_radio_mode;
538 #define AO_RADIO_MODE_BITS_PACKET 1
539 #define AO_RADIO_MODE_BITS_PACKET_TX 2
540 #define AO_RADIO_MODE_BITS_TX_BUF 4
541 #define AO_RADIO_MODE_BITS_TX_FINISH 8
542 #define AO_RADIO_MODE_BITS_PACKET_RX 16
543 #define AO_RADIO_MODE_BITS_RDF 32
544 #define AO_RADIO_MODE_BITS_APRS 64
545 #define AO_RADIO_MODE_BITS_TEST 128
546 #define AO_RADIO_MODE_BITS_INFINITE 256
547 #define AO_RADIO_MODE_BITS_FIXED 512
549 #define AO_RADIO_MODE_NONE 0
550 #define AO_RADIO_MODE_PACKET_TX_BUF (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_BUF)
551 #define AO_RADIO_MODE_PACKET_TX_FINISH (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_FINISH)
552 #define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_RX)
553 #define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_TX_FINISH)
554 #define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
555 #define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF)
556 #define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
557 #define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
560 _ao_radio_set_regs(const uint16_t *regs, int nreg)
564 for (i = 0; i < nreg; i++) {
565 ao_radio_reg_write(regs[0], regs[1]);
570 #define ao_radio_set_regs(setup) _ao_radio_set_regs(setup, (sizeof (setup) / sizeof(setup[0])) >> 1)
573 ao_radio_set_mode(uint16_t new_mode)
577 if (new_mode == ao_radio_mode)
580 changes = new_mode & (~ao_radio_mode);
582 if (changes & AO_RADIO_MODE_BITS_PACKET) {
583 ao_radio_set_regs(packet_setup);
585 switch (ao_config.radio_rate) {
587 case AO_RADIO_RATE_38400:
588 ao_radio_set_regs(packet_setup_384);
590 case AO_RADIO_RATE_9600:
591 ao_radio_set_regs(packet_setup_96);
593 case AO_RADIO_RATE_2400:
594 ao_radio_set_regs(packet_setup_24);
599 if (changes & AO_RADIO_MODE_BITS_PACKET_TX)
600 ao_radio_set_regs(packet_tx_setup);
602 if (changes & AO_RADIO_MODE_BITS_TX_BUF)
603 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR);
605 if (changes & AO_RADIO_MODE_BITS_TX_FINISH)
606 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_RX0TX1_CFG);
608 if (changes & AO_RADIO_MODE_BITS_PACKET_RX)
609 ao_radio_set_regs(packet_rx_setup);
611 if (changes & AO_RADIO_MODE_BITS_RDF)
612 ao_radio_set_regs(rdf_setup);
614 if (changes & AO_RADIO_MODE_BITS_APRS)
615 ao_radio_set_regs(aprs_setup);
617 if (changes & AO_RADIO_MODE_BITS_TEST)
618 ao_radio_set_regs(test_setup);
620 if (changes & AO_RADIO_MODE_BITS_INFINITE)
621 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_INFINITE);
623 if (changes & AO_RADIO_MODE_BITS_FIXED)
624 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_FIXED);
626 ao_radio_mode = new_mode;
629 static const uint16_t radio_setup[] = {
630 #include "ao_cc1200_CC1200.h"
633 static uint8_t ao_radio_configured = 0;
638 // ao_radio_strobe(CC1200_SRES);
640 ao_radio_set_regs(radio_setup);
646 ao_radio_configured = 1;
650 ao_radio_set_len(uint8_t len)
652 static uint8_t last_len;
654 if (len != last_len) {
655 ao_radio_reg_write(CC1200_PKT_LEN, len);
661 ao_radio_get(uint8_t len)
663 static uint32_t last_radio_setting;
664 static uint8_t last_radio_rate;
666 ao_mutex_get(&ao_radio_mutex);
668 if (!ao_radio_configured)
670 if (ao_config.radio_setting != last_radio_setting) {
671 ao_radio_reg_write(CC1200_FREQ2, ao_config.radio_setting >> 16);
672 ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8);
673 ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting);
674 last_radio_setting = ao_config.radio_setting;
676 if (ao_config.radio_rate != last_radio_rate) {
677 ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET;
678 last_radio_rate = ao_config.radio_rate;
680 ao_radio_set_len(len);
683 #define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
686 ao_rdf_start(uint8_t len)
691 ao_radio_set_mode(AO_RADIO_MODE_RDF);
701 ao_arch_block_interrupts();
702 while (!ao_radio_wake && !ao_radio_abort && !ao_radio_mcu_wake)
703 ao_sleep(&ao_radio_wake);
704 ao_arch_release_interrupts();
705 if (ao_radio_mcu_wake)
706 ao_radio_check_marc_status();
715 ao_rdf_start(AO_RADIO_RDF_LEN);
717 ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
723 ao_radio_continuity(uint8_t c)
728 ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
730 status = ao_radio_fifo_write_start();
731 for (i = 0; i < 3; i++) {
732 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
734 ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
736 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
738 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
739 status = ao_radio_fifo_write_stop(status);
745 ao_radio_rdf_abort(void)
748 ao_wakeup(&ao_radio_wake);
752 ao_radio_test_cmd(void)
755 static uint8_t radio_on;
757 if (ao_cmd_lex_c != '\n') {
759 mode = (uint8_t) ao_cmd_lex_u32;
762 if ((mode & 2) && !radio_on) {
764 ao_monitor_disable();
767 ao_packet_slave_stop();
770 ao_radio_set_mode(AO_RADIO_MODE_TEST);
771 ao_radio_strobe(CC1200_STX);
774 for (t = 0; t < 10; t++) {
775 printf ("status: %02x\n", ao_radio_status());
776 ao_delay(AO_MS_TO_TICKS(100));
783 printf ("Hit a character to stop..."); flush();
787 if ((mode & 1) && radio_on) {
798 ao_radio_wait_isr(uint16_t timeout)
802 ao_arch_block_interrupts();
803 while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort)
804 if (ao_sleep(&ao_radio_wake))
806 ao_arch_release_interrupts();
809 if (ao_radio_mcu_wake)
810 ao_radio_check_marc_status();
814 ao_radio_send(const void *d, uint8_t size)
820 #define AO_RADIO_LOTS 64
823 ao_radio_send_aprs(ao_radio_fill_func fill)
825 uint8_t buf[AO_RADIO_LOTS], *b;
833 fifo_space = CC1200_FIFO_SIZE;
835 cnt = (*fill)(buf, sizeof(buf));
842 /* At the last buffer, set the total length */
844 ao_radio_set_len(total & 0xff);
848 uint8_t this_len = cnt;
850 /* Wait for some space in the fifo */
851 while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) {
853 ao_radio_wait_isr(0);
857 if (this_len > fifo_space)
858 this_len = fifo_space;
864 ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF);
866 ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
868 ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
870 ao_radio_fifo_write(b, this_len);
877 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
879 if (ao_radio_abort) {
883 /* Wait for the transmitter to go idle */
885 ao_radio_wait_isr(0);
891 ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
901 static char *cc1200_state_name[] = {
902 [CC1200_STATUS_STATE_IDLE] = "IDLE",
903 [CC1200_STATUS_STATE_RX] = "RX",
904 [CC1200_STATUS_STATE_TX] = "TX",
905 [CC1200_STATUS_STATE_FSTXON] = "FSTXON",
906 [CC1200_STATUS_STATE_CALIBRATE] = "CALIBRATE",
907 [CC1200_STATUS_STATE_SETTLING] = "SETTLING",
908 [CC1200_STATUS_STATE_RX_FIFO_ERROR] = "RX_FIFO_ERROR",
909 [CC1200_STATUS_STATE_TX_FIFO_ERROR] = "TX_FIFO_ERROR",
912 struct ao_cc1200_reg {
917 static const struct ao_cc1200_reg ao_cc1200_reg[] = {
918 { .addr = CC1200_IOCFG3, .name = "IOCFG3" },
919 { .addr = CC1200_IOCFG2, .name = "IOCFG2" },
920 { .addr = CC1200_IOCFG1, .name = "IOCFG1" },
921 { .addr = CC1200_IOCFG0, .name = "IOCFG0" },
922 { .addr = CC1200_SYNC3, .name = "SYNC3" },
923 { .addr = CC1200_SYNC2, .name = "SYNC2" },
924 { .addr = CC1200_SYNC1, .name = "SYNC1" },
925 { .addr = CC1200_SYNC0, .name = "SYNC0" },
926 { .addr = CC1200_SYNC_CFG1, .name = "SYNC_CFG1" },
927 { .addr = CC1200_SYNC_CFG0, .name = "SYNC_CFG0" },
928 { .addr = CC1200_DEVIATION_M, .name = "DEVIATION_M" },
929 { .addr = CC1200_MODCFG_DEV_E, .name = "MODCFG_DEV_E" },
930 { .addr = CC1200_DCFILT_CFG, .name = "DCFILT_CFG" },
931 { .addr = CC1200_PREAMBLE_CFG1, .name = "PREAMBLE_CFG1" },
932 { .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
933 { .addr = CC1200_IQIC, .name = "IQIC" },
934 { .addr = CC1200_CHAN_BW, .name = "CHAN_BW" },
935 { .addr = CC1200_MDMCFG1, .name = "MDMCFG1" },
936 { .addr = CC1200_MDMCFG0, .name = "MDMCFG0" },
937 { .addr = CC1200_SYMBOL_RATE2, .name = "SYMBOL_RATE2" },
938 { .addr = CC1200_SYMBOL_RATE1, .name = "SYMBOL_RATE1" },
939 { .addr = CC1200_SYMBOL_RATE0, .name = "SYMBOL_RATE0" },
940 { .addr = CC1200_AGC_REF, .name = "AGC_REF" },
941 { .addr = CC1200_AGC_CS_THR, .name = "AGC_CS_THR" },
942 { .addr = CC1200_AGC_GAIN_ADJUST, .name = "AGC_GAIN_ADJUST" },
943 { .addr = CC1200_AGC_CFG3, .name = "AGC_CFG3" },
944 { .addr = CC1200_AGC_CFG2, .name = "AGC_CFG2" },
945 { .addr = CC1200_AGC_CFG1, .name = "AGC_CFG1" },
946 { .addr = CC1200_AGC_CFG0, .name = "AGC_CFG0" },
947 { .addr = CC1200_FIFO_CFG, .name = "FIFO_CFG" },
948 { .addr = CC1200_DEV_ADDR, .name = "DEV_ADDR" },
949 { .addr = CC1200_SETTLING_CFG, .name = "SETTLING_CFG" },
950 { .addr = CC1200_FS_CFG, .name = "FS_CFG" },
951 { .addr = CC1200_WOR_CFG1, .name = "WOR_CFG1" },
952 { .addr = CC1200_WOR_CFG0, .name = "WOR_CFG0" },
953 { .addr = CC1200_WOR_EVENT0_MSB, .name = "WOR_EVENT0_MSB" },
954 { .addr = CC1200_WOR_EVENT0_LSB, .name = "WOR_EVENT0_LSB" },
955 { .addr = CC1200_RXDCM_TIME, .name = "RXDCM_TIME" },
956 { .addr = CC1200_PKT_CFG2, .name = "PKT_CFG2" },
957 { .addr = CC1200_PKT_CFG1, .name = "PKT_CFG1" },
958 { .addr = CC1200_PKT_CFG0, .name = "PKT_CFG0" },
959 { .addr = CC1200_RFEND_CFG1, .name = "RFEND_CFG1" },
960 { .addr = CC1200_RFEND_CFG0, .name = "RFEND_CFG0" },
961 { .addr = CC1200_PA_CFG1, .name = "PA_CFG1" },
962 { .addr = CC1200_PA_CFG0, .name = "PA_CFG0" },
963 { .addr = CC1200_PKT_LEN, .name = "PKT_LEN" },
964 { .addr = CC1200_IF_MIX_CFG, .name = "IF_MIX_CFG" },
965 { .addr = CC1200_FREQOFF_CFG, .name = "FREQOFF_CFG" },
966 { .addr = CC1200_TOC_CFG, .name = "TOC_CFG" },
967 { .addr = CC1200_MARC_SPARE, .name = "MARC_SPARE" },
968 { .addr = CC1200_ECG_CFG, .name = "ECG_CFG" },
969 { .addr = CC1200_EXT_CTRL, .name = "EXT_CTRL" },
970 { .addr = CC1200_RCCAL_FINE, .name = "RCCAL_FINE" },
971 { .addr = CC1200_RCCAL_COARSE, .name = "RCCAL_COARSE" },
972 { .addr = CC1200_RCCAL_OFFSET, .name = "RCCAL_OFFSET" },
973 { .addr = CC1200_FREQOFF1, .name = "FREQOFF1" },
974 { .addr = CC1200_FREQOFF0, .name = "FREQOFF0" },
975 { .addr = CC1200_FREQ2, .name = "FREQ2" },
976 { .addr = CC1200_FREQ1, .name = "FREQ1" },
977 { .addr = CC1200_FREQ0, .name = "FREQ0" },
978 { .addr = CC1200_IF_ADC2, .name = "IF_ADC2" },
979 { .addr = CC1200_IF_ADC1, .name = "IF_ADC1" },
980 { .addr = CC1200_IF_ADC0, .name = "IF_ADC0" },
981 { .addr = CC1200_FS_DIG1, .name = "FS_DIG1" },
982 { .addr = CC1200_FS_DIG0, .name = "FS_DIG0" },
983 { .addr = CC1200_FS_CAL3, .name = "FS_CAL3" },
984 { .addr = CC1200_FS_CAL2, .name = "FS_CAL2" },
985 { .addr = CC1200_FS_CAL1, .name = "FS_CAL1" },
986 { .addr = CC1200_FS_CAL0, .name = "FS_CAL0" },
987 { .addr = CC1200_FS_CHP, .name = "FS_CHP" },
988 { .addr = CC1200_FS_DIVTWO, .name = "FS_DIVTWO" },
989 { .addr = CC1200_FS_DSM1, .name = "FS_DSM1" },
990 { .addr = CC1200_FS_DSM0, .name = "FS_DSM0" },
991 { .addr = CC1200_FS_DVC1, .name = "FS_DVC1" },
992 { .addr = CC1200_FS_DVC0, .name = "FS_DVC0" },
993 { .addr = CC1200_FS_LBI, .name = "FS_LBI" },
994 { .addr = CC1200_FS_PFD, .name = "FS_PFD" },
995 { .addr = CC1200_FS_PRE, .name = "FS_PRE" },
996 { .addr = CC1200_FS_REG_DIV_CML, .name = "FS_REG_DIV_CML" },
997 { .addr = CC1200_FS_SPARE, .name = "FS_SPARE" },
998 { .addr = CC1200_FS_VCO4, .name = "FS_VCO4" },
999 { .addr = CC1200_FS_VCO3, .name = "FS_VCO3" },
1000 { .addr = CC1200_FS_VCO2, .name = "FS_VCO2" },
1001 { .addr = CC1200_FS_VCO1, .name = "FS_VCO1" },
1002 { .addr = CC1200_FS_VCO0, .name = "FS_VCO0" },
1003 { .addr = CC1200_GBIAS6, .name = "GBIAS6" },
1004 { .addr = CC1200_GBIAS5, .name = "GBIAS5" },
1005 { .addr = CC1200_GBIAS4, .name = "GBIAS4" },
1006 { .addr = CC1200_GBIAS3, .name = "GBIAS3" },
1007 { .addr = CC1200_GBIAS2, .name = "GBIAS2" },
1008 { .addr = CC1200_GBIAS1, .name = "GBIAS1" },
1009 { .addr = CC1200_GBIAS0, .name = "GBIAS0" },
1010 { .addr = CC1200_IFAMP, .name = "IFAMP" },
1011 { .addr = CC1200_LNA, .name = "LNA" },
1012 { .addr = CC1200_RXMIX, .name = "RXMIX" },
1013 { .addr = CC1200_XOSC5, .name = "XOSC5" },
1014 { .addr = CC1200_XOSC4, .name = "XOSC4" },
1015 { .addr = CC1200_XOSC3, .name = "XOSC3" },
1016 { .addr = CC1200_XOSC2, .name = "XOSC2" },
1017 { .addr = CC1200_XOSC1, .name = "XOSC1" },
1018 { .addr = CC1200_XOSC0, .name = "XOSC0" },
1019 { .addr = CC1200_ANALOG_SPARE, .name = "ANALOG_SPARE" },
1020 { .addr = CC1200_PA_CFG3, .name = "PA_CFG3" },
1021 { .addr = CC1200_WOR_TIME1, .name = "WOR_TIME1" },
1022 { .addr = CC1200_WOR_TIME0, .name = "WOR_TIME0" },
1023 { .addr = CC1200_WOR_CAPTURE1, .name = "WOR_CAPTURE1" },
1024 { .addr = CC1200_WOR_CAPTURE0, .name = "WOR_CAPTURE0" },
1025 { .addr = CC1200_BIST, .name = "BIST" },
1026 { .addr = CC1200_DCFILTOFFSET_I1, .name = "DCFILTOFFSET_I1" },
1027 { .addr = CC1200_DCFILTOFFSET_I0, .name = "DCFILTOFFSET_I0" },
1028 { .addr = CC1200_DCFILTOFFSET_Q1, .name = "DCFILTOFFSET_Q1" },
1029 { .addr = CC1200_DCFILTOFFSET_Q0, .name = "DCFILTOFFSET_Q0" },
1030 { .addr = CC1200_IQIE_I1, .name = "IQIE_I1" },
1031 { .addr = CC1200_IQIE_I0, .name = "IQIE_I0" },
1032 { .addr = CC1200_IQIE_Q1, .name = "IQIE_Q1" },
1033 { .addr = CC1200_IQIE_Q0, .name = "IQIE_Q0" },
1034 { .addr = CC1200_RSSI1, .name = "RSSI1" },
1035 { .addr = CC1200_RSSI0, .name = "RSSI0" },
1036 { .addr = CC1200_MARCSTATE, .name = "MARCSTATE" },
1037 { .addr = CC1200_LQI_VAL, .name = "LQI_VAL" },
1038 { .addr = CC1200_PQT_SYNC_ERR, .name = "PQT_SYNC_ERR" },
1039 { .addr = CC1200_DEM_STATUS, .name = "DEM_STATUS" },
1040 { .addr = CC1200_FREQOFF_EST1, .name = "FREQOFF_EST1" },
1041 { .addr = CC1200_FREQOFF_EST0, .name = "FREQOFF_EST0" },
1042 { .addr = CC1200_AGC_GAIN3, .name = "AGC_GAIN3" },
1043 { .addr = CC1200_AGC_GAIN2, .name = "AGC_GAIN2" },
1044 { .addr = CC1200_AGC_GAIN1, .name = "AGC_GAIN1" },
1045 { .addr = CC1200_AGC_GAIN0, .name = "AGC_GAIN0" },
1046 { .addr = CC1200_SOFT_RX_DATA_OUT, .name = "SOFT_RX_DATA_OUT" },
1047 { .addr = CC1200_SOFT_TX_DATA_IN, .name = "SOFT_TX_DATA_IN" },
1048 { .addr = CC1200_ASK_SOFT_RX_DATA, .name = "ASK_SOFT_RX_DATA" },
1049 { .addr = CC1200_RNDGEN, .name = "RNDGEN" },
1050 { .addr = CC1200_MAGN2, .name = "MAGN2" },
1051 { .addr = CC1200_MAGN1, .name = "MAGN1" },
1052 { .addr = CC1200_MAGN0, .name = "MAGN0" },
1053 { .addr = CC1200_ANG1, .name = "ANG1" },
1054 { .addr = CC1200_ANG0, .name = "ANG0" },
1055 { .addr = CC1200_CHFILT_I2, .name = "CHFILT_I2" },
1056 { .addr = CC1200_CHFILT_I1, .name = "CHFILT_I1" },
1057 { .addr = CC1200_CHFILT_I0, .name = "CHFILT_I0" },
1058 { .addr = CC1200_CHFILT_Q2, .name = "CHFILT_Q2" },
1059 { .addr = CC1200_CHFILT_Q1, .name = "CHFILT_Q1" },
1060 { .addr = CC1200_CHFILT_Q0, .name = "CHFILT_Q0" },
1061 { .addr = CC1200_GPIO_STATUS, .name = "GPIO_STATUS" },
1062 { .addr = CC1200_FSCAL_CTRL, .name = "FSCAL_CTRL" },
1063 { .addr = CC1200_PHASE_ADJUST, .name = "PHASE_ADJUST" },
1064 { .addr = CC1200_PARTNUMBER, .name = "PARTNUMBER" },
1065 { .addr = CC1200_PARTVERSION, .name = "PARTVERSION" },
1066 { .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" },
1067 { .addr = CC1200_RX_STATUS, .name = "RX_STATUS" },
1068 { .addr = CC1200_TX_STATUS, .name = "TX_STATUS" },
1069 { .addr = CC1200_MARC_STATUS1, .name = "MARC_STATUS1" },
1070 { .addr = CC1200_MARC_STATUS0, .name = "MARC_STATUS0" },
1071 { .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
1072 { .addr = CC1200_FSRF_TEST, .name = "FSRF_TEST" },
1073 { .addr = CC1200_PRE_TEST, .name = "PRE_TEST" },
1074 { .addr = CC1200_PRE_OVR, .name = "PRE_OVR" },
1075 { .addr = CC1200_ADC_TEST, .name = "ADC_TEST" },
1076 { .addr = CC1200_DVC_TEST, .name = "DVC_TEST" },
1077 { .addr = CC1200_ATEST, .name = "ATEST" },
1078 { .addr = CC1200_ATEST_LVDS, .name = "ATEST_LVDS" },
1079 { .addr = CC1200_ATEST_MODE, .name = "ATEST_MODE" },
1080 { .addr = CC1200_XOSC_TEST1, .name = "XOSC_TEST1" },
1081 { .addr = CC1200_XOSC_TEST0, .name = "XOSC_TEST0" },
1082 { .addr = CC1200_RXFIRST, .name = "RXFIRST" },
1083 { .addr = CC1200_TXFIRST, .name = "TXFIRST" },
1084 { .addr = CC1200_RXLAST, .name = "RXLAST" },
1085 { .addr = CC1200_TXLAST, .name = "TXLAST" },
1086 { .addr = CC1200_NUM_TXBYTES, .name = "NUM_TXBYTES" },
1087 { .addr = CC1200_NUM_RXBYTES, .name = "NUM_RXBYTES" },
1088 { .addr = CC1200_FIFO_NUM_TXBYTES, .name = "FIFO_NUM_TXBYTES" },
1089 { .addr = CC1200_FIFO_NUM_RXBYTES, .name = "FIFO_NUM_RXBYTES" },
1092 #define AO_NUM_CC1200_REG (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0])
1094 static void ao_radio_show(void) {
1095 uint8_t status = ao_radio_status();
1099 status = ao_radio_status();
1100 printf ("Status: %02x\n", status);
1101 printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1);
1102 printf ("STATE: %s\n", cc1200_state_name[(status >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK]);
1103 printf ("MARC: %02x\n", ao_radio_get_marc_status());
1105 for (i = 0; i < AO_NUM_CC1200_REG; i++)
1106 printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1200_reg[i].addr), ao_cc1200_reg[i].name);
1111 static void ao_radio_beep(void) {
1115 static void ao_radio_packet(void) {
1116 static const uint8_t packet[] = {
1118 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1119 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1120 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1121 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1127 ao_radio_send(packet, sizeof (packet));
1131 ao_radio_test_recv(void)
1136 if (ao_radio_recv(bytes, 34, 0)) {
1137 if (bytes[33] & 0x80)
1141 printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32]));
1142 for (b = 0; b < 32; b++)
1143 printf (" %02x", bytes[b]);
1149 #include <ao_aprs.h>
1154 ao_packet_slave_stop();
1161 ao_radio_strobe_test(void)
1166 if (ao_cmd_status != ao_cmd_success)
1168 r = ao_radio_strobe(ao_cmd_lex_i);
1169 printf ("Strobe %02x -> %02x (rdy %d state %d)\n",
1177 ao_radio_write_test(void)
1183 if (ao_cmd_status != ao_cmd_success)
1185 addr = ao_cmd_lex_i;
1187 if (ao_cmd_status != ao_cmd_success)
1189 data = ao_cmd_lex_i;
1190 printf ("Write %04x = %02x\n", addr, data);
1191 ao_radio_reg_write(addr, data);
1195 ao_radio_read_test(void)
1201 if (ao_cmd_status != ao_cmd_success)
1203 addr = ao_cmd_lex_i;
1204 data = ao_radio_reg_read(addr);
1205 printf ("Read %04x = %02x\n", addr, data);
1208 static const struct ao_cmds ao_radio_cmds[] = {
1209 { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
1212 { ao_radio_aprs, "G\0Send APRS packet" },
1214 { ao_radio_show, "R\0Show CC1200 status" },
1215 { ao_radio_beep, "b\0Emit an RDF beacon" },
1216 { ao_radio_packet, "p\0Send a test packet" },
1217 { ao_radio_test_recv, "q\0Recv a test packet" },
1219 { ao_radio_strobe_test, "S <value>\0Strobe radio" },
1220 { ao_radio_write_test, "W <addr> <value>\0Write radio reg" },
1221 { ao_radio_read_test, "R <addr>\0Read radio reg" },
1228 ao_radio_configured = 0;
1229 ao_spi_init_cs (AO_CC1200_SPI_CS_PORT, (1 << AO_CC1200_SPI_CS_PIN));
1232 AO_CC1200_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC1200_SPI_CS_PIN));
1233 for (i = 0; i < 10000; i++) {
1234 if ((SPI_2_PORT->idr & (1 << SPI_2_MISO_PIN)) == 0)
1237 AO_CC1200_SPI_CS_PORT->bsrr = (1 << AO_CC1200_SPI_CS_PIN);
1239 ao_panic(AO_PANIC_SELF_TEST_CC1200);
1242 /* Enable the EXTI interrupt for the appropriate pin */
1243 ao_enable_port(AO_CC1200_INT_PORT);
1244 ao_exti_setup(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN,
1245 AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH,
1248 ao_cmd_register(&ao_radio_cmds[0]);