Use 128rfa1 interrupts instead of timing.

Generalize DEBUGFLOW macro for use in multiple routines.
This commit is contained in:
David Kopf 2011-08-15 15:06:38 -04:00
parent b55dddcd38
commit 577215deca
4 changed files with 158 additions and 117 deletions

View file

@ -58,7 +58,13 @@
* which communicates directly with the contiki core MAC layer.
* It is optimized for speed at the expense of generality.
*/
#include "contiki-conf.h"
#if DEBUGFLOWSIZE
extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
#else
#define DEBUGFLOW(c)
#endif
/*============================ INCLUDE =======================================*/
@ -814,118 +820,88 @@ volatile char rf230interruptflag;
#endif
#if defined(__AVR_ATmega128RFA1__)
/* The atmega128rfa1 has individual interrupts for the integrated radio */
/* Whichever are enabled by the RF230 driver must be present even if not used! */
/* The atmega128rfa1 has individual interrupts for the integrated radio'
* Whichever are enabled by the RF230 driver must be present even if not used!
*/
/* Received packet interrupt */
ISR(TRX24_RX_END_vect)
{
INTERRUPTDEBUG(11);
/* 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
if (rxframe[rxframe_tail].length) INTERRUPTDEBUG(42); else INTERRUPTDEBUG(12);
/* Get the rssi from ED if extended mode */
#if RF230_CONF_AUTOACK
rf230_last_rssi=hal_register_read(RG_PHY_ED_LEVEL);
#endif
/* Buffer the frame and call rf230_interrupt to schedule poll for rf230 receive process */
/* Is a ram buffer available? */
if (rxframe[rxframe_tail].length) {DEBUGFLOW('0');} else DEBUGFLOW('1');
#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 */
#if RF230_CONF_AUTOACK
// 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 (1) {
#endif
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
}
/* Discard packets weaker than the minimum if defined. This is for testing miniature meshes */
/* This does not prevent an autoack. TODO:rfa1 radio can be set up to not autoack weak packets */
if (rf230_last_rssi >= RF230_MIN_RX_POWER) {
#else
if (1) {
#endif
// DEBUGFLOW('2');
hal_frame_read(&rxframe[rxframe_tail]);
rxframe_tail++;if (rxframe_tail >= RF230_CONF_RX_BUFFERS) rxframe_tail=0;
rf230_interrupt();
}
}
/* Preamble detected, starting frame reception */
ISR(TRX24_RX_START_vect)
{
INTERRUPTDEBUG(10);
/* Save RSSI for this packet if not in extended mode, scaling to 1dB resolution */
// DEBUGFLOW('3');
/* Save RSSI for this packet if not in extended mode, scaling to 1dB resolution */
#if !RF230_CONF_AUTOACK
rf230_last_rssi = 3 * hal_subregister_read(SR_RSSI);
#endif
}
/* PLL has locked, either from a transition out of TRX_OFF or a channel change while on */
ISR(TRX24_PLL_LOCK_vect)
{
// DEBUGFLOW('4');
}
/* PLL has unexpectedly unlocked */
ISR(TRX24_PLL_UNLOCK_vect)
{
DEBUGFLOW('5');
}
/* Flag is set by the following interrupts */
extern volatile uint8_t rf230_interruptwait;
#if 0
HAL_RF230_ISR() //for reference, for now
/* Wake has finished */
ISR(TRX24_AWAKE_vect)
{
/*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?
// isr_timestamp /= HAL_US_PER_SYMBOL; /* Divide so that we get time in 16us resolution. */
// isr_timestamp &= HAL_SYMBOL_MASK;
uint8_t interrupt_source;
INTERRUPTDEBUG(1);
/*Read Interrupt source.*/
interrupt_source = IRQ_STATUS;
/*Handle the incomming interrupt. Prioritized.*/
if (interrupt_source & (1>>RX_START)){
INTERRUPTDEBUG(10);
/* Save RSSI for this packet if not in extended mode, scaling to 1dB resolution */
#if !RF230_CONF_AUTOACK
rf230_last_rssi = 3 * hal_subregister_read(SR_RSSI);
#endif
} else if (interrupt_source & (1<<RX_END)){
INTERRUPTDEBUG(11);
/* 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
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 */
#if RF230_CONF_AUTOACK
// 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 (1) {
#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);
#ifdef RF230_MIN_RX_POWER
}
#endif
} else if (interrupt_source & (1<<TX_END)){
INTERRUPTDEBUG(13);
;
} else if (interrupt_source & (1<<PLL_UNLOCK)){
INTERRUPTDEBUG(14);
;
} else if (interrupt_source & (1<<PLL_LOCK)){
INTERRUPTDEBUG(15);
// hal_pll_lock_flag++;
;
} else {
INTERRUPTDEBUG(99);
;
}
// DEBUGFLOW('6');
rf230_interruptwait=0;
}
#endif
/* Transmission has ended */
ISR(TRX24_TX_END_vect)
{
// DEBUGFLOW('7');
rf230_interruptwait=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 */
ISR(TRX24_CCA_ED_DONE_vect)
{
DEBUGFLOW('4');
rf230_interruptwait=0;
}
#else /* defined(__AVR_ATmega128RFA1__) */
/* Separate RF230 has a single radio interrupt and the source must be read from the IRQ_STATUS register */
HAL_RF230_ISR()

View file

@ -166,10 +166,9 @@ uint8_t rf230_calibrate;
uint8_t rf230_calibrated; //for debugging, prints from main loop when calibration occurs
#endif
/* Track flow through driver, see contiki-raven-main.c for example of use */
//#define DEBUGFLOWSIZE 128
/* Track flow through mac, rdc and radio drivers, see contiki-raven-main.c for example of use */
#if DEBUGFLOWSIZE
uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
#else
#define DEBUGFLOW(c)
@ -186,7 +185,11 @@ static unsigned long total_time_for_transmission, total_transmission_len;
static int num_transmissions;
#endif
static uint8_t volatile pending;
#if defined(__AVR_ATmega128RFA1__)
volatile uint8_t rf230_interruptwait;
#endif
uint8_t volatile rf230_pending;
/* RF230 hardware delay times, from datasheet */
typedef enum{
@ -217,7 +220,7 @@ static int rf230_transmit(unsigned short len);
static int rf230_send(const void *data, unsigned short len);
static int rf230_receiving_packet(void);
static int pending_packet(void);
static int rf230_pending_packet(void);
static int rf230_cca(void);
uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
@ -231,7 +234,7 @@ const struct radio_driver rf230_driver =
rf230_read,
rf230_cca,
rf230_receiving_packet,
pending_packet,
rf230_pending_packet,
rf230_on,
rf230_off
};
@ -320,6 +323,7 @@ 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);
hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF);
@ -495,6 +499,15 @@ on(void)
#endif
if (hal_get_slptr()) {
#if defined(__AVR_ATmega128RFA1__)
rf230_interruptwait=1;
ENERGEST_ON(ENERGEST_TYPE_LED_RED);
PORTE|=(1<<PE1); //ledon
hal_set_slptr_low();
while (rf230_interruptwait) {}
// rf230_waitidle(); //?
}
#else
uint8_t sreg = SREG;
cli();
// DEBUGFLOW('0');
@ -505,6 +518,7 @@ on(void)
SREG=sreg;
}
rf230_waitidle();
#endif
#if RF230_CONF_AUTOACK
// radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON);
@ -523,7 +537,6 @@ static void
off(void)
{
RF230_receive_on = 0;
#ifdef RF230BB_HOOK_RADIO_OFF
RF230BB_HOOK_RADIO_OFF();
#endif
@ -540,6 +553,8 @@ off(void)
radio_reset_state_machine();
#if RADIOSLEEPSWHENOFF
/* Sleep Radio */
ENERGEST_OFF(ENERGEST_TYPE_LED_RED);
// PORTE&=~(1<<PE1); //ledoff
hal_set_slptr_high();
// DEBUGFLOW('d');
delay_us(TIME_SLEEP_TO_TRX_OFF); //?
@ -800,6 +815,7 @@ void rf230_warm_reset(void) {
}
/*---------------------------------------------------------------------------*/
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN];
static int
rf230_transmit(unsigned short payload_len)
{
@ -819,10 +835,22 @@ rf230_transmit(unsigned short payload_len)
/* If radio is sleeping we have to turn it on first */
/* This automatically does the PLL calibrations */
if (hal_get_slptr()) {
#if defined(__AVR_ATmega128RFA1__)
if (radiowason) DEBUGFLOW('e');
radiowason=0;
// DEBUGFLOW('j');
ENERGEST_ON(ENERGEST_TYPE_LED_RED);
// PORTE|=(1<<PE1); //ledon
rf230_interruptwait=1;
hal_set_slptr_low();
while (rf230_interruptwait) {}
#else
hal_set_slptr_low();
DEBUGFLOW('j');
delay_us(TIME_SLEEP_TO_TRX_OFF);
delay_us(TIME_SLEEP_TO_TRX_OFF);
#endif
} else {
#if RADIO_CONF_CALIBRATE_INTERVAL
/* If nonzero, do periodic calibration. See clock.c */
@ -922,6 +950,8 @@ rf230_transmit(unsigned short payload_len)
if(radiowason) {
DEBUGFLOW('l');
on();
} else {
off();
}
#if RF230_CONF_TIMESTAMPS
@ -1207,7 +1237,7 @@ if (RF230_receive_on) {
TIMETABLE_TIMESTAMP(rf230_timetable, "interrupt");
#endif /* RF230_TIMETABLE_PROFILING */
pending = 1;
rf230_pending = 1;
#if RADIOSTATS //TODO:This will double count buffered packets
RF230_receivepackets++;
@ -1247,7 +1277,7 @@ PROCESS_THREAD(rf230_process, ev, data)
TIMETABLE_TIMESTAMP(rf230_timetable, "poll");
#endif /* RF230_TIMETABLE_PROFILING */
pending = 0;
rf230_pending = 0;
packetbuf_clear();
len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
@ -1520,25 +1550,31 @@ rf230_cca(void)
{
uint8_t cca=0;
uint8_t radio_was_off = 0;
uint8_t volatile saved_sreg = SREG;
/* If the radio is locked by an underlying thread (because we are
being invoked through an interrupt), we preted that the coast is
clear (i.e., no packet is currently being transmitted by a
neighbor). */
if(locked) {
DEBUGFLOW('1');
return 1;
DEBUGFLOW('|');
// return 1; rf230 hangs on occasion?
return 0;
}
/* Don't allow interrupts! */
//#if !defined(__AVR_ATmega128RFA1__)
cli();
//#endif
/* Turn radio on if necessary. If radio is currently busy return busy channel */
/* This may happen when testing radio duty cycling with RADIOALWAYSON */
if(RF230_receive_on) {
if (hal_get_slptr()) {
if (hal_get_slptr()) { //should not be sleeping!
DEBUGFLOW('<');
return 0;
goto busyexit;
} else {
if (!rf230_isidle()) {DEBUGFLOW('2');return 0;}
if (!rf230_isidle()) {DEBUGFLOW('2');goto busyexit;}
}
} else {
DEBUGFLOW('3');
@ -1552,21 +1588,34 @@ rf230_cca(void)
/* Start the CCA, wait till done, return result */
/* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */
#if defined(__AVR_ATmega128RFA1__)&&0
rf230_interruptwait=1;
hal_subregister_write(SR_CCA_REQUEST,1);
sei();
while (rf230_interruptwait) {}
// while ((cca & 0x80) == 0 ) {//TODO:why does this hang the 128rfa1?
cca=hal_register_read(RG_TRX_STATUS);
// }
#else
hal_subregister_write(SR_CCA_REQUEST,1);
delay_us(TIME_CCA);
while ((cca & 0x80) == 0 ) {
// while ((cca & 0x80) == 0 ) { //hangs 128rfa1
cca=hal_register_read(RG_TRX_STATUS);
}
// }
#endif
if(radio_was_off) {
rf230_off();
}
// if (cca & 0x40) {/*DEBUGFLOW('3')*/;} else {pending=1;DEBUGFLOW('4');}
// if (cca & 0x40) {/*DEBUGFLOW('3')*/;} else {rf230_pending=1;DEBUGFLOW('4');}
if (cca & 0x40) {
// DEBUGFLOW('5');
SREG=saved_sreg;
return 1;
} else {
// DEBUGFLOW('6');
// DEBUGFLOW('6');
busyexit:
SREG=saved_sreg;
return 0;
}
}
@ -1576,12 +1625,12 @@ rf230_receiving_packet(void)
{
uint8_t radio_state;
if (hal_get_slptr()) {
DEBUGFLOW('7');
DEBUGFLOW('=');
} else {
radio_state = hal_subregister_read(SR_TRX_STATUS);
if ((radio_state==BUSY_RX) || (radio_state==BUSY_RX_AACK)) {
DEBUGFLOW('8');
pending=1;
// DEBUGFLOW('8');
// rf230_pending=1;
return 1;
}
}
@ -1589,10 +1638,10 @@ rf230_receiving_packet(void)
}
/*---------------------------------------------------------------------------*/
static int
pending_packet(void)
rf230_pending_packet(void)
{
if (pending) DEBUGFLOW('9');
return pending;
if (rf230_pending) DEBUGFLOW('@');
return rf230_pending;
}
/*---------------------------------------------------------------------------*/
#if RF230_CONF_SNEEZER && JACKDAW

View file

@ -69,7 +69,11 @@
/* RF230 does not support RX_START interrupts in extended mode, but it seems harmless to always enable it. */
/* In non-extended mode this allows RX_START to sample the RF rssi at the end of the preamble */
//#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x0C ) //disable RX_START
#if defined(__AVR_ATmega128RFA1__)
#define RF230_SUPPORTED_INTERRUPT_MASK ( 0xFF )
#else
#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x0F )
#endif
#define RF230_MIN_CHANNEL ( 11 )
#define RF230_MAX_CHANNEL ( 26 )

View file

@ -77,9 +77,18 @@
#define TIFR TIFR1
#endif
/* Track flow through rtimer interrupts*/
#if DEBUGFLOWSIZE&&0
extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
#else
#define DEBUGFLOW(c)
#endif
/*---------------------------------------------------------------------------*/
#if defined(TCNT3) && RTIMER_ARCH_PRESCALER
ISR (TIMER3_COMPA_vect) {
DEBUGFLOW('/');
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/* Disable rtimer interrupts */
@ -96,14 +105,17 @@ ISR (TIMER3_COMPA_vect) {
rtimer_run_next();
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
DEBUGFLOW('\\');
}
#elif RTIMER_ARCH_PRESCALER
#warning "No Timer3 in rtimer-arch.c - using Timer1 instead"
ISR (TIMER1_COMPA_vect) {
DEBUGFLOW('/');
TIMSK &= ~((1<<TICIE1)|(1<<OCIE1A)|(1<<OCIE1B)|(1<<TOIE1));
rtimer_run_next();
DEBUGFLOW('\\');
}
#endif
@ -191,7 +203,7 @@ rtimer_arch_schedule(rtimer_clock_t t)
uint8_t sreg;
sreg = SREG;
cli ();
DEBUGFLOW(':');
#ifdef TCNT3
/* Set compare register */
OCR3A = t;