From a9cbbb45709cefb674c408d8260b95a3160ae07a Mon Sep 17 00:00:00 2001 From: dak664 Date: Wed, 23 Mar 2011 18:08:07 -0400 Subject: [PATCH] Add sneezer mode and tx power change --- cpu/avr/radio/rf230bb/rf230bb.c | 73 +++++++- cpu/avr/radio/rf230bb/rf230bb.h | 2 + platform/avr-ravenusb/cdc_task.c | 218 ++++++++++++++++++----- platform/avr-ravenusb/contiki-conf.h | 10 +- platform/avr-ravenusb/sicslow_ethernet.c | 13 +- platform/avr-ravenusb/sicslow_ethernet.h | 1 + 6 files changed, 254 insertions(+), 63 deletions(-) diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index 9ee74f3f5..fc9005704 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -702,6 +702,27 @@ rf230_init(void) PRINTF("rf230: Unsupported manufacturer ID %u\n",tmanu); PRINTF("rf230: Version %u, ID %u\n",tvers,tmanu); + + rf230_warm_reset(); + + /* Start the packet receive process */ + process_start(&rf230_process, NULL); + + /* Leave radio in on state (?)*/ + on(); + + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Used to reinitialize radio parameters without losing pan and mac address, channel, power, etc. */ +void rf230_warm_reset(void) { +#if RF230_CONF_SNEEZER && JACKDAW + /* Take jackdaw radio out of test mode */ +#warning Manipulating PORTB pins for RF230 Sneezer mode! + PORTB &= ~(1<<7); + DDRB &= ~(1<<7); +#endif + 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 */ @@ -738,19 +759,10 @@ rf230_init(void) hal_subregister_write(SR_TX_AUTO_CRC_ON, 1); #endif - /* Start the packet receive process */ - process_start(&rf230_process, NULL); - /* Limit tx power for testing miniature Raven mesh */ #ifdef RF230_MAX_TX_POWER set_txpower(RF230_MAX_TX_POWER); //0=3dbm 15=-17.2dbm #endif - - /* Leave radio in on state (?)*/ - on(); - - - return 1; } /*---------------------------------------------------------------------------*/ static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN]; @@ -1509,3 +1521,46 @@ pending_packet(void) return pending; } /*---------------------------------------------------------------------------*/ +#if RF230_CONF_SNEEZER && JACKDAW +/* See A.2 in the datasheet for the sequence needed. + * This version for RF230 only, hence Jackdaw. + * A full reset seems not necessary and allows keeping the pan address, etc. + * for an easy reset back to network mode. + */ +void rf230_start_sneeze(void) { +//write buffer with random data for uniform spectral noise + +//uint8_t txpower = hal_register_read(0x05); //save auto_crc bit and power +// hal_set_rst_low(); +// hal_set_slptr_low(); +// delay_us(TIME_RESET); +// hal_set_rst_high(); + hal_register_write(0x0E, 0x01); + hal_register_write(0x02, 0x03); + hal_register_write(0x03, 0x10); + // hal_register_write(0x08, 0x20+26); //channel 26 + hal_subregister_write(SR_CCA_MODE,1); //leave channel unchanged + + // hal_register_write(0x05, 0x00); //output power maximum + hal_subregister_write(SR_TX_AUTO_CRC_ON, 0); //clear AUTO_CRC, leave output power unchanged + + hal_register_read(0x01); //should be trx-off state=0x08 + hal_frame_write(buffer, 127); //maximum length, random for spectral noise + + hal_register_write(0x36,0x0F); //configure continuous TX + hal_register_write(0x3D,0x00); //Modulated frame, other options are: +// hal_register_write(RG_TX_2,0x10); //CW -2MHz +// hal_register_write(RG_TX_2,0x80); //CW -500KHz +// hal_register_write(RG_TX_2,0xC0); //CW +500KHz + + DDRB |= 1<<7; //Raven USB stick has PB7 connected to the RF230 TST pin. + PORTB |= 1<<7; //Raise it to enable continuous TX Test Mode. + + hal_register_write(0x02,0x09); //Set TRX_STATE to PLL_ON + delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE); + delay_us(TIME_PLL_LOCK); + delay_us(TIME_PLL_LOCK); + // while (hal_register_read(0x0f)!=1) {continue;} //wait for pll lock-hangs + hal_register_write(0x02,0x02); //Set TRX_STATE to TX_START +} +#endif \ No newline at end of file diff --git a/cpu/avr/radio/rf230bb/rf230bb.h b/cpu/avr/radio/rf230bb/rf230bb.h index 718113c22..5cd424e56 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.h +++ b/cpu/avr/radio/rf230bb/rf230bb.h @@ -202,6 +202,8 @@ typedef void (*radio_rx_callback) (uint16_t data); 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); diff --git a/platform/avr-ravenusb/cdc_task.c b/platform/avr-ravenusb/cdc_task.c index 1b0d46413..a53b8e400 100644 --- a/platform/avr-ravenusb/cdc_task.c +++ b/platform/avr-ravenusb/cdc_task.c @@ -116,9 +116,18 @@ static uint8_t timer = 0; static struct etimer et; #define CONVERTTXPOWER 1 -#if CONVERTTXPOWER //adds 92 bytes to program flash size +#if CONVERTTXPOWER //adds ~120 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'}; +static void printtxpower(void) { + 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]); + if (tens=='0') {tens=sign;sign=' ';} + PRINTF_P(PSTR("%c%c%c.%cdBm"),sign,tens,ones,tenths); +} #endif PROCESS(cdc_process, "CDC serial process"); @@ -153,7 +162,7 @@ PROCESS_THREAD(cdc_process, ev, data_proc) previous_stdout = stdout; uart_usb_init(); uart_usb_set_stdout(); - menu_print(); + // menu_print(); do this later } else { stdout = previous_stdout; } @@ -206,16 +215,21 @@ PROCESS_THREAD(cdc_process, ev, data_proc) void menu_print(void) { PRINTF_P(PSTR("\n\r*********** Jackdaw Menu **********\n\r")); - PRINTF_P(PSTR("* *\n\r")); + PRINTF_P(PSTR(" [Built "__DATE__"] \n\r")); +// PRINTF_P(PSTR("* *\n\r")); PRINTF_P(PSTR("* m Print current 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("* c Set RF channel *\n\r")); + PRINTF_P(PSTR("* p Set RF power *\n\r")); PRINTF_P(PSTR("* 6 Toggle 6lowpan *\n\r")); PRINTF_P(PSTR("* r Toggle raw mode *\n\r")); #if USB_CONF_RS232 PRINTF_P(PSTR("* d Toggle RS232 output *\n\r")); #endif +#if RF230BB && RF230_CONF_SNEEZER + PRINTF_P(PSTR("* S Enable sneezer mode *\n\r")); +#endif #if UIP_CONF_IPV6_RPL PRINTF_P(PSTR("* N RPL Neighbors *\n\r")); PRINTF_P(PSTR("* G RPL Global Repair *\n\r")); @@ -227,12 +241,11 @@ void menu_print(void) if(bootloader_is_present()) PRINTF_P(PSTR("* D Switch to DFU mode *\n\r")); PRINTF_P(PSTR("* R Reset (via WDT) *\n\r")); - PRINTF_P(PSTR("* h,? Print this menu *\n\r")); + PRINTF_P(PSTR("* h,? Print this menu *\n\r")); PRINTF_P(PSTR("* *\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("***********************************\n\r")); - PRINTF_P(PSTR("[Built "__DATE__"]\n\r")); } #if UIP_CONF_IPV6_RPL @@ -266,11 +279,12 @@ void menu_process(char c) static enum menustate_enum /* Defines an enumeration type */ { normal, - channel + channel, + txpower } menustate = normal; static char channel_string[3]; - static uint8_t channel_string_i = 0; + static uint8_t channel_string_i;// = 0; int tempchannel; @@ -295,14 +309,14 @@ void menu_process(char c) } else { #endif #if JACKDAW_CONF_USE_SETTINGS - if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)!=SETTINGS_STATUS_OK) { - PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel); - } else + if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)==SETTINGS_STATUS_OK) { + PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel); + } else { + PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel); + } #else - eeprom_write_byte((uint8_t *) 9, tempchannel); //Write channel - eeprom_write_byte((uint8_t *)10, ~tempchannel); //Bit inverse as check + PRINTF_P(PSTR("\n\rChannel changed to %d.\n\r"),tempchannel); #endif - PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel); } } else { PRINTF_P(PSTR("\n\rChannel unchanged.\n\r")); @@ -346,11 +360,87 @@ void menu_process(char c) default: break; } + } else if (menustate == txpower) { + switch(c) { + case '\r': + case '\n': + + if (channel_string_i) { + channel_string[channel_string_i] = 0; + tempchannel = atoi(channel_string); +#if RF230BB + if ((tempchannel < 0) || (tempchannel > 15)) { + PRINTF_P(PSTR("\n\rInvalid input\n\r")); + } else { + PRINTF_P(PSTR(" ")); //for some reason needs a print here to clear the string input... + rf230_set_txpower(tempchannel); +#else + if(radio_set_tx_power_level(tempchannel)!=RADIO_SUCCESS) { + PRINTF_P(PSTR("\n\rInvalid input\n\r")); + } else { +#endif +#if JACKDAW_CONF_USE_SETTINGS + if(settings_set_uint8(SETTINGS_KEY_TXPOWER, tempchannel)==SETTINGS_STATUS_OK) { + PRINTF_P(PSTR("\n\rTransmit power changed to %d, and stored in EEPROM.\n\r"),tempchannel); + } else { + PRINTF_P(PSTR("\n\rTransmit power changed to %d, but unable to store in EEPROM!\n\r"),tempchannel); + } +#else + PRINTF_P(PSTR("\n\rTransmit power changed to %d.\n\r"),tempchannel); +#endif + } + } else { + PRINTF_P(PSTR("\n\rTransmit power unchanged.\n\r")); + } + menustate = normal; + break; + + case '\b': + + if (channel_string_i) { + channel_string_i--; + PRINTF_P(PSTR("\b \b")); + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (channel_string_i > 1) { + // This time the user has gone too far. + // Beep at them. + putc('\a', stdout); + //uart_usb_putchar('\a'); + break; + } + putc(c, stdout); + //uart_usb_putchar(c); + + channel_string[channel_string_i] = c; + channel_string_i++; + break; + + default: + break; + } + } else { uint8_t i; + + /* Any attempt to read an RF230 register in sneeze mode (e.g. rssi) will hang the MCU */ + /* So convert any command into a sneeze off */ + if (usbstick_mode.sneeze) c='S'; + switch(c) { case '\r': case '\n': @@ -369,9 +459,10 @@ void menu_process(char c) PRINTF_P(PSTR("Bringing interface up\n\r")); usb_eth_set_active(1); break; - - case 't': +#if JACKDAW_CONF_RANDOM_MAC + case 'T': // Test "strong" random number generator of R Quattlebaum + // This can potentially reboot the stick! PRINTF_P(PSTR("RNG Output: ")); { uint8_t value = rng_get_uint8(); @@ -384,24 +475,49 @@ void menu_process(char c) watchdog_periodic(); } break; - +#endif case 's': PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r")); usbstick_mode.sendToRf = 0; usbstick_mode.translate = 0; #if RF230BB - rf230_listen_channel(rf230_get_channel()); + rf230_listen_channel(rf230_get_channel()); #else - radio_set_trx_state(RX_ON); + radio_set_trx_state(RX_ON); #endif break; +#if RF230BB && RF230_CONF_SNEEZER + case 'S': + if (usbstick_mode.sneeze) { + rf230_warm_reset(); + PRINTF_P(PSTR("Jackdaw now behaving itself.\n\r")); + usbstick_mode.sneeze = 0; + } else { + if (rf230_get_txpower()<3) + PRINTF_P(PSTR("*****WARNING Radio may overheat in this mode*******\n\r")); + rf230_start_sneeze(); + PRINTF_P(PSTR("********Jackdaw is continuously broadcasting*******\n\r")); +#if CONVERTTXPOWER + PRINTF_P(PSTR("*********on channel %2d with power "),rf230_get_channel()); + printtxpower(); + PRINTF_P(PSTR("*********\n\r")); +#else + PRINTF_P(PSTR("************on channel %2d with power %2d************\n\r"),rf230_get_channel(),rf230_get_txpower()); +#endif + PRINTF_P(PSTR("Press any key to stop.\n\r")); + watchdog_periodic(); + usbstick_mode.sneeze = 1; + } + break; +#endif + case 'n': PRINTF_P(PSTR("Jackdaw now in network mode\n\r")); usbstick_mode.sendToRf = 1; usbstick_mode.translate = 1; #if RF230BB - rf230_set_channel(rf230_get_channel()); + rf230_set_channel(rf230_get_channel()); #else radio_set_trx_state(RX_AACK_ON); //TODO: Use startup state which may be RX_ON #endif @@ -442,14 +558,25 @@ void menu_process(char c) case 'c': #if RF230BB - PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel()); + PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel()); #else - PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel()); + PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel()); #endif menustate = channel; channel_string_i = 0; break; + case 'p': +#if RF230BB + PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), rf230_get_txpower()); +#else +// PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), ?_power());; +#endif + menustate = txpower; + channel_string_i = 0; + break; + + #if UIP_CONF_IPV6_RPL #include "rpl.h" extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; @@ -457,13 +584,13 @@ extern uip_ds6_route_t uip_ds6_routing_table[]; extern uip_ds6_netif_t uip_ds6_if; case 'N': { uint8_t i,j; - PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB); - for (i=0;i14?'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); - } + PRINTF_P(PSTR(" * Operates on channel %d with TX power "),rf230_get_channel()); + printtxpower(); + PRINTF_P(PSTR("\n\r")); #else //just show the raw value 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()); #endif - if (rf230_smallest_rssi) { - PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/%ddBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1),-91+(rf230_smallest_rssi-1)); - rf230_smallest_rssi=0; - } else { - PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/--dBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1)); - } + if (rf230_smallest_rssi) { + PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/%ddBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1),-91+(rf230_smallest_rssi-1)); + rf230_smallest_rssi=0; + } else { + PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/--dBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1)); + } #else /* RF230BB */ PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel()); @@ -584,8 +706,8 @@ extern uip_ds6_netif_t uip_ds6_if; #endif /* RF230BB */ 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")); + if (usb_eth_is_active == 0) PRINTF_P(PSTR("not ")); + PRINTF_P(PSTR("active\n\r")); #if CONFIG_STACK_MONITOR /* See contiki-raven-main.c for initialization of the magic numbers */ @@ -601,7 +723,7 @@ uint16_t p=(uint16_t)&__bss_end; } while (ptype != UIP_HTONS(UIP_ETHTYPE_IPV6)) { PRINTF("eth2low: Dropping packet w/type=0x%04x\n",uip_ntohs(((struct uip_eth_hdr *) ethHeader)->type)); // printf("!ipv6"); @@ -1043,10 +1044,12 @@ mac_log_802_15_4_rx(const uint8_t* buf, size_t len) { usb_eth_send(raw_buf, sendlen, 0); } } - +/* The rf230bb send driver may call this routine via RF230BB_HOOK_IS_SEND_ENABLED */ bool mac_is_send_enabled(void) { - return usbstick_mode.sendToRf; + if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) return 0; + return 1; +//return usbstick_mode.sendToRf; } /** @} */ diff --git a/platform/avr-ravenusb/sicslow_ethernet.h b/platform/avr-ravenusb/sicslow_ethernet.h index 4a5b632b1..b5956b470 100644 --- a/platform/avr-ravenusb/sicslow_ethernet.h +++ b/platform/avr-ravenusb/sicslow_ethernet.h @@ -65,6 +65,7 @@ typedef struct { uint8_t translate :1; uint8_t raw :1; uint8_t debugOn :1; + uint8_t sneeze :1; } usbstick_mode_t;