From b43dad00b0d598c7ee9f974b4a820a8fe5082d2e Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Tue, 4 Sep 2012 11:12:18 -0600 Subject: [PATCH] Cleaned up RF230BB, and refactored FRAME_RETRIES and CSMA_RETRIES #defines. --- cpu/avr/radio/rf230bb/hal.h | 148 +------- cpu/avr/radio/rf230bb/halbb.c | 395 +++++----------------- cpu/avr/radio/rf230bb/rf230bb.c | 357 +++++++++++-------- cpu/avr/radio/rf230bb/rf230bb.h | 5 +- platform/avr-atmega128rfa1/contiki-conf.h | 23 +- platform/avr-raven/contiki-conf.h | 16 +- platform/avr-ravenusb/contiki-conf.h | 12 +- platform/avr-zigbit/contiki-conf.h | 2 +- 8 files changed, 320 insertions(+), 638 deletions(-) diff --git a/cpu/avr/radio/rf230bb/hal.h b/cpu/avr/radio/rf230bb/hal.h index 2044575e2..4b4753471 100644 --- a/cpu/avr/radio/rf230bb/hal.h +++ b/cpu/avr/radio/rf230bb/hal.h @@ -10,6 +10,7 @@ * Kevin Brown kbrown3@uccs.edu * Nate Bohlmann nate@elfwerks.com * David Kopf dak664@embarqmail.com + * Ivan Delamer delamer@ieee.com * * All rights reserved. * @@ -60,10 +61,6 @@ #include "contiki-conf.h" /*============================ MACROS ========================================*/ -// TEST CODE -#define TRIG1 DDRB |= 0x04, PINB |= 0x04 -#define TRIG2 DDRD |= 0x80, PIND |= 0x80 - /** \name This is the list of pin configurations needed for a given platform. * \brief Change these values to port to other platforms. * \{ @@ -97,10 +94,6 @@ # define IRQPIN (0x04) # define SLPTRPORT B # define SLPTRPIN (0x04) -# define USART 1 -# define USARTVECT USART1_RX_vect -# define TICKTIMER 3 -# define HAS_SPARE_TIMER #elif PLATFORM_TYPE == ZIGBIT /* 1281V Zigbit */ @@ -116,12 +109,6 @@ # define IRQPIN (0x05) # define SLPTRPORT B # define SLPTRPIN (0x04) -# define TXCWPORT B -# define TXCWPIN (0x07) -# define USART 1 -# define USARTVECT USART1_RX_vect -//# define TICKTIMER 3 -//# define HAS_SPARE_TIMER // Not used #elif PLATFORM_TYPE == RAVEN_D @@ -138,13 +125,6 @@ # define IRQPIN (0x06) # define SLPTRPORT B # define SLPTRPIN (0x03) -# define TXCWPORT B -# define TXCWPIN (0x00) -# define USART 1 -# define USARTVECT USART1_RX_vect -# define TICKTIMER 3 -# define HAS_CW_MODE -# define HAS_SPARE_TIMER #elif PLATFORM_TYPE == RAVENUSB_C /* 1287USB raven */ @@ -160,23 +140,11 @@ # define IRQPIN (0x04) # define SLPTRPORT B # define SLPTRPIN (0x04) -# define TXCWPORT B -# define TXCWPIN (0x07) -# define USART 1 -# define USARTVECT USART1_RX_vect -# define TICKTIMER 3 -# define HAS_CW_MODE -# define HAS_SPARE_TIMER #elif PLATFORM_TYPE == ATMEGA128RFA1 /* ATmega1281 with internal AT86RF231 radio */ # define SLPTRPORT TRXPR # define SLPTRPIN 1 -# define USART 1 -# define USARTVECT USART1_RX_vect -# define TICKTIMER 3 -# define HAS_CW_MODE -# define HAS_SPARE_TIMER #elif CONTIKI_TARGET_MULLE /* mulle 5.2 (TODO: move to platform specific) */ @@ -194,7 +162,6 @@ # define IRQPIN 3 # define SLPTRPORT 0 # define SLPTRPIN 7 -# define HAS_SPARE_TIMER #elif PLATFORM_TYPE == IRIS /* 1281 IRIS */ @@ -210,12 +177,6 @@ # define IRQPIN (0x04) # define SLPTRPORT B # define SLPTRPIN (0x07) -//# define TXCWPORT B -//# define TXCWPIN (0x07) -# define USART 1 -# define USARTVECT USART1_RX_vect -//# define TICKTIMER 3 -//# define HAS_SPARE_TIMER // Not used #else #error "PLATFORM_TYPE undefined in hal.h" @@ -252,63 +213,17 @@ */ #if defined(__AVR__) #define CAT(x, y) x##y -#define CAT2(x, y, z) x##y##z #define DDR(x) CAT(DDR, x) #define PORT(x) CAT(PORT, x) #define PIN(x) CAT(PIN, x) -#define UCSR(num, let) CAT2(UCSR,num,let) -#define RXEN(x) CAT(RXEN,x) -#define TXEN(x) CAT(TXEN,x) -#define TXC(x) CAT(TXC,x) -#define RXC(x) CAT(RXC,x) -#define RXCIE(x) CAT(RXCIE,x) -#define UCSZ(x,y) CAT2(UCSZ,x,y) -#define UBRR(x,y) CAT2(UBRR,x,y) -#define UDRE(x) CAT(UDRE,x) -#define UDRIE(x) CAT(UDRIE,x) -#define UDR(x) CAT(UDR,x) -#define TCNT(x) CAT(TCNT,x) -#define TIMSK(x) CAT(TIMSK,x) -#define TCCR(x,y) CAT2(TCCR,x,y) -#define COM(x,y) CAT2(COM,x,y) -#define OCR(x,y) CAT2(OCR,x,y) -#define CS(x,y) CAT2(CS,x,y) -#define WGM(x,y) CAT2(WGM,x,y) -#define OCIE(x,y) CAT2(OCIE,x,y) -#define COMPVECT(x) CAT2(TIMER,x,_COMPA_vect) -#define UDREVECT(x) CAT2(USART,x,_UDRE_vect) -#define RXVECT(x) CAT2(USART,x,_RX_vect) #endif /* TODO: Move to CPU specific */ #if defined(CONTIKI_TARGET_MULLE) #define CAT(x, y) x##y.BYTE -#define CAT2(x, y, z) x##y##z.BYTE #define DDR(x) CAT(PD, x) #define PORT(x) CAT(P, x) #define PIN(x) CAT(P, x) -#define UCSR(num, let) CAT2(UCSR,num,let) -#define RXEN(x) CAT(RXEN,x) -#define TXEN(x) CAT(TXEN,x) -#define TXC(x) CAT(TXC,x) -#define RXC(x) CAT(RXC,x) -#define RXCIE(x) CAT(RXCIE,x) -#define UCSZ(x,y) CAT2(UCSZ,x,y) -#define UBRR(x,y) CAT2(UBRR,x,y) -#define UDRE(x) CAT(UDRE,x) -#define UDRIE(x) CAT(UDRIE,x) -#define UDR(x) CAT(UDR,x) -#define TCNT(x) CAT(TCNT,x) -#define TIMSK(x) CAT(TIMSK,x) -#define TCCR(x,y) CAT2(TCCR,x,y) -#define COM(x,y) CAT2(COM,x,y) -#define OCR(x,y) CAT2(OCR,x,y) -#define CS(x,y) CAT2(CS,x,y) -#define WGM(x,y) CAT2(WGM,x,y) -#define OCIE(x,y) CAT2(OCIE,x,y) -#define COMPVECT(x) CAT2(TIMER,x,_COMPA_vect) -#define UDREVECT(x) CAT2(USART,x,_UDRE_vect) -#define RXVECT(x) CAT2(USART,x,_RX_vect) #endif /** \} */ @@ -325,7 +240,6 @@ #define hal_set_rst_high( ) ( TRXPR |= ( 1 << TRXRST ) ) /**< This macro pulls the RST pin high. */ #define hal_set_slptr_high( ) ( TRXPR |= ( 1 << SLPTR ) ) /**< This macro pulls the SLP_TR pin high. */ #define hal_set_slptr_low( ) ( TRXPR &= ~( 1 << SLPTR ) ) /**< This macro pulls the SLP_TR pin low. */ -//#define hal_get_slptr( ) ( ( TRXPR & ( 1 << SLPTR ) ) >> SLPTR ) /**< Read current state of the SLP_TR pin (High/Low). */ #define hal_get_slptr( ) ( TRXPR & ( 1 << SLPTR ) ) /**< Read current state of the SLP_TR pin (High/Low). */ #else @@ -335,7 +249,6 @@ #define PIN_SLP_TR PIN( SLPTRPORT ) /**< Pin (Read Access) where SLP_TR is connected. */ #define hal_set_slptr_high( ) ( PORT_SLP_TR |= ( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin high. */ #define hal_set_slptr_low( ) ( PORT_SLP_TR &= ~( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin low. */ -//#define hal_get_slptr( ) ( ( PIN_SLP_TR & ( 1 << SLP_TR ) ) >> SLP_TR ) /**< Read current state of the SLP_TR pin (High/Low). */ #define hal_get_slptr( ) ( PIN_SLP_TR & ( 1 << SLP_TR ) ) /**< Read current state of the SLP_TR pin (High/Low). */ #define RST RSTPIN /**< Pin number that corresponds to the RST pin. */ #define DDR_RST DDR( RSTPORT ) /**< Data Direction Register that corresponds to the port where RST is */ @@ -370,42 +283,7 @@ #define HAL_SS_HIGH( ) (HAL_PORT_SS |= ( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS high. */ #define HAL_SS_LOW( ) (HAL_PORT_SS &= ~( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS low. */ -/** \brief Macros defined for HAL_TIMER1. - * - * These macros are used to define the correct setupt of the AVR's Timer1, and - * to ensure that the hal_get_system_time function returns the system time in - * symbols (16 us ticks). - */ - #if defined(__AVR__) -#if ( F_CPU == 16000000UL ) - #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS12 ) ) - #define HAL_US_PER_SYMBOL ( 1 ) - #define HAL_SYMBOL_MASK ( 0xFFFFffff ) -#elif ( F_CPU == 0x800000UL ) - #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) ) - #define HAL_US_PER_SYMBOL ( 2 ) - #define HAL_SYMBOL_MASK ( 0x7FFFffff ) -#elif ( F_CPU == 8000000UL ) - #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) ) - #define HAL_US_PER_SYMBOL ( 2 ) - #define HAL_SYMBOL_MASK ( 0x7FFFffff ) -//#elif ( F_CPU == 7953408UL ) -#elif ( F_CPU == 7954432UL ) - #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) ) - #define HAL_US_PER_SYMBOL ( 2 ) - #define HAL_SYMBOL_MASK ( 0x7FFFffff ) -#elif ( F_CPU == 4000000UL ) - #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) ) - #define HAL_US_PER_SYMBOL ( 1 ) - #define HAL_SYMBOL_MASK ( 0xFFFFffff ) -#elif ( F_CPU == 1000000UL ) - #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) ) - #define HAL_US_PER_SYMBOL ( 2 ) - #define HAL_SYMBOL_MASK ( 0x7FFFffff ) -#else - #error "Clock speed not supported." -#endif #if PLATFORM_TYPE == ZIGBIT // IRQ E5 for Zigbit example @@ -485,32 +363,10 @@ typedef struct{ bool crc; /**< Flag - did CRC pass for received frame? */ } hal_rx_frame_t; -/** RX_START event handler callback type. Is called with timestamp in IEEE 802.15.4 symbols and frame length. See hal_set_rx_start_event_handler(). */ -typedef void (*hal_rx_start_isr_event_handler_t)(uint32_t const isr_timestamp, uint8_t const frame_length); - -/** RRX_END event handler callback type. Is called with timestamp in IEEE 802.15.4 symbols and frame length. See hal_set_trx_end_event_handler(). */ -typedef void (*hal_trx_end_isr_event_handler_t)(uint32_t const isr_timestamp); - -typedef void (*rx_callback_t) (uint16_t data); /*============================ PROTOTYPES ====================================*/ void hal_init( void ); -void hal_reset_flags( void ); -uint8_t hal_get_bat_low_flag( void ); -void hal_clear_bat_low_flag( void ); - -hal_trx_end_isr_event_handler_t hal_get_trx_end_event_handler( void ); -void hal_set_trx_end_event_handler( hal_trx_end_isr_event_handler_t trx_end_callback_handle ); -void hal_clear_trx_end_event_handler( void ); - -hal_rx_start_isr_event_handler_t hal_get_rx_start_event_handler( void ); -void hal_set_rx_start_event_handler( hal_rx_start_isr_event_handler_t rx_start_callback_handle ); -void hal_clear_rx_start_event_handler( void ); - -uint8_t hal_get_pll_lock_flag( void ); -void hal_clear_pll_lock_flag( void ); - /* Hack for atmega128rfa1 with integrated radio. Access registers directly, not through SPI */ #if defined(__AVR_ATmega128RFA1__) //#define hal_register_read(address) _SFR_MEM8((uint16_t)address) @@ -534,8 +390,6 @@ void hal_subregister_write( uint8_t address, uint8_t mask, uint8_t position, -//void hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback); -/* For speed RF230BB does not use a callback */ void hal_frame_read(hal_rx_frame_t *rx_frame); void hal_frame_write( uint8_t *write_buffer, uint8_t length ); void hal_sram_read( uint8_t address, uint8_t length, uint8_t *data ); diff --git a/cpu/avr/radio/rf230bb/halbb.c b/cpu/avr/radio/rf230bb/halbb.c index 4b31fd9ed..53deb1c8a 100644 --- a/cpu/avr/radio/rf230bb/halbb.c +++ b/cpu/avr/radio/rf230bb/halbb.c @@ -10,6 +10,7 @@ * Kevin Brown kbrown3@uccs.edu * Nate Bohlmann nate@elfwerks.com * David Kopf dak664@embarqmail.com + * Ivan Delamer delamer@ieee.com * * All rights reserved. * @@ -80,66 +81,18 @@ extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; #endif /*============================ VARIABLES =====================================*/ -/** \brief This is a file internal variable that contains the 16 MSB of the - * system time. - * - * The system time (32-bit) is the current time in microseconds. For the - * AVR microcontroller implementation this is solved by using a 16-bit - * timer (Timer1) with a clock frequency of 1MHz. The hal_system_time is - * incremented when the 16-bit timer overflows, representing the 16 MSB. - * The timer value it self (TCNT1) is then the 16 LSB. - * - * \see hal_get_system_time - */ -static uint16_t hal_system_time = 0; -volatile extern signed char rf230_last_rssi; -//static uint8_t volatile hal_bat_low_flag; -//static uint8_t volatile hal_pll_lock_flag; +volatile extern signed char rf230_last_rssi; /*============================ CALLBACKS =====================================*/ -/** \brief This function is called when a rx_start interrupt is signaled. - * - * If this function pointer is set to something else than NULL, it will - * be called when a RX_START event is signaled. The function takes two - * parameters: timestamp in IEEE 802.15.4 symbols (16 us resolution) and - * frame length. The event handler will be called in the interrupt domain, - * so the function must be kept short and not be blocking! Otherwise the - * system performance will be greatly degraded. - * - * \see hal_set_rx_start_event_handler - */ -//static hal_rx_start_isr_event_handler_t rx_start_callback; - -/** \brief This function is called when a trx_end interrupt is signaled. - * - * If this function pointer is set to something else than NULL, it will - * be called when a TRX_END event is signaled. The function takes one - * parameter: timestamp in IEEE 802.15.4 symbols (16 us resolution). - * The event handler will be called in the interrupt domain, - * so the function must not block! - * - * \see hal_set_trx_end_event_handler - */ -//static hal_trx_end_isr_event_handler_t trx_end_callback; /*============================ IMPLEMENTATION ================================*/ #if defined(__AVR_ATmega128RFA1__) -//#include -#include + /* AVR1281 with internal RF231 radio */ -#define HAL_SPI_TRANSFER_OPEN() -//#define HAL_SPI_TRANSFER_WRITE(to_write) (SPDR = (to_write)) -#define HAL_SPI_TRANSFER_WAIT() -#define HAL_SPI_TRANSFER_READ() (SPDR) -#define HAL_SPI_TRANSFER_CLOSE() -#if 0 -#define HAL_SPI_TRANSFER(to_write) ( \ - HAL_SPI_TRANSFER_WRITE(to_write), \ - HAL_SPI_TRANSFER_WAIT(), \ - HAL_SPI_TRANSFER_READ() ) -#endif +#include + #elif defined(__AVR__) /* * AVR with hardware SPI tranfers (TODO: move to hw spi hal for avr cpu) @@ -206,30 +159,22 @@ inline uint8_t spiWrite(uint8_t byte) /** \brief This function initializes the Hardware Abstraction Layer. */ #if defined(__AVR_ATmega128RFA1__) -//#define HAL_RF230_ISR() ISR(RADIO_VECT) -#define HAL_TIME_ISR() ISR(TIMER1_OVF_vect) -#define HAL_TICK_UPCNT() (TCNT1) + void hal_init(void) { /*Reset variables used in file.*/ - hal_system_time = 0; - // TCCR1B = HAL_TCCR1B_CONFIG; /* Set clock prescaler */ - // TIFR1 |= (1 << ICF1); /* Clear Input Capture Flag. */ - // HAL_ENABLE_OVERFLOW_INTERRUPT(); /* Enable Timer1 overflow interrupt. */ - //hal_enable_trx_interrupt(); /* NOT USED: Enable interrupt pin from the radio transceiver. */ + /* (none at the moment) */ } #elif defined(__AVR__) + #define HAL_RF230_ISR() ISR(RADIO_VECT) -#define HAL_TIME_ISR() ISR(TIMER1_OVF_vect) -#define HAL_TICK_UPCNT() (TCNT1) + void hal_init(void) { /*Reset variables used in file.*/ - hal_system_time = 0; -// hal_reset_flags(); /*IO Specific Initialization - sleep and reset pins. */ /* Set pins low before they are initialized as output? Does not seem to matter */ @@ -249,11 +194,8 @@ hal_init(void) SPCR = (1 << SPE) | (1 << MSTR); /* Enable SPI module and master operation. */ SPSR = (1 << SPI2X); /* Enable doubled SPI speed in master mode. */ - /*TIMER1 Specific Initialization.*/ - TCCR1B = HAL_TCCR1B_CONFIG; /* Set clock prescaler */ - TIFR1 |= (1 << ICF1); /* Clear Input Capture Flag. */ - HAL_ENABLE_OVERFLOW_INTERRUPT(); /* Enable Timer1 overflow interrupt. */ - hal_enable_trx_interrupt(); /* Enable interrupts from the radio transceiver. */ + /* Enable interrupts from the radio transceiver. */ + hal_enable_trx_interrupt(); } #else /* __AVR__ */ @@ -266,8 +208,6 @@ void hal_init(void) { /*Reset variables used in file.*/ - hal_system_time = 0; -// hal_reset_flags(); /*IO Specific Initialization - sleep and reset pins. */ DDR_SLP_TR |= (1 << SLP_TR); /* Enable SLP_TR as output. */ @@ -295,144 +235,12 @@ hal_init(void) TBSR.BIT.TB4S = 1; // Start Timer B4 INT1IC.BIT.POL = 1; // Select rising edge HAL_ENABLE_OVERFLOW_INTERRUPT(); /* Enable Timer overflow interrupt. */ - hal_enable_trx_interrupt(); /* Enable interrupts from the radio transceiver. */ + + /* Enable interrupts from the radio transceiver. */ + hal_enable_trx_interrupt(); } #endif /* !__AVR__ */ -/*----------------------------------------------------------------------------*/ -/** \brief This function reset the interrupt flags and interrupt event handlers - * (Callbacks) to their default value. - */ -//void -//hal_reset_flags(void) -//{ -// HAL_ENTER_CRITICAL_REGION(); - - /* Reset Flags. */ -// hal_bat_low_flag = 0; -// hal_pll_lock_flag = 0; - - /* Reset Associated Event Handlers. */ -// rx_start_callback = NULL; -// trx_end_callback = NULL; - -// HAL_LEAVE_CRITICAL_REGION(); -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function returns the current value of the BAT_LOW flag. - * - * The BAT_LOW flag is incremented each time a BAT_LOW event is signaled from the - * radio transceiver. This way it is possible for the end user to poll the flag - * for new event occurances. - */ -//uint8_t -//hal_get_bat_low_flag(void) -//{ -// return hal_bat_low_flag; -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function clears the BAT_LOW flag. - */ -//void -//hal_clear_bat_low_flag(void) -//{ -// HAL_ENTER_CRITICAL_REGION(); -// hal_bat_low_flag = 0; -// HAL_LEAVE_CRITICAL_REGION(); -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function is used to set new TRX_END event handler, overriding - * old handler reference. - */ -//hal_trx_end_isr_event_handler_t -//hal_get_trx_end_event_handler(void) -//{ -// return trx_end_callback; -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function is used to set new TRX_END event handler, overriding - * old handler reference. - */ -//void -//hal_set_trx_end_event_handler(hal_trx_end_isr_event_handler_t trx_end_callback_handle) -//{ -// HAL_ENTER_CRITICAL_REGION(); -// trx_end_callback = trx_end_callback_handle; -// HAL_LEAVE_CRITICAL_REGION(); -//} - -/*----------------------------------------------------------------------------*/ -/** \brief Remove event handler reference. - */ -//void -//hal_clear_trx_end_event_handler(void) -//{ -// HAL_ENTER_CRITICAL_REGION(); -// trx_end_callback = NULL; -// HAL_LEAVE_CRITICAL_REGION(); -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function returns the active RX_START event handler - * - * \return Current RX_START event handler registered. - */ -//hal_rx_start_isr_event_handler_t -//hal_get_rx_start_event_handler(void) -//{ -// return rx_start_callback; -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function is used to set new RX_START event handler, overriding - * old handler reference. - */ -//void -//hal_set_rx_start_event_handler(hal_rx_start_isr_event_handler_t rx_start_callback_handle) -//{ -// HAL_ENTER_CRITICAL_REGION(); -// rx_start_callback = rx_start_callback_handle; -// HAL_LEAVE_CRITICAL_REGION(); -//} - -/*----------------------------------------------------------------------------*/ -/** \brief Remove event handler reference. - */ -//void -//hal_clear_rx_start_event_handler(void) -//{ -// HAL_ENTER_CRITICAL_REGION(); -// rx_start_callback = NULL; -// HAL_LEAVE_CRITICAL_REGION(); -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function returns the current value of the PLL_LOCK flag. - * - * The PLL_LOCK flag is incremented each time a PLL_LOCK event is signaled from the - * radio transceiver. This way it is possible for the end user to poll the flag - * for new event occurances. - */ -//uint8_t -//hal_get_pll_lock_flag(void) -//{ -// return hal_pll_lock_flag; -//} - -/*----------------------------------------------------------------------------*/ -/** \brief This function clears the PLL_LOCK flag. - */ -//void -//hal_clear_pll_lock_flag(void) -//{ -// HAL_ENTER_CRITICAL_REGION(); -// hal_pll_lock_flag = 0; -// HAL_LEAVE_CRITICAL_REGION(); -//} #if defined(__AVR_ATmega128RFA1__) /* Hack for internal radio registers. hal_register_read and hal_register_write are @@ -459,14 +267,16 @@ void hal_subregister_write(uint16_t address, uint8_t mask, uint8_t position, uint8_t value) { - cli(); + HAL_ENTER_CRITICAL_REGION(); + uint8_t register_value = _SFR_MEM8(address); register_value &= ~mask; value <<= position; value &= mask; value |= register_value; _SFR_MEM8(address) = value; - sei(); + + HAL_LEAVE_CRITICAL_REGION(); } #else /* defined(__AVR_ATmega128RFA1__) */ @@ -597,41 +407,57 @@ hal_frame_read(hal_rx_frame_t *rx_frame) * Bypassing the length check can result in overrun if buffer is < 256 bytes. */ frame_length = TST_RX_LENGTH; - if ( 0 || ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))) { - rx_frame->length = frame_length; + if ((frame_length < HAL_MIN_FRAME_LENGTH) || (frame_length > HAL_MAX_FRAME_LENGTH)) { + /* Length test failed */ + rx_frame->length = 0; + rx_frame->lqi = 0; + rx_frame->crc = false; + return; + } + rx_frame->length = frame_length; - /* Start of buffer in I/O space, pointer to RAM buffer */ - rx_buffer=(uint8_t *)0x180; - rx_data = (rx_frame->data); + /* Start of buffer in I/O space, pointer to RAM buffer */ + rx_buffer=(uint8_t *)0x180; + rx_data = (rx_frame->data); - do{ - *rx_data++ = _SFR_MEM8(rx_buffer++); - } while (--frame_length > 0); + do{ + *rx_data++ = _SFR_MEM8(rx_buffer++); + } while (--frame_length > 0); - /*Read LQI value for this frame.*/ - rx_frame->lqi = *rx_buffer; + /*Read LQI value for this frame.*/ + rx_frame->lqi = *rx_buffer; + + /* If crc was calculated set crc field in hal_rx_frame_t accordingly. + * Else show the crc has passed the hardware check. + */ + rx_frame->crc = true; #else /* defined(__AVR_ATmega128RFA1__) */ - uint8_t *rx_data; + uint8_t frame_length, *rx_data; /*Send frame read (long mode) command.*/ HAL_SPI_TRANSFER_OPEN(); HAL_SPI_TRANSFER(0x20); /*Read frame length. This includes the checksum. */ - uint8_t frame_length = HAL_SPI_TRANSFER(0); + frame_length = HAL_SPI_TRANSFER(0); /*Check for correct frame length. Bypassing this test can result in a buffer overrun! */ - if ( 0 || ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))) { - + if ((frame_length < HAL_MIN_FRAME_LENGTH) || (frame_length > HAL_MAX_FRAME_LENGTH)) { + /* Length test failed */ + rx_frame->length = 0; + rx_frame->lqi = 0; + rx_frame->crc = false; + } + else { rx_data = (rx_frame->data); rx_frame->length = frame_length; /*Transfer frame buffer to RAM buffer */ - HAL_SPI_TRANSFER_WRITE(0); - HAL_SPI_TRANSFER_WAIT(); + HAL_SPI_TRANSFER_WRITE(0); + HAL_SPI_TRANSFER_WAIT(); do{ *rx_data++ = HAL_SPI_TRANSFER_READ(); HAL_SPI_TRANSFER_WRITE(0); @@ -643,7 +469,7 @@ hal_frame_read(hal_rx_frame_t *rx_frame) * The 802.15.4 standard requires 640us after a greater than 18 byte frame. * With a low interrupt latency overwrites should never occur. */ -// crc = _crc_ccitt_update(crc, tempData); + // crc = _crc_ccitt_update(crc, tempData); HAL_SPI_TRANSFER_WAIT(); @@ -651,23 +477,17 @@ hal_frame_read(hal_rx_frame_t *rx_frame) /*Read LQI value for this frame.*/ - rx_frame->lqi = HAL_SPI_TRANSFER_READ(); - -#endif /* defined(__AVR_ATmega128RFA1__) */ + rx_frame->lqi = HAL_SPI_TRANSFER_READ(); /* If crc was calculated set crc field in hal_rx_frame_t accordingly. * Else show the crc has passed the hardware check. */ rx_frame->crc = true; - - } else { - /* Length test failed */ - rx_frame->length = 0; - rx_frame->lqi = 0; - rx_frame->crc = false; } HAL_SPI_TRANSFER_CLOSE(); + +#endif /* defined(__AVR_ATmega128RFA1__) */ } /*----------------------------------------------------------------------------*/ @@ -765,25 +585,27 @@ hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) * \param length Length of the write burst * \param data Pointer to an array of bytes that should be written */ -//void -//hal_sram_write(uint8_t address, uint8_t length, uint8_t *data) -//{ -// HAL_SPI_TRANSFER_OPEN(); +#if 0 //omit unless needed +void +hal_sram_write(uint8_t address, uint8_t length, uint8_t *data) +{ + HAL_SPI_TRANSFER_OPEN(); /*Send SRAM write command.*/ -// HAL_SPI_TRANSFER(0x40); + HAL_SPI_TRANSFER(0x40); /*Send address where to start writing to.*/ -// HAL_SPI_TRANSFER(address); + HAL_SPI_TRANSFER(address); /*Upload the chosen memory area.*/ -// do{ -// HAL_SPI_TRANSFER(*data++); -// } while (--length > 0); + do{ + HAL_SPI_TRANSFER(*data++); + } while (--length > 0); -// HAL_SPI_TRANSFER_CLOSE(); + HAL_SPI_TRANSFER_CLOSE(); -//} +} +#endif /*----------------------------------------------------------------------------*/ /* This #if compile switch is used to provide a "standard" function body for the */ @@ -862,28 +684,26 @@ ISR(TRX24_PLL_UNLOCK_vect) DEBUGFLOW('5'); } /* Flag is set by the following interrupts */ -extern volatile uint8_t rf230_interruptwait,rf230_ccawait; +extern volatile uint8_t rf230_wakewait, rf230_txendwait,rf230_ccawait; /* Wake has finished */ ISR(TRX24_AWAKE_vect) { // DEBUGFLOW('6'); - rf230_interruptwait=0; + rf230_wakewait=0; } /* Transmission has ended */ ISR(TRX24_TX_END_vect) { // DEBUGFLOW('7'); - rf230_interruptwait=0; + rf230_txendwait=0; } /* Frame address has matched ours */ -extern volatile uint8_t rf230_pending; ISR(TRX24_XAH_AMI_vect) { // DEBUGFLOW('8'); - rf230_pending=1; } /* CCAED measurement has completed */ @@ -897,14 +717,6 @@ ISR(TRX24_CCA_ED_DONE_vect) /* Separate RF230 has a single radio interrupt and the source must be read from the IRQ_STATUS register */ HAL_RF230_ISR() { - /*The following code reads the current system time. This is done by first - reading the hal_system_time and then adding the 16 LSB directly from the - hardware counter. - */ -// uint32_t isr_timestamp = hal_system_time; -// isr_timestamp <<= 16; -// isr_timestamp |= HAL_TICK_UPCNT(); // TODO: what if this wraps after reading hal_system_time? - volatile uint8_t state; uint8_t interrupt_source; /* used after HAL_SPI_TRANSFER_OPEN/CLOSE block */ @@ -919,22 +731,10 @@ HAL_RF230_ISR() /*Send Register address and read register content.*/ HAL_SPI_TRANSFER_WRITE(0x80 | RG_IRQ_STATUS); - /* This is the second part of the convertion of system time to a 16 us time - base. The division is moved here so we can spend less time waiting for SPI - data. - */ -// isr_timestamp /= HAL_US_PER_SYMBOL; /* Divide so that we get time in 16us resolution. */ -// isr_timestamp &= HAL_SYMBOL_MASK; - HAL_SPI_TRANSFER_WAIT(); /* AFTER possible interleaved processing */ -#if 0 //dak - interrupt_source = HAL_SPI_TRANSFER_READ(); /* The interrupt variable is used as a dummy read. */ - - interrupt_source = HAL_SPI_TRANSFER(interrupt_source); -#else interrupt_source = HAL_SPI_TRANSFER(0); -#endif + HAL_SPI_TRANSFER_CLOSE(); /*Handle the incomming interrupt. Prioritized.*/ @@ -950,44 +750,30 @@ HAL_RF230_ISR() rf230_last_rssi = 3 * hal_subregister_read(SR_RSSI); #endif #endif -// if(rx_start_callback != NULL){ -// /* Read Frame length and call rx_start callback. */ -// HAL_SPI_TRANSFER_OPEN(); -// uint8_t frame_length = HAL_SPI_TRANSFER(0x20); -// frame_length = HAL_SPI_TRANSFER(frame_length); -// HAL_SPI_TRANSFER_CLOSE(); - -// rx_start_callback(isr_timestamp, frame_length); -// } } else if (interrupt_source & HAL_TRX_END_MASK){ INTERRUPTDEBUG(11); -// if(trx_end_callback != NULL){ -// trx_end_callback(isr_timestamp); -// } state = hal_subregister_read(SR_TRX_STATUS); if((state == BUSY_RX_AACK) || (state == RX_ON) || (state == BUSY_RX) || (state == RX_AACK_ON)){ - /* Received packet interrupt */ - /* Buffer the frame and call rf230_interrupt to schedule poll for rf230 receive process */ -// if (rxframe.length) break; //toss packet if last one not processed yet + /* Received packet interrupt */ + /* Buffer the frame and call rf230_interrupt to schedule poll for rf230 receive process */ if (rxframe[rxframe_tail].length) INTERRUPTDEBUG(42); else INTERRUPTDEBUG(12); #ifdef RF230_MIN_RX_POWER - /* Discard packets weaker than the minimum if defined. This is for testing miniature meshes.*/ - /* Save the rssi for printing in the main loop */ + /* Discard packets weaker than the minimum if defined. This is for testing miniature meshes.*/ + /* Save the rssi for printing in the main loop */ #if RF230_CONF_AUTOACK - // rf230_last_rssi=hal_subregister_read(SR_ED_LEVEL); - rf230_last_rssi=hal_register_read(RG_PHY_ED_LEVEL); + //rf230_last_rssi=hal_subregister_read(SR_ED_LEVEL); + rf230_last_rssi=hal_register_read(RG_PHY_ED_LEVEL); #endif - if (rf230_last_rssi >= RF230_MIN_RX_POWER) { + if (rf230_last_rssi >= RF230_MIN_RX_POWER) { #endif - hal_frame_read(&rxframe[rxframe_tail]); - rxframe_tail++;if (rxframe_tail >= RF230_CONF_RX_BUFFERS) rxframe_tail=0; - rf230_interrupt(); -// trx_end_callback(isr_timestamp); + hal_frame_read(&rxframe[rxframe_tail]); + rxframe_tail++;if (rxframe_tail >= RF230_CONF_RX_BUFFERS) rxframe_tail=0; + rf230_interrupt(); #ifdef RF230_MIN_RX_POWER - } + } #endif } @@ -1000,7 +786,6 @@ HAL_RF230_ISR() ; } else if (interrupt_source & HAL_PLL_LOCK_MASK){ INTERRUPTDEBUG(15); -// hal_pll_lock_flag++; ; } else if (interrupt_source & HAL_BAT_LOW_MASK){ /* Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */ @@ -1009,7 +794,6 @@ HAL_RF230_ISR() uint8_t trx_isr_mask = hal_register_read(RG_IRQ_MASK); trx_isr_mask &= ~HAL_BAT_LOW_MASK; hal_register_write(RG_IRQ_MASK, trx_isr_mask); -// hal_bat_low_flag++; /* Increment BAT_LOW flag. */ INTERRUPTDEBUG(16); ; } else { @@ -1020,21 +804,6 @@ HAL_RF230_ISR() #endif /* defined(__AVR_ATmega128RFA1__) */ # endif /* defined(DOXYGEN) */ -/*----------------------------------------------------------------------------*/ -/* This #if compile switch is used to provide a "standard" function body for the */ -/* doxygen documentation. */ -#if defined(DOXYGEN) -/** \brief Timer Overflow ISR - * This is the interrupt service routine for timer1 overflow. - */ -void TIMER1_OVF_vect(void); -#else /* !DOXYGEN */ -HAL_TIME_ISR() -{ - hal_system_time++; -} -#endif - /** @} */ /** @} */ diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index cc3eb4db4..65f961693 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -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<=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< 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<=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 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 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; } } diff --git a/cpu/avr/radio/rf230bb/rf230bb.h b/cpu/avr/radio/rf230bb/rf230bb.h index 2cadfa6e7..020c3250f 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.h +++ b/cpu/avr/radio/rf230bb/rf230bb.h @@ -10,6 +10,7 @@ * Kevin Brown kbrown3@uccs.edu * Nate Bohlmann nate@elfwerks.com * David Kopf dak664@embarqmail.com + * Ivan Delamer delamer@ieee.com * * All rights reserved. * @@ -82,7 +83,6 @@ #define RF230_MIN_ED_THRESHOLD ( 0 ) #define RF230_MAX_ED_THRESHOLD ( 15 ) #define RF230_MAX_TX_FRAME_LENGTH ( 127 ) /**< 127 Byte PSDU. */ -//#define RF230_MAX_PACKET_LEN 127 #define TX_PWR_3DBM ( 0 ) #define TX_PWR_17_2DBM ( 15 ) @@ -166,7 +166,6 @@ typedef enum{ * */ typedef enum{ -// CCA_ED = 0, /**< Use energy detection above threshold mode. */ conflicts with atmega128rfa1 mcu definition CCA_ENERGY_DETECT = 0, /**< Use energy detection above threshold mode. */ CCA_CARRIER_SENSE = 1, /**< Use carrier sense mode. */ CCA_CARRIER_SENSE_WITH_ED = 2 /**< Use a combination of both energy detection and carrier sense. */ @@ -210,8 +209,6 @@ const struct radio_driver rf230_driver; int rf230_init(void); void rf230_warm_reset(void); void rf230_start_sneeze(void); -//int rf230_on(void); -//int rf230_off(void); void rf230_set_channel(uint8_t channel); void rf230_listen_channel(uint8_t channel); uint8_t rf230_get_channel(void); diff --git a/platform/avr-atmega128rfa1/contiki-conf.h b/platform/avr-atmega128rfa1/contiki-conf.h index 0cf995e34..aeec6959a 100644 --- a/platform/avr-atmega128rfa1/contiki-conf.h +++ b/platform/avr-atmega128rfa1/contiki-conf.h @@ -137,7 +137,7 @@ typedef unsigned short uip_stats_t; /* Network setup */ /* TX routine passes the cca/ack result in the return parameter */ #define RDC_CONF_HARDWARE_ACK 1 -/* TX routine does automatic cca and optional backoff */ +/* TX routine does automatic cca and optional backoffs */ #define RDC_CONF_HARDWARE_CSMA 1 /* Allow MCU sleeping between channel checks */ #define RDC_CONF_MCU_SLEEP 1 @@ -193,8 +193,10 @@ typedef unsigned short uip_stats_t; #define RF230_CONF_AUTOACK 1 /* Request 802.15.4 ACK on all packets sent (else autoretry). This is primarily for testing. */ #define SICSLOWPAN_CONF_ACK_ALL 0 -/* Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode with CCA) */ -#define RF230_CONF_AUTORETRIES 2 +/* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode) */ +#define RF230_CONF_FRAME_RETRIES 2 +/* Number of csma retry attempts 0-5 in extended tx mode (7 does immediate tx with no csma) */ +#define RF230_CONF_CSMA_RETRIES 5 /* Default is one RAM buffer for received packets. More than one may benefit multiple TCP connections or ports */ #define RF230_CONF_RX_BUFFERS 3 #define SICSLOWPAN_CONF_FRAG 1 @@ -250,9 +252,10 @@ typedef unsigned short uip_stats_t; #define RTIMER_CONF_NESTED_INTERRUPTS 1 #define RF230_CONF_AUTOACK 1 /* A 0 here means non-extended mode; 1 means extended mode with no retry, >1 for retrys */ -#define RF230_CONF_AUTORETRIES 1 -/* A 0 here means no cca; 1 means extended mode with cca but no retry, >1 for backoff retrys */ -#define RF230_CONF_CSMARETRIES 1 +/* Contikimac strobes on its own, but hardware retries are faster */ +#define RF230_CONF_FRAME_RETRIES 1 +/* Long csma backoffs will compromise radio cycling; set to 0 for 1 csma */ +#define RF230_CONF_CSMA_RETRIES 0 #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 3 /* 211 bytes per queue buffer. Contikimac burst mode needs 15 for a 1280 byte MTU */ @@ -263,7 +266,7 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_MAX_CONNECTIONS 2 #define UIP_CONF_MAX_LISTENPORTS 4 #define UIP_CONF_UDP_CONNS 5 -#define UIP_CONF_DS6_NBR_NBU 4 +#define UIP_CONF_DS6_NBR_NBU 20 #define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_ROUTE_NBU 4 @@ -274,8 +277,10 @@ typedef unsigned short uip_stats_t; #elif 1 /* cx-mac radio cycling */ /* RF230 does clear-channel assessment in extended mode (autoretries>0) */ -#define RF230_CONF_AUTORETRIES 1 -#if RF230_CONF_AUTORETRIES +/* These values are guesses */ +#define RF230_CONF_FRAME_RETRIES 10 +#define RF230_CONF_CSMA_RETRIES 2 +#if RF230_CONF_CSMA_RETRIES #define NETSTACK_CONF_MAC nullmac_driver #else #define NETSTACK_CONF_MAC csma_driver diff --git a/platform/avr-raven/contiki-conf.h b/platform/avr-raven/contiki-conf.h index 1bde0694b..733b3cacb 100644 --- a/platform/avr-raven/contiki-conf.h +++ b/platform/avr-raven/contiki-conf.h @@ -204,9 +204,9 @@ typedef unsigned short uip_stats_t; /* Request 802.15.4 ACK on all packets sent (else autoretry). This is primarily for testing. */ #define SICSLOWPAN_CONF_ACK_ALL 0 /* Number of auto retry attempts+1, 1-16. Set zero to disable extended TX_ARET_ON mode with CCA) */ -#define RF230_CONF_AUTORETRIES 3 +#define RF230_CONF_FRAME_RETRIES 3 /* Number of CSMA attempts 0-7. 802.15.4 2003 standard max is 5. */ -#define RF230_CONF_CSMARETRIES 5 +#define RF230_CONF_CSMA_RETRIES 5 /* CCA theshold energy -91 to -61 dBm (default -77). Set this smaller than the expected minimum rssi to avoid packet collisions */ /* The Jackdaw menu 'm' command is helpful for determining the smallest ever received rssi */ #define RF230_CONF_CCA_THRES -85 @@ -262,9 +262,9 @@ typedef unsigned short uip_stats_t; #define RTIMER_CONF_NESTED_INTERRUPTS 1 #define RF230_CONF_AUTOACK 1 /* A 0 here means non-extended mode; 1 means extended mode with no retry, >1 for retrys */ -#define RF230_CONF_AUTORETRIES 1 -/* A 0 here means no cca; 1 means extended mode with cca but no retry, >1 for backoff retrys */ -#define RF230_CONF_CSMARETRIES 1 +#define RF230_CONF_FRAME_RETRIES 1 +/* A 0 here means cca but no retry, >1= for backoff retrys */ +#define RF230_CONF_CSMA_RETRIES 1 #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 3 /* 211 bytes per queue buffer. Contikimac burst mode needs 15 for a 1280 byte MTU */ @@ -284,9 +284,9 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_DS6_AADDR_NBU 0 #elif 1 /* cx-mac radio cycling */ -/* RF230 does clear-channel assessment in extended mode (autoretries>0) */ -#define RF230_CONF_AUTORETRIES 1 -#if RF230_CONF_AUTORETRIES +/* RF230 does clear-channel assessment in extended mode (frame retries>0) */ +#define RF230_CONF_FRAME_RETRIES 1 +#if RF230_CONF_FRAME_RETRIES #define NETSTACK_CONF_MAC nullmac_driver #else #define NETSTACK_CONF_MAC csma_driver diff --git a/platform/avr-ravenusb/contiki-conf.h b/platform/avr-ravenusb/contiki-conf.h index 0571502b2..cef41e176 100644 --- a/platform/avr-ravenusb/contiki-conf.h +++ b/platform/avr-ravenusb/contiki-conf.h @@ -282,13 +282,13 @@ typedef unsigned short uip_stats_t; /* Request 802.15.4 ACK on all packets sent by sicslowpan.c (else autoretry) */ /* Broadcasts will be duplicated by the retry count, since no one will ACK them! */ #define SICSLOWPAN_CONF_ACK_ALL 0 -/* Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode with CCA) */ -#define RF230_CONF_AUTORETRIES 2 +/* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode with CCA) */ +#define RF230_CONF_FRAME_RETRIES 2 /* CCA theshold energy -91 to -61 dBm (default -77). Set this smaller than the expected minimum rssi to avoid packet collisions */ /* The Jackdaw menu 'm' command is helpful for determining the smallest ever received rssi */ #define RF230_CONF_CCA_THRES -85 /* Number of CSMA attempts 0-7. 802.15.4 2003 standard max is 5. */ -#define RF230_CONF_CSMARETRIES 5 +#define RF230_CONF_CSMA_RETRIES 5 /* Allow sneeze command from jackdaw menu. Useful for testing CCA on other radios */ /* During sneezing, any access to an RF230 register will hang the MCU and cause a watchdog reset */ /* The host interface, jackdaw menu and rf230_send routines are temporarily disabled to prevent this */ @@ -310,9 +310,9 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_RADIO rf230_driver #define CHANNEL_802_15_4 26 /* Enable extended mode with autoack, but no csma/autoretry */ -#define RF230_CONF_AUTORETRIES 1 +#define RF230_CONF_FRAME_RETRIES 1 #define RF230_CONF_AUTOACK 1 -#define RF230_CONF_CSMARETRIES 0 +#define RF230_CONF_CSMA_RETRIES 0 #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 3 /* Jackdaw has USB power, can be always listening */ @@ -347,7 +347,7 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_RADIO rf230_driver #define CHANNEL_802_15_4 26 #define RF230_CONF_AUTOACK 1 -#define RF230_CONF_AUTORETRIES 1 +#define RF230_CONF_FRAME_RETRIES 1 #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 3 #define CXMAC_CONF_ANNOUNCEMENTS 0 diff --git a/platform/avr-zigbit/contiki-conf.h b/platform/avr-zigbit/contiki-conf.h index 03943d991..4a7c4ab8b 100644 --- a/platform/avr-zigbit/contiki-conf.h +++ b/platform/avr-zigbit/contiki-conf.h @@ -116,7 +116,7 @@ void clock_adjust_ticks(clock_time_t howmany); #define NETSTACK_CONF_RADIO rf230_driver #define CHANNEL_802_15_4 26 #define RF230_CONF_AUTOACK 1 -#define RF230_CONF_AUTORETRIES 2 +#define RF230_CONF_FRAME_RETRIES 2 #define SICSLOWPAN_CONF_FRAG 1 //Most browsers reissue GETs after 3 seconds which stops frag reassembly, longer MAXAGE does no good #define SICSLOWPAN_CONF_MAXAGE 3