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 static uint8_t ao_radio_mutex;
26 static uint8_t ao_radio_wake; /* radio ready. Also used as sleep address */
27 static uint8_t ao_radio_abort; /* radio operation should abort */
29 int8_t ao_radio_rssi; /* Last received RSSI value */
32 #define CC1200_DEBUG 0
35 #ifndef CC1200_LOW_LEVEL_DEBUG
36 #define CC1200_LOW_LEVEL_DEBUG 0
39 #define CC1200_TRACE 0
40 #define CC1200_APRS_TRACE 0
42 extern const uint32_t ao_radio_cal;
46 #define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_FAST)
47 #define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS)
48 #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1200_SPI_BUS)
49 #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS)
50 #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1200_SPI_BUS)
51 #define ao_radio_duplex(o,i,l) ao_spi_duplex((o), (i), (l), AO_CC1200_SPI_BUS)
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();
132 ao_radio_fifo_read(uint8_t *data, uint8_t len)
134 uint8_t addr = ((1 << CC1200_READ) |
135 (1 << CC1200_BURST) |
140 ao_radio_duplex(&addr, &status, 1);
141 ao_radio_spi_recv(data, len);
147 ao_radio_fifo_write_start(void)
149 uint8_t addr = ((0 << CC1200_READ) |
150 (1 << CC1200_BURST) |
155 ao_radio_duplex(&addr, &status, 1);
159 static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) {
165 ao_radio_fifo_write(const uint8_t *data, uint8_t len)
167 uint8_t status = ao_radio_fifo_write_start();
168 ao_radio_spi_send(data, len);
169 return ao_radio_fifo_write_stop(status);
173 ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
175 uint8_t status = ao_radio_fifo_write_start();
176 ao_radio_spi_send_fixed(data, len);
177 return ao_radio_fifo_write_stop(status);
181 ao_radio_tx_fifo_space(void)
183 return CC1200_FIFO_SIZE - ao_radio_reg_read(CC1200_NUM_TXBYTES);
187 ao_radio_status(void)
189 return ao_radio_strobe (CC1200_SNOP);
193 ao_radio_recv_abort(void)
196 ao_wakeup(&ao_radio_wake);
199 #define ao_radio_rdf_value 0x55
204 ao_exti_disable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
206 ao_wakeup(&ao_radio_wake);
210 ao_radio_start_tx(void)
212 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
213 ao_radio_strobe(CC1200_STX);
217 ao_radio_start_rx(void)
219 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
220 ao_radio_strobe(CC1200_SRX);
227 uint8_t state = (ao_radio_strobe(CC1200_SIDLE) >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
228 if (state == CC1200_STATUS_STATE_IDLE)
230 if (state == CC1200_STATUS_STATE_TX_FIFO_ERROR)
231 ao_radio_strobe(CC1200_SFTX);
232 if (state == CC1200_STATUS_STATE_RX_FIFO_ERROR)
233 ao_radio_strobe(CC1200_SFRX);
235 /* Flush any pending data in the fifos */
236 ao_radio_strobe(CC1200_SFTX);
237 ao_radio_strobe(CC1200_SFRX);
238 /* Make sure the RF calibration is current */
239 ao_radio_strobe(CC1200_SCAL);
245 * fdev = fosc >> 22 * (256 + dev_m) << dev_e
247 * Deviation for 38400 baud should be 20.5kHz:
249 * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 3) = 20523Hz
251 * Deviation for 9600 baud should be 5.125kHz:
253 * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 1) = 5131Hz
255 * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and
256 * cc115l can't do that, so we'll use 1.5kHz instead:
258 * 40e6 / (2 ** 21) * (79) = 1506Hz
261 #define PACKET_DEV_M_384 13
262 #define PACKET_DEV_E_384 3
264 #define PACKET_DEV_M_96 13
265 #define PACKET_DEV_E_96 1
267 #define PACKET_DEV_M_24 79
268 #define PACKET_DEV_E_24 0
271 * For our packet data
273 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
274 * Rdata = -------------------------------------- * fosc
277 * Given the bit period of the baseband, T, the bandwidth of the
278 * baseband signal is B = 1/(2T). The overall bandwidth of the
279 * modulated signal is then Channel bandwidth = 2Δf + 2B.
281 * 38400 -- 2 * 20500 + 38400 = 79.4 kHz
282 * 9600 -- 2 * 5.125 + 9600 = 19.9 kHz
283 * 2400 -- 2 * 1.5 + 2400 = 5.4 khz
285 * Symbol rate 38400 Baud:
287 * DATARATE_M = 1013008
291 * Symbol rate 9600 Baud:
293 * DATARATE_M = 1013008
295 * CHANBW = 26.042 (round to 19.8)
297 * Symbol rate 2400 Baud:
299 * DATARATE_M = 1013008
301 * CHANBW = 5.0 (round to 9.5)
304 #define PACKET_SYMBOL_RATE_M 1013008
306 #define PACKET_SYMBOL_RATE_E_384 8
309 #define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
310 (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
312 #define PACKET_SYMBOL_RATE_E_96 6
314 #define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
315 (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
317 #define PACKET_SYMBOL_RATE_E_24 4
319 #define PACKET_CHAN_BW_24 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
320 (44 << CC1200_CHAN_BW_BB_CIC_DECFACT))
322 static const uint16_t packet_setup[] = {
323 CC1200_SYMBOL_RATE1, ((PACKET_SYMBOL_RATE_M >> 8) & 0xff),
324 CC1200_SYMBOL_RATE0, ((PACKET_SYMBOL_RATE_M >> 0) & 0xff),
325 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
326 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
327 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
328 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
329 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
330 ((1 << CC1200_PKT_CFG1_FEC_EN) |
331 (1 << CC1200_PKT_CFG1_WHITE_DATA) |
332 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
333 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
334 (CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES << CC1200_PKT_CFG1_CRC_CFG) |
335 (1 << CC1200_PKT_CFG1_APPEND_STATUS)),
336 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
337 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
340 static const uint16_t packet_setup_384[] = {
341 CC1200_DEVIATION_M, PACKET_DEV_M_384,
342 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
343 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
344 (PACKET_DEV_E_384 << CC1200_MODCFG_DEV_E_DEV_E)),
345 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_384 << CC1200_SYMBOL_RATE2_DATARATE_E) |
346 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
347 CC1200_CHAN_BW, PACKET_CHAN_BW_384,
348 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
349 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
350 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
351 (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
352 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
355 static const uint16_t packet_setup_96[] = {
356 CC1200_DEVIATION_M, PACKET_DEV_M_96,
357 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
358 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
359 (PACKET_DEV_E_96 << CC1200_MODCFG_DEV_E_DEV_E)),
360 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) |
361 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
362 CC1200_CHAN_BW, PACKET_CHAN_BW_96,
363 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
364 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
365 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
366 (CC1200_MDMCFG2_UPSAMPLER_P_32 << CC1200_MDMCFG2_UPSAMPLER_P) |
367 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
370 static const uint16_t packet_setup_24[] = {
371 CC1200_DEVIATION_M, PACKET_DEV_M_24,
372 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
373 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
374 (PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)),
375 CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) |
376 (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
377 CC1200_CHAN_BW, PACKET_CHAN_BW_24,
378 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
379 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
380 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
381 (CC1200_MDMCFG2_UPSAMPLER_P_64 << CC1200_MDMCFG2_UPSAMPLER_P) |
382 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
386 * RDF deviation is 3kHz
388 * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
389 * fdev = fosc >> 21 * dev_m dev_e == 0
391 * 40e6 / (2 ** 21) * 157 = 2995Hz
395 #define RDF_DEV_M 157
398 * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone)
400 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
401 * Rdata = -------------------------------------- * fosc
404 * DATARATE_M = 669411
407 * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes
409 #define RDF_SYMBOL_RATE_E 4
410 #define RDF_SYMBOL_RATE_M 669411
411 #define RDF_PACKET_LEN 50
413 static const uint16_t rdf_setup[] = {
414 CC1200_DEVIATION_M, RDF_DEV_M,
415 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
416 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
417 (RDF_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
418 CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
419 (((RDF_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
420 CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff),
421 CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff),
422 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
423 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
424 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
425 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
426 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
427 ((0 << CC1200_PKT_CFG1_FEC_EN) |
428 (0 << CC1200_PKT_CFG1_WHITE_DATA) |
429 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
430 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
431 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
432 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
433 CC1200_PREAMBLE_CFG1,
434 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
435 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
436 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
437 ((0 << CC1200_MDMCFG2_ASK_SHAPE) |
438 (0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
439 (12 << CC1200_MDMCFG2_UPSAMPLER_P) |
440 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
444 * APRS deviation is 3kHz
446 * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
447 * fdev = fosc >> 21 * dev_m dev_e == 0
449 * 40e6 / (2 ** 21) * 157 = 2995Hz
453 #define APRS_DEV_M 157
456 * For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate)
458 * (2**20 + DATARATE_M) * 2 ** DATARATE_E
459 * Rdata = -------------------------------------- * fosc
462 * DATARATE_M = 1013008
465 * Rdata = 9599.998593330383301
468 #define APRS_SYMBOL_RATE_E 6
469 #define APRS_SYMBOL_RATE_M 1013008
471 static const uint16_t aprs_setup[] = {
472 CC1200_DEVIATION_M, APRS_DEV_M,
473 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
474 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
475 (APRS_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
476 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
477 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
478 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
479 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
480 CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
481 ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
482 (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
483 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
484 CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
485 ((0 << CC1200_PKT_CFG1_FEC_EN) |
486 (0 << CC1200_PKT_CFG1_WHITE_DATA) |
487 (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
488 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
489 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
490 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
491 CC1200_PKT_CFG0, /* Packet Configuration Reg. 0 */
492 ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
493 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
494 (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
495 (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
496 CC1200_PREAMBLE_CFG1,
497 ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
498 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
499 CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
500 ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
501 (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
502 (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
503 (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
507 * For Test mode, we want an unmodulated carrier. To do that, we
508 * set the deviation to zero and enable a preamble so that the radio
509 * turns on before we send any data
512 static const uint16_t test_setup[] = {
513 CC1200_DEVIATION_M, 0,
514 CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
515 (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
516 (0 << CC1200_MODCFG_DEV_E_DEV_E)),
517 CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
518 (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
519 CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
520 CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
521 CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
522 (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
523 CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
524 (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
525 (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
526 (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
527 CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
528 (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
531 #define AO_PKT_CFG0_INFINITE ((CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
532 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
533 (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
534 (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
536 #define AO_PKT_CFG0_FIXED ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
537 (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
538 (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
539 (0 << CC1200_PKT_CFG0_UART_SWAP_EN))
541 static uint16_t ao_radio_mode;
543 #define AO_RADIO_MODE_BITS_PACKET 1
544 #define AO_RADIO_MODE_BITS_TX_BUF 4
545 #define AO_RADIO_MODE_BITS_TX_FINISH 8
546 #define AO_RADIO_MODE_BITS_RX 16
547 #define AO_RADIO_MODE_BITS_RDF 32
548 #define AO_RADIO_MODE_BITS_APRS 64
549 #define AO_RADIO_MODE_BITS_TEST 128
550 #define AO_RADIO_MODE_BITS_INFINITE 256
551 #define AO_RADIO_MODE_BITS_FIXED 512
553 #define AO_RADIO_MODE_NONE 0
554 #define AO_RADIO_MODE_PACKET_TX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
555 #define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_RX)
556 #define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
557 #define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
558 #define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF)
559 #define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
560 #define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
563 _ao_radio_set_regs(const uint16_t *regs, int nreg)
567 for (i = 0; i < nreg; i++) {
568 ao_radio_reg_write(regs[0], regs[1]);
573 #define ao_radio_set_regs(setup) _ao_radio_set_regs(setup, (sizeof (setup) / sizeof(setup[0])) >> 1)
576 ao_radio_set_mode(uint16_t new_mode)
580 if (new_mode == ao_radio_mode)
583 changes = new_mode & (~ao_radio_mode);
585 if (changes & AO_RADIO_MODE_BITS_PACKET) {
586 ao_radio_set_regs(packet_setup);
588 switch (ao_config.radio_rate) {
590 case AO_RADIO_RATE_38400:
591 ao_radio_set_regs(packet_setup_384);
593 case AO_RADIO_RATE_9600:
594 ao_radio_set_regs(packet_setup_96);
596 case AO_RADIO_RATE_2400:
597 ao_radio_set_regs(packet_setup_24);
602 if (changes & AO_RADIO_MODE_BITS_TX_BUF) {
603 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR);
604 ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
607 if (changes & AO_RADIO_MODE_BITS_TX_FINISH) {
608 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
609 ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
612 if (changes & AO_RADIO_MODE_BITS_RX) {
613 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP);
614 ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH);
617 if (changes & AO_RADIO_MODE_BITS_RDF)
618 ao_radio_set_regs(rdf_setup);
620 if (changes & AO_RADIO_MODE_BITS_APRS)
621 ao_radio_set_regs(aprs_setup);
623 if (changes & AO_RADIO_MODE_BITS_TEST)
624 ao_radio_set_regs(test_setup);
626 if (changes & AO_RADIO_MODE_BITS_INFINITE)
627 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_INFINITE);
629 if (changes & AO_RADIO_MODE_BITS_FIXED)
630 ao_radio_reg_write(CC1200_PKT_CFG0, AO_PKT_CFG0_FIXED);
632 ao_radio_mode = new_mode;
635 static const uint16_t radio_setup[] = {
636 #include "ao_cc1200_CC1200.h"
639 static uint8_t ao_radio_configured = 0;
644 ao_radio_strobe(CC1200_SRES);
646 ao_radio_set_regs(radio_setup);
654 ao_radio_configured = 1;
658 ao_radio_set_len(uint8_t len)
660 static uint8_t last_len;
662 if (len != last_len) {
663 ao_radio_reg_write(CC1200_PKT_LEN, len);
669 ao_radio_get(uint8_t len)
671 static uint32_t last_radio_setting;
672 static uint8_t last_radio_rate;
674 ao_mutex_get(&ao_radio_mutex);
676 if (!ao_radio_configured)
678 if (ao_config.radio_setting != last_radio_setting) {
679 ao_radio_reg_write(CC1200_FREQ2, ao_config.radio_setting >> 16);
680 ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8);
681 ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting);
682 last_radio_setting = ao_config.radio_setting;
683 ao_radio_strobe(CC1200_SCAL);
685 if (ao_config.radio_rate != last_radio_rate) {
686 ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET;
687 last_radio_rate = ao_config.radio_rate;
689 ao_radio_set_len(len);
692 #define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
694 static inline uint8_t
697 return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
702 ao_radio_show_state(char *where)
704 printf("%s: state %d len %d rxbytes %d\n",
705 where, ao_radio_state(),
706 ao_radio_reg_read(CC1200_PKT_LEN),
707 ao_radio_reg_read(CC1200_NUM_RXBYTES));
710 #define ao_radio_show_state(where)
713 /* Wait for the radio to signal an interrupt
716 ao_radio_wait_isr(uint16_t timeout)
721 ao_arch_block_interrupts();
722 while (!ao_radio_wake && !ao_radio_abort)
723 if (ao_sleep(&ao_radio_wake))
725 ao_arch_release_interrupts();
732 ao_rdf_start(uint8_t len)
737 ao_radio_set_mode(AO_RADIO_MODE_RDF);
747 ao_radio_wait_isr(0);
756 ao_rdf_start(AO_RADIO_RDF_LEN);
758 ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
764 ao_radio_continuity(uint8_t c)
769 ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
771 status = ao_radio_fifo_write_start();
772 for (i = 0; i < 3; i++) {
773 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
775 ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
777 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
779 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
780 status = ao_radio_fifo_write_stop(status);
786 ao_radio_rdf_abort(void)
789 ao_wakeup(&ao_radio_wake);
793 ao_radio_test_cmd(void)
796 static uint8_t radio_on;
798 if (ao_cmd_lex_c != '\n') {
800 mode = (uint8_t) ao_cmd_lex_u32;
803 if ((mode & 2) && !radio_on) {
805 ao_monitor_disable();
808 ao_packet_slave_stop();
811 ao_radio_set_mode(AO_RADIO_MODE_TEST);
812 ao_radio_strobe(CC1200_STX);
815 for (t = 0; t < 10; t++) {
816 printf ("status: %02x\n", ao_radio_status());
817 ao_delay(AO_MS_TO_TICKS(100));
824 printf ("Hit a character to stop..."); flush();
828 if ((mode & 1) && radio_on) {
839 ao_radio_send(const void *d, uint8_t size)
842 ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX);
844 ao_radio_fifo_write(d, size);
850 #define AO_RADIO_LOTS 64
853 ao_radio_send_aprs(ao_radio_fill_func fill)
855 uint8_t buf[AO_RADIO_LOTS], *b;
864 fifo_space = CC1200_FIFO_SIZE;
866 cnt = (*fill)(buf, sizeof(buf));
871 #if CC1200_APRS_TRACE
872 printf("APRS fill %d bytes done %d\n", cnt, done);
876 /* At the last buffer, set the total length */
878 ao_radio_set_len(total & 0xff);
882 uint8_t this_len = cnt;
884 /* Wait for some space in the fifo */
885 while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) {
886 #if CC1200_APRS_TRACE
887 printf("APRS space %d cnt %d\n", fifo_space, cnt); flush();
890 ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
894 if (this_len > fifo_space)
895 this_len = fifo_space;
901 ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF);
903 ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
905 ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
907 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
909 ao_radio_fifo_write(b, this_len);
911 #if CC1200_APRS_TRACE
912 printf("APRS write fifo %d space now %d\n", this_len, ao_radio_tx_fifo_space());
915 #if CC1200_APRS_TRACE
916 printf("APRS start\n");
918 ao_radio_strobe(CC1200_STX);
919 #if CC1200_APRS_TRACE
921 for (t = 0; t < 20; t++) {
922 uint8_t status = ao_radio_status();
923 uint8_t space = ao_radio_tx_fifo_space();
924 printf ("status: %02x fifo %d\n", status, space);
925 if ((status >> 4) == 2)
927 ao_delay(AO_MS_TO_TICKS(0));
934 if (ao_radio_abort) {
939 /* Wait for the transmitter to go idle */
941 #if CC1200_APRS_TRACE
942 printf("APRS wait idle\n"); flush();
944 ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
945 #if CC1200_APRS_TRACE
946 printf("APRS abort %d\n", ao_radio_abort);
953 ao_radio_marc_state(void)
955 return ao_radio_reg_read(CC1200_MARCSTATE);
959 ao_radio_modem_status1(void)
961 return ao_radio_reg_read(CC1200_MODEM_STATUS1);
965 ao_radio_modem_status0(void)
967 return ao_radio_reg_read(CC1200_MODEM_STATUS0);
970 struct ao_radio_state {
973 uint8_t marc_status1;
974 uint8_t marc_status0;
975 uint8_t modem_status1;
976 uint8_t modem_status0;
980 ao_radio_fill_state(char *where, struct ao_radio_state *s)
982 strcpy(s->where, where);
983 s->marc_state = ao_radio_marc_state();
984 s->marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
985 s->marc_status0 = ao_radio_reg_read(CC1200_MARC_STATUS0);
986 s->modem_status1 = ao_radio_modem_status1();
987 s->modem_status0 = ao_radio_modem_status0();
991 ao_radio_dump_state(struct ao_radio_state *s)
993 printf ("%s: marc %2x marc1 %2x marc0 %2x modem1 %2x modem0 %2x\n",
994 s->where, s->marc_state, s->marc_status1, s->marc_status0, s->modem_status1, s->modem_status0);
999 ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
1001 uint8_t success = 0;
1004 ao_radio_get(size - 2);
1005 ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
1007 ao_radio_start_rx();
1009 while (!ao_radio_abort) {
1010 ao_radio_wait_isr(timeout);
1011 if (ao_radio_wake) {
1012 uint8_t marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
1014 /* Check the receiver status to see what happened
1016 switch (marc_status1) {
1017 case CC1200_MARC_STATUS1_RX_FINISHED:
1018 case CC1200_MARC_STATUS1_ADDRESS:
1019 case CC1200_MARC_STATUS1_CRC:
1020 /* Normal return, go fetch the bytes from the FIFO
1021 * and give them back to the caller
1025 case CC1200_MARC_STATUS1_RX_TIMEOUT:
1026 case CC1200_MARC_STATUS1_RX_TERMINATION:
1027 case CC1200_MARC_STATUS1_EWOR_SYNC_LOST:
1028 case CC1200_MARC_STATUS1_MAXIMUM_LENGTH:
1029 case CC1200_MARC_STATUS1_RX_FIFO_OVERFLOW:
1030 case CC1200_MARC_STATUS1_RX_FIFO_UNDERFLOW:
1031 /* Something weird happened; reset the radio and
1037 /* some other status; go wait for the radio to do something useful
1043 uint8_t modem_status1 = ao_radio_reg_read(CC1200_MODEM_STATUS1);
1045 /* Check to see if the packet header has been seen, in which case we'll
1046 * want to keep waiting for the rest of the packet to appear
1048 if (modem_status1 & (1 << CC1200_MODEM_STATUS1_SYNC_FOUND))
1052 /* Set a timeout based on the packet length so that we make sure to
1053 * wait long enough to receive the whole thing.
1055 * timeout = bits * FEC expansion / rate
1057 switch (ao_config.radio_rate) {
1059 case AO_RADIO_RATE_38400:
1060 timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 384) + 1;
1062 case AO_RADIO_RATE_9600:
1063 timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 96) + 1;
1065 case AO_RADIO_RATE_2400:
1066 timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 24) + 1;
1077 status = ao_radio_fifo_read(d, size);
1079 rssi = ((int8_t *) d)[size - 2];
1080 ao_radio_rssi = rssi;
1082 /* Bound it to the representable range */
1086 /* Write it back to the packet */
1087 ((int8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi);
1099 static char *cc1200_state_name[] = {
1100 [CC1200_STATUS_STATE_IDLE] = "IDLE",
1101 [CC1200_STATUS_STATE_RX] = "RX",
1102 [CC1200_STATUS_STATE_TX] = "TX",
1103 [CC1200_STATUS_STATE_FSTXON] = "FSTXON",
1104 [CC1200_STATUS_STATE_CALIBRATE] = "CALIBRATE",
1105 [CC1200_STATUS_STATE_SETTLING] = "SETTLING",
1106 [CC1200_STATUS_STATE_RX_FIFO_ERROR] = "RX_FIFO_ERROR",
1107 [CC1200_STATUS_STATE_TX_FIFO_ERROR] = "TX_FIFO_ERROR",
1110 struct ao_cc1200_reg {
1115 static const struct ao_cc1200_reg ao_cc1200_reg[] = {
1116 { .addr = CC1200_IOCFG3, .name = "IOCFG3" },
1117 { .addr = CC1200_IOCFG2, .name = "IOCFG2" },
1118 { .addr = CC1200_IOCFG1, .name = "IOCFG1" },
1119 { .addr = CC1200_IOCFG0, .name = "IOCFG0" },
1120 { .addr = CC1200_SYNC3, .name = "SYNC3" },
1121 { .addr = CC1200_SYNC2, .name = "SYNC2" },
1122 { .addr = CC1200_SYNC1, .name = "SYNC1" },
1123 { .addr = CC1200_SYNC0, .name = "SYNC0" },
1124 { .addr = CC1200_SYNC_CFG1, .name = "SYNC_CFG1" },
1125 { .addr = CC1200_SYNC_CFG0, .name = "SYNC_CFG0" },
1126 { .addr = CC1200_DEVIATION_M, .name = "DEVIATION_M" },
1127 { .addr = CC1200_MODCFG_DEV_E, .name = "MODCFG_DEV_E" },
1128 { .addr = CC1200_DCFILT_CFG, .name = "DCFILT_CFG" },
1129 { .addr = CC1200_PREAMBLE_CFG1, .name = "PREAMBLE_CFG1" },
1130 { .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
1131 { .addr = CC1200_IQIC, .name = "IQIC" },
1132 { .addr = CC1200_CHAN_BW, .name = "CHAN_BW" },
1133 { .addr = CC1200_MDMCFG2, .name = "MDMCFG2" },
1134 { .addr = CC1200_MDMCFG1, .name = "MDMCFG1" },
1135 { .addr = CC1200_MDMCFG0, .name = "MDMCFG0" },
1136 { .addr = CC1200_SYMBOL_RATE2, .name = "SYMBOL_RATE2" },
1137 { .addr = CC1200_SYMBOL_RATE1, .name = "SYMBOL_RATE1" },
1138 { .addr = CC1200_SYMBOL_RATE0, .name = "SYMBOL_RATE0" },
1139 { .addr = CC1200_AGC_REF, .name = "AGC_REF" },
1140 { .addr = CC1200_AGC_CS_THR, .name = "AGC_CS_THR" },
1141 { .addr = CC1200_AGC_GAIN_ADJUST, .name = "AGC_GAIN_ADJUST" },
1142 { .addr = CC1200_AGC_CFG3, .name = "AGC_CFG3" },
1143 { .addr = CC1200_AGC_CFG2, .name = "AGC_CFG2" },
1144 { .addr = CC1200_AGC_CFG1, .name = "AGC_CFG1" },
1145 { .addr = CC1200_AGC_CFG0, .name = "AGC_CFG0" },
1146 { .addr = CC1200_FIFO_CFG, .name = "FIFO_CFG" },
1147 { .addr = CC1200_DEV_ADDR, .name = "DEV_ADDR" },
1148 { .addr = CC1200_SETTLING_CFG, .name = "SETTLING_CFG" },
1149 { .addr = CC1200_FS_CFG, .name = "FS_CFG" },
1150 { .addr = CC1200_WOR_CFG1, .name = "WOR_CFG1" },
1151 { .addr = CC1200_WOR_CFG0, .name = "WOR_CFG0" },
1152 { .addr = CC1200_WOR_EVENT0_MSB, .name = "WOR_EVENT0_MSB" },
1153 { .addr = CC1200_WOR_EVENT0_LSB, .name = "WOR_EVENT0_LSB" },
1154 { .addr = CC1200_RXDCM_TIME, .name = "RXDCM_TIME" },
1155 { .addr = CC1200_PKT_CFG2, .name = "PKT_CFG2" },
1156 { .addr = CC1200_PKT_CFG1, .name = "PKT_CFG1" },
1157 { .addr = CC1200_PKT_CFG0, .name = "PKT_CFG0" },
1158 { .addr = CC1200_RFEND_CFG1, .name = "RFEND_CFG1" },
1159 { .addr = CC1200_RFEND_CFG0, .name = "RFEND_CFG0" },
1160 { .addr = CC1200_PA_CFG1, .name = "PA_CFG1" },
1161 { .addr = CC1200_PA_CFG0, .name = "PA_CFG0" },
1162 { .addr = CC1200_PKT_LEN, .name = "PKT_LEN" },
1163 { .addr = CC1200_IF_MIX_CFG, .name = "IF_MIX_CFG" },
1164 { .addr = CC1200_FREQOFF_CFG, .name = "FREQOFF_CFG" },
1165 { .addr = CC1200_TOC_CFG, .name = "TOC_CFG" },
1166 { .addr = CC1200_MARC_SPARE, .name = "MARC_SPARE" },
1167 { .addr = CC1200_ECG_CFG, .name = "ECG_CFG" },
1168 { .addr = CC1200_EXT_CTRL, .name = "EXT_CTRL" },
1169 { .addr = CC1200_RCCAL_FINE, .name = "RCCAL_FINE" },
1170 { .addr = CC1200_RCCAL_COARSE, .name = "RCCAL_COARSE" },
1171 { .addr = CC1200_RCCAL_OFFSET, .name = "RCCAL_OFFSET" },
1172 { .addr = CC1200_FREQOFF1, .name = "FREQOFF1" },
1173 { .addr = CC1200_FREQOFF0, .name = "FREQOFF0" },
1174 { .addr = CC1200_FREQ2, .name = "FREQ2" },
1175 { .addr = CC1200_FREQ1, .name = "FREQ1" },
1176 { .addr = CC1200_FREQ0, .name = "FREQ0" },
1177 { .addr = CC1200_IF_ADC2, .name = "IF_ADC2" },
1178 { .addr = CC1200_IF_ADC1, .name = "IF_ADC1" },
1179 { .addr = CC1200_IF_ADC0, .name = "IF_ADC0" },
1180 { .addr = CC1200_FS_DIG1, .name = "FS_DIG1" },
1181 { .addr = CC1200_FS_DIG0, .name = "FS_DIG0" },
1182 { .addr = CC1200_FS_CAL3, .name = "FS_CAL3" },
1183 { .addr = CC1200_FS_CAL2, .name = "FS_CAL2" },
1184 { .addr = CC1200_FS_CAL1, .name = "FS_CAL1" },
1185 { .addr = CC1200_FS_CAL0, .name = "FS_CAL0" },
1186 { .addr = CC1200_FS_CHP, .name = "FS_CHP" },
1187 { .addr = CC1200_FS_DIVTWO, .name = "FS_DIVTWO" },
1188 { .addr = CC1200_FS_DSM1, .name = "FS_DSM1" },
1189 { .addr = CC1200_FS_DSM0, .name = "FS_DSM0" },
1190 { .addr = CC1200_FS_DVC1, .name = "FS_DVC1" },
1191 { .addr = CC1200_FS_DVC0, .name = "FS_DVC0" },
1192 { .addr = CC1200_FS_LBI, .name = "FS_LBI" },
1193 { .addr = CC1200_FS_PFD, .name = "FS_PFD" },
1194 { .addr = CC1200_FS_PRE, .name = "FS_PRE" },
1195 { .addr = CC1200_FS_REG_DIV_CML, .name = "FS_REG_DIV_CML" },
1196 { .addr = CC1200_FS_SPARE, .name = "FS_SPARE" },
1197 { .addr = CC1200_FS_VCO4, .name = "FS_VCO4" },
1198 { .addr = CC1200_FS_VCO3, .name = "FS_VCO3" },
1199 { .addr = CC1200_FS_VCO2, .name = "FS_VCO2" },
1200 { .addr = CC1200_FS_VCO1, .name = "FS_VCO1" },
1201 { .addr = CC1200_FS_VCO0, .name = "FS_VCO0" },
1202 { .addr = CC1200_GBIAS6, .name = "GBIAS6" },
1203 { .addr = CC1200_GBIAS5, .name = "GBIAS5" },
1204 { .addr = CC1200_GBIAS4, .name = "GBIAS4" },
1205 { .addr = CC1200_GBIAS3, .name = "GBIAS3" },
1206 { .addr = CC1200_GBIAS2, .name = "GBIAS2" },
1207 { .addr = CC1200_GBIAS1, .name = "GBIAS1" },
1208 { .addr = CC1200_GBIAS0, .name = "GBIAS0" },
1209 { .addr = CC1200_IFAMP, .name = "IFAMP" },
1210 { .addr = CC1200_LNA, .name = "LNA" },
1211 { .addr = CC1200_RXMIX, .name = "RXMIX" },
1212 { .addr = CC1200_XOSC5, .name = "XOSC5" },
1213 { .addr = CC1200_XOSC4, .name = "XOSC4" },
1214 { .addr = CC1200_XOSC3, .name = "XOSC3" },
1215 { .addr = CC1200_XOSC2, .name = "XOSC2" },
1216 { .addr = CC1200_XOSC1, .name = "XOSC1" },
1217 { .addr = CC1200_XOSC0, .name = "XOSC0" },
1218 { .addr = CC1200_ANALOG_SPARE, .name = "ANALOG_SPARE" },
1219 { .addr = CC1200_PA_CFG3, .name = "PA_CFG3" },
1220 { .addr = CC1200_WOR_TIME1, .name = "WOR_TIME1" },
1221 { .addr = CC1200_WOR_TIME0, .name = "WOR_TIME0" },
1222 { .addr = CC1200_WOR_CAPTURE1, .name = "WOR_CAPTURE1" },
1223 { .addr = CC1200_WOR_CAPTURE0, .name = "WOR_CAPTURE0" },
1224 { .addr = CC1200_BIST, .name = "BIST" },
1225 { .addr = CC1200_DCFILTOFFSET_I1, .name = "DCFILTOFFSET_I1" },
1226 { .addr = CC1200_DCFILTOFFSET_I0, .name = "DCFILTOFFSET_I0" },
1227 { .addr = CC1200_DCFILTOFFSET_Q1, .name = "DCFILTOFFSET_Q1" },
1228 { .addr = CC1200_DCFILTOFFSET_Q0, .name = "DCFILTOFFSET_Q0" },
1229 { .addr = CC1200_IQIE_I1, .name = "IQIE_I1" },
1230 { .addr = CC1200_IQIE_I0, .name = "IQIE_I0" },
1231 { .addr = CC1200_IQIE_Q1, .name = "IQIE_Q1" },
1232 { .addr = CC1200_IQIE_Q0, .name = "IQIE_Q0" },
1233 { .addr = CC1200_RSSI1, .name = "RSSI1" },
1234 { .addr = CC1200_RSSI0, .name = "RSSI0" },
1235 { .addr = CC1200_MARCSTATE, .name = "MARCSTATE" },
1236 { .addr = CC1200_LQI_VAL, .name = "LQI_VAL" },
1237 { .addr = CC1200_PQT_SYNC_ERR, .name = "PQT_SYNC_ERR" },
1238 { .addr = CC1200_DEM_STATUS, .name = "DEM_STATUS" },
1239 { .addr = CC1200_FREQOFF_EST1, .name = "FREQOFF_EST1" },
1240 { .addr = CC1200_FREQOFF_EST0, .name = "FREQOFF_EST0" },
1241 { .addr = CC1200_AGC_GAIN3, .name = "AGC_GAIN3" },
1242 { .addr = CC1200_AGC_GAIN2, .name = "AGC_GAIN2" },
1243 { .addr = CC1200_AGC_GAIN1, .name = "AGC_GAIN1" },
1244 { .addr = CC1200_AGC_GAIN0, .name = "AGC_GAIN0" },
1245 { .addr = CC1200_SOFT_RX_DATA_OUT, .name = "SOFT_RX_DATA_OUT" },
1246 { .addr = CC1200_SOFT_TX_DATA_IN, .name = "SOFT_TX_DATA_IN" },
1247 { .addr = CC1200_ASK_SOFT_RX_DATA, .name = "ASK_SOFT_RX_DATA" },
1248 { .addr = CC1200_RNDGEN, .name = "RNDGEN" },
1249 { .addr = CC1200_MAGN2, .name = "MAGN2" },
1250 { .addr = CC1200_MAGN1, .name = "MAGN1" },
1251 { .addr = CC1200_MAGN0, .name = "MAGN0" },
1252 { .addr = CC1200_ANG1, .name = "ANG1" },
1253 { .addr = CC1200_ANG0, .name = "ANG0" },
1254 { .addr = CC1200_CHFILT_I2, .name = "CHFILT_I2" },
1255 { .addr = CC1200_CHFILT_I1, .name = "CHFILT_I1" },
1256 { .addr = CC1200_CHFILT_I0, .name = "CHFILT_I0" },
1257 { .addr = CC1200_CHFILT_Q2, .name = "CHFILT_Q2" },
1258 { .addr = CC1200_CHFILT_Q1, .name = "CHFILT_Q1" },
1259 { .addr = CC1200_CHFILT_Q0, .name = "CHFILT_Q0" },
1260 { .addr = CC1200_GPIO_STATUS, .name = "GPIO_STATUS" },
1261 { .addr = CC1200_FSCAL_CTRL, .name = "FSCAL_CTRL" },
1262 { .addr = CC1200_PHASE_ADJUST, .name = "PHASE_ADJUST" },
1263 { .addr = CC1200_PARTNUMBER, .name = "PARTNUMBER" },
1264 { .addr = CC1200_PARTVERSION, .name = "PARTVERSION" },
1265 { .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" },
1266 { .addr = CC1200_MODEM_STATUS1, .name = "MODEM_STATUS1" },
1267 { .addr = CC1200_MODEM_STATUS0, .name = "MODEM_STATUS0" },
1268 { .addr = CC1200_MARC_STATUS1, .name = "MARC_STATUS1" },
1269 { .addr = CC1200_MARC_STATUS0, .name = "MARC_STATUS0" },
1270 { .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
1271 { .addr = CC1200_FSRF_TEST, .name = "FSRF_TEST" },
1272 { .addr = CC1200_PRE_TEST, .name = "PRE_TEST" },
1273 { .addr = CC1200_PRE_OVR, .name = "PRE_OVR" },
1274 { .addr = CC1200_ADC_TEST, .name = "ADC_TEST" },
1275 { .addr = CC1200_DVC_TEST, .name = "DVC_TEST" },
1276 { .addr = CC1200_ATEST, .name = "ATEST" },
1277 { .addr = CC1200_ATEST_LVDS, .name = "ATEST_LVDS" },
1278 { .addr = CC1200_ATEST_MODE, .name = "ATEST_MODE" },
1279 { .addr = CC1200_XOSC_TEST1, .name = "XOSC_TEST1" },
1280 { .addr = CC1200_XOSC_TEST0, .name = "XOSC_TEST0" },
1281 { .addr = CC1200_RXFIRST, .name = "RXFIRST" },
1282 { .addr = CC1200_TXFIRST, .name = "TXFIRST" },
1283 { .addr = CC1200_RXLAST, .name = "RXLAST" },
1284 { .addr = CC1200_TXLAST, .name = "TXLAST" },
1285 { .addr = CC1200_NUM_TXBYTES, .name = "NUM_TXBYTES" },
1286 { .addr = CC1200_NUM_RXBYTES, .name = "NUM_RXBYTES" },
1287 { .addr = CC1200_FIFO_NUM_TXBYTES, .name = "FIFO_NUM_TXBYTES" },
1288 { .addr = CC1200_FIFO_NUM_RXBYTES, .name = "FIFO_NUM_RXBYTES" },
1291 #define AO_NUM_CC1200_REG (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0])
1294 ao_radio_get_marc_status(void)
1296 return ao_radio_reg_read(CC1200_MARC_STATUS1);
1299 static void ao_radio_show(void) {
1303 ao_mutex_get(&ao_radio_mutex);
1304 status = ao_radio_status();
1305 printf ("Status: %02x\n", status);
1306 printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1);
1307 printf ("STATE: %s\n", cc1200_state_name[(status >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK]);
1308 printf ("MARC: %02x\n", ao_radio_get_marc_status());
1310 for (i = 0; i < AO_NUM_CC1200_REG; i++)
1311 printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1200_reg[i].addr), ao_cc1200_reg[i].name);
1316 static void ao_radio_beep(void) {
1320 static void ao_radio_packet(void) {
1321 static const uint8_t packet[] = {
1323 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1324 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1325 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1326 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1332 ao_radio_send(packet, sizeof (packet));
1336 ao_radio_test_recv(void)
1341 if (ao_radio_recv(bytes, 34, 0)) {
1342 if (bytes[33] & 0x80)
1346 printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32]));
1347 for (b = 0; b < 32; b++)
1348 printf (" %02x", bytes[b]);
1350 printf (" RSSI %02x LQI %02x", bytes[32], bytes[33]);
1356 #include <ao_aprs.h>
1361 #if PACKET_HAS_SLAVE
1362 ao_packet_slave_stop();
1369 #if CC1200_LOW_LEVEL_DEBUG
1371 ao_radio_strobe_test(void)
1376 if (ao_cmd_status != ao_cmd_success)
1378 r = ao_radio_strobe(ao_cmd_lex_i);
1379 printf ("Strobe %02x -> %02x (rdy %d state %d)\n",
1387 ao_radio_write_test(void)
1393 if (ao_cmd_status != ao_cmd_success)
1395 addr = ao_cmd_lex_i;
1397 if (ao_cmd_status != ao_cmd_success)
1399 data = ao_cmd_lex_i;
1400 printf ("Write %04x = %02x\n", addr, data);
1401 ao_radio_reg_write(addr, data);
1405 ao_radio_read_test(void)
1411 if (ao_cmd_status != ao_cmd_success)
1413 addr = ao_cmd_lex_i;
1414 data = ao_radio_reg_read(addr);
1415 printf ("Read %04x = %02x\n", addr, data);
1419 static const struct ao_cmds ao_radio_cmds[] = {
1420 { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
1423 { ao_radio_aprs, "G\0Send APRS packet" },
1425 { ao_radio_show, "R\0Show CC1200 status" },
1426 { ao_radio_beep, "b\0Emit an RDF beacon" },
1427 { ao_radio_packet, "p\0Send a test packet" },
1428 { ao_radio_test_recv, "q\0Recv a test packet" },
1430 #if CC1200_LOW_LEVEL_DEBUG
1431 { ao_radio_strobe_test, "A <value>\0Strobe radio" },
1432 { ao_radio_write_test, "W <addr> <value>\0Write radio reg" },
1433 { ao_radio_read_test, "B <addr>\0Read radio reg" },
1441 ao_radio_configured = 0;
1442 ao_spi_init_cs (AO_CC1200_SPI_CS_PORT, (1 << AO_CC1200_SPI_CS_PIN));
1445 AO_CC1200_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC1200_SPI_CS_PIN));
1446 for (i = 0; i < 10000; i++) {
1447 if ((SPI_2_PORT->idr & (1 << SPI_2_MISO_PIN)) == 0)
1450 AO_CC1200_SPI_CS_PORT->bsrr = (1 << AO_CC1200_SPI_CS_PIN);
1452 ao_panic(AO_PANIC_SELF_TEST_CC1200);
1455 /* Enable the EXTI interrupt for the appropriate pin */
1456 ao_enable_port(AO_CC1200_INT_PORT);
1457 ao_exti_setup(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN,
1458 AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH,
1461 ao_cmd_register(&ao_radio_cmds[0]);