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);
605 if (changes & AO_RADIO_MODE_BITS_TX_FINISH)
606 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
608 if (changes & AO_RADIO_MODE_BITS_RX)
609 ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
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);
648 ao_radio_configured = 1;
652 ao_radio_set_len(uint8_t len)
654 static uint8_t last_len;
656 if (len != last_len) {
657 ao_radio_reg_write(CC1200_PKT_LEN, len);
663 ao_radio_get(uint8_t len)
665 static uint32_t last_radio_setting;
666 static uint8_t last_radio_rate;
668 ao_mutex_get(&ao_radio_mutex);
670 if (!ao_radio_configured)
672 if (ao_config.radio_setting != last_radio_setting) {
673 ao_radio_reg_write(CC1200_FREQ2, ao_config.radio_setting >> 16);
674 ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8);
675 ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting);
676 last_radio_setting = ao_config.radio_setting;
677 ao_radio_strobe(CC1200_SCAL);
679 if (ao_config.radio_rate != last_radio_rate) {
680 ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET;
681 last_radio_rate = ao_config.radio_rate;
683 ao_radio_set_len(len);
686 #define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
688 static inline uint8_t
691 return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
696 ao_radio_show_state(char *where)
698 printf("%s: state %d len %d rxbytes %d\n",
699 where, ao_radio_state(),
700 ao_radio_reg_read(CC1200_PKT_LEN),
701 ao_radio_reg_read(CC1200_NUM_RXBYTES));
704 #define ao_radio_show_state(where)
707 /* Wait for the radio to signal an interrupt
710 ao_radio_wait_isr(uint16_t timeout)
714 state = ao_radio_state();
716 case CC1200_STATUS_STATE_IDLE:
717 case CC1200_STATUS_STATE_RX_FIFO_ERROR:
718 case CC1200_STATUS_STATE_TX_FIFO_ERROR:
719 #if CC1200_LOW_LEVEL_DEBUG
720 printf("before wait, state %d\n", state); flush();
729 ao_arch_block_interrupts();
730 while (!ao_radio_wake && !ao_radio_abort)
731 if (ao_sleep(&ao_radio_wake))
733 ao_arch_release_interrupts();
739 ao_rdf_start(uint8_t len)
744 ao_radio_set_mode(AO_RADIO_MODE_RDF);
754 ao_radio_wait_isr(0);
763 ao_rdf_start(AO_RADIO_RDF_LEN);
765 ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
771 ao_radio_continuity(uint8_t c)
776 ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
778 status = ao_radio_fifo_write_start();
779 for (i = 0; i < 3; i++) {
780 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
782 ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
784 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
786 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
787 status = ao_radio_fifo_write_stop(status);
793 ao_radio_rdf_abort(void)
796 ao_wakeup(&ao_radio_wake);
800 ao_radio_test_cmd(void)
803 static uint8_t radio_on;
805 if (ao_cmd_lex_c != '\n') {
807 mode = (uint8_t) ao_cmd_lex_u32;
810 if ((mode & 2) && !radio_on) {
812 ao_monitor_disable();
815 ao_packet_slave_stop();
818 ao_radio_set_mode(AO_RADIO_MODE_TEST);
819 ao_radio_strobe(CC1200_STX);
822 for (t = 0; t < 10; t++) {
823 printf ("status: %02x\n", ao_radio_status());
824 ao_delay(AO_MS_TO_TICKS(100));
831 printf ("Hit a character to stop..."); flush();
835 if ((mode & 1) && radio_on) {
846 ao_radio_send(const void *d, uint8_t size)
849 ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX);
851 ao_radio_fifo_write(d, size);
857 #define AO_RADIO_LOTS 64
860 ao_radio_send_aprs(ao_radio_fill_func fill)
862 uint8_t buf[AO_RADIO_LOTS], *b;
871 fifo_space = CC1200_FIFO_SIZE;
873 cnt = (*fill)(buf, sizeof(buf));
878 #if CC1200_APRS_TRACE
879 printf("APRS fill %d bytes done %d\n", cnt, done);
883 /* At the last buffer, set the total length */
885 ao_radio_set_len(total & 0xff);
889 uint8_t this_len = cnt;
891 /* Wait for some space in the fifo */
892 while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) {
893 #if CC1200_APRS_TRACE
894 printf("APRS space %d cnt %d\n", fifo_space, cnt); flush();
897 ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
901 if (this_len > fifo_space)
902 this_len = fifo_space;
908 ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF);
910 ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
912 ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
914 ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
916 ao_radio_fifo_write(b, this_len);
918 #if CC1200_APRS_TRACE
919 printf("APRS write fifo %d space now %d\n", this_len, ao_radio_tx_fifo_space());
922 #if CC1200_APRS_TRACE
923 printf("APRS start\n");
925 ao_radio_strobe(CC1200_STX);
926 #if CC1200_APRS_TRACE
928 for (t = 0; t < 20; t++) {
929 uint8_t status = ao_radio_status();
930 uint8_t space = ao_radio_tx_fifo_space();
931 printf ("status: %02x fifo %d\n", status, space);
932 if ((status >> 4) == 2)
934 ao_delay(AO_MS_TO_TICKS(0));
941 if (ao_radio_abort) {
946 /* Wait for the transmitter to go idle */
948 #if CC1200_APRS_TRACE
949 printf("APRS wait idle\n"); flush();
951 ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
952 #if CC1200_APRS_TRACE
953 printf("APRS abort %d\n", ao_radio_abort);
960 ao_radio_marc_state(void)
962 return ao_radio_reg_read(CC1200_MARCSTATE);
966 ao_radio_modem_status1(void)
968 return ao_radio_reg_read(CC1200_MODEM_STATUS1);
972 ao_radio_modem_status0(void)
974 return ao_radio_reg_read(CC1200_MODEM_STATUS0);
977 struct ao_radio_state {
980 uint8_t marc_status1;
981 uint8_t marc_status0;
982 uint8_t modem_status1;
983 uint8_t modem_status0;
987 ao_radio_fill_state(char *where, struct ao_radio_state *s)
989 strcpy(s->where, where);
990 s->marc_state = ao_radio_marc_state();
991 s->marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
992 s->marc_status0 = ao_radio_reg_read(CC1200_MARC_STATUS0);
993 s->modem_status1 = ao_radio_modem_status1();
994 s->modem_status0 = ao_radio_modem_status0();
998 ao_radio_dump_state(struct ao_radio_state *s)
1000 printf ("%s: marc %2x marc1 %2x marc0 %2x modem1 %2x modem0 %2x\n",
1001 s->where, s->marc_state, s->marc_status1, s->marc_status0, s->modem_status1, s->modem_status0);
1006 ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
1010 ao_radio_get(size - 2);
1011 ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
1013 ao_radio_start_rx();
1014 ao_radio_wait_isr(timeout);
1015 if (ao_radio_wake) {
1019 status = ao_radio_fifo_read(d, size);
1021 rssi = ((int8_t *) d)[size - 2];
1022 ao_radio_rssi = rssi;
1024 /* Bound it to the representable range */
1028 /* Write it back to the packet */
1029 ((int8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi);
1036 return ao_radio_wake;
1041 static char *cc1200_state_name[] = {
1042 [CC1200_STATUS_STATE_IDLE] = "IDLE",
1043 [CC1200_STATUS_STATE_RX] = "RX",
1044 [CC1200_STATUS_STATE_TX] = "TX",
1045 [CC1200_STATUS_STATE_FSTXON] = "FSTXON",
1046 [CC1200_STATUS_STATE_CALIBRATE] = "CALIBRATE",
1047 [CC1200_STATUS_STATE_SETTLING] = "SETTLING",
1048 [CC1200_STATUS_STATE_RX_FIFO_ERROR] = "RX_FIFO_ERROR",
1049 [CC1200_STATUS_STATE_TX_FIFO_ERROR] = "TX_FIFO_ERROR",
1052 struct ao_cc1200_reg {
1057 static const struct ao_cc1200_reg ao_cc1200_reg[] = {
1058 { .addr = CC1200_IOCFG3, .name = "IOCFG3" },
1059 { .addr = CC1200_IOCFG2, .name = "IOCFG2" },
1060 { .addr = CC1200_IOCFG1, .name = "IOCFG1" },
1061 { .addr = CC1200_IOCFG0, .name = "IOCFG0" },
1062 { .addr = CC1200_SYNC3, .name = "SYNC3" },
1063 { .addr = CC1200_SYNC2, .name = "SYNC2" },
1064 { .addr = CC1200_SYNC1, .name = "SYNC1" },
1065 { .addr = CC1200_SYNC0, .name = "SYNC0" },
1066 { .addr = CC1200_SYNC_CFG1, .name = "SYNC_CFG1" },
1067 { .addr = CC1200_SYNC_CFG0, .name = "SYNC_CFG0" },
1068 { .addr = CC1200_DEVIATION_M, .name = "DEVIATION_M" },
1069 { .addr = CC1200_MODCFG_DEV_E, .name = "MODCFG_DEV_E" },
1070 { .addr = CC1200_DCFILT_CFG, .name = "DCFILT_CFG" },
1071 { .addr = CC1200_PREAMBLE_CFG1, .name = "PREAMBLE_CFG1" },
1072 { .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
1073 { .addr = CC1200_IQIC, .name = "IQIC" },
1074 { .addr = CC1200_CHAN_BW, .name = "CHAN_BW" },
1075 { .addr = CC1200_MDMCFG2, .name = "MDMCFG2" },
1076 { .addr = CC1200_MDMCFG1, .name = "MDMCFG1" },
1077 { .addr = CC1200_MDMCFG0, .name = "MDMCFG0" },
1078 { .addr = CC1200_SYMBOL_RATE2, .name = "SYMBOL_RATE2" },
1079 { .addr = CC1200_SYMBOL_RATE1, .name = "SYMBOL_RATE1" },
1080 { .addr = CC1200_SYMBOL_RATE0, .name = "SYMBOL_RATE0" },
1081 { .addr = CC1200_AGC_REF, .name = "AGC_REF" },
1082 { .addr = CC1200_AGC_CS_THR, .name = "AGC_CS_THR" },
1083 { .addr = CC1200_AGC_GAIN_ADJUST, .name = "AGC_GAIN_ADJUST" },
1084 { .addr = CC1200_AGC_CFG3, .name = "AGC_CFG3" },
1085 { .addr = CC1200_AGC_CFG2, .name = "AGC_CFG2" },
1086 { .addr = CC1200_AGC_CFG1, .name = "AGC_CFG1" },
1087 { .addr = CC1200_AGC_CFG0, .name = "AGC_CFG0" },
1088 { .addr = CC1200_FIFO_CFG, .name = "FIFO_CFG" },
1089 { .addr = CC1200_DEV_ADDR, .name = "DEV_ADDR" },
1090 { .addr = CC1200_SETTLING_CFG, .name = "SETTLING_CFG" },
1091 { .addr = CC1200_FS_CFG, .name = "FS_CFG" },
1092 { .addr = CC1200_WOR_CFG1, .name = "WOR_CFG1" },
1093 { .addr = CC1200_WOR_CFG0, .name = "WOR_CFG0" },
1094 { .addr = CC1200_WOR_EVENT0_MSB, .name = "WOR_EVENT0_MSB" },
1095 { .addr = CC1200_WOR_EVENT0_LSB, .name = "WOR_EVENT0_LSB" },
1096 { .addr = CC1200_RXDCM_TIME, .name = "RXDCM_TIME" },
1097 { .addr = CC1200_PKT_CFG2, .name = "PKT_CFG2" },
1098 { .addr = CC1200_PKT_CFG1, .name = "PKT_CFG1" },
1099 { .addr = CC1200_PKT_CFG0, .name = "PKT_CFG0" },
1100 { .addr = CC1200_RFEND_CFG1, .name = "RFEND_CFG1" },
1101 { .addr = CC1200_RFEND_CFG0, .name = "RFEND_CFG0" },
1102 { .addr = CC1200_PA_CFG1, .name = "PA_CFG1" },
1103 { .addr = CC1200_PA_CFG0, .name = "PA_CFG0" },
1104 { .addr = CC1200_PKT_LEN, .name = "PKT_LEN" },
1105 { .addr = CC1200_IF_MIX_CFG, .name = "IF_MIX_CFG" },
1106 { .addr = CC1200_FREQOFF_CFG, .name = "FREQOFF_CFG" },
1107 { .addr = CC1200_TOC_CFG, .name = "TOC_CFG" },
1108 { .addr = CC1200_MARC_SPARE, .name = "MARC_SPARE" },
1109 { .addr = CC1200_ECG_CFG, .name = "ECG_CFG" },
1110 { .addr = CC1200_EXT_CTRL, .name = "EXT_CTRL" },
1111 { .addr = CC1200_RCCAL_FINE, .name = "RCCAL_FINE" },
1112 { .addr = CC1200_RCCAL_COARSE, .name = "RCCAL_COARSE" },
1113 { .addr = CC1200_RCCAL_OFFSET, .name = "RCCAL_OFFSET" },
1114 { .addr = CC1200_FREQOFF1, .name = "FREQOFF1" },
1115 { .addr = CC1200_FREQOFF0, .name = "FREQOFF0" },
1116 { .addr = CC1200_FREQ2, .name = "FREQ2" },
1117 { .addr = CC1200_FREQ1, .name = "FREQ1" },
1118 { .addr = CC1200_FREQ0, .name = "FREQ0" },
1119 { .addr = CC1200_IF_ADC2, .name = "IF_ADC2" },
1120 { .addr = CC1200_IF_ADC1, .name = "IF_ADC1" },
1121 { .addr = CC1200_IF_ADC0, .name = "IF_ADC0" },
1122 { .addr = CC1200_FS_DIG1, .name = "FS_DIG1" },
1123 { .addr = CC1200_FS_DIG0, .name = "FS_DIG0" },
1124 { .addr = CC1200_FS_CAL3, .name = "FS_CAL3" },
1125 { .addr = CC1200_FS_CAL2, .name = "FS_CAL2" },
1126 { .addr = CC1200_FS_CAL1, .name = "FS_CAL1" },
1127 { .addr = CC1200_FS_CAL0, .name = "FS_CAL0" },
1128 { .addr = CC1200_FS_CHP, .name = "FS_CHP" },
1129 { .addr = CC1200_FS_DIVTWO, .name = "FS_DIVTWO" },
1130 { .addr = CC1200_FS_DSM1, .name = "FS_DSM1" },
1131 { .addr = CC1200_FS_DSM0, .name = "FS_DSM0" },
1132 { .addr = CC1200_FS_DVC1, .name = "FS_DVC1" },
1133 { .addr = CC1200_FS_DVC0, .name = "FS_DVC0" },
1134 { .addr = CC1200_FS_LBI, .name = "FS_LBI" },
1135 { .addr = CC1200_FS_PFD, .name = "FS_PFD" },
1136 { .addr = CC1200_FS_PRE, .name = "FS_PRE" },
1137 { .addr = CC1200_FS_REG_DIV_CML, .name = "FS_REG_DIV_CML" },
1138 { .addr = CC1200_FS_SPARE, .name = "FS_SPARE" },
1139 { .addr = CC1200_FS_VCO4, .name = "FS_VCO4" },
1140 { .addr = CC1200_FS_VCO3, .name = "FS_VCO3" },
1141 { .addr = CC1200_FS_VCO2, .name = "FS_VCO2" },
1142 { .addr = CC1200_FS_VCO1, .name = "FS_VCO1" },
1143 { .addr = CC1200_FS_VCO0, .name = "FS_VCO0" },
1144 { .addr = CC1200_GBIAS6, .name = "GBIAS6" },
1145 { .addr = CC1200_GBIAS5, .name = "GBIAS5" },
1146 { .addr = CC1200_GBIAS4, .name = "GBIAS4" },
1147 { .addr = CC1200_GBIAS3, .name = "GBIAS3" },
1148 { .addr = CC1200_GBIAS2, .name = "GBIAS2" },
1149 { .addr = CC1200_GBIAS1, .name = "GBIAS1" },
1150 { .addr = CC1200_GBIAS0, .name = "GBIAS0" },
1151 { .addr = CC1200_IFAMP, .name = "IFAMP" },
1152 { .addr = CC1200_LNA, .name = "LNA" },
1153 { .addr = CC1200_RXMIX, .name = "RXMIX" },
1154 { .addr = CC1200_XOSC5, .name = "XOSC5" },
1155 { .addr = CC1200_XOSC4, .name = "XOSC4" },
1156 { .addr = CC1200_XOSC3, .name = "XOSC3" },
1157 { .addr = CC1200_XOSC2, .name = "XOSC2" },
1158 { .addr = CC1200_XOSC1, .name = "XOSC1" },
1159 { .addr = CC1200_XOSC0, .name = "XOSC0" },
1160 { .addr = CC1200_ANALOG_SPARE, .name = "ANALOG_SPARE" },
1161 { .addr = CC1200_PA_CFG3, .name = "PA_CFG3" },
1162 { .addr = CC1200_WOR_TIME1, .name = "WOR_TIME1" },
1163 { .addr = CC1200_WOR_TIME0, .name = "WOR_TIME0" },
1164 { .addr = CC1200_WOR_CAPTURE1, .name = "WOR_CAPTURE1" },
1165 { .addr = CC1200_WOR_CAPTURE0, .name = "WOR_CAPTURE0" },
1166 { .addr = CC1200_BIST, .name = "BIST" },
1167 { .addr = CC1200_DCFILTOFFSET_I1, .name = "DCFILTOFFSET_I1" },
1168 { .addr = CC1200_DCFILTOFFSET_I0, .name = "DCFILTOFFSET_I0" },
1169 { .addr = CC1200_DCFILTOFFSET_Q1, .name = "DCFILTOFFSET_Q1" },
1170 { .addr = CC1200_DCFILTOFFSET_Q0, .name = "DCFILTOFFSET_Q0" },
1171 { .addr = CC1200_IQIE_I1, .name = "IQIE_I1" },
1172 { .addr = CC1200_IQIE_I0, .name = "IQIE_I0" },
1173 { .addr = CC1200_IQIE_Q1, .name = "IQIE_Q1" },
1174 { .addr = CC1200_IQIE_Q0, .name = "IQIE_Q0" },
1175 { .addr = CC1200_RSSI1, .name = "RSSI1" },
1176 { .addr = CC1200_RSSI0, .name = "RSSI0" },
1177 { .addr = CC1200_MARCSTATE, .name = "MARCSTATE" },
1178 { .addr = CC1200_LQI_VAL, .name = "LQI_VAL" },
1179 { .addr = CC1200_PQT_SYNC_ERR, .name = "PQT_SYNC_ERR" },
1180 { .addr = CC1200_DEM_STATUS, .name = "DEM_STATUS" },
1181 { .addr = CC1200_FREQOFF_EST1, .name = "FREQOFF_EST1" },
1182 { .addr = CC1200_FREQOFF_EST0, .name = "FREQOFF_EST0" },
1183 { .addr = CC1200_AGC_GAIN3, .name = "AGC_GAIN3" },
1184 { .addr = CC1200_AGC_GAIN2, .name = "AGC_GAIN2" },
1185 { .addr = CC1200_AGC_GAIN1, .name = "AGC_GAIN1" },
1186 { .addr = CC1200_AGC_GAIN0, .name = "AGC_GAIN0" },
1187 { .addr = CC1200_SOFT_RX_DATA_OUT, .name = "SOFT_RX_DATA_OUT" },
1188 { .addr = CC1200_SOFT_TX_DATA_IN, .name = "SOFT_TX_DATA_IN" },
1189 { .addr = CC1200_ASK_SOFT_RX_DATA, .name = "ASK_SOFT_RX_DATA" },
1190 { .addr = CC1200_RNDGEN, .name = "RNDGEN" },
1191 { .addr = CC1200_MAGN2, .name = "MAGN2" },
1192 { .addr = CC1200_MAGN1, .name = "MAGN1" },
1193 { .addr = CC1200_MAGN0, .name = "MAGN0" },
1194 { .addr = CC1200_ANG1, .name = "ANG1" },
1195 { .addr = CC1200_ANG0, .name = "ANG0" },
1196 { .addr = CC1200_CHFILT_I2, .name = "CHFILT_I2" },
1197 { .addr = CC1200_CHFILT_I1, .name = "CHFILT_I1" },
1198 { .addr = CC1200_CHFILT_I0, .name = "CHFILT_I0" },
1199 { .addr = CC1200_CHFILT_Q2, .name = "CHFILT_Q2" },
1200 { .addr = CC1200_CHFILT_Q1, .name = "CHFILT_Q1" },
1201 { .addr = CC1200_CHFILT_Q0, .name = "CHFILT_Q0" },
1202 { .addr = CC1200_GPIO_STATUS, .name = "GPIO_STATUS" },
1203 { .addr = CC1200_FSCAL_CTRL, .name = "FSCAL_CTRL" },
1204 { .addr = CC1200_PHASE_ADJUST, .name = "PHASE_ADJUST" },
1205 { .addr = CC1200_PARTNUMBER, .name = "PARTNUMBER" },
1206 { .addr = CC1200_PARTVERSION, .name = "PARTVERSION" },
1207 { .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" },
1208 { .addr = CC1200_MODEM_STATUS1, .name = "MODEM_STATUS1" },
1209 { .addr = CC1200_MODEM_STATUS0, .name = "MODEM_STATUS0" },
1210 { .addr = CC1200_MARC_STATUS1, .name = "MARC_STATUS1" },
1211 { .addr = CC1200_MARC_STATUS0, .name = "MARC_STATUS0" },
1212 { .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
1213 { .addr = CC1200_FSRF_TEST, .name = "FSRF_TEST" },
1214 { .addr = CC1200_PRE_TEST, .name = "PRE_TEST" },
1215 { .addr = CC1200_PRE_OVR, .name = "PRE_OVR" },
1216 { .addr = CC1200_ADC_TEST, .name = "ADC_TEST" },
1217 { .addr = CC1200_DVC_TEST, .name = "DVC_TEST" },
1218 { .addr = CC1200_ATEST, .name = "ATEST" },
1219 { .addr = CC1200_ATEST_LVDS, .name = "ATEST_LVDS" },
1220 { .addr = CC1200_ATEST_MODE, .name = "ATEST_MODE" },
1221 { .addr = CC1200_XOSC_TEST1, .name = "XOSC_TEST1" },
1222 { .addr = CC1200_XOSC_TEST0, .name = "XOSC_TEST0" },
1223 { .addr = CC1200_RXFIRST, .name = "RXFIRST" },
1224 { .addr = CC1200_TXFIRST, .name = "TXFIRST" },
1225 { .addr = CC1200_RXLAST, .name = "RXLAST" },
1226 { .addr = CC1200_TXLAST, .name = "TXLAST" },
1227 { .addr = CC1200_NUM_TXBYTES, .name = "NUM_TXBYTES" },
1228 { .addr = CC1200_NUM_RXBYTES, .name = "NUM_RXBYTES" },
1229 { .addr = CC1200_FIFO_NUM_TXBYTES, .name = "FIFO_NUM_TXBYTES" },
1230 { .addr = CC1200_FIFO_NUM_RXBYTES, .name = "FIFO_NUM_RXBYTES" },
1233 #define AO_NUM_CC1200_REG (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0])
1236 ao_radio_get_marc_status(void)
1238 return ao_radio_reg_read(CC1200_MARC_STATUS1);
1241 static void ao_radio_show(void) {
1245 ao_mutex_get(&ao_radio_mutex);
1246 status = ao_radio_status();
1247 printf ("Status: %02x\n", status);
1248 printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1);
1249 printf ("STATE: %s\n", cc1200_state_name[(status >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK]);
1250 printf ("MARC: %02x\n", ao_radio_get_marc_status());
1252 for (i = 0; i < AO_NUM_CC1200_REG; i++)
1253 printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1200_reg[i].addr), ao_cc1200_reg[i].name);
1258 static void ao_radio_beep(void) {
1262 static void ao_radio_packet(void) {
1263 static const uint8_t packet[] = {
1265 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1266 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1267 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1268 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1274 ao_radio_send(packet, sizeof (packet));
1278 ao_radio_test_recv(void)
1283 if (ao_radio_recv(bytes, 34, 0)) {
1284 if (bytes[33] & 0x80)
1288 printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32]));
1289 for (b = 0; b < 32; b++)
1290 printf (" %02x", bytes[b]);
1292 printf (" RSSI %02x LQI %02x", bytes[32], bytes[33]);
1298 #include <ao_aprs.h>
1303 #if PACKET_HAS_SLAVE
1304 ao_packet_slave_stop();
1311 #if CC1200_LOW_LEVEL_DEBUG
1313 ao_radio_strobe_test(void)
1318 if (ao_cmd_status != ao_cmd_success)
1320 r = ao_radio_strobe(ao_cmd_lex_i);
1321 printf ("Strobe %02x -> %02x (rdy %d state %d)\n",
1329 ao_radio_write_test(void)
1335 if (ao_cmd_status != ao_cmd_success)
1337 addr = ao_cmd_lex_i;
1339 if (ao_cmd_status != ao_cmd_success)
1341 data = ao_cmd_lex_i;
1342 printf ("Write %04x = %02x\n", addr, data);
1343 ao_radio_reg_write(addr, data);
1347 ao_radio_read_test(void)
1353 if (ao_cmd_status != ao_cmd_success)
1355 addr = ao_cmd_lex_i;
1356 data = ao_radio_reg_read(addr);
1357 printf ("Read %04x = %02x\n", addr, data);
1361 static const struct ao_cmds ao_radio_cmds[] = {
1362 { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
1365 { ao_radio_aprs, "G\0Send APRS packet" },
1367 { ao_radio_show, "R\0Show CC1200 status" },
1368 { ao_radio_beep, "b\0Emit an RDF beacon" },
1369 { ao_radio_packet, "p\0Send a test packet" },
1370 { ao_radio_test_recv, "q\0Recv a test packet" },
1372 #if CC1200_LOW_LEVEL_DEBUG
1373 { ao_radio_strobe_test, "A <value>\0Strobe radio" },
1374 { ao_radio_write_test, "W <addr> <value>\0Write radio reg" },
1375 { ao_radio_read_test, "B <addr>\0Read radio reg" },
1383 ao_radio_configured = 0;
1384 ao_spi_init_cs (AO_CC1200_SPI_CS_PORT, (1 << AO_CC1200_SPI_CS_PIN));
1387 AO_CC1200_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC1200_SPI_CS_PIN));
1388 for (i = 0; i < 10000; i++) {
1389 if ((SPI_2_PORT->idr & (1 << SPI_2_MISO_PIN)) == 0)
1392 AO_CC1200_SPI_CS_PORT->bsrr = (1 << AO_CC1200_SPI_CS_PIN);
1394 ao_panic(AO_PANIC_SELF_TEST_CC1200);
1397 /* Enable the EXTI interrupt for the appropriate pin */
1398 ao_enable_port(AO_CC1200_INT_PORT);
1399 ao_exti_setup(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN,
1400 AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH,
1403 ao_cmd_register(&ao_radio_cmds[0]);