#define FOSC 32000000
+#define ao_radio_try_select(task_id) ao_spi_try_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz, task_id)
#define ao_radio_select() ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz)
#define ao_radio_deselect() ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS)
+#define ao_radio_spi_send_sync(d,l) ao_spi_send_sync((d), (l), AO_CC1120_SPI_BUS)
#define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1120_SPI_BUS)
#define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS)
#define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1120_SPI_BUS)
}
static void
-ao_radio_burst_read_start (uint16_t addr)
+_ao_radio_burst_read_start (uint16_t addr)
{
uint8_t data[2];
uint8_t d;
addr);
d = 1;
}
- ao_radio_select();
- ao_radio_spi_send(data, d);
+
+ ao_radio_spi_send_sync(data, d);
}
static void
return CC1120_FIFO_SIZE - ao_radio_reg_read(CC1120_NUM_TXBYTES);
}
-#if 0
+#if CC1120_DEBUG
static uint8_t
ao_radio_status(void)
{
ao_radio_idle(void)
{
for (;;) {
- uint8_t state = ao_radio_strobe(CC1120_SIDLE);
- if ((state >> CC1120_STATUS_STATE) == CC1120_STATUS_STATE_IDLE)
+ uint8_t state = (ao_radio_strobe(CC1120_SIDLE) >> CC1120_STATUS_STATE) & CC1120_STATUS_STATE_MASK;
+ if (state == CC1120_STATUS_STATE_IDLE)
break;
- if ((state >> CC1120_STATUS_STATE) == CC1120_STATUS_STATE_TX_FIFO_ERROR)
+ if (state == CC1120_STATUS_STATE_TX_FIFO_ERROR)
ao_radio_strobe(CC1120_SFTX);
+ if (state == CC1120_STATUS_STATE_RX_FIFO_ERROR)
+ ao_radio_strobe(CC1120_SFRX);
}
/* Flush any pending TX bytes */
ao_radio_strobe(CC1120_SFTX);
static uint16_t rx_data_cur;
static uint8_t rx_ignore;
static uint8_t rx_waiting;
+static uint8_t rx_starting;
+static uint8_t rx_task_id;
+static uint32_t rx_fast_start;
+static uint32_t rx_slow_start;
+static uint32_t rx_missed;
#if AO_PROFILE
static uint32_t rx_start_tick, rx_packet_tick, rx_done_tick, rx_last_done_tick;
{
uint8_t d;
+ if (rx_task_id) {
+ if (ao_radio_try_select(rx_task_id)) {
+ ++rx_fast_start;
+ rx_task_id = 0;
+ _ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT);
+ } else {
+ if (rx_ignore)
+ --rx_ignore;
+ else {
+ ao_radio_abort = 1;
+ rx_missed++;
+ }
+ return;
+ }
+ }
+ if (rx_starting) {
+ rx_starting = 0;
+ ao_wakeup(&ao_radio_wake);
+ }
d = AO_CC1120_SPI.dr;
AO_CC1120_SPI.dr = 0;
if (rx_ignore == 0) {
- if (rx_data_cur >= rx_data_count)
- ao_exti_disable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
- else
+ if (rx_data_cur < rx_data_count)
rx_data[rx_data_cur++] = d;
+ if (rx_data_cur >= rx_data_count) {
+ ao_spi_clr_cs(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN));
+ ao_exti_disable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
+ }
if (rx_waiting && rx_data_cur - rx_data_consumed >= AO_FEC_DECODE_BLOCK) {
#if AO_PROFILE
if (!rx_packet_tick)
static uint16_t
ao_radio_rx_wait(void)
{
- do {
- if (ao_radio_mcu_wake)
- ao_radio_check_marc_status();
- ao_alarm(AO_MS_TO_TICKS(100));
- ao_arch_block_interrupts();
- rx_waiting = 1;
- while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK &&
- !ao_radio_abort &&
- !ao_radio_mcu_wake)
- {
- if (ao_sleep(&ao_radio_wake))
- ao_radio_abort = 1;
- }
- rx_waiting = 0;
- ao_arch_release_interrupts();
- ao_clear_alarm();
- } while (ao_radio_mcu_wake);
- if (ao_radio_abort)
+ ao_alarm(AO_MS_TO_TICKS(100));
+ ao_arch_block_interrupts();
+ rx_waiting = 1;
+ while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK &&
+ !ao_radio_abort &&
+ !ao_radio_mcu_wake)
+ {
+ if (ao_sleep(&ao_radio_wake))
+ ao_radio_abort = 1;
+ }
+ rx_waiting = 0;
+ ao_arch_release_interrupts();
+ ao_clear_alarm();
+ if (ao_radio_abort || ao_radio_mcu_wake)
return 0;
rx_data_consumed += AO_FEC_DECODE_BLOCK;
#if AO_PROFILE
*/
ao_radio_abort = 0;
- /* configure interrupt pin */
ao_radio_get(len);
- ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
ao_radio_wake = 0;
ao_radio_mcu_wake = 0;
- AO_CC1120_SPI.cr2 = 0;
-
- /* clear any RXNE */
- (void) AO_CC1120_SPI.dr;
+ ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
- /* Have the radio signal when the preamble quality goes high */
- ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_PQT_REACHED);
+ /* configure interrupt pin */
+ ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_CLKEN_SOFT);
ao_exti_set_mode(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN,
- AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH);
- ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_isr);
+ AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
+
+ ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_rx_isr);
ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
- ao_exti_enable(AO_CC1120_MCU_WAKEUP_PORT, AO_CC1120_MCU_WAKEUP_PIN);
+
+ rx_starting = 1;
+ rx_task_id = ao_cur_task->task_id;
ao_radio_strobe(CC1120_SRX);
- /* Wait for the preamble to appear */
- ao_radio_wait_isr(timeout);
+ if (timeout)
+ ao_alarm(timeout);
+ ao_arch_block_interrupts();
+ while (rx_starting && !ao_radio_abort) {
+ if (ao_sleep(&ao_radio_wake))
+ ao_radio_abort = 1;
+ }
+ uint8_t rx_task_id_save = rx_task_id;
+ rx_task_id = 0;
+ rx_starting = 0;
+ ao_arch_release_interrupts();
+ if (timeout)
+ ao_clear_alarm();
+
if (ao_radio_abort) {
ret = 0;
+ rx_task_id = 0;
goto abort;
}
- ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_CLKEN_SOFT);
- ao_exti_set_mode(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN,
- AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
-
- ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_rx_isr);
- ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
-
- ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT);
+ if (rx_task_id_save) {
+ ++rx_slow_start;
+ ao_radio_select();
+ _ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT);
+ if (rx_ignore) {
+ uint8_t ignore = AO_CC1120_SPI.dr;
+ (void) ignore;
+ AO_CC1120_SPI.dr = 0;
+ --rx_ignore;
+ }
+ }
ret = ao_fec_decode(rx_data, rx_data_count, d, size + 2, ao_radio_rx_wait);
ao_radio_burst_read_stop();
+ if (ao_radio_mcu_wake)
+ ao_radio_check_marc_status();
+ if (ao_radio_abort)
+ ret = 0;
+
abort:
/* Convert from 'real' rssi to cc1111-style values */
radio_rssi = AO_RADIO_FROM_RSSI (rssi);
}
- ao_radio_strobe(CC1120_SIDLE);
+ ao_radio_idle();
ao_radio_put();
char *name;
};
-const static struct ao_cc1120_reg ao_cc1120_reg[] = {
+static const struct ao_cc1120_reg ao_cc1120_reg[] = {
{ .addr = CC1120_IOCFG3, .name = "IOCFG3" },
{ .addr = CC1120_IOCFG2, .name = "IOCFG2" },
{ .addr = CC1120_IOCFG1, .name = "IOCFG1" },
static void ao_radio_show(void) {
uint8_t status = ao_radio_status();
- int i;
+ unsigned int i;
ao_radio_get(0xff);
status = ao_radio_status();
for (i = 0; i < AO_NUM_CC1120_REG; i++)
printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1120_reg[i].addr), ao_cc1120_reg[i].name);
+
+ printf("RX fast start: %u\n", rx_fast_start);
+ printf("RX slow start: %u\n", rx_slow_start);
+ printf("RX missed: %u\n", rx_missed);
ao_radio_put();
}
}
void
-ao_radio_test_recv()
+ao_radio_test_recv(void)
{
uint8_t bytes[34];
uint8_t b;
- if (ao_radio_recv(bytes, 34)) {
+ if (ao_radio_recv(bytes, 34, 0)) {
if (bytes[33] & 0x80)
printf ("CRC OK");
else
#include <ao_aprs.h>
static void
-ao_radio_aprs()
+ao_radio_aprs(void)
{
ao_packet_slave_stop();
ao_aprs_send();
}
#endif
-
#endif
static const struct ao_cmds ao_radio_cmds[] = {