2 * Copyright © 2013 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_cc115l.h>
21 #include <ao_telemetry.h>
24 #define AO_RADIO_MAX_SEND sizeof (struct ao_telemetry_generic)
26 static uint8_t ao_radio_mutex;
28 static uint8_t ao_radio_wake; /* radio ready. Also used as sleep address */
29 static uint8_t ao_radio_abort; /* radio operation should abort */
30 static uint8_t ao_radio_mcu_wake; /* MARC status change */
31 static uint8_t ao_radio_marcstate; /* Last read MARC state value */
33 #define CC115L_DEBUG 1
34 #define CC115L_TRACE 1
38 #define ao_radio_select() ao_spi_get_mask(AO_CC115L_SPI_CS_PORT,(1 << AO_CC115L_SPI_CS_PIN),AO_CC115L_SPI_BUS,AO_SPI_SPEED_1MHz)
39 #define ao_radio_deselect() ao_spi_put_mask(AO_CC115L_SPI_CS_PORT,(1 << AO_CC115L_SPI_CS_PIN),AO_CC115L_SPI_BUS)
40 #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC115L_SPI_BUS)
41 #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC115L_SPI_BUS)
42 #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC115L_SPI_BUS)
43 #define ao_radio_duplex(o,i,l) ao_spi_duplex((o), (i), (l), AO_CC115L_SPI_BUS)
46 ao_radio_reg_read(uint16_t addr)
52 printf("\t\tao_radio_reg_read (%04x): ", addr); flush();
54 data[0] = ((1 << CC115L_READ) |
58 ao_radio_spi_send(data, 1);
59 ao_radio_spi_recv(data, 1);
62 printf (" %02x\n", data[0]);
68 ao_radio_reg_write(uint16_t addr, uint8_t value)
74 printf("\t\tao_radio_reg_write (%04x): %02x\n", addr, value);
76 data[0] = ((0 << CC115L_READ) |
81 ao_radio_spi_send(data, 2);
86 ao_radio_burst_read_start (uint16_t addr)
91 data[0] = ((1 << CC115L_READ) |
95 ao_radio_spi_send(data, 1);
99 ao_radio_burst_read_stop (void)
106 ao_radio_strobe(uint8_t addr)
111 printf("\t\tao_radio_strobe (%02x): ", addr); flush();
114 ao_radio_duplex(&addr, &in, 1);
117 printf("%02x\n", in); flush();
123 ao_radio_fifo_write_start(void)
125 uint8_t addr = ((0 << CC115L_READ) |
126 (1 << CC115L_BURST) |
131 ao_radio_duplex(&addr, &status, 1);
135 static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) {
141 ao_radio_fifo_write(uint8_t *data, uint8_t len)
143 uint8_t status = ao_radio_fifo_write_start();
145 printf ("fifo_write %d\n", len);
147 ao_radio_spi_send(data, len);
148 return ao_radio_fifo_write_stop(status);
152 ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
154 uint8_t status = ao_radio_fifo_write_start();
157 printf ("fifo_write_fixed %02x %d\n", data, len);
159 ao_radio_spi_send_fixed(data, len);
160 return ao_radio_fifo_write_stop(status);
164 ao_radio_tx_fifo_space(void)
166 return CC115L_FIFO_SIZE - (ao_radio_reg_read(CC115L_TXBYTES) & CC115L_TXBYTES_NUM_TX_BYTES_MASK);
170 ao_radio_status(void)
172 return ao_radio_strobe (CC115L_SNOP);
175 #define ao_radio_rdf_value 0x55
178 ao_radio_get_marcstate(void)
180 return ao_radio_reg_read(CC115L_MARCSTATE) & CC115L_MARCSTATE_MASK;
184 ao_radio_mcu_wakeup_isr(void)
186 ao_radio_mcu_wake = 1;
187 ao_wakeup(&ao_radio_wake);
192 ao_radio_check_marcstate(void)
194 ao_radio_mcu_wake = 0;
195 ao_radio_marcstate = ao_radio_get_marcstate();
197 /* Anyt other than 'tx finished' means an error occurred */
198 if (ao_radio_marcstate != CC115L_MARCSTATE_TX_END)
205 ao_exti_disable(AO_CC115L_INT_PORT, AO_CC115L_INT_PIN);
207 ao_wakeup(&ao_radio_wake);
211 ao_radio_start_tx(void)
214 ao_exti_set_callback(AO_CC115L_INT_PORT, AO_CC115L_INT_PIN, ao_radio_isr);
215 ao_exti_enable(AO_CC115L_INT_PORT, AO_CC115L_INT_PIN);
216 ao_exti_enable(AO_CC115L_MCU_WAKEUP_PORT, AO_CC115L_MCU_WAKEUP_PIN);
217 ao_radio_strobe(CC115L_STX);
225 uint8_t state = ao_radio_strobe(CC115L_SIDLE);
226 if ((state >> CC115L_STATUS_STATE) == CC115L_STATUS_STATE_IDLE)
229 /* Flush any pending TX bytes */
230 ao_radio_strobe(CC115L_SFTX);
234 * Packet deviation is 20.5kHz
236 * fdev = fosc >> 17 * (8 + dev_m) << dev_e
238 * 26e6 / (2 ** 17) * (8 + 5) * (2 ** 3) = 20630Hz
241 #define PACKET_DEV_E 3
242 #define PACKET_DEV_M 5
245 * For our packet data, set the symbol rate to 38400 Baud
247 * (256 + DATARATE_M) * 2 ** DATARATE_E
248 * Rdata = -------------------------------------- * fosc
251 * (256 + 131) * (2 ** 10) / (2**28) * 26e6 = 38383
256 #define PACKET_DRATE_E 10
257 #define PACKET_DRATE_M 131
259 static const uint16_t packet_setup[] = {
260 CC115L_DEVIATN, ((PACKET_DEV_E << CC115L_DEVIATN_DEVIATION_E) |
261 (PACKET_DEV_M << CC115L_DEVIATN_DEVIATION_M)),
262 CC115L_MDMCFG4, ((0xf << 4) |
263 (PACKET_DRATE_E << CC115L_MDMCFG4_DRATE_E)),
264 CC115L_MDMCFG3, (PACKET_DRATE_M),
269 * RDF deviation is 5kHz
271 * fdev = fosc >> 17 * (8 + dev_m) << dev_e
273 * 26e6 / (2 ** 17) * (8 + 4) * (2 ** 1) = 4761Hz
280 * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone)
282 * (256 + DATARATE_M) * 2 ** DATARATE_E
283 * Rdata = -------------------------------------- * fosc
286 * (256 + 67) * (2 ** 6) / (2**28) * 26e6 = 2002
291 * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes
293 #define RDF_DRATE_E 6
294 #define RDF_DRATE_M 67
295 #define RDF_PACKET_LEN 50
297 static const uint16_t rdf_setup[] = {
298 CC115L_DEVIATN, ((RDF_DEV_E << CC115L_DEVIATN_DEVIATION_E) |
299 (RDF_DEV_M << CC115L_DEVIATN_DEVIATION_M)),
300 CC115L_MDMCFG4, ((0xf << 4) |
301 (RDF_DRATE_E << CC115L_MDMCFG4_DRATE_E)),
302 CC115L_MDMCFG3, (RDF_DRATE_M),
306 * APRS deviation is the same as RDF
309 #define APRS_DEV_E RDF_DEV_E
310 #define APRS_DEV_M RDF_DEV_E
313 * For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate)
315 * (256 + DATARATE_M) * 2 ** DATARATE_E
316 * Rdata = -------------------------------------- * fosc
319 * (256 + 131) * (2 ** 8) / (2**28) * 26e6 = 9596
325 #define APRS_DRATE_E 8
326 #define APRS_DRATE_M 131
328 static const uint16_t aprs_setup[] = {
329 CC115L_DEVIATN, ((APRS_DEV_E << CC115L_DEVIATN_DEVIATION_E) |
330 (APRS_DEV_M << CC115L_DEVIATN_DEVIATION_M)),
331 CC115L_MDMCFG4, ((0xf << 4) |
332 (APRS_DRATE_E << CC115L_MDMCFG4_DRATE_E)),
333 CC115L_MDMCFG3, (APRS_DRATE_M),
336 #define AO_PKTCTRL0_INFINITE ((CC115L_PKTCTRL0_PKT_FORMAT_NORMAL << CC115L_PKTCTRL0_PKT_FORMAT) | \
337 (0 << CC115L_PKTCTRL0_PKT_CRC_EN) | \
338 (CC115L_PKTCTRL0_PKT_LENGTH_CONFIG_INFINITE << CC115L_PKTCTRL0_PKT_LENGTH_CONFIG))
339 #define AO_PKTCTRL0_FIXED ((CC115L_PKTCTRL0_PKT_FORMAT_NORMAL << CC115L_PKTCTRL0_PKT_FORMAT) | \
340 (0 << CC115L_PKTCTRL0_PKT_CRC_EN) | \
341 (CC115L_PKTCTRL0_PKT_LENGTH_CONFIG_FIXED << CC115L_PKTCTRL0_PKT_LENGTH_CONFIG))
343 static uint16_t ao_radio_mode;
345 #define AO_RADIO_MODE_BITS_PACKET_TX 1
346 #define AO_RADIO_MODE_BITS_TX_BUF 2
347 #define AO_RADIO_MODE_BITS_TX_FINISH 4
348 #define AO_RADIO_MODE_BITS_RDF 8
349 #define AO_RADIO_MODE_BITS_APRS 16
350 #define AO_RADIO_MODE_BITS_INFINITE 32
351 #define AO_RADIO_MODE_BITS_FIXED 64
353 #define AO_RADIO_MODE_NONE 0
354 #define AO_RADIO_MODE_PACKET_TX_BUF (AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_BUF)
355 #define AO_RADIO_MODE_PACKET_TX_FINISH (AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_FINISH)
356 #define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_TX_FINISH)
357 #define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
358 #define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF)
359 #define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
362 ao_radio_set_mode(uint16_t new_mode)
367 if (new_mode == ao_radio_mode)
370 changes = new_mode & (~ao_radio_mode);
371 if (changes & AO_RADIO_MODE_BITS_PACKET_TX)
372 for (i = 0; i < sizeof (packet_setup) / sizeof (packet_setup[0]); i += 2)
373 ao_radio_reg_write(packet_setup[i], packet_setup[i+1]);
375 if (changes & AO_RADIO_MODE_BITS_TX_BUF)
376 ao_radio_reg_write(AO_CC115L_INT_GPIO_IOCFG, CC115L_IOCFG_GPIO_CFG_TXFIFO_THR);
378 if (changes & AO_RADIO_MODE_BITS_TX_FINISH)
379 ao_radio_reg_write(AO_CC115L_INT_GPIO_IOCFG, CC115L_IOCFG_GPIO_CFG_PKT_SYNC_TX | (1 << CC115L_IOCFG_GPIO_INV));
381 if (changes & AO_RADIO_MODE_BITS_RDF)
382 for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2)
383 ao_radio_reg_write(rdf_setup[i], rdf_setup[i+1]);
385 if (changes & AO_RADIO_MODE_BITS_APRS)
386 for (i = 0; i < sizeof (aprs_setup) / sizeof (aprs_setup[0]); i += 2)
387 ao_radio_reg_write(aprs_setup[i], aprs_setup[i+1]);
389 if (changes & AO_RADIO_MODE_BITS_INFINITE)
390 ao_radio_reg_write(CC115L_PKTCTRL0, AO_PKTCTRL0_INFINITE);
392 if (changes & AO_RADIO_MODE_BITS_FIXED)
393 ao_radio_reg_write(CC115L_PKTCTRL0, AO_PKTCTRL0_FIXED);
395 ao_radio_mode = new_mode;
398 static const uint16_t radio_setup[] = {
399 #include "ao_rf_cc115l.h"
402 static uint8_t ao_radio_configured = 0;
410 ao_gpio_set(AO_CC115L_SPI_CS_PORT, AO_CC115L_SPI_CS_PIN, AO_CC115L_SPI_CS, 0);
411 for (i = 0; i < 10000; i++) {
412 if (ao_gpio_get(SPI_2_PORT, SPI_2_MISO_PIN, SPI_2_MISO) == 0) {
413 printf ("Chip clock alive\n");
417 ao_gpio_set(AO_CC115L_SPI_CS_PORT, AO_CC115L_SPI_CS_PIN, AO_CC115L_SPI_CS, 1);
419 printf ("Chip clock not alive\n");
422 ao_radio_strobe(CC115L_SRES);
423 ao_delay(AO_MS_TO_TICKS(10));
425 printf ("Part %x\n", ao_radio_reg_read(CC115L_PARTNUM));
426 printf ("Version %x\n", ao_radio_reg_read(CC115L_VERSION));
428 for (i = 0; i < sizeof (radio_setup) / sizeof (radio_setup[0]); i += 2) {
429 ao_radio_reg_write(radio_setup[i], radio_setup[i+1]);
430 ao_radio_reg_read(radio_setup[i]);
437 ao_radio_configured = 1;
441 ao_radio_set_len(uint8_t len)
443 static uint8_t last_len;
445 if (len != last_len) {
446 ao_radio_reg_write(CC115L_PKTLEN, len);
452 ao_radio_get(uint8_t len)
454 static uint32_t last_radio_setting;
456 ao_mutex_get(&ao_radio_mutex);
457 if (!ao_radio_configured)
459 if (ao_config.radio_setting != last_radio_setting) {
460 ao_radio_reg_write(CC115L_FREQ2, ao_config.radio_setting >> 16);
461 ao_radio_reg_write(CC115L_FREQ1, ao_config.radio_setting >> 8);
462 ao_radio_reg_write(CC115L_FREQ0, ao_config.radio_setting);
463 last_radio_setting = ao_config.radio_setting;
465 ao_radio_set_len(len);
468 #define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
471 ao_rdf_start(uint8_t len)
476 ao_radio_set_mode(AO_RADIO_MODE_RDF);
486 ao_arch_block_interrupts();
487 while (!ao_radio_wake && !ao_radio_abort && !ao_radio_mcu_wake)
488 ao_sleep(&ao_radio_wake);
489 ao_arch_release_interrupts();
490 if (ao_radio_mcu_wake)
491 ao_radio_check_marcstate();
501 ao_rdf_start(AO_RADIO_RDF_LEN);
503 ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
509 ao_radio_continuity(uint8_t c)
514 ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
516 status = ao_radio_fifo_write_start();
517 for (i = 0; i < 3; i++) {
518 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
520 ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
522 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
524 ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
525 status = ao_radio_fifo_write_stop(status);
531 ao_radio_rdf_abort(void)
534 ao_wakeup(&ao_radio_wake);
538 ao_radio_test_cmd(void)
541 static uint8_t radio_on;
543 if (ao_cmd_lex_c != '\n') {
545 mode = (uint8_t) ao_cmd_lex_u32;
548 if ((mode & 2) && !radio_on) {
550 ao_monitor_disable();
553 ao_packet_slave_stop();
557 ao_radio_strobe(CC115L_STX);
560 for (t = 0; t < 10; t++) {
561 printf ("status: %02x\n", ao_radio_status());
562 ao_delay(AO_MS_TO_TICKS(100));
569 printf ("Hit a character to stop..."); flush();
573 if ((mode & 1) && radio_on) {
584 ao_radio_wait_isr(void)
586 ao_arch_block_interrupts();
587 while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort)
588 ao_sleep(&ao_radio_wake);
589 ao_arch_release_interrupts();
590 if (ao_radio_mcu_wake)
591 ao_radio_check_marcstate();
595 ao_radio_wait_tx(uint8_t wait_fifo)
597 uint8_t fifo_space = 0;
603 fifo_space = ao_radio_tx_fifo_space();
604 } while (!fifo_space && !ao_radio_abort);
608 static uint8_t tx_data[(AO_RADIO_MAX_SEND + 4) * 2];
611 ao_radio_send(const void *d, uint8_t size)
614 uint8_t *e = tx_data;
620 encode_len = ao_fec_encode(d, size, tx_data);
622 ao_radio_get(encode_len);
625 fifo_space = CC115L_FIFO_SIZE;
627 this_len = encode_len;
630 if (this_len > fifo_space) {
631 this_len = fifo_space;
632 ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX_BUF);
634 ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX_FINISH);
637 ao_radio_fifo_write(e, this_len);
639 encode_len -= this_len;
645 ao_exti_enable(AO_CC115L_INT_PORT, AO_CC115L_INT_PIN);
648 fifo_space = ao_radio_wait_tx(encode_len != 0);
649 if (ao_radio_abort) {
658 #define AO_RADIO_LOTS 64
661 ao_radio_send_lots(ao_radio_fill_func fill)
663 uint8_t buf[AO_RADIO_LOTS], *b;
671 fifo_space = CC115L_FIFO_SIZE;
673 cnt = (*fill)(buf, sizeof(buf));
680 /* At the last buffer, set the total length */
682 ao_radio_set_len(total & 0xff);
686 uint8_t this_len = cnt;
688 /* Wait for some space in the fifo */
689 while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) {
695 if (this_len > fifo_space)
696 this_len = fifo_space;
702 ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF);
704 ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
706 ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
708 ao_radio_fifo_write(b, this_len);
715 ao_exti_enable(AO_CC115L_INT_PORT, AO_CC115L_INT_PIN);
717 if (ao_radio_abort) {
721 /* Wait for the transmitter to go idle */
729 static char *cc115l_state_name[] = {
730 [CC115L_STATUS_STATE_IDLE] = "IDLE",
731 [CC115L_STATUS_STATE_TX] = "TX",
732 [CC115L_STATUS_STATE_FSTXON] = "FSTXON",
733 [CC115L_STATUS_STATE_CALIBRATE] = "CALIBRATE",
734 [CC115L_STATUS_STATE_SETTLING] = "SETTLING",
735 [CC115L_STATUS_STATE_TX_FIFO_UNDERFLOW] = "TX_FIFO_UNDERFLOW",
738 struct ao_cc115l_reg {
743 const static struct ao_cc115l_reg ao_cc115l_reg[] = {
744 { .addr = CC115L_IOCFG2, .name = "IOCFG2" },
745 { .addr = CC115L_IOCFG1, .name = "IOCFG1" },
746 { .addr = CC115L_IOCFG0, .name = "IOCFG0" },
747 { .addr = CC115L_FIFOTHR, .name = "FIFOTHR" },
748 { .addr = CC115L_SYNC1, .name = "SYNC1" },
749 { .addr = CC115L_SYNC0, .name = "SYNC0" },
750 { .addr = CC115L_PKTLEN, .name = "PKTLEN" },
751 { .addr = CC115L_PKTCTRL0, .name = "PKTCTRL0" },
752 { .addr = CC115L_CHANNR, .name = "CHANNR" },
753 { .addr = CC115L_FSCTRL0, .name = "FSCTRL0" },
754 { .addr = CC115L_FREQ2, .name = "FREQ2" },
755 { .addr = CC115L_FREQ1, .name = "FREQ1" },
756 { .addr = CC115L_FREQ0, .name = "FREQ0" },
757 { .addr = CC115L_MDMCFG4, .name = "MDMCFG4" },
758 { .addr = CC115L_MDMCFG3, .name = "MDMCFG3" },
759 { .addr = CC115L_MDMCFG2, .name = "MDMCFG2" },
760 { .addr = CC115L_MDMCFG1, .name = "MDMCFG1" },
761 { .addr = CC115L_MDMCFG0, .name = "MDMCFG0" },
762 { .addr = CC115L_DEVIATN, .name = "DEVIATN" },
763 { .addr = CC115L_MCSM1, .name = "MCSM1" },
764 { .addr = CC115L_MCSM0, .name = "MCSM0" },
765 { .addr = CC115L_RESERVED_0X20, .name = "RESERVED_0X20" },
766 { .addr = CC115L_FREND0, .name = "FREND0" },
767 { .addr = CC115L_FSCAL3, .name = "FSCAL3" },
768 { .addr = CC115L_FSCAL2, .name = "FSCAL2" },
769 { .addr = CC115L_FSCAL1, .name = "FSCAL1" },
770 { .addr = CC115L_FSCAL0, .name = "FSCAL0" },
771 { .addr = CC115L_RESERVED_0X29, .name = "RESERVED_0X29" },
772 { .addr = CC115L_RESERVED_0X2A, .name = "RESERVED_0X2A" },
773 { .addr = CC115L_RESERVED_0X2B, .name = "RESERVED_0X2B" },
774 { .addr = CC115L_TEST2, .name = "TEST2" },
775 { .addr = CC115L_TEST1, .name = "TEST1" },
776 { .addr = CC115L_TEST0, .name = "TEST0" },
777 { .addr = CC115L_PARTNUM, .name = "PARTNUM" },
778 { .addr = CC115L_VERSION, .name = "VERSION" },
779 { .addr = CC115L_MARCSTATE, .name = "MARCSTATE" },
780 { .addr = CC115L_PKTSTATUS, .name = "PKTSTATUS" },
781 { .addr = CC115L_TXBYTES, .name = "TXBYTES" },
782 { .addr = CC115L_PA, .name = "PA" },
785 #define AO_NUM_CC115L_REG (sizeof ao_cc115l_reg / sizeof ao_cc115l_reg[0])
787 static void ao_radio_show(void) {
788 uint8_t status = ao_radio_status();
792 status = ao_radio_status();
793 printf ("Status: %02x\n", status);
794 printf ("CHIP_RDY: %d\n", (status >> CC115L_STATUS_CHIP_RDY) & 1);
795 printf ("STATE: %s\n", cc115l_state_name[(status >> CC115L_STATUS_STATE) & CC115L_STATUS_STATE_MASK]);
796 printf ("MARC: %02x\n", ao_radio_get_marcstate());
798 for (i = 0; i < AO_NUM_CC115L_REG; i++)
799 printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc115l_reg[i].addr), ao_cc115l_reg[i].name);
803 static void ao_radio_beep(void) {
807 static void ao_radio_packet(void) {
808 static const uint8_t packet[] = {
810 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
811 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
812 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
813 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
819 ao_radio_send(packet, sizeof (packet));
829 ao_packet_slave_stop();
835 static const struct ao_cmds ao_radio_cmds[] = {
836 { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
839 { ao_radio_aprs, "G\0Send APRS packet" },
841 { ao_radio_show, "R\0Show CC115L status" },
842 { ao_radio_beep, "b\0Emit an RDF beacon" },
843 { ao_radio_packet, "p\0Send a test packet" },
853 ao_radio_configured = 0;
854 ao_spi_init_cs (AO_CC115L_SPI_CS_PORT, (1 << AO_CC115L_SPI_CS_PIN));
857 AO_CC115L_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC115L_SPI_CS_PIN));
858 for (i = 0; i < 10000; i++) {
859 if ((SPI_2_PORT->idr & (1 << SPI_2_MISO_PIN)) == 0)
862 AO_CC115L_SPI_CS_PORT->bsrr = (1 << AO_CC115L_SPI_CS_PIN);
864 ao_panic(AO_PANIC_SELF_TEST_CC115L);
867 /* Enable the EXTI interrupt for the appropriate pin */
868 ao_enable_port(AO_CC115L_INT_PORT);
869 ao_exti_setup(AO_CC115L_INT_PORT, AO_CC115L_INT_PIN,
870 AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH,
873 /* Enable the hacked up GPIO3 pin */
874 ao_enable_port(AO_CC115L_MCU_WAKEUP_PORT);
875 ao_exti_setup(AO_CC115L_MCU_WAKEUP_PORT, AO_CC115L_MCU_WAKEUP_PIN,
876 AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_MED,
877 ao_radio_mcu_wakeup_isr);
881 ao_cmd_register(&ao_radio_cmds[0]);