Cleaned up RF230BB, and refactored FRAME_RETRIES and CSMA_RETRIES
#defines.
This commit is contained in:
parent
2e72ec3594
commit
b43dad00b0
8 changed files with 320 additions and 638 deletions
|
@ -2,6 +2,11 @@
|
|||
* Copyright (c) 2007, Swedish Institute of Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Additional fixes for AVR contributed by:
|
||||
*
|
||||
* David Kopf dak664@embarqmail.com
|
||||
* Ivan Delamer delamer@ieee.com
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
@ -91,13 +96,17 @@
|
|||
static bool is_promiscuous;
|
||||
#endif
|
||||
|
||||
/* RF230_CONF_AUTORETRIES is 1 plus the number written to the hardware. */
|
||||
/* RF230_CONF_FRAME_RETRIES is 1 plus the number written to the hardware. */
|
||||
/* Valid range 1-16, zero disables extended mode. */
|
||||
#ifndef RF230_CONF_AUTORETRIES
|
||||
#define RF230_CONF_AUTORETRIES 3
|
||||
#ifndef RF230_CONF_FRAME_RETRIES
|
||||
#ifdef RF230_CONF_AUTORETRIES /* Support legacy definition. */
|
||||
#define RF230_CONF_FRAME_RETRIES RF230_CONF_AUTORETRIES
|
||||
#else
|
||||
#define RF230_CONF_FRAME_RETRIES 0 /* Extended mode disabled by default. */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* In extended mode (AUTORETRIES>0) the tx routine waits for hardware
|
||||
/* In extended mode (FRAME_RETRIES>0) the tx routine waits for hardware
|
||||
* processing of an expected ACK and returns RADIO_TX_OK/NOACK result.
|
||||
* In non-extended mode the ACK is treated as a normal rx packet.
|
||||
* If the caller needs the ACK to be returned as an rx packet,
|
||||
|
@ -109,15 +118,19 @@ static bool is_promiscuous;
|
|||
* that use the TX_OK result to signal a successful ACK.
|
||||
* Adds 100 bytes of program flash and two bytes of RAM.
|
||||
*/
|
||||
#if RF320_CONF_INSERTACK && RF230_CONF_AUTORETRIES
|
||||
#if RF320_CONF_INSERTACK && RF230_CONF_FRAME_RETRIES
|
||||
#define RF230_INSERTACK 1
|
||||
uint8_t ack_pending,ack_seqnum;
|
||||
#endif
|
||||
|
||||
/* RF230_CONF_CSMARETRIES is number of random-backoff/CCA retries. */
|
||||
/* RF230_CONF_CSMA_RETRIES is number of random-backoff/CCA retries. */
|
||||
/* The hardware will accept 0-7, but 802.15.4-2003 only allows 5 maximum */
|
||||
#ifndef RF230_CONF_CSMARETRIES
|
||||
#define RF230_CONF_CSMARETRIES 5
|
||||
/* In RF231/128RFA1, a value of 7 means no CSMA bebofe the Tx. */
|
||||
/* CSMA backoffs are long and can block radio duty cycling
|
||||
* over several channel check periods! */
|
||||
/* Used only if RF230_CONF_FRAME_RETRIES > 0. */
|
||||
#ifndef RF230_CONF_CSMA_RETRIES
|
||||
#define RF230_CONF_CSMA_RETRIES 5
|
||||
#endif
|
||||
|
||||
//Automatic and manual CRC both append 2 bytes to packets
|
||||
|
@ -191,18 +204,18 @@ extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
|
|||
#endif
|
||||
|
||||
/* XXX hack: these will be made as Chameleon packet attributes */
|
||||
#if RF230_CONF_TIMESTAMPS
|
||||
rtimer_clock_t rf230_time_of_arrival, rf230_time_of_departure;
|
||||
|
||||
int rf230_authority_level_of_sender;
|
||||
|
||||
#if RF230_CONF_TIMESTAMPS
|
||||
static rtimer_clock_t setup_time_for_transmission;
|
||||
static unsigned long total_time_for_transmission, total_transmission_len;
|
||||
static int num_transmissions;
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATmega128RFA1__)
|
||||
volatile uint8_t rf230_interruptwait,rf230_ccawait;
|
||||
volatile uint8_t rf230_wakewait, rf230_txendwait, rf230_ccawait;
|
||||
#endif
|
||||
|
||||
uint8_t volatile rf230_pending;
|
||||
|
@ -226,8 +239,8 @@ typedef enum{
|
|||
PROCESS(rf230_process, "RF230 driver");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
int rf230_on(void);
|
||||
int rf230_off(void);
|
||||
static int rf230_on(void);
|
||||
static int rf230_off(void);
|
||||
|
||||
static int rf230_read(void *buf, unsigned short bufsize);
|
||||
|
||||
|
@ -340,9 +353,17 @@ static bool radio_is_sleeping(void)
|
|||
static void
|
||||
radio_reset_state_machine(void)
|
||||
{
|
||||
if (hal_get_slptr()) DEBUGFLOW('"');
|
||||
hal_set_slptr_low();
|
||||
delay_us(TIME_NOCLK_TO_WAKE);
|
||||
/* The data sheet is not clear on what happens when slptr is raised in RX on
|
||||
* states, it "remains in the new state and returns to the preceding state
|
||||
* when slptr is lowered". Possibly that is why there is an undocumented
|
||||
* TIME_NOCLK_TO_WAKE delay here?
|
||||
*/
|
||||
if (hal_get_slptr()) {
|
||||
DEBUGFLOW('V');
|
||||
hal_set_slptr_low();
|
||||
delay_us(TIME_NOCLK_TO_WAKE);
|
||||
}
|
||||
|
||||
hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF);
|
||||
delay_us(TIME_CMD_FORCE_TRX_OFF);
|
||||
}
|
||||
|
@ -351,33 +372,36 @@ static char
|
|||
rf230_isidle(void)
|
||||
{
|
||||
uint8_t radio_state;
|
||||
/* Contikimac can turn the radio off during an interrupt, so we always check
|
||||
* slptr before doing the SPI transfer. The caller must also make this test
|
||||
* if it could otherwise hang waiting for idle! */
|
||||
if (hal_get_slptr()) {
|
||||
DEBUGFLOW(']');
|
||||
return 1;
|
||||
} else {
|
||||
radio_state = hal_subregister_read(SR_TRX_STATUS);
|
||||
if (radio_state != BUSY_TX_ARET &&
|
||||
if (RF230_receive_on) DEBUGFLOW('-');
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
radio_state = hal_subregister_read(SR_TRX_STATUS);
|
||||
if (radio_state != BUSY_TX_ARET &&
|
||||
radio_state != BUSY_RX_AACK &&
|
||||
radio_state != STATE_TRANSITION &&
|
||||
radio_state != BUSY_RX &&
|
||||
radio_state != BUSY_TX) {
|
||||
return(1);
|
||||
} else {
|
||||
// printf(".%u",radio_state);
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rf230_waitidle(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<10000;i++) { //to avoid potential hangs
|
||||
// while (1) {
|
||||
/* TX_ARET with multiple csma retries can take a very long time to finish */
|
||||
while (1) {
|
||||
if (hal_get_slptr()) return;
|
||||
if (rf230_isidle()) break;
|
||||
}
|
||||
if (i>=10000) {DEBUGFLOW('H');DEBUGFLOW('R');}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
@ -402,9 +426,9 @@ int i;
|
|||
static radio_status_t
|
||||
radio_set_trx_state(uint8_t new_state)
|
||||
{
|
||||
uint8_t original_state;
|
||||
uint8_t current_state;
|
||||
|
||||
/*Check function paramter and current state of the radio transceiver.*/
|
||||
/*Check function parameter and current state of the radio transceiver.*/
|
||||
if (!((new_state == TRX_OFF) ||
|
||||
(new_state == RX_ON) ||
|
||||
(new_state == PLL_ON) ||
|
||||
|
@ -413,23 +437,16 @@ radio_set_trx_state(uint8_t new_state)
|
|||
return RADIO_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (hal_get_slptr()) {
|
||||
if (hal_get_slptr()) {
|
||||
DEBUGFLOW('W');
|
||||
return RADIO_WRONG_STATE;
|
||||
}
|
||||
|
||||
/* Wait for radio to finish previous operation */
|
||||
rf230_waitidle();
|
||||
// for(;;)
|
||||
// {
|
||||
original_state = radio_get_trx_state();
|
||||
// if (original_state != BUSY_TX_ARET &&
|
||||
// original_state != BUSY_RX_AACK &&
|
||||
// original_state != BUSY_RX &&
|
||||
// original_state != BUSY_TX)
|
||||
// break;
|
||||
// }
|
||||
current_state = radio_get_trx_state();
|
||||
|
||||
if (new_state == original_state){
|
||||
if (new_state == current_state){
|
||||
return RADIO_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -440,14 +457,15 @@ radio_set_trx_state(uint8_t new_state)
|
|||
/* The radio transceiver can be in one of the following states: */
|
||||
/* TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON, TX_ARET_ON. */
|
||||
if(new_state == TRX_OFF){
|
||||
if (hal_get_slptr()) DEBUGFLOW('K');DEBUGFLOW('K');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));
|
||||
radio_reset_state_machine(); /* Go to TRX_OFF from any state. */
|
||||
} else {
|
||||
/* It is not allowed to go from RX_AACK_ON or TX_AACK_ON and directly to */
|
||||
/* TX_AACK_ON or RX_AACK_ON respectively. Need to go via PLL_ON. */
|
||||
/* (Old datasheets allowed other transitions, but this code complies with */
|
||||
/* the current specification for RF230, RF231 and 128RFA1.) */
|
||||
if (((new_state == TX_ARET_ON) && (original_state == RX_AACK_ON)) ||
|
||||
((new_state == RX_AACK_ON) && (original_state == TX_ARET_ON))){
|
||||
if (((new_state == TX_ARET_ON) && (current_state == RX_AACK_ON)) ||
|
||||
((new_state == RX_AACK_ON) && (current_state == TX_ARET_ON))){
|
||||
/* First do intermediate state transition to PLL_ON. */
|
||||
/* The final state transition is handled after the if-else if. */
|
||||
hal_subregister_write(SR_TRX_CMD, PLL_ON);
|
||||
|
@ -459,21 +477,28 @@ radio_set_trx_state(uint8_t new_state)
|
|||
|
||||
/* When the PLL is active most states can be reached in 1us. However, from */
|
||||
/* TRX_OFF the PLL needs time to activate. */
|
||||
if (original_state == TRX_OFF){
|
||||
if (current_state == TRX_OFF){
|
||||
delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE);
|
||||
} else {
|
||||
delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE);
|
||||
}
|
||||
} /* end: if(new_state == TRX_OFF) ... */
|
||||
|
||||
/*Verify state transition.*/
|
||||
radio_status_t set_state_status = RADIO_TIMED_OUT;
|
||||
|
||||
if (radio_get_trx_state() == new_state){
|
||||
set_state_status = RADIO_SUCCESS;
|
||||
/* Verify state transition.
|
||||
* Radio could have already switched to an RX_BUSY state, at least in cooja.
|
||||
* Don't know what the hardware does but this would not be an error.*/
|
||||
current_state = radio_get_trx_state();
|
||||
if (current_state != new_state) {
|
||||
if (((new_state == RX_ON) && (current_state == BUSY_RX)) ||
|
||||
((new_state == RX_AACK_ON) && (current_state == BUSY_RX_AACK))) {
|
||||
/* This is OK. */
|
||||
} else {
|
||||
DEBUGFLOW('N');DEBUGFLOW('A'+new_state);DEBUGFLOW('A'+radio_get_trx_state());DEBUGFLOW('N');
|
||||
return RADIO_TIMED_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
return set_state_status;
|
||||
return RADIO_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -504,7 +529,7 @@ flushrx(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
on(void)
|
||||
radio_on(void)
|
||||
{
|
||||
// ENERGEST_OFF(ENERGEST_TYPE_LISTEN);//testing
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
|
@ -520,11 +545,22 @@ on(void)
|
|||
PORTE|=(1<<PE1); //ledon
|
||||
#endif
|
||||
#if defined(__AVR_ATmega128RFA1__)
|
||||
/* Use the poweron interrupt for delay */
|
||||
rf230_interruptwait=1;
|
||||
sei();
|
||||
hal_set_slptr_low();
|
||||
while (rf230_interruptwait) {}
|
||||
/* Use the poweron interrupt for delay */
|
||||
rf230_wakewait=1;
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
sei();
|
||||
if (hal_get_slptr() == 0) DEBUGFLOW('$');
|
||||
hal_set_slptr_low();
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<10000;i++) {
|
||||
if (!rf230_wakewait) break;
|
||||
}
|
||||
if (i>=10000) {DEBUGFLOW('G');DEBUGFLOW('g');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));}
|
||||
}
|
||||
SREG = sreg;
|
||||
}
|
||||
#else
|
||||
/* SPI based radios. The wake time depends on board capacitance.
|
||||
* Make sure the delay is long enough, as using SPI too soon will reset the MCU!
|
||||
|
@ -533,7 +569,6 @@ on(void)
|
|||
// uint8_t sreg = SREG;cli();
|
||||
hal_set_slptr_low();
|
||||
delay_us(2*TIME_SLEEP_TO_TRX_OFF);
|
||||
// delay_us(TIME_SLEEP_TO_TRX_OFF+TIME_SLEEP_TO_TRX_OFF/2);
|
||||
// SREG=sreg;
|
||||
#endif
|
||||
}
|
||||
|
@ -547,8 +582,14 @@ on(void)
|
|||
rf230_waitidle();
|
||||
}
|
||||
static void
|
||||
off(void)
|
||||
radio_off(void)
|
||||
{
|
||||
RF230_receive_on = 0;
|
||||
if (hal_get_slptr()) {
|
||||
DEBUGFLOW('F');
|
||||
return;
|
||||
}
|
||||
|
||||
#if RF230BB_CONF_LEDONPORTE1
|
||||
PORTE&=~(1<<PE1); //ledoff
|
||||
#endif
|
||||
|
@ -563,7 +604,12 @@ off(void)
|
|||
/* Do not transmit autoacks when stack thinks radio is off */
|
||||
radio_set_trx_state(RX_ON);
|
||||
#else
|
||||
/* Force the device into TRX_OFF. */
|
||||
/* Force the device into TRX_OFF.
|
||||
* First make sure an interrupt did not initiate a sleep. */
|
||||
if (hal_get_slptr()) {
|
||||
DEBUGFLOW('?');
|
||||
return;
|
||||
}
|
||||
radio_reset_state_machine();
|
||||
#if RADIOSLEEPSWHENOFF
|
||||
/* Sleep Radio */
|
||||
|
@ -572,7 +618,6 @@ off(void)
|
|||
#endif
|
||||
#endif /* RADIOALWAYSON */
|
||||
|
||||
RF230_receive_on = 0;
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -586,7 +631,7 @@ set_txpower(uint8_t power)
|
|||
DEBUGFLOW('f');
|
||||
PRINTF("rf230_set_txpower:Sleeping"); //happens with cxmac
|
||||
} else {
|
||||
DEBUGFLOW('g');
|
||||
//DEBUGFLOW('g');
|
||||
hal_subregister_write(SR_TX_PWR, power);
|
||||
}
|
||||
}
|
||||
|
@ -718,13 +763,14 @@ rf230_init(void)
|
|||
// printf_P(PSTR("After calibration OSCCAL=%x\n"),OSCCAL);
|
||||
|
||||
/* Set receive buffers empty and point to the first */
|
||||
for (i=0;i<RF230_CONF_RX_BUFFERS;i++) rxframe[i].length=0;
|
||||
for (i=0;i<RF230_CONF_RX_BUFFERS;i++) {
|
||||
rxframe[i].length=0;
|
||||
}
|
||||
rxframe_head=0;rxframe_tail=0;
|
||||
|
||||
/* Do full rf230 Reset */
|
||||
hal_set_rst_low();
|
||||
hal_set_slptr_low();
|
||||
#if 1
|
||||
/* On powerup a TIME_RESET delay is needed here, however on some other MCU reset
|
||||
* (JTAG, WDT, Brownout) the radio may be sleeping. It can enter an uncertain
|
||||
* state (sending wrong hardware FCS for example) unless the full wakeup delay
|
||||
|
@ -733,9 +779,7 @@ rf230_init(void)
|
|||
* See www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=78725
|
||||
*/
|
||||
delay_us(2*TIME_SLEEP_TO_TRX_OFF);
|
||||
#else
|
||||
delay_us(TIME_RESET);
|
||||
#endif
|
||||
//delay_us(TIME_RESET); /* Old impl. */
|
||||
hal_set_rst_high();
|
||||
|
||||
/* Force transition to TRX_OFF */
|
||||
|
@ -761,7 +805,7 @@ rf230_init(void)
|
|||
process_start(&rf230_process, NULL);
|
||||
|
||||
/* Leave radio in on state (?)*/
|
||||
on();
|
||||
radio_on();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -777,11 +821,13 @@ void rf230_warm_reset(void) {
|
|||
|
||||
hal_register_write(RG_IRQ_MASK, RF230_SUPPORTED_INTERRUPT_MASK);
|
||||
|
||||
/* Set up number of automatic retries 0-15 (0 implies PLL_ON sends instead of the extended TX_ARET mode */
|
||||
hal_subregister_write(SR_MAX_FRAME_RETRIES, RF230_CONF_AUTORETRIES );
|
||||
/* Set up number of automatic retries 0-15
|
||||
* (0 implies PLL_ON sends instead of the extended TX_ARET mode */
|
||||
hal_subregister_write(SR_MAX_FRAME_RETRIES,
|
||||
(RF230_CONF_FRAME_RETRIES > 0) ? (RF230_CONF_FRAME_RETRIES - 1) : 0 );
|
||||
|
||||
/* Set up carrier sense/clear channel assesment parameters for extended operating mode */
|
||||
hal_subregister_write(SR_MAX_CSMA_RETRIES, 5 );//highest allowed retries
|
||||
hal_subregister_write(SR_MAX_CSMA_RETRIES, RF230_CONF_CSMA_RETRIES );//highest allowed retries
|
||||
hal_register_write(RG_CSMA_BE, 0x80); //min backoff exponent 0, max 8 (highest allowed)
|
||||
hal_register_write(RG_CSMA_SEED_0,hal_register_read(RG_PHY_RSSI) );//upper two RSSI reg bits RND_VALUE are random in rf231
|
||||
// hal_register_write(CSMA_SEED_1,42 );
|
||||
|
@ -855,20 +901,19 @@ rf230_transmit(unsigned short payload_len)
|
|||
#if RF230BB_CONF_LEDONPORTE1
|
||||
PORTE|=(1<<PE1); //ledon
|
||||
#endif
|
||||
rf230_interruptwait=1;
|
||||
hal_set_slptr_low();
|
||||
// while (rf230_interruptwait) {}
|
||||
rf230_wakewait=1;
|
||||
hal_set_slptr_low();
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<10000;i++) {
|
||||
if (!rf230_interruptwait) break;
|
||||
if (!rf230_wakewait) break;
|
||||
}
|
||||
if (i>=10000) {DEBUGFLOW('G');DEBUGFLOW('G');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));}
|
||||
}
|
||||
#else
|
||||
hal_set_slptr_low();
|
||||
DEBUGFLOW('j');
|
||||
delay_us(2*TIME_SLEEP_TO_TRX_OFF); //extra delay depends on board capacitance
|
||||
// delay_us(TIME_SLEEP_TO_TRX_OFF+TIME_SLEEP_TO_TRX_OFF/2);
|
||||
delay_us(2*TIME_SLEEP_TO_TRX_OFF); //extra delay (2x) depends on board capacitance
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
@ -891,7 +936,7 @@ rf230_transmit(unsigned short payload_len)
|
|||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
}
|
||||
/* Prepare to transmit */
|
||||
#if RF230_CONF_AUTORETRIES
|
||||
#if RF230_CONF_FRAME_RETRIES
|
||||
radio_set_trx_state(TX_ARET_ON);
|
||||
DEBUGFLOW('t');
|
||||
#else
|
||||
|
@ -916,20 +961,17 @@ rf230_transmit(unsigned short payload_len)
|
|||
|
||||
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
|
||||
|
||||
#if defined(__AVR_ATmega128RFA1__)
|
||||
/* No interrupts across frame download! */
|
||||
cli();
|
||||
/* slow down the transmit? */
|
||||
// delay_us(500);
|
||||
#endif
|
||||
/* Toggle the SLP_TR pin to initiate the frame transmission */
|
||||
HAL_ENTER_CRITICAL_REGION();
|
||||
|
||||
/* Toggle the SLP_TR pin to initiate the frame transmission */
|
||||
hal_set_slptr_high();
|
||||
hal_set_slptr_low();
|
||||
hal_frame_write(buffer, total_len);
|
||||
#if defined(__AVR_ATmega128RFA1__)
|
||||
sei();
|
||||
#endif
|
||||
|
||||
HAL_LEAVE_CRITICAL_REGION();
|
||||
PRINTF("rf230_transmit: %d\n", (int)total_len);
|
||||
|
||||
#if DEBUG>1
|
||||
/* Note the dumped packet will have a zero checksum unless compiled with RF230_CONF_CHECKSUM
|
||||
* since we don't know what it will be if calculated by the hardware.
|
||||
|
@ -951,7 +993,7 @@ rf230_transmit(unsigned short payload_len)
|
|||
rf230_waitidle();
|
||||
|
||||
/* Get the transmission result */
|
||||
#if RF230_CONF_AUTORETRIES
|
||||
#if RF230_CONF_FRAME_RETRIES
|
||||
tx_result = hal_subregister_read(SR_TRAC_STATUS);
|
||||
#else
|
||||
tx_result=RADIO_TX_OK;
|
||||
|
@ -981,13 +1023,13 @@ rf230_transmit(unsigned short payload_len)
|
|||
if(RF230_receive_on) {
|
||||
DEBUGFLOW('l');
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
on();
|
||||
radio_on();
|
||||
} else {
|
||||
#if RADIOALWAYSON
|
||||
/* Enable reception */
|
||||
on();
|
||||
radio_on();
|
||||
#else
|
||||
off();
|
||||
radio_off();
|
||||
PRINTF("rf230_transmit: turning radio off\n");
|
||||
#endif
|
||||
}
|
||||
|
@ -1123,36 +1165,39 @@ bail:
|
|||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
static int
|
||||
rf230_off(void)
|
||||
{
|
||||
/* Don't do anything if we are already turned off. */
|
||||
if(RF230_receive_on == 0) {
|
||||
//if (!hal_get_slptr()) DEBUGFLOW('5');
|
||||
return 0;
|
||||
}
|
||||
//if (hal_get_slptr()) DEBUGFLOW('6');
|
||||
|
||||
/* If we are currently receiving a packet, we still call off(),
|
||||
/* If we are currently receiving a packet, we still call radio_off(),
|
||||
as that routine waits until Rx is complete (packet uploaded in ISR
|
||||
so no worries about losing it). If using RX_AACK_MODE, chances are
|
||||
the packet is not for us and will be discarded. */
|
||||
so no worries about losing it). The transmit routine may also turn
|
||||
+ the radio off on a return to sleep. rf230_isidle checks for that. */
|
||||
if (!rf230_isidle()) {
|
||||
//DEBUGFLOW('X');DEBUGFLOW('X');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));
|
||||
PRINTF("rf230_off: busy receiving\r\n");
|
||||
//return 1;
|
||||
}
|
||||
|
||||
off();
|
||||
radio_off();
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
static int
|
||||
rf230_on(void)
|
||||
{
|
||||
if(RF230_receive_on) {
|
||||
DEBUGFLOW('q');
|
||||
//if (hal_get_slptr()) DEBUGFLOW('Q');//Cooja TODO: shows sleeping occasionally
|
||||
return 1;
|
||||
}
|
||||
|
||||
on();
|
||||
radio_on();
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -1296,18 +1341,26 @@ PROCESS_THREAD(rf230_process, ev, data)
|
|||
TIMETABLE_TIMESTAMP(rf230_timetable, "poll");
|
||||
#endif /* RF230_TIMETABLE_PROFILING */
|
||||
|
||||
rf230_pending = 0;
|
||||
|
||||
packetbuf_clear();
|
||||
|
||||
/* Turn off interrupts to avoid ISR writing to the same buffers we are reading. */
|
||||
HAL_ENTER_CRITICAL_REGION();
|
||||
|
||||
len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
|
||||
len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
|
||||
|
||||
/* Restore interrupts. */
|
||||
HAL_LEAVE_CRITICAL_REGION();
|
||||
PRINTF("rf230_read: %u bytes lqi %u\n",len,rf230_last_correlation);
|
||||
#if DEBUG>1
|
||||
{
|
||||
uint8_t i;
|
||||
unsigned const char * rxdata = packetbuf_dataptr();
|
||||
PRINTF("0000");
|
||||
for (i=0;i<len+AUX_LEN;i++) PRINTF(" %02x",rxdata[i]);
|
||||
PRINTF("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
RF230PROCESSFLAG(1);
|
||||
if(len > 0) {
|
||||
|
@ -1372,19 +1425,6 @@ rf230_read(void *buf, unsigned short bufsize)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if RADIOALWAYSON
|
||||
if (RF230_receive_on) {
|
||||
#else
|
||||
if (hal_get_slptr()) {
|
||||
DEBUGFLOW('!');
|
||||
return 0;
|
||||
}
|
||||
if (!RF230_receive_on) {
|
||||
DEBUGFLOW('[');
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RF230_CONF_TIMESTAMPS
|
||||
if(interrupt_time_set) {
|
||||
rf230_time_of_arrival = interrupt_time;
|
||||
|
@ -1395,19 +1435,6 @@ if (!RF230_receive_on) {
|
|||
rf230_time_of_departure = 0;
|
||||
#endif /* RF230_CONF_TIMESTAMPS */
|
||||
|
||||
// can't use PRINTF as interrupts are disabled
|
||||
// PRINTSHORT("r%d",rxframe[rxframe_head].length);
|
||||
//PRINTF("rf230_read: %u bytes lqi %u crc %u\n",rxframe[rxframe_head].length,rxframe[rxframe_head].lqi,rxframe[rxframe_head].crc);
|
||||
#if DEBUG>1
|
||||
{
|
||||
//uint8_t i;
|
||||
//PRINTF("0000");
|
||||
//for (i=0;i<rxframe[rxframe_head].length;i++) PRINTF(" %02x",rxframe[rxframe_head].data[i]);
|
||||
//PRINTF("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
//if(len > RF230_MAX_PACKET_LEN) {
|
||||
if(len > RF230_MAX_TX_FRAME_LENGTH) {
|
||||
/* Oops, we must be out of sync. */
|
||||
DEBUGFLOW('u');
|
||||
|
@ -1431,6 +1458,7 @@ if (!RF230_receive_on) {
|
|||
RIMESTATS_ADD(toolong);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Transfer the frame, stripping the footer, but copying the checksum */
|
||||
framep=&(rxframe[rxframe_head].data[0]);
|
||||
memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
|
||||
|
@ -1438,9 +1466,17 @@ if (!RF230_receive_on) {
|
|||
|
||||
/* Clear the length field to allow buffering of the next packet */
|
||||
rxframe[rxframe_head].length=0;
|
||||
rxframe_head++;if (rxframe_head >= RF230_CONF_RX_BUFFERS) rxframe_head=0;
|
||||
rxframe_head++;
|
||||
if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
|
||||
rxframe_head=0;
|
||||
}
|
||||
/* If another packet has been buffered, schedule another receive poll */
|
||||
if (rxframe[rxframe_head].length) rf230_interrupt();
|
||||
if (rxframe[rxframe_head].length) {
|
||||
rf230_interrupt();
|
||||
}
|
||||
else {
|
||||
rf230_pending = 0;
|
||||
}
|
||||
|
||||
/* Point to the checksum */
|
||||
framep+=len-AUX_LEN;
|
||||
|
@ -1518,13 +1554,6 @@ if (!RF230_receive_on) {
|
|||
|
||||
/* Here return just the data length. The checksum is however still in the buffer for packet sniffing */
|
||||
return len - AUX_LEN;
|
||||
|
||||
#if RADIOALWAYSON
|
||||
} else {
|
||||
DEBUGFLOW('y'); //Stack thought radio was off
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -1589,13 +1618,17 @@ rf230_cca(void)
|
|||
uint8_t radio_was_off = 0;
|
||||
|
||||
/* Turn radio on if necessary. If radio is currently busy return busy channel */
|
||||
/* This may happen when testing radio duty cycling with RADIOALWAYSON */
|
||||
/* This may happen when testing radio duty cycling with RADIOALWAYSON,
|
||||
* or because a packet just started. */
|
||||
if(RF230_receive_on) {
|
||||
if (hal_get_slptr()) { //should not be sleeping!
|
||||
DEBUGFLOW('<');
|
||||
goto busyexit;
|
||||
} else {
|
||||
if (!rf230_isidle()) {DEBUGFLOW('2');goto busyexit;}
|
||||
if (!rf230_isidle()) {
|
||||
//DEBUGFLOW('2');
|
||||
goto busyexit;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
radio_was_off = 1;
|
||||
|
@ -1611,18 +1644,30 @@ rf230_cca(void)
|
|||
/* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */
|
||||
#if defined(__AVR_ATmega128RFA1__)
|
||||
#if 1 //interrupt method
|
||||
sei();
|
||||
//rf230_waitidle();
|
||||
//TODO:disable reception for version bug
|
||||
radio_set_trx_state(RX_ON);
|
||||
// rf230_waitidle();
|
||||
/* Disable rx transitions to busy (RX_PDT_BIT) */
|
||||
/* Note: for speed this resets rx threshold to the compiled default */
|
||||
#ifdef RF230_MIN_RX_POWER
|
||||
hal_register_write(RG_RX_SYN, RF230_MIN_RX_POWER/6 + 0x81);
|
||||
#else
|
||||
hal_register_write(RG_RX_SYN, 0x80);
|
||||
#endif
|
||||
/* Switch to RX_ON for measurement. This will wait if a packet is being received */
|
||||
radio_set_trx_state(RX_ON);
|
||||
|
||||
rf230_ccawait=1;
|
||||
//CCA_REQUEST is supposed to trigger the interrupt but it doesn't
|
||||
// hal_subregister_write(SR_CCA_REQUEST,1);
|
||||
hal_register_write(PHY_ED_LEVEL,0);
|
||||
// delay_us(TIME_CCA);
|
||||
// if (hal_register_read(RG_PHY_ED_LEVEL)<(91-77)) cca=0xff;
|
||||
while (rf230_ccawait) {}
|
||||
|
||||
/* Write to ED_LEVEL register to start CCA */
|
||||
{
|
||||
uint8_t volatile saved_sreg = SREG;
|
||||
sei( );
|
||||
hal_register_write(PHY_ED_LEVEL,0);
|
||||
while (rf230_ccawait) {}
|
||||
SREG = saved_sreg;
|
||||
}
|
||||
|
||||
/* Use ED register to determine result. 77dBm is poweron csma default.*/
|
||||
#ifdef RF230_CONF_CCA_THRES
|
||||
if (hal_register_read(RG_PHY_ED_LEVEL)<(91+RF230_CONF_CCA_THRES) cca=0xff;
|
||||
#else
|
||||
|
@ -1631,8 +1676,17 @@ rf230_cca(void)
|
|||
//TODO:see if the status register works!
|
||||
// cca=hal_register_read(RG_TRX_STATUS);
|
||||
#if RF230_CONF_AUTOACK
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
#endif
|
||||
|
||||
/* Enable packet reception */
|
||||
#ifdef RF230_MIN_RX_POWER
|
||||
hal_register_write(RG_RX_SYN, RF230_MIN_RX_POWER/6 + 0x01);
|
||||
#else
|
||||
hal_register_write(RG_RX_SYN, 0x00);
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
/* If already in receive mode can read the current ED register without delay */
|
||||
/* CCA energy threshold = -91dB + 2*SR_CCA_ED_THRESH. Reset defaults to -77dB */
|
||||
|
@ -1654,6 +1708,10 @@ rf230_cca(void)
|
|||
hal_subregister_write(SR_CCA_REQUEST,1);
|
||||
delay_us(TIME_CCA);
|
||||
while ((cca & 0x80) == 0 ) {
|
||||
if (hal_get_slptr()) {
|
||||
DEBUGFLOW('S');
|
||||
break;
|
||||
}
|
||||
cca=hal_register_read(RG_TRX_STATUS);
|
||||
}
|
||||
SREG=saved_sreg;
|
||||
|
@ -1684,7 +1742,6 @@ rf230_receiving_packet(void)
|
|||
radio_state = hal_subregister_read(SR_TRX_STATUS);
|
||||
if ((radio_state==BUSY_RX) || (radio_state==BUSY_RX_AACK)) {
|
||||
// DEBUGFLOW('8');
|
||||
// rf230_pending=1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue