X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fdrivers%2Fao_cc1200.c;h=93bb2c6c4f752b5794585ea663235d1202cb1bf7;hp=930680b286722ec7bf96c0eb6a0faa886d3b515f;hb=eabeb76a2a9acb624ae364c4f0f315bfc3549d98;hpb=2163f6e6b341b7840f03e89d568699b8ea186435 diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index 930680b2..93bb2c6c 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -599,14 +599,20 @@ ao_radio_set_mode(uint16_t new_mode) } } - 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) + 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_RX) - ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX); + 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); @@ -709,20 +715,6 @@ ao_radio_show_state(char *where) static void ao_radio_wait_isr(uint16_t timeout) { - uint8_t state; - - state = ao_radio_state(); - switch (state) { - case CC1200_STATUS_STATE_IDLE: - case CC1200_STATUS_STATE_RX_FIFO_ERROR: - case CC1200_STATUS_STATE_TX_FIFO_ERROR: -#if CC1200_LOW_LEVEL_DEBUG - printf("before wait, state %d\n", state); flush(); -#endif - ao_radio_abort = 1; - return; - } - if (timeout) ao_alarm(timeout); @@ -731,6 +723,7 @@ ao_radio_wait_isr(uint16_t timeout) if (ao_sleep(&ao_radio_wake)) ao_radio_abort = 1; ao_arch_release_interrupts(); + if (timeout) ao_clear_alarm(); } @@ -1005,14 +998,80 @@ ao_radio_dump_state(struct ao_radio_state *s) uint8_t ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) { - ao_radio_abort = 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(); - ao_radio_wait_isr(timeout); - if (ao_radio_wake) { + + 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) | + (1 << CC1200_MODEM_STATUS1_PQT_REACHED))) + { + 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; @@ -1033,7 +1092,7 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) } ao_radio_put(); - return ao_radio_wake; + return success; }