*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
#include <ao_exti.h>
#include <ao_fec.h>
#include <ao_packet.h>
-
-#define AO_RADIO_MAX_RECV sizeof(struct ao_packet)
-#define AO_RADIO_MAX_SEND sizeof(struct ao_packet)
+#if HAS_PAD
+#include <ao_pad.h>
+#endif
static uint8_t ao_radio_mutex;
static uint8_t ao_radio_wake; /* radio ready. Also used as sleep address */
static uint8_t ao_radio_abort; /* radio operation should abort */
-static uint8_t ao_radio_mcu_wake; /* MARC status change */
-static uint8_t ao_radio_marc_status; /* Last read MARC status value */
-static uint8_t ao_radio_tx_finished; /* MARC status indicates TX finished */
int8_t ao_radio_rssi; /* Last received RSSI value */
-#define CC1200_DEBUG 1
-#define CC1200_TRACE 1
+#ifndef CC1200_DEBUG
+#define CC1200_DEBUG 0
+#endif
+
+#ifndef CC1200_LOW_LEVEL_DEBUG
+#define CC1200_LOW_LEVEL_DEBUG 0
+#endif
+
+#define CC1200_TRACE 0
+#define CC1200_APRS_TRACE 0
extern const uint32_t ao_radio_cal;
-#define FOSC 32000000
+#ifdef AO_CC1200_FOSC
+#define FOSC AO_CC1200_FOSC
+#else
+#define FOSC 40000000
+#endif
-#define ao_radio_try_select(task_id) ao_spi_try_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_125kHz, task_id)
-#define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_125kHz)
+#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)
#define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS)
-#define ao_radio_spi_send_sync(d,l) ao_spi_send_sync((d), (l), AO_CC1200_SPI_BUS)
#define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1200_SPI_BUS)
#define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS)
#define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1200_SPI_BUS)
return in;
}
-#if 0
static uint8_t
ao_radio_fifo_read(uint8_t *data, uint8_t len)
{
ao_radio_deselect();
return status;
}
-#endif
static uint8_t
ao_radio_fifo_write_start(void)
}
static uint8_t
-ao_radio_fifo_write(uint8_t *data, uint8_t len)
+ao_radio_fifo_write(const uint8_t *data, uint8_t len)
{
uint8_t status = ao_radio_fifo_write_start();
ao_radio_spi_send(data, len);
}
static uint8_t
-ao_radio_tx_fifo_space(void)
+ao_radio_int_pin(void)
{
- return CC1200_FIFO_SIZE - ao_radio_reg_read(CC1200_NUM_TXBYTES);
+ return ao_gpio_get(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_CC1200_INT);
}
-#if CC1200_DEBUG || CC1200_TRACE
static uint8_t
ao_radio_status(void)
{
return ao_radio_strobe (CC1200_SNOP);
}
-#endif
void
ao_radio_recv_abort(void)
#define ao_radio_rdf_value 0x55
-static uint8_t
-ao_radio_get_marc_status(void)
-{
- return ao_radio_reg_read(CC1200_MARC_STATUS1);
-}
-
-static void
-ao_radio_check_marc_status(void)
-{
- ao_radio_mcu_wake = 0;
- ao_radio_marc_status = ao_radio_get_marc_status();
-
- /* Anyt other than 'tx/rx finished' means an error occurred */
- if (ao_radio_marc_status & ~(CC1200_MARC_STATUS1_TX_FINISHED|CC1200_MARC_STATUS1_RX_FINISHED))
- ao_radio_abort = 1;
- if (ao_radio_marc_status & (CC1200_MARC_STATUS1_TX_FINISHED))
- ao_radio_tx_finished = 1;
-}
-
static void
ao_radio_isr(void)
{
static void
ao_radio_start_tx(void)
{
- ao_exti_set_callback(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, ao_radio_isr);
ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
- ao_radio_tx_finished = 0;
ao_radio_strobe(CC1200_STX);
}
+static void
+ao_radio_start_rx(void)
+{
+ ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
+ ao_radio_strobe(CC1200_SRX);
+}
+
static void
ao_radio_idle(void)
{
if (state == CC1200_STATUS_STATE_RX_FIFO_ERROR)
ao_radio_strobe(CC1200_SFRX);
}
- /* Flush any pending TX bytes */
+ /* Flush any pending data in the fifos */
ao_radio_strobe(CC1200_SFTX);
+ ao_radio_strobe(CC1200_SFRX);
+ /* Make sure the RF calibration is current */
+ ao_radio_strobe(CC1200_SCAL);
}
/*
* Packet deviation
*
- * fdev = fosc >> 24 * (256 + dev_m) << dev_e
+ * fdev = fosc >> 22 * (256 + dev_m) << dev_e
*
* Deviation for 38400 baud should be 20.5kHz:
*
- * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 5) = 20508Hz
+ * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 3) = 20523Hz
*
* Deviation for 9600 baud should be 5.125kHz:
*
- * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 3) = 5127Hz
+ * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 1) = 5131Hz
*
* Deviation for 2400 baud should be 1.28125kHz, but cc1111 and
* cc115l can't do that, so we'll use 1.5kHz instead:
*
- * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 1) = 1499Hz
+ * 40e6 / (2 ** 21) * (79) = 1506Hz
*/
-#define PACKET_DEV_M_384 80
-#define PACKET_DEV_E_384 5
+#define PACKET_DEV_M_384 13
+#define PACKET_DEV_E_384 3
-#define PACKET_DEV_M_96 80
-#define PACKET_DEV_E_96 3
+#define PACKET_DEV_M_96 13
+#define PACKET_DEV_E_96 1
-#define PACKET_DEV_M_24 137
-#define PACKET_DEV_E_24 1
+#define PACKET_DEV_M_24 79
+#define PACKET_DEV_E_24 0
/*
* For our packet data
*
* Symbol rate 38400 Baud:
*
- * DATARATE_M = 239914
- * DATARATE_E = 9
- * CHANBW = 79.4 (79.4)
+ * DATARATE_M = 1013008
+ * DATARATE_E = 8
+ * CHANBW = 104.16667
*
* Symbol rate 9600 Baud:
*
- * DATARATE_M = 239914
- * DATARATE_E = 7
- * CHANBW = 19.9 (round to 19.8)
+ * DATARATE_M = 1013008
+ * DATARATE_E = 6
+ * CHANBW = 26.042 (round to 19.8)
*
* Symbol rate 2400 Baud:
*
- * DATARATE_M = 239914
- * DATARATE_E = 5
+ * DATARATE_M = 1013008
+ * DATARATE_E = 4
* CHANBW = 5.0 (round to 9.5)
*/
-#define PACKET_SYMBOL_RATE_M 239914
+#if FOSC == 40000000
+#define PACKET_SYMBOL_RATE_M 1013008
+#define PACKET_SYMBOL_RATE_E_384 8
+#define PACKET_SYMBOL_RATE_E_96 6
+#define PACKET_SYMBOL_RATE_E_24 4
+#endif
+#if FOSC == 32000000
+#define PACKET_SYMBOL_RATE_M 239914
#define PACKET_SYMBOL_RATE_E_384 9
+#define PACKET_SYMBOL_RATE_E_96 7
+#define PACKET_SYMBOL_RATE_E_24 5
+#endif
/* 200 / 2 = 100 */
#define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
- (21 << CC1200_CHAN_BW_BB_CIC_DECFACT))
+ (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
-#define PACKET_SYMBOL_RATE_E_96 7
/* 200 / 10 = 20 */
#define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
- (21 << CC1200_CHAN_BW_BB_CIC_DECFACT))
+ (16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
-#define PACKET_SYMBOL_RATE_E_24 5
/* 200 / 25 = 8 */
#define PACKET_CHAN_BW_24 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
(44 << CC1200_CHAN_BW_BB_CIC_DECFACT))
static const uint16_t packet_setup[] = {
CC1200_SYMBOL_RATE1, ((PACKET_SYMBOL_RATE_M >> 8) & 0xff),
CC1200_SYMBOL_RATE0, ((PACKET_SYMBOL_RATE_M >> 0) & 0xff),
- CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
- (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
- CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
- (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
- (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
- (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
- CC1200_PKT_CFG0, ((0 << CC1200_PKT_CFG0_RESERVED7) |
- (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
- (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
- (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
- (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
+ CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
+ ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
+ (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
+ (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
+ CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
+ ((1 << CC1200_PKT_CFG1_FEC_EN) |
+ (1 << CC1200_PKT_CFG1_WHITE_DATA) |
+ (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
+ (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
+ (CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES << CC1200_PKT_CFG1_CRC_CFG) |
+ (1 << CC1200_PKT_CFG1_APPEND_STATUS)),
CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
(CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
};
CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
(CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
(PACKET_DEV_E_384 << CC1200_MODCFG_DEV_E_DEV_E)),
- CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_384 << CC1200_SYMBOL_RATE2_DATARATE_E) |
+ CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_384 << CC1200_SYMBOL_RATE2_DATARATE_E) |
(((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
CC1200_CHAN_BW, PACKET_CHAN_BW_384,
- CC1200_PA_CFG0, 0x7b,
+ CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
+ ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
+ (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
+ (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
+ (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
};
static const uint16_t packet_setup_96[] = {
CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
(CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
(PACKET_DEV_E_96 << CC1200_MODCFG_DEV_E_DEV_E)),
- CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) |
+ CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) |
(((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
CC1200_CHAN_BW, PACKET_CHAN_BW_96,
- CC1200_PA_CFG0, 0x7d,
+ CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
+ ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
+ (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
+ (CC1200_MDMCFG2_UPSAMPLER_P_32 << CC1200_MDMCFG2_UPSAMPLER_P) |
+ (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
};
static const uint16_t packet_setup_24[] = {
CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
(CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
(PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)),
- CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) |
+ CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) |
(((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
CC1200_CHAN_BW, PACKET_CHAN_BW_24,
- CC1200_PA_CFG0, 0x7e,
-};
-
-static const uint16_t packet_tx_setup[] = {
- CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
- (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
- AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_RX0TX1_CFG,
-};
-
-static const uint16_t packet_rx_setup[] = {
- CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
- (CC1200_PKT_CFG2_PKT_FORMAT_SYNCHRONOUS_SERIAL << CC1200_PKT_CFG2_PKT_FORMAT)),
- AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_CLKEN_SOFT,
+ CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
+ ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
+ (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
+ (CC1200_MDMCFG2_UPSAMPLER_P_64 << CC1200_MDMCFG2_UPSAMPLER_P) |
+ (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
};
/*
- * RDF deviation is 5kHz
+ * RDF deviation is 3kHz
*
- * fdev = fosc >> 24 * (256 + dev_m) << dev_e
+ * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
+ * fdev = fosc >> 21 * dev_m dev_e == 0
*
- * 32e6Hz / (2 ** 24) * (256 + 71) * (2 ** 3) = 4989
+ * 40e6 / (2 ** 21) * 157 = 2995Hz
*/
-#define RDF_DEV_E 3
-#define RDF_DEV_M 71
+#define RDF_DEV_E 0
+#define RDF_DEV_M 157
/*
* For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone)
* Rdata = -------------------------------------- * fosc
* 2 ** 39
*
- * DATARATE_M = 25166
- * DATARATE_E = 5
+ * DATARATE_M = 669411
+ * DATARATE_E = 4
*
* To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes
*/
-#define RDF_SYMBOL_RATE_E 5
-#define RDF_SYMBOL_RATE_M 25166
+#define RDF_SYMBOL_RATE_E 4
+#define RDF_SYMBOL_RATE_M 669411
#define RDF_PACKET_LEN 50
static const uint16_t rdf_setup[] = {
CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
(CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
(RDF_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
- CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
+ CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
(((RDF_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
- CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff),
- CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff),
- CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
- (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
- CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
- (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
- (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
- (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
- CC1200_PKT_CFG0, ((0 << CC1200_PKT_CFG0_RESERVED7) |
- (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
- (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
- (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
- (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
- CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
- (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
- CC1200_PA_CFG0, 0x7e,
+ CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff),
+ CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff),
+ CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
+ ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
+ (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
+ (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
+ CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
+ ((0 << CC1200_PKT_CFG1_FEC_EN) |
+ (0 << CC1200_PKT_CFG1_WHITE_DATA) |
+ (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
+ (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
+ (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
+ (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
+ CC1200_PREAMBLE_CFG1,
+ ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
+ (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
+ CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
+ ((0 << CC1200_MDMCFG2_ASK_SHAPE) |
+ (0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
+ (12 << CC1200_MDMCFG2_UPSAMPLER_P) |
+ (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
};
/*
* APRS deviation is 3kHz
*
- * fdev = fosc >> 24 * (256 + dev_m) << dev_e
+ * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0
+ * fdev = fosc >> 21 * dev_m dev_e == 0
*
- * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 2) = 2998Hz
+ * 40e6 / (2 ** 21) * 157 = 2995Hz
*/
-#define APRS_DEV_E 2
-#define APRS_DEV_M 137
+#define APRS_DEV_E 0
+#define APRS_DEV_M 157
/*
* For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate)
* Rdata = -------------------------------------- * fosc
* 2 ** 39
*
- * DATARATE_M = 239914
- * DATARATE_E = 7
+ * DATARATE_M = 1013008
+ * DATARATE_E = 6
*
* Rdata = 9599.998593330383301
*
*/
-#define APRS_SYMBOL_RATE_E 7
-#define APRS_SYMBOL_RATE_M 239914
+#define APRS_SYMBOL_RATE_E 6
+#define APRS_SYMBOL_RATE_M 1013008
+#define APRS_BUFFER_SIZE 64
static const uint16_t aprs_setup[] = {
CC1200_DEVIATION_M, APRS_DEV_M,
CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) |
(CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) |
(APRS_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)),
- CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
+ CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) |
(((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)),
- CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
- CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
- CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
- (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
- CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) |
- (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
- (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
- (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
- CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
- (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
- CC1200_PA_CFG0, 0x7d,
+ CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff),
+ CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff),
+ CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */
+ ((0 << CC1200_PKT_CFG2_FG_MODE_EN) |
+ (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) |
+ (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)),
+ CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */
+ ((0 << CC1200_PKT_CFG1_FEC_EN) |
+ (0 << CC1200_PKT_CFG1_WHITE_DATA) |
+ (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) |
+ (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) |
+ (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) |
+ (0 << CC1200_PKT_CFG1_APPEND_STATUS)),
+ CC1200_PKT_CFG0, /* Packet Configuration Reg. 0 */
+ ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) |
+ (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) |
+ (0 << CC1200_PKT_CFG0_UART_MODE_EN) |
+ (0 << CC1200_PKT_CFG0_UART_SWAP_EN)),
+ CC1200_PREAMBLE_CFG1,
+ ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) |
+ (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
+ CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */
+ ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) |
+ (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
+ (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
+ (0 << CC1200_MDMCFG2_CFM_DATA_EN)),
+ CC1200_FIFO_CFG,
+ ((0 << CC1200_FIFO_CFG_CRC_AUTOFLUSH) |
+ (APRS_BUFFER_SIZE << CC1200_FIFO_CFG_FIFO_THR)),
};
/*
(CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)),
};
-#define AO_PKT_CFG0_INFINITE ((0 << CC1200_PKT_CFG0_RESERVED7) | \
- (CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
+#define AO_PKT_CFG0_INFINITE ((CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
(0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
(0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
(0 << CC1200_PKT_CFG0_UART_SWAP_EN))
-#define AO_PKT_CFG0_FIXED ((0 << CC1200_PKT_CFG0_RESERVED7) | \
- (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
+#define AO_PKT_CFG0_FIXED ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \
(0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \
(0 << CC1200_PKT_CFG0_UART_MODE_EN) | \
(0 << CC1200_PKT_CFG0_UART_SWAP_EN))
static uint16_t ao_radio_mode;
#define AO_RADIO_MODE_BITS_PACKET 1
-#define AO_RADIO_MODE_BITS_PACKET_TX 2
#define AO_RADIO_MODE_BITS_TX_BUF 4
#define AO_RADIO_MODE_BITS_TX_FINISH 8
-#define AO_RADIO_MODE_BITS_PACKET_RX 16
+#define AO_RADIO_MODE_BITS_RX 16
#define AO_RADIO_MODE_BITS_RDF 32
#define AO_RADIO_MODE_BITS_APRS 64
#define AO_RADIO_MODE_BITS_TEST 128
#define AO_RADIO_MODE_BITS_FIXED 512
#define AO_RADIO_MODE_NONE 0
-#define AO_RADIO_MODE_PACKET_TX_BUF (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_BUF)
-#define AO_RADIO_MODE_PACKET_TX_FINISH (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_FINISH)
-#define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_RX)
-#define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_TX_FINISH)
-#define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
-#define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF)
-#define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
-#define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
+#define AO_RADIO_MODE_PACKET_TX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
+#define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_RX)
+#define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
+#define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
+#define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF)
+#define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH)
+#define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
static void
_ao_radio_set_regs(const uint16_t *regs, int nreg)
}
}
- if (changes & AO_RADIO_MODE_BITS_PACKET_TX)
- ao_radio_set_regs(packet_tx_setup);
-
- if (changes & AO_RADIO_MODE_BITS_TX_BUF)
+ if (changes & AO_RADIO_MODE_BITS_TX_BUF) {
ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR);
+ ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
+ }
- if (changes & AO_RADIO_MODE_BITS_TX_FINISH)
- ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_RX0TX1_CFG);
+ if (changes & AO_RADIO_MODE_BITS_TX_FINISH) {
+ ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX);
+ ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
+ }
- if (changes & AO_RADIO_MODE_BITS_PACKET_RX)
- ao_radio_set_regs(packet_rx_setup);
+ if (changes & AO_RADIO_MODE_BITS_RX) {
+ ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP);
+ ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH);
+ }
if (changes & AO_RADIO_MODE_BITS_RDF)
ao_radio_set_regs(rdf_setup);
static void
ao_radio_setup(void)
{
-// ao_radio_strobe(CC1200_SRES);
+ ao_radio_strobe(CC1200_SRES);
ao_radio_set_regs(radio_setup);
ao_radio_mode = 0;
+ ao_radio_idle();
+
ao_config_get();
ao_radio_configured = 1;
ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8);
ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting);
last_radio_setting = ao_config.radio_setting;
+ ao_radio_strobe(CC1200_SCAL);
}
if (ao_config.radio_rate != last_radio_rate) {
ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET;
#define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
+static inline uint8_t
+ao_radio_state(void)
+{
+ return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK;
+}
+
+#if CC1200_DEBUG
+void
+ao_radio_show_state(char *where)
+{
+ printf("%s: state %d len %d rxbytes %d\n",
+ where, ao_radio_state(),
+ ao_radio_reg_read(CC1200_PKT_LEN),
+ ao_radio_reg_read(CC1200_NUM_RXBYTES));
+}
+#else
+#define ao_radio_show_state(where)
+#endif
+
+/* Wait for the radio to signal an interrupt
+ */
+static void
+ao_radio_wait_isr(uint16_t timeout)
+{
+ ao_arch_block_interrupts();
+ while (!ao_radio_wake && !ao_radio_abort)
+ if (ao_sleep_for(&ao_radio_wake, timeout))
+ ao_radio_abort = 1;
+ ao_arch_release_interrupts();
+}
+
static void
ao_rdf_start(uint8_t len)
{
ao_radio_set_mode(AO_RADIO_MODE_RDF);
ao_radio_wake = 0;
-
}
static void
-ao_rdf_run(void)
+ao_radio_run(void)
{
+ ao_radio_wake = 0;
+ ao_radio_abort = 0;
ao_radio_start_tx();
-
- ao_arch_block_interrupts();
- while (!ao_radio_wake && !ao_radio_abort && !ao_radio_mcu_wake)
- ao_sleep(&ao_radio_wake);
- ao_arch_release_interrupts();
- if (ao_radio_mcu_wake)
- ao_radio_check_marc_status();
+ ao_radio_wait_isr(0);
if (!ao_radio_wake)
ao_radio_idle();
ao_radio_put();
ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
- ao_rdf_run();
+ ao_radio_run();
}
void
ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
status = ao_radio_fifo_write_stop(status);
(void) status;
- ao_rdf_run();
+ ao_radio_run();
}
void
ao_wakeup(&ao_radio_wake);
}
-static void
-ao_radio_test_cmd(void)
+static uint8_t radio_on;
+
+void
+ao_radio_test_on(void)
{
- uint8_t mode = 2;
- static uint8_t radio_on;
- ao_cmd_white();
- if (ao_cmd_lex_c != '\n') {
- ao_cmd_decimal();
- mode = (uint8_t) ao_cmd_lex_u32;
- }
- mode++;
- if ((mode & 2) && !radio_on) {
+ if (!radio_on) {
#if HAS_MONITOR
ao_monitor_disable();
#endif
#if PACKET_HAS_SLAVE
ao_packet_slave_stop();
+#endif
+#if HAS_PAD
+ ao_pad_disable();
#endif
ao_radio_get(0xff);
ao_radio_set_mode(AO_RADIO_MODE_TEST);
#endif
radio_on = 1;
}
- if (mode == 3) {
- printf ("Hit a character to stop..."); flush();
- getchar();
- putchar('\n');
- }
- if ((mode & 1) && radio_on) {
+}
+
+void
+ao_radio_test_off(void)
+{
+ if (radio_on) {
ao_radio_idle();
ao_radio_put();
radio_on = 0;
#if HAS_MONITOR
ao_monitor_enable();
+#endif
+#if HAS_PAD
+ ao_pad_enable();
#endif
}
}
static void
-ao_radio_wait_isr(uint16_t timeout)
+ao_radio_test_cmd(void)
{
- if (timeout)
- ao_alarm(timeout);
- ao_arch_block_interrupts();
- while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort)
- if (ao_sleep(&ao_radio_wake))
- ao_radio_abort = 1;
- ao_arch_release_interrupts();
- if (timeout)
- ao_clear_alarm();
- if (ao_radio_mcu_wake)
- ao_radio_check_marc_status();
+ uint8_t mode = 2;
+ ao_cmd_white();
+ if (ao_cmd_lex_c != '\n') {
+ ao_cmd_decimal();
+ mode = (uint8_t) ao_cmd_lex_u32;
+ }
+ mode++;
+ if ((mode & 2))
+ ao_radio_test_on();
+ if (mode == 3) {
+ printf ("Hit a character to stop..."); flush();
+ getchar();
+ putchar('\n');
+ }
+ if ((mode & 1))
+ ao_radio_test_off();
}
void
ao_radio_send(const void *d, uint8_t size)
{
- (void) d;
- (void) size;
-}
+ ao_radio_get(size);
+ ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX);
+
+ ao_radio_fifo_write(d, size);
-#define AO_RADIO_LOTS 64
+ ao_radio_run();
+}
void
ao_radio_send_aprs(ao_radio_fill_func fill)
{
- uint8_t buf[AO_RADIO_LOTS], *b;
+ uint8_t buf[APRS_BUFFER_SIZE];
int cnt;
int total = 0;
uint8_t done = 0;
uint8_t started = 0;
- uint8_t fifo_space;
+ ao_radio_abort = 0;
ao_radio_get(0xff);
- fifo_space = CC1200_FIFO_SIZE;
- while (!done) {
+ ao_radio_wake = 0;
+ while (!done && !ao_radio_abort) {
cnt = (*fill)(buf, sizeof(buf));
if (cnt < 0) {
done = 1;
if (done)
ao_radio_set_len(total & 0xff);
- b = buf;
- while (cnt) {
- uint8_t this_len = cnt;
-
- /* Wait for some space in the fifo */
- while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) {
- ao_radio_wake = 0;
- ao_radio_wait_isr(0);
- }
- if (ao_radio_abort)
- break;
- if (this_len > fifo_space)
- this_len = fifo_space;
-
- cnt -= this_len;
-
- if (done) {
- if (cnt)
- ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF);
- else
- ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
- } else
- ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
-
- ao_radio_fifo_write(b, this_len);
- b += this_len;
-
- if (!started) {
- ao_radio_start_tx();
- started = 1;
- } else
- ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
+ /* Wait for some space in the fifo */
+ while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) {
+ ao_radio_wake = 0;
+ ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
+ ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
}
- if (ao_radio_abort) {
- ao_radio_idle();
+ if (ao_radio_abort)
break;
+
+ if (done)
+ ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH);
+ else
+ ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF);
+
+ ao_radio_fifo_write(buf, cnt);
+ if (!started) {
+ ao_radio_strobe(CC1200_STX);
+ started = 1;
}
- /* Wait for the transmitter to go idle */
+ }
+ /* Wait for the transmitter to go idle */
+ while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) {
ao_radio_wake = 0;
- ao_radio_wait_isr(0);
+ ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN);
+ ao_radio_wait_isr(AO_MS_TO_TICKS(1000));
}
+ if (ao_radio_abort)
+ ao_radio_idle();
ao_radio_put();
}
+#if 0
+static uint8_t
+ao_radio_marc_state(void)
+{
+ return ao_radio_reg_read(CC1200_MARCSTATE);
+}
+
+static uint8_t
+ao_radio_modem_status1(void)
+{
+ return ao_radio_reg_read(CC1200_MODEM_STATUS1);
+}
+
+static uint8_t
+ao_radio_modem_status0(void)
+{
+ return ao_radio_reg_read(CC1200_MODEM_STATUS0);
+}
+
+struct ao_radio_state {
+ char where[4];
+ uint8_t marc_state;
+ uint8_t marc_status1;
+ uint8_t marc_status0;
+ uint8_t modem_status1;
+ uint8_t modem_status0;
+};
+
+static void
+ao_radio_fill_state(char *where, struct ao_radio_state *s)
+{
+ strcpy(s->where, where);
+ s->marc_state = ao_radio_marc_state();
+ s->marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
+ s->marc_status0 = ao_radio_reg_read(CC1200_MARC_STATUS0);
+ s->modem_status1 = ao_radio_modem_status1();
+ s->modem_status0 = ao_radio_modem_status0();
+}
+
+static void
+ao_radio_dump_state(struct ao_radio_state *s)
+{
+ printf ("%s: marc %2x marc1 %2x marc0 %2x modem1 %2x modem0 %2x\n",
+ s->where, s->marc_state, s->marc_status1, s->marc_status0, s->modem_status1, s->modem_status0);
+}
+#endif
+
uint8_t
ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
{
- (void) d;
- (void) size;
- (void) timeout;
- return 0;
+ uint8_t success = 0;
+
+ ao_radio_abort = 0;
+ ao_radio_get(size - 2);
+ ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
+ ao_radio_wake = 0;
+ ao_radio_start_rx();
+
+ while (!ao_radio_abort) {
+ ao_radio_wait_isr(timeout);
+ if (ao_radio_wake) {
+ uint8_t marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1);
+
+ /* Check the receiver status to see what happened
+ */
+ switch (marc_status1) {
+ case CC1200_MARC_STATUS1_RX_FINISHED:
+ case CC1200_MARC_STATUS1_ADDRESS:
+ case CC1200_MARC_STATUS1_CRC:
+ /* Normal return, go fetch the bytes from the FIFO
+ * and give them back to the caller
+ */
+ success = 1;
+ break;
+ case CC1200_MARC_STATUS1_RX_TIMEOUT:
+ case CC1200_MARC_STATUS1_RX_TERMINATION:
+ case CC1200_MARC_STATUS1_EWOR_SYNC_LOST:
+ case CC1200_MARC_STATUS1_MAXIMUM_LENGTH:
+ case CC1200_MARC_STATUS1_RX_FIFO_OVERFLOW:
+ case CC1200_MARC_STATUS1_RX_FIFO_UNDERFLOW:
+ /* Something weird happened; reset the radio and
+ * return failure
+ */
+ success = 0;
+ break;
+ default:
+ /* some other status; go wait for the radio to do something useful
+ */
+ continue;
+ }
+ break;
+ } else {
+ uint8_t modem_status1 = ao_radio_reg_read(CC1200_MODEM_STATUS1);
+
+ /* Check to see if the packet header has been seen, in which case we'll
+ * want to keep waiting for the rest of the packet to appear
+ */
+ if (modem_status1 & (1 << CC1200_MODEM_STATUS1_SYNC_FOUND))
+ {
+ ao_radio_abort = 0;
+
+ /* Set a timeout based on the packet length so that we make sure to
+ * wait long enough to receive the whole thing.
+ *
+ * timeout = bits * FEC expansion / rate
+ */
+ switch (ao_config.radio_rate) {
+ default:
+ case AO_RADIO_RATE_38400:
+ timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 384) + 1;
+ break;
+ case AO_RADIO_RATE_9600:
+ timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 96) + 1;
+ break;
+ case AO_RADIO_RATE_2400:
+ timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 24) + 1;
+ break;
+ }
+ }
+ }
+ }
+
+ if (success) {
+ int8_t rssi;
+ uint8_t status;
+
+ status = ao_radio_fifo_read(d, size);
+ (void) status;
+ rssi = ((int8_t *) d)[size - 2];
+ ao_radio_rssi = rssi;
+
+ /* Bound it to the representable range */
+ if (rssi > -11)
+ rssi = -11;
+
+ /* Write it back to the packet */
+ ((int8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi);
+ } else {
+ ao_radio_idle();
+ ao_radio_rssi = 0;
+ }
+
+ ao_radio_put();
+ return success;
}
{ .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
{ .addr = CC1200_IQIC, .name = "IQIC" },
{ .addr = CC1200_CHAN_BW, .name = "CHAN_BW" },
+ { .addr = CC1200_MDMCFG2, .name = "MDMCFG2" },
{ .addr = CC1200_MDMCFG1, .name = "MDMCFG1" },
{ .addr = CC1200_MDMCFG0, .name = "MDMCFG0" },
{ .addr = CC1200_SYMBOL_RATE2, .name = "SYMBOL_RATE2" },
{ .addr = CC1200_PARTNUMBER, .name = "PARTNUMBER" },
{ .addr = CC1200_PARTVERSION, .name = "PARTVERSION" },
{ .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" },
- { .addr = CC1200_RX_STATUS, .name = "RX_STATUS" },
- { .addr = CC1200_TX_STATUS, .name = "TX_STATUS" },
+ { .addr = CC1200_MODEM_STATUS1, .name = "MODEM_STATUS1" },
+ { .addr = CC1200_MODEM_STATUS0, .name = "MODEM_STATUS0" },
{ .addr = CC1200_MARC_STATUS1, .name = "MARC_STATUS1" },
{ .addr = CC1200_MARC_STATUS0, .name = "MARC_STATUS0" },
{ .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
#define AO_NUM_CC1200_REG (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0])
+static uint8_t
+ao_radio_get_marc_status(void)
+{
+ return ao_radio_reg_read(CC1200_MARC_STATUS1);
+}
+
static void ao_radio_show(void) {
- uint8_t status = ao_radio_status();
+ uint8_t status;
unsigned int i;
- ao_radio_get(0xff);
+ ao_mutex_get(&ao_radio_mutex);
status = ao_radio_status();
printf ("Status: %02x\n", status);
printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1);
printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32]));
for (b = 0; b < 32; b++)
printf (" %02x", bytes[b]);
+
+ printf (" RSSI %02x LQI %02x", bytes[32], bytes[33]);
printf ("\n");
}
}
static void
ao_radio_aprs(void)
{
+#if PACKET_HAS_SLAVE
ao_packet_slave_stop();
+#endif
ao_aprs_send();
}
#endif
#endif
+#if CC1200_LOW_LEVEL_DEBUG
static void
ao_radio_strobe_test(void)
{
data = ao_radio_reg_read(addr);
printf ("Read %04x = %02x\n", addr, data);
}
+#endif
static const struct ao_cmds ao_radio_cmds[] = {
{ ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
{ ao_radio_packet, "p\0Send a test packet" },
{ ao_radio_test_recv, "q\0Recv a test packet" },
#endif
- { ao_radio_strobe_test, "S <value>\0Strobe radio" },
+#if CC1200_LOW_LEVEL_DEBUG
+ { ao_radio_strobe_test, "A <value>\0Strobe radio" },
{ ao_radio_write_test, "W <addr> <value>\0Write radio reg" },
- { ao_radio_read_test, "R <addr>\0Read radio reg" },
+ { ao_radio_read_test, "B <addr>\0Read radio reg" },
+#endif
{ 0, NULL }
};