Get rssi correctly in either rx mode, clean up radio driver debugging

This commit is contained in:
dak664 2010-11-26 20:39:15 +00:00
parent 353bb07cc9
commit dc028b3f85
5 changed files with 107 additions and 43 deletions

View File

@ -640,11 +640,11 @@ void RADIO_VECT(void);
/* These link to the RF230BB driver in rf230.c */ /* These link to the RF230BB driver in rf230.c */
void rf230_interrupt(void); void rf230_interrupt(void);
extern hal_rx_frame_t rxframe; extern hal_rx_frame_t rxframe;
/* rf230interruptflag can be printed in the main idle loop for debugging */
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
volatile char rf230_interrupt_flag=0; volatile char rf230interruptflag;
#define INTERRUPTDEBUG(arg) rf230_interrupt_flag=arg #define INTERRUPTDEBUG(arg) rf230interruptflag=arg
#else #else
#define INTERRUPTDEBUG(arg) #define INTERRUPTDEBUG(arg)
#endif #endif
@ -717,11 +717,17 @@ ISR(RADIO_VECT)
if (rxframe.length) INTERRUPTDEBUG(42); else INTERRUPTDEBUG(12); if (rxframe.length) INTERRUPTDEBUG(42); else INTERRUPTDEBUG(12);
#ifdef RF230_MIN_RX_POWER #ifdef RF230_MIN_RX_POWER
/* Discard packets weaker than the minimum if defined */ /* Discard packets weaker than the minimum if defined. This is for testing miniature meshes.*/
/* Save the rssi for printing in the main loop */
volatile extern signed char rf230_last_rssi;
#if RF230_CONF_AUTOACK #if RF230_CONF_AUTOACK
if (hal_subregister_read(SR_ED_LEVEL) >= RF230_MIN_RX_POWER) { rf230_last_rssi=hal_subregister_read(SR_ED_LEVEL);
if (rf230_last_rssi >= RF230_MIN_RX_POWER) {
// if (hal_subregister_read(SR_ED_LEVEL) >= RF230_MIN_RX_POWER) {
#else #else
if (hal_subregister_read(SR_RSSI) >= RF230_MIN_RX_POWER) { rf230_last_rssi=hal_subregister_read(SR_RSSI);
// if (hal_subregister_read(SR_RSSI) >= RF230_MIN_RX_POWER/3) {
if (rf230_last_rssi >= RF230_MIN_RX_POWER/3) {
#endif #endif
#endif #endif
hal_frame_read(&rxframe, NULL); hal_frame_read(&rxframe, NULL);

View File

@ -28,7 +28,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* @(#)$Id: rf230bb.c,v 1.13 2010/11/24 18:46:59 dak664 Exp $ * @(#)$Id: rf230bb.c,v 1.14 2010/11/26 20:39:15 dak664 Exp $
*/ */
/* /*
* This code is almost device independent and should be easy to port. * This code is almost device independent and should be easy to port.
@ -965,17 +965,24 @@ if (RF230_receive_on) {
/* Process to handle input packets /* Process to handle input packets
* Receive interrupts cause this process to be polled * Receive interrupts cause this process to be polled
* It calls the core MAC layer which calls rf230_read to get the packet * It calls the core MAC layer which calls rf230_read to get the packet
* rf230processflag can be printed in the main idle loop for debugging
*/ */
char rf230processflag; //for debugging process call problems #if 1
uint8_t rf230processflag;
#define RF230PROCESSFLAG(arg) rf230processflag=arg
#else
#define RF230PROCESSFLAG(arg)
#endif
PROCESS_THREAD(rf230_process, ev, data) PROCESS_THREAD(rf230_process, ev, data)
{ {
int len; int len;
PROCESS_BEGIN(); PROCESS_BEGIN();
rf230processflag=99; RF230PROCESSFLAG(99);
while(1) { while(1) {
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
rf230processflag=42; RF230PROCESSFLAG(42);
#if RF230_TIMETABLE_PROFILING #if RF230_TIMETABLE_PROFILING
TIMETABLE_TIMESTAMP(rf230_timetable, "poll"); TIMETABLE_TIMESTAMP(rf230_timetable, "poll");
#endif /* RF230_TIMETABLE_PROFILING */ #endif /* RF230_TIMETABLE_PROFILING */
@ -984,12 +991,10 @@ PROCESS_THREAD(rf230_process, ev, data)
packetbuf_clear(); packetbuf_clear();
len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
// printf_P(PSTR("RSSI reads %x "),hal_subregister_read(SR_RSSI)); RF230PROCESSFLAG(1);
// printf_P(PSTR("ED reads %d "),hal_subregister_read(SR_ED_LEVEL));
rf230processflag=1;
if(len > 0) { if(len > 0) {
packetbuf_set_datalen(len); packetbuf_set_datalen(len);
rf230processflag=2; RF230PROCESSFLAG(2);
NETSTACK_RDC.input(); NETSTACK_RDC.input();
#if RF230_TIMETABLE_PROFILING #if RF230_TIMETABLE_PROFILING
TIMETABLE_TIMESTAMP(rf230_timetable, "end"); TIMETABLE_TIMESTAMP(rf230_timetable, "end");
@ -1105,11 +1110,17 @@ if (RF230_receive_on) {
checksum == crc16_data(buf, len - AUX_LEN, 0)) { checksum == crc16_data(buf, len - AUX_LEN, 0)) {
#endif /* RF230_CONF_CHECKSUM */ #endif /* RF230_CONF_CHECKSUM */
/* Get the received signal strength for the packet, 0-84 dB above rx threshold */
#if 0 //more general
rf230_last_rssi = rf230_get_raw_rssi();
#else //faster
#if RF230_CONF_AUTOACK #if RF230_CONF_AUTOACK
rf230_last_rssi = hal_subregister_read(SR_ED_LEVEL); //0-84 resolution 1 dB rf230_last_rssi = hal_subregister_read(SR_ED_LEVEL); //0-84 resolution 1 dB
#else #else
rf230_last_rssi = 3*hal_subregister_read(SR_RSSI); //0-28 resolution 3 dB rf230_last_rssi = 3*hal_subregister_read(SR_RSSI); //0-28 resolution 3 dB
#endif #endif
#endif /* speed vs. generality */
rf230_last_correlation = rxframe.lqi; rf230_last_correlation = rxframe.lqi;
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi); packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi);
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation); packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation);
@ -1188,7 +1199,7 @@ rf230_get_txpower(void)
uint8_t uint8_t
rf230_get_raw_rssi(void) rf230_get_raw_rssi(void)
{ {
uint8_t rssi; uint8_t rssi,state;
bool radio_was_off = 0; bool radio_was_off = 0;
/*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/ /*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/
@ -1196,12 +1207,15 @@ rf230_get_raw_rssi(void)
radio_was_off = 1; radio_was_off = 1;
rf230_on(); rf230_on();
} }
/* The energy detect register is used in extended mode (since RSSI will read 0) */ /* The energy detect register is used in extended mode (since RSSI will read 0) */
#if RF230_CONF_AUTOACK /* The rssi register is multiplied by 3 to a consistent value from either register */
state=radio_get_trx_state();
if ((state==RX_AACK_ON) || (state==BUSY_RX_AACK)) {
rssi = hal_subregister_read(SR_ED_LEVEL); //0-84, resolution 1 dB rssi = hal_subregister_read(SR_ED_LEVEL); //0-84, resolution 1 dB
#else } else {
rssi = 3*hal_subregister_read(SR_RSSI); //0-28, resolution 3 dB rssi = 3*hal_subregister_read(SR_RSSI); //0-28, resolution 3 dB
#endif }
if(radio_was_off) { if(radio_was_off) {
rf230_off(); rf230_off();

View File

@ -115,6 +115,11 @@ static uint8_t previous_uart_usb_control_line_state = 0;
static uint8_t timer = 0; static uint8_t timer = 0;
static struct etimer et; static struct etimer et;
#define CONVERTTXPOWER 1
#if CONVERTTXPOWER //adds 92 bytes to program flash size
const char txonesdigit[16] PROGMEM = {'3','2','2','1','1','0','0','1','2','3','4','5','7','9','2','7'};
const char txtenthsdigit[16] PROGMEM = {'0','6','1','6','1','5','2','2','2','2','2','2','2','2','2','2'};
#endif
PROCESS(cdc_process, "CDC serial process"); PROCESS(cdc_process, "CDC serial process");
@ -200,10 +205,8 @@ PROCESS_THREAD(cdc_process, ev, data_proc)
*/ */
void menu_print(void) void menu_print(void)
{ {
PRINTF_P(PSTR("\n\r********** Jackdaw Menu *********\n\r")); PRINTF_P(PSTR("\n\r*********** Jackdaw Menu **********\n\r"));
PRINTF_P(PSTR("* *\n\r")); PRINTF_P(PSTR("* *\n\r"));
PRINTF_P(PSTR("* Main Menu: *\n\r"));
PRINTF_P(PSTR("* h,? Print this menu *\n\r"));
PRINTF_P(PSTR("* m Print current mode *\n\r")); PRINTF_P(PSTR("* m Print current mode *\n\r"));
PRINTF_P(PSTR("* s Set to sniffer mode *\n\r")); PRINTF_P(PSTR("* s Set to sniffer mode *\n\r"));
PRINTF_P(PSTR("* n Set to network mode *\n\r")); PRINTF_P(PSTR("* n Set to network mode *\n\r"));
@ -224,6 +227,7 @@ void menu_print(void)
if(bootloader_is_present()) if(bootloader_is_present())
PRINTF_P(PSTR("* D Switch to DFU mode *\n\r")); PRINTF_P(PSTR("* D Switch to DFU mode *\n\r"));
PRINTF_P(PSTR("* R Reset (via WDT) *\n\r")); PRINTF_P(PSTR("* R Reset (via WDT) *\n\r"));
PRINTF_P(PSTR("* h,? Print this menu *\n\r"));
PRINTF_P(PSTR("* *\n\r")); PRINTF_P(PSTR("* *\n\r"));
PRINTF_P(PSTR("* Make selection at any time by *\n\r")); PRINTF_P(PSTR("* Make selection at any time by *\n\r"));
PRINTF_P(PSTR("* pressing your choice on keyboard*\n\r")); PRINTF_P(PSTR("* pressing your choice on keyboard*\n\r"));
@ -475,6 +479,20 @@ extern uip_ds6_route_t uip_ds6_routing_table[];
case 'G': case 'G':
PRINTF_P(PSTR("Global repair returns %d\n\r"),rpl_repair_dag(rpl_get_dag(RPL_ANY_INSTANCE))); PRINTF_P(PSTR("Global repair returns %d\n\r"),rpl_repair_dag(rpl_get_dag(RPL_ANY_INSTANCE)));
break; break;
case 'L':
rpl_local_repair(rpl_get_dag(RPL_ANY_INSTANCE));
PRINTF_P(PSTR("Local repair initiated\n\r"));
break;
case 'Z': //zap the routing table
{ uint8_t i;
for (i = 0; i < UIP_DS6_ROUTE_NB; i++) {
uip_ds6_routing_table[i].isused=0;
}
PRINTF_P(PSTR("Routing table cleared!\n\r"));
break;
}
#endif #endif
case 'm': case 'm':
@ -515,11 +533,22 @@ extern uip_ds6_route_t uip_ds6_routing_table[];
((uint8_t *)&macLongAddr)[7] ((uint8_t *)&macLongAddr)[7]
); );
#if RF230BB #if RF230BB
#if CONVERTTXPOWER
{
uint8_t power=rf230_get_txpower()&0xf;
char sign=(power<6?'+':'-');
char tens=(power>14?'1':'0');
char ones=pgm_read_byte(&txonesdigit[power]);
char tenths=pgm_read_byte(&txtenthsdigit[power]);
PRINTF_P(PSTR(" * Operates on channel %d with TX power %c%c%c.%cdBm\n\r"), rf230_get_channel(),sign,tens,ones,tenths);
}
#else //just show the raw value
PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel()); PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel());
PRINTF_P(PSTR(" * TX Power(0=3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower()); PRINTF_P(PSTR(" * TX Power(0=3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower());
PRINTF_P(PSTR(" * Current RSSI: %ddB\n\r"), -91+(rf230_rssi()-1)); #endif
PRINTF_P(PSTR(" * Last RSSI: %ddB\n\r"), -91+(rf230_last_rssi-1)); PRINTF_P(PSTR(" * Current/Last RSSI: %d/%ddBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1));
#else // RF230BB
#else /* RF230BB */
PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel()); PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel());
PRINTF_P(PSTR(" * TX Power Level: 0x%02X\n\r"), radio_get_tx_power_level()); PRINTF_P(PSTR(" * TX Power Level: 0x%02X\n\r"), radio_get_tx_power_level());
{ {
@ -531,9 +560,12 @@ extern uip_ds6_route_t uip_ds6_routing_table[];
PRINTF_P(PSTR("Unknown\n\r")); PRINTF_P(PSTR("Unknown\n\r"));
} }
#endif // !RF230BB #endif /* RF230BB */
PRINTF_P(PSTR(" * Configuration: %d\n\r"), usb_configuration_nb);
PRINTF_P(PSTR(" * usb_eth_is_active: %d\n\r"), usb_eth_is_active); PRINTF_P(PSTR(" * Configuration: %d, USB<->ETH is "), usb_configuration_nb);
if (usb_eth_is_active == 0) PRINTF_P(PSTR("not "));
PRINTF_P(PSTR("active\n\r"));
break; break;
case 'e': case 'e':
@ -562,9 +594,10 @@ extern uip_ds6_route_t uip_ds6_routing_table[];
#endif #endif
_delay_us(3*10); _delay_us(3*10);
#if RF230BB #if RF230BB
RSSI = rf230_rssi(); RSSI = rf230_rssi(); //multiplies rssi register by 3 for consistency with energy-detect register
#else // RF230BB #else // RF230BB
radio_get_rssi_value(&RSSI); radio_get_rssi_value(&RSSI);
RSSI*=3;
#endif #endif
maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI); maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI);
accRSSI[i-11]+=RSSI; accRSSI[i-11]+=RSSI;
@ -588,7 +621,7 @@ extern uip_ds6_route_t uip_ds6_routing_table[];
PRINTF_P(PSTR("\n")); PRINTF_P(PSTR("\n"));
for(i=11;i<=26;i++) { for(i=11;i<=26;i++) {
uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7)); uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7));
PRINTF_P(PSTR(" %d: %02ddB "),i, -91+3*(maxRSSI[i-11]-1)); PRINTF_P(PSTR(" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1));
for(;activity--;maxRSSI[i-11]--) { for(;activity--;maxRSSI[i-11]--) {
PRINTF_P(PSTR("#")); PRINTF_P(PSTR("#"));
} }

View File

@ -301,8 +301,10 @@ or include the needed source files in /plaftorm/avr-ravenusb/Makefile.avr-ravenu
* tx=0 (3dbm, default) to 15 (-17.2dbm) * tx=0 (3dbm, default) to 15 (-17.2dbm)
* RF230_CONF_AUTOACK sets the extended mode using the energy-detect register with rx=0 (-91dBm) to 84 (-7dBm) * RF230_CONF_AUTOACK sets the extended mode using the energy-detect register with rx=0 (-91dBm) to 84 (-7dBm)
* else the rssi register is used having range 0 (91dBm) to 28 (-10dBm) * else the rssi register is used having range 0 (91dBm) to 28 (-10dBm)
* For simplicity RF230_MIN_RX_POWER is based on the rssi value and multiplied by 3 when autoack is set. * For simplicity RF230_MIN_RX_POWER is based on the energy-detect value and divided by 3 when autoack is not set.
* On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested. * On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested.
* These numbers applied to both Raven and Jackdaw give a maximum communication distance of about 15 cm
* and a 10 meter range to a full-sensitivity RF230 sniffer.
*/ */
#define RF230_MAX_TX_POWER 15 #define RF230_MAX_TX_POWER 15
#define RF230_MIN_RX_POWER 30 #define RF230_MIN_RX_POWER 30

View File

@ -91,8 +91,6 @@
#include "radio/rf230bb/rf230bb.h" #include "radio/rf230bb/rf230bb.h"
#include "net/mac/frame802154.h" #include "net/mac/frame802154.h"
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
extern int rf230_interrupt_flag;
extern uint8_t rf230processflag;
rimeaddr_t macLongAddr; rimeaddr_t macLongAddr;
#define tmp_addr macLongAddr #define tmp_addr macLongAddr
#else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC #else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC
@ -488,6 +486,15 @@ main(void)
watchdog_periodic(); watchdog_periodic();
/* Print rssi of all received packets, useful for range testing */
#ifdef RF230_MIN_RX_POWER
uint8_t lastprint;
if (rf230_last_rssi != lastprint) { //can be set in halbb.c interrupt routine
printf_P(PSTR("%u "),rf230_last_rssi);
lastprint=rf230_last_rssi;
}
#endif
#if TESTRTIMER #if TESTRTIMER
if (rtimerflag) { //8 seconds is maximum interval, my jackdaw 4% slow if (rtimerflag) { //8 seconds is maximum interval, my jackdaw 4% slow
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
@ -507,8 +514,7 @@ main(void)
} }
#endif /* TESTRTIMER */ #endif /* TESTRTIMER */
//Use with RF230BB DEBUGFLOW to show path through driver /* Use with rf230bb.c DEBUGFLOW to show the sequence of driver calls from the uip stack */
//Warning, Jackdaw doesn't handle simultaneous radio and USB interrupts very well.
#if RF230BB&&0 #if RF230BB&&0
extern uint8_t debugflowsize,debugflow[]; extern uint8_t debugflowsize,debugflow[];
if (debugflowsize) { if (debugflowsize) {
@ -518,16 +524,19 @@ extern uint8_t debugflowsize,debugflow[];
} }
#endif #endif
/* Use for low level interrupt debugging */
#if RF230BB&&0 #if RF230BB&&0
extern uint8_t rf230interruptflag; //in halbb.c
extern uint8_t rf230processflag; //in rf230bb.c
if (rf230processflag) { if (rf230processflag) {
printf("**RF230 process flag %u\n\r",rf230processflag); printf("**RF230 process flag %u\n\r",rf230processflag);
rf230processflag=0; rf230processflag=0;
} }
if (rf230_interrupt_flag) { if (rf230interruptflag) {
// if (rf230_interrupt_flag!=11) { // if (rf230interruptflag!=11) {
printf("**RF230 Interrupt %u\n\r",rf230_interrupt_flag); printf("**RF230 Interrupt %u\n\r",rf230interruptflag);
// } // }
rf230_interrupt_flag=0; rf230interruptflag=0;
} }
#endif #endif
} }