diff --git a/drivers/cc110x/Jamfile b/drivers/cc110x/Jamfile index b96d897d9e..528cef8d1b 100755 --- a/drivers/cc110x/Jamfile +++ b/drivers/cc110x/Jamfile @@ -31,5 +31,5 @@ HDRS += $(TOP)/drivers/cc110x ; Module cc110x : cc1100.c cc1100-csmaca-mac.c cc1100-defaultSettings.c cc1100_phy.c cc1100_spi.c - : board_cc1100 swtimer protocol_multiplex gpioint ; + : board_cc110x swtimer protocol_multiplex gpioint ; diff --git a/drivers/cc110x/arch_cc1100.h b/drivers/cc110x/arch_cc1100.h index ef61dd61c9..7c8b018a50 100644 --- a/drivers/cc110x/arch_cc1100.h +++ b/drivers/cc110x/arch_cc1100.h @@ -38,13 +38,13 @@ and the mailinglist (subscription via web site) #include -uint8_t cc1100_txrx(uint8_t c); +uint8_t cc110x_txrx(uint8_t c); -void cc1100_gdo0_enable(void); -void cc1100_gdo0_disable(void); -void cc1100_gdo2_enable(void); -void cc1100_gdo2_disable(void); -void cc1100_init_interrupts(void); +void cc110x_gdo0_enable(void); +void cc110x_gdo0_disable(void); +void cc110x_gdo2_enable(void); +void cc110x_gdo2_disable(void); +void cc110x_init_interrupts(void); -void cc1100_before_send(void); -void cc1100_after_send(void); +void cc110x_before_send(void); +void cc110x_after_send(void); diff --git a/drivers/cc110x/cc1100-csmaca-mac.c b/drivers/cc110x/cc1100-csmaca-mac.c index fab9610cc3..3dc9c3b2fa 100644 --- a/drivers/cc110x/cc1100-csmaca-mac.c +++ b/drivers/cc110x/cc1100-csmaca-mac.c @@ -38,7 +38,7 @@ and the mailinglist (subscription via web site) */ #include -//#include +#include #include #include "cc1100.h" @@ -47,6 +47,7 @@ and the mailinglist (subscription via web site) #include "protocol-multiplex.h" #include "hwtimer.h" +#include /*---------------------------------------------------------------------------*/ @@ -106,9 +107,9 @@ int cc1100_send_csmaca(radio_address_t address, protocol_t protocol, int priorit collisions_per_sec = 0; collision_state = COLLISION_STATE_MEASURE; } else if (collision_state == COLLISION_STATE_MEASURE) { - uint64_t timespan = swtimer_now() - collision_measurement_start; - if (timespan > 1000000) { - collisions_per_sec = (collision_count * 1000000) / (double) timespan; + uint64_t timespan = swtimer_now() - collision_measurement_start; + if (timespan > 1000000) { + collisions_per_sec = (collision_count * 1000000) / (double) timespan; if (collisions_per_sec > 0.5 && collisions_per_sec <= 2.2) { collision_measurement_start = swtimer_now(); collision_state = COLLISION_STATE_KEEP; @@ -120,8 +121,8 @@ int cc1100_send_csmaca(radio_address_t address, protocol_t protocol, int priorit } } } else if (collision_state == COLLISION_STATE_KEEP) { - uint64_t timespan = swtimer_now() - collision_measurement_start; - if (timespan > 5000000) { + uint64_t timespan = swtimer_now() - collision_measurement_start; + if (timespan > 5000000) { collision_state = COLLISION_STATE_INITIAL; } } diff --git a/drivers/cc110x/cc1100.c b/drivers/cc110x/cc1100.c index 5b671b3ad8..7199694d23 100644 --- a/drivers/cc110x/cc1100.c +++ b/drivers/cc110x/cc1100.c @@ -160,19 +160,19 @@ volatile int wor_hwtimer_id = -1; void cc1100_disable_interrupts(void) { - cc1100_gdo2_disable(); - cc1100_gdo0_disable(); + cc110x_gdo2_disable(); + cc110x_gdo0_disable(); } -void cc1100_gdo0_irq(void) +void cc110x_gdo0_irq(void) { // Air was not free -> Clear CCA flag rflags.CAA = false; // Disable carrier sense detection (GDO0 interrupt) - cc1100_gdo0_disable(); + cc110x_gdo0_disable(); } -void cc1100_gdo2_irq(void) +void cc110x_gdo2_irq(void) { cc1100_phy_rx_handler(); } @@ -251,9 +251,9 @@ bool cc1100_spi_receive_packet(uint8_t *rxBuffer, uint8_t length) void cc1100_set_idle(void) { if (radio_state == RADIO_WOR) { // Wake up the chip from WOR/sleep - cc1100_spi_select(); + cc110x_spi_select(); hwtimer_wait(RTIMER_TICKS(122)); - cc1100_spi_unselect(); + cc110x_spi_unselect(); radio_state = RADIO_IDLE; // XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms) hwtimer_wait(FS_CAL_TIME); @@ -292,9 +292,9 @@ static void wakeup_from_wor(void) return; } // Wake up the chip from WOR/sleep - cc1100_spi_select(); + cc110x_spi_select(); hwtimer_wait(RTIMER_TICKS(122)); - cc1100_spi_unselect(); + cc110x_spi_unselect(); radio_state = RADIO_IDLE; // XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms) hwtimer_wait(FS_CAL_TIME); @@ -305,7 +305,7 @@ static void wakeup_from_wor(void) */ void switch_to_wor2(void) { - if (cc1100_get_gdo2()) return; // If incoming packet, then don't go to WOR now + if (cc110x_get_gdo2()) return; // If incoming packet, then don't go to WOR now cc1100_spi_strobe(CC1100_SIDLE); // Put CC1100 to IDLE radio_state = RADIO_IDLE; // Radio state now IDLE cc1100_spi_write_reg(CC1100_MCSM2, @@ -336,7 +336,7 @@ static void hwtimer_switch_to_wor2_wrapper(void* ptr) static void switch_to_wor(void) { // Any incoming packet? - if (cc1100_get_gdo2()) + if (cc110x_get_gdo2()) { // Then don't go to WOR now return; @@ -558,16 +558,16 @@ void cc1100_hwtimer_go_receive_wrapper(void *ptr) static void reset(void) { cc1100_go_idle(); - cc1100_spi_select(); + cc110x_spi_select(); cc1100_spi_strobe(CC1100_SRES); hwtimer_wait(RTIMER_TICKS(10)); } static void power_up_reset(void) { - cc1100_spi_unselect(); - cc1100_spi_cs(); - cc1100_spi_unselect(); + cc110x_spi_unselect(); + cc110x_spi_cs(); + cc110x_spi_unselect(); hwtimer_wait(RESET_WAIT_TIME); reset(); radio_state = RADIO_IDLE; @@ -587,7 +587,7 @@ void cc1100_send_raw(uint8_t *tx_buffer, uint8_t size) if (size > PACKET_LENGTH) return; // Disables RX interrupt etc. - cc1100_before_send(); + cc110x_before_send(); // But CC1100 in IDLE mode to flush the FIFO cc1100_spi_strobe(CC1100_SIDLE); @@ -600,7 +600,7 @@ void cc1100_send_raw(uint8_t *tx_buffer, uint8_t size) unsigned int cpsr = disableIRQ(); cc1100_spi_strobe(CC1100_STX); // Wait for GDO2 to be set -> sync word transmitted - while (cc1100_get_gdo2() == 0) { + while (cc110x_get_gdo2() == 0) { abort_count++; if (abort_count > CC1100_SYNC_WORD_TX_TIME) { // Abort waiting. CC1100 maybe in wrong mode @@ -611,9 +611,9 @@ void cc1100_send_raw(uint8_t *tx_buffer, uint8_t size) } restoreIRQ(cpsr); // Wait for GDO2 to be cleared -> end of packet - while (cc1100_get_gdo2() != 0); + while (cc110x_get_gdo2() != 0); // Experimental - TOF Measurement - cc1100_after_send(); + cc110x_after_send(); } /*---------------------------------------------------------------------------*/ @@ -742,7 +742,7 @@ rssi_2_dbm(uint8_t rssi) void cc1100_init(void) { // Initialize SPI - cc1100_spi_init(); + cc110x_spi_init(); // Set default mode (with default (energy optimized) RX interval) cc1100_set_mode0(CC1100_RADIO_MODE, T_RX_INTERVAL); @@ -834,7 +834,7 @@ rd_set_mode(int mode) switch (mode) { case RADIO_MODE_ON: - cc1100_init_interrupts(); // Enable interrupts + cc110x_init_interrupts(); // Enable interrupts cc1100_setup_mode(); // Set chip to desired mode break; case RADIO_MODE_OFF: @@ -877,19 +877,19 @@ void cc1100_cs_set_enabled(bool enabled) if (enabled) { // Enable carrier sense detection (GDO0 interrupt) - cc1100_gdo0_enable(); + cc110x_gdo0_enable(); } else { // Disable carrier sense detection (GDO0 interrupt) - cc1100_gdo0_disable(); + cc110x_gdo0_disable(); } } int cc1100_cs_read(void) { /* GDO0 reflects CS (high: air not free, low: air free) */ - return cc1100_get_gdo0(); + return cc110x_get_gdo0(); } int cc1100_cs_read_cca(void) diff --git a/drivers/cc110x/cc1100_phy.c b/drivers/cc110x/cc1100_phy.c index d97a3857a6..acc374761d 100644 --- a/drivers/cc110x/cc1100_phy.c +++ b/drivers/cc110x/cc1100_phy.c @@ -45,7 +45,7 @@ and the mailinglist (subscription via web site) #include #include "hwtimer.h" -#include "swtimer.h" +#include #include "cc1100.h" #include "cc1100_spi.h" @@ -382,7 +382,7 @@ static bool contains_seq_entry(uint8_t src, uint8_t id) { // Check if time stamp is OK cmp = (radio_mode == CC1100_MODE_WOR) ? cc1100_wor_config.rx_interval : 16000; // constant RX ~16ms - if ((now - seq_buffer[i].m_ticks) <= cmp) + if ((now - seq_buffer[i].m_ticks) <= cmp) { return true; } @@ -412,7 +412,7 @@ static void add_seq_entry(uint8_t src, uint8_t id) // Add new entry seq_buffer[seq_buffer_pos].source = src; seq_buffer[seq_buffer_pos].identification = id; - seq_buffer[seq_buffer_pos].m_ticks = swtimer_now(); + seq_buffer[seq_buffer_pos].m_ticks = swtimer_now(); // Store 16 bit sequence number of layer 0 for speedup last_seq_num = src; @@ -625,6 +625,7 @@ int cc1100_set_packet_handler(protocol_t protocol, packet_handler_t handler) static void cc1100_event_handler_function(void) { msg_t m; + while (1) { if (cc1100_watch_dog_period != 0) { diff --git a/drivers/cc110x/cc1100_spi.c b/drivers/cc110x/cc1100_spi.c index ef5206cb64..2614caf20a 100644 --- a/drivers/cc110x/cc1100_spi.c +++ b/drivers/cc110x/cc1100_spi.c @@ -61,13 +61,13 @@ cc1100_spi_writeburst_reg(uint8_t addr, char *src, uint8_t count) { int i = 0; unsigned int cpsr = disableIRQ(); - cc1100_spi_select(); - cc1100_txrx(addr | CC1100_WRITE_BURST); + cc110x_spi_select(); + cc110x_txrx(addr | CC1100_WRITE_BURST); while (i < count) { - cc1100_txrx(src[i]); + cc110x_txrx(src[i]); i++; } - cc1100_spi_unselect(); + cc110x_spi_unselect(); restoreIRQ(cpsr); return count; } @@ -77,13 +77,13 @@ cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count) { int i = 0; unsigned int cpsr = disableIRQ(); - cc1100_spi_select(); - cc1100_txrx(addr | CC1100_READ_BURST); + cc110x_spi_select(); + cc110x_txrx(addr | CC1100_READ_BURST); while (i < count) { - buffer[i] = cc1100_txrx(NOBYTE); + buffer[i] = cc110x_txrx(NOBYTE); i++; } - cc1100_spi_unselect(); + cc110x_spi_unselect(); restoreIRQ(cpsr); } @@ -91,10 +91,10 @@ void cc1100_spi_write_reg(uint8_t addr, uint8_t value) { unsigned int cpsr = disableIRQ(); - cc1100_spi_select(); - cc1100_txrx(addr); - cc1100_txrx(value); - cc1100_spi_unselect(); + cc110x_spi_select(); + cc110x_txrx(addr); + cc110x_txrx(value); + cc110x_spi_unselect(); restoreIRQ(cpsr); } @@ -102,10 +102,10 @@ uint8_t cc1100_spi_read_reg(uint8_t addr) { uint8_t result; unsigned int cpsr = disableIRQ(); - cc1100_spi_select(); - cc1100_txrx(addr | CC1100_READ_SINGLE); - result = cc1100_txrx(NOBYTE); - cc1100_spi_unselect(); + cc110x_spi_select(); + cc110x_txrx(addr | CC1100_READ_SINGLE); + result = cc110x_txrx(NOBYTE); + cc110x_spi_unselect(); restoreIRQ(cpsr); return result; } @@ -114,10 +114,10 @@ uint8_t cc1100_spi_read_status(uint8_t addr) { uint8_t result; unsigned int cpsr = disableIRQ(); - cc1100_spi_select(); - cc1100_txrx(addr | CC1100_READ_BURST); - result = cc1100_txrx(NOBYTE); - cc1100_spi_unselect(); + cc110x_spi_select(); + cc110x_txrx(addr | CC1100_READ_BURST); + result = cc110x_txrx(NOBYTE); + cc110x_spi_unselect(); restoreIRQ(cpsr); return result; } @@ -126,9 +126,9 @@ uint8_t cc1100_spi_strobe(uint8_t c) { uint8_t result; unsigned int cpsr = disableIRQ(); - cc1100_spi_select(); - result = cc1100_txrx(c); - cc1100_spi_unselect(); + cc110x_spi_select(); + result = cc110x_txrx(c); + cc110x_spi_unselect(); restoreIRQ(cpsr); return result; } diff --git a/drivers/cc110x/cc1100_spi.h b/drivers/cc110x/cc1100_spi.h index 736f982187..e76deb8b27 100644 --- a/drivers/cc110x/cc1100_spi.h +++ b/drivers/cc110x/cc1100_spi.h @@ -44,14 +44,14 @@ and the mailinglist (subscription via web site) #ifndef CC1100_SPI_H_ #define CC1100_SPI_H_ -int cc1100_get_gdo0(void); -int cc1100_get_gdo1(void); -int cc1100_get_gdo2(void); +int cc110x_get_gdo0(void); +int cc110x_get_gdo1(void); +int cc110x_get_gdo2(void); -void cc1100_spi_init(void); -void cc1100_spi_cs(void); -void cc1100_spi_select(void); -void cc1100_spi_unselect(void); +void cc110x_spi_init(void); +void cc110x_spi_cs(void); +void cc110x_spi_select(void); +void cc110x_spi_unselect(void); uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *buffer, uint8_t count); void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count); diff --git a/projects/WEAtHeR/Jamfile b/projects/WEAtHeR/Jamfile index 3576888c65..4974b6d046 100644 --- a/projects/WEAtHeR/Jamfile +++ b/projects/WEAtHeR/Jamfile @@ -1,5 +1,5 @@ SubDir TOP projects WEAtHeR ; -Module WEAtHeR : main.c weather_routing.c protocol_msg_gateway.c : sht11 ltc4150 cc110x gpioint swtimer shell shell_commands posix_io uart0 auto_init rtc ; +Module WEAtHeR : main.c weather_routing.c protocol_msg_gateway.c : ltc4150 cc110x gpioint vtimer shell shell_commands posix_io uart0 auto_init rtc ; UseModule WEAtHeR ; diff --git a/projects/WEAtHeR/main.c b/projects/WEAtHeR/main.c index 878c5bba34..c89c8fa16a 100644 --- a/projects/WEAtHeR/main.c +++ b/projects/WEAtHeR/main.c @@ -1,49 +1,88 @@ +/* stdlib includes */ +#include +#include +#include #include -#include -#include -#include -#include -#include -#include + +/* core includes */ #include #include +#include + +#define ENABLE_DEBUG +#include + +/* sensors and actors */ #include +#include +#include + +/* shell */ #include +#include +#include + +/* transceiver */ #include + +/* real time clock */ #include #include -#include +/* application header */ #include "weather_routing.h" #include "weather_protocol.h" #include "protocol_msg_gateway.h" -#define SHELL_STACK_SIZE (2048) -#define PH_STACK_SIZE (2048) +/* some local defines */ +#define SECOND (1000 * 1000) +#define MINUTE (1 * SECOND) -/* per default not acting as data sink */ -static uint8_t data_sink = 0; -static uint8_t data_src = 0; +/* size of weather data packet without hop list */ +#define EMPTY_WDP_SIZE (sizeof(weather_data_pkt_t) - MAX_HOP_LIST) + +/* default values */ +#define DEFAULT_INTERVAL (5 * SECOND) + +/* stack space for threads */ +#define SHELL_STACK_SIZE (4048) +#define PH_STACK_SIZE (4048) char shell_stack_buffer[SHELL_STACK_SIZE]; char ph_stack_buffer[PH_STACK_SIZE]; -void weather_send(char* unused); -void weather_sink(char* unused); +/* per default acting only as relay */ +static uint8_t data_sink = 0; +static uint8_t data_src = 0; +static uint32_t sending_interval = DEFAULT_INTERVAL; + +extern uint8_t gossip_probability; + +/* function prototypes */ +static void weather_send(char* unused); +static void weather_sink(char* unused); +static void set_interval(char* interval); +static void set_probability(char* prob); +static void print_cc1100_info(char* unused); + +/* shell commands */ shell_t shell; const shell_command_t sc[] = { {"sender", "Enables node as data source.", weather_send}, {"sink", "Enables node as data sink.", weather_sink}, + {"int", "Set the sending interval in seconds", set_interval}, + {"prob", "Set the gossiping probability", set_probability}, + {"cc1100", "Show state, statistics and config of cc1100", print_cc1100_info}, {NULL, NULL, NULL}}; -void shell_runner(void) { +static void shell_runner(void) { shell_init(&shell, sc, uart0_readc, uart0_putc); posix_open(uart0_handler_pid, 0); shell_run(&shell); } -void weather_send(char* unused) { +static void weather_send(char* unused) { if (data_src) { data_src = 0; puts("Disabling data source mode."); @@ -54,7 +93,7 @@ void weather_send(char* unused) { } } -void weather_sink(char* unused) { +static void weather_sink(char* unused) { if (data_sink) { data_sink = 0; puts("Disabling data sink mode."); @@ -65,23 +104,61 @@ void weather_sink(char* unused) { } } +static void set_interval(char* interval) { + uint16_t a; + + a = atoi(interval+4); + if (strlen(interval) > 4) { + printf("[WEAtHeR] Set interval to %u\n ", a); + sending_interval = a * SECOND; + } + else { + printf("[WEAtHeR] Current interval is %lu\n ", (sending_interval / SECOND)); + } +} + +static void set_probability(char* prob) { + uint16_t a; + + a = atoi(prob+4); + if (strlen(prob) > 4) { + printf("[WEAtHeR] Set probability to %hu\n ", a); + gossip_probability = a; + } + else { + printf("[WEAtHeR] Current probability is %hu\n ", gossip_probability); + } +} + +static void print_cc1100_info(char* unused) { + puts("=================================================="); + cc1100_print_statistic(); + puts("--------------------------------------------------"); + cc1100_print_config(); + puts("=================================================="); +} + +/* packet handling */ static void handle_packet(void* msg, int msg_size, packet_info_t* packet_info) { weather_packet_header_t *header = (weather_packet_header_t*) msg; - printf("\n\t Pkt received from phy: %u\n" + /* packet origins at current node, just ignore it */ + if (header->src == cc1100_get_address()) { + return; + } + DEBUG("\n\t Pkt received from phy: %u (%u bytes)\n" "\t -> SEQ: %u | TYPE: %u | SRC: %hu \n\n", packet_info->phy_src, + msg_size, header->seq_nr, header->type, header->src ); - - /* when destination is set, but I'm not the receiver, pass to routing */ + /* while not acting as sink and packet contains data, route the packet */ if (!data_sink) { if (header->type == WEATHER_DATA) { weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg; - /* ;;;;;;; */ - printf("%hu;%hu;%04lX;%04X;%.2f;%.2f;%.2f;%.2f\n", + DEBUG("$0;%hu;%hu;%04lX;%04X;%.2f;%.2f;%.2f;%.2f\n", header->src, 0, wdp->timestamp, @@ -90,14 +167,14 @@ static void handle_packet(void* msg, int msg_size, packet_info_t* packet_info) { wdp->relhum, wdp->relhum_temp, wdp->energy); + DEBUG("Not for me, routing, baby!\n"); + route_packet(msg, msg_size); } - puts("Not for me, routing, baby!"); - route_packet(msg, msg_size); return; } - /* in all other cases handle the packet */ + /* if current node acts as sink, handle packet */ switch (header->type) { case WEATHER_HELLO: { if (msg_size < sizeof(weather_hello_pkt_t)) { @@ -115,21 +192,26 @@ static void handle_packet(void* msg, int msg_size, packet_info_t* packet_info) { } case WEATHER_DATA: { weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg; + uint8_t i; time_t local_time = rtc_time(NULL); /* ;;;;;;; */ - printf("%hu;%u;%04lX;%04lX;%.2f;%.2f;%.2f;%.2f\n", + printf("$1;%hu;%u;%04lX;%04lX;%.2f;%.2f;%.2f;%.2f;", header->src, - 1, + cc1100_get_address(), wdp->timestamp, local_time, wdp->temperature, wdp->relhum, wdp->relhum_temp, wdp->energy); + for (i = 0; i < wdp->hop_counter; i++) { + printf("%03u-", wdp->hops[i]); + } + puts(""); break; } default: { - printf("Unknown packet type \"%i\" received.", header->type); + printf("Unknown packet type \"%i\" received.\n", header->type); } } } @@ -147,6 +229,7 @@ static void protocol_handler_thread(void) { packet = packet_buffer[pos]; handle_packet(packet.payload, packet.msg_size, &(packet.packet_info)); + DEBUG("Packet handler done\n"); } } @@ -154,32 +237,59 @@ int main(void) { weather_data_pkt_t wdp; sht11_val_t sht11_val; + /* initialize variables */ uint8_t success = 0; + int sending_state = 0; + gossip_probability = FLOODING_PROB; + /* fill some fields of the packet */ wdp.header.seq_nr = 0; wdp.header.type = WEATHER_DATA; - + wdp.hop_counter = 1; + + /* set initial channel */ + cc1100_set_channel(10); + + /* boot screen */ puts(""); puts("WEAtHeR: Wireless Energy-Aware mulTi-Hop sEnsor Reading."); - /* ;;;;;;; */ - puts("Printing \"node id of data source;node id of sink;timestamp of measurement;timestamp at data sink;temperature in °C;relative humidity;temperature compensated relative humidity;energy value\"."); puts(""); - + printf("Sending interval: %lu\n", sending_interval / SECOND); + + /* start shell */ thread_create(shell_stack_buffer, SHELL_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, shell_runner, "shell"); + /* initialize message gateway */ + init_protocol_msg_gateway(); /* create thread for radio packet handling */ - int pid = thread_create(ph_stack_buffer, PH_STACK_SIZE, PRIORITY_MAIN-5, CREATE_STACKTEST, protocol_handler_thread, "protocol_handler"); + int pid = thread_create(ph_stack_buffer, PH_STACK_SIZE, PRIORITY_MAIN-2, CREATE_STACKTEST, protocol_handler_thread, "protocol_handler"); set_protocol_handler_thread(pid); + /* start coulomb counter and RTC */ ltc4150_start(); rtc_enable(); + /* loop forever */ while (1) { + DEBUG("Measurement in progress...\n"); +#ifndef ENABLE_DEBUG + success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE); +#else + success = 1; + sht11_val.temperature = 1; + sht11_val.relhum = 2; + sht11_val.relhum_temp = 3; +#endif + DEBUG("...done.\n"); + if (data_src) { wdp.header.src = cc1100_get_address(); + DEBUG("Src filled\n"); wdp.timestamp = rtc_time(NULL); + DEBUG("Timestamp filled\n"); wdp.energy = ltc4150_get_total_mAh(); - success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE); + DEBUG("Energy filled\n"); + if (!success) { printf("error;error;error\n"); } @@ -187,16 +297,47 @@ int main(void) { wdp.temperature = sht11_val.temperature; wdp.relhum = sht11_val.relhum; wdp.relhum_temp = sht11_val.relhum_temp; - if (cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)&wdp, sizeof(weather_data_pkt_t))) { - printf("Successfully sent packet: \n"); + wdp.hops[0] = cc1100_get_address(); + DEBUG("Ready for sending\n"); + /* send packet with one entry in hop list */ + sending_state = cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)&wdp, (EMPTY_WDP_SIZE + 1)); + if (sending_state > 0) { + DEBUG("Sending %lu bytes.\n", (EMPTY_WDP_SIZE + 1)); wdp.header.seq_nr++; } else { - puts("Error on sending packet!"); + printf("Error on sending packet with code %i!\n", sending_state); } } + LED_GREEN_TOGGLE; + } + else { LED_RED_TOGGLE; } - swtimer_usleep(60 * 1000*1000); + + if (!success) { + printf("error;error;error\n"); + } + else { +#ifdef ENABLE_DEBUG + puts("=================================================="); + cc1100_print_statistic(); + puts("--------------------------------------------------"); + cc1100_print_config(); + puts("=================================================="); +#endif + + printf("$0;%hu;%hu;%04lX;%04X;%.2f;%.2f;%.2f;%.2f\n", + cc1100_get_address(), + 0, + rtc_time(NULL), + 0, + sht11_val.temperature, + sht11_val.relhum, + sht11_val.relhum_temp, + ltc4150_get_total_mAh()); + } + hwtimer_wait(sending_interval); } + puts("Something went wrong."); } diff --git a/projects/WEAtHeR/protocol_msg_gateway.c b/projects/WEAtHeR/protocol_msg_gateway.c index 1e439c5d53..baccab5e9a 100644 --- a/projects/WEAtHeR/protocol_msg_gateway.c +++ b/projects/WEAtHeR/protocol_msg_gateway.c @@ -8,6 +8,7 @@ #include #include "protocol_msg_gateway.h" +#include "weather_protocol.h" #define NUM_PROTOCOL_HANDLER_PIDS 8 @@ -16,12 +17,14 @@ static uint16_t protocol_handler_pid; static int packet_buffer_next = 0; packet_t packet_buffer[PACKET_BUFFER_SIZE]; -static void protocol_msg_gateway(void* payload, int msg_size, protocol_t protocol, packet_info_t* packet_info) { +static void protocol_msg_gateway(void* payload, int msg_size, packet_info_t* packet_info) { msg_t m; -// if ((((int16_t) packet_info->phy_src) > (((int16_t) cc1100_get_address()) + 10)) || (((int16_t) packet_info->phy_src) < (((int16_t) cc1100_get_address()) - 10))) { - // return; - // } + if (!cc1100_get_address()) { + puts("No address configured, not processing incoming packet"); + return; + } + if (protocol_handler_pid <= 0) { puts("protocol_handler(): received packet without protocol handler. msg dropped."); return; @@ -45,7 +48,8 @@ static void protocol_msg_gateway(void* payload, int msg_size, protocol_t protoco } void init_protocol_msg_gateway() { - cc1100_set_packet_monitor(protocol_msg_gateway); + puts("Init protocol msg gateway"); + cc1100_set_packet_handler(WEATHER_PROTOCOL_NR, protocol_msg_gateway); } int set_protocol_handler_thread(int pid) { diff --git a/projects/WEAtHeR/weather_protocol.h b/projects/WEAtHeR/weather_protocol.h index f504204c92..8785fd0264 100644 --- a/projects/WEAtHeR/weather_protocol.h +++ b/projects/WEAtHeR/weather_protocol.h @@ -5,6 +5,7 @@ #include #define WEATHER_PROTOCOL_NR 6 +#define MAX_HOP_LIST (11) typedef enum { WEATHER_HELLO, @@ -16,7 +17,6 @@ typedef struct { uint16_t seq_nr; uint8_t src; uint8_t type; - uint8_t resevered; } weather_packet_header_t; typedef struct __attribute__ ((packed)) { @@ -29,13 +29,15 @@ typedef struct { char mesg[40]; } weather_chat_pkt_t; -typedef struct { +typedef struct __attribute__ ((packed)) { weather_packet_header_t header; time_t timestamp; double temperature; double relhum; double relhum_temp; double energy; + uint8_t hop_counter; + uint8_t hops[MAX_HOP_LIST]; } weather_data_pkt_t; #endif diff --git a/projects/WEAtHeR/weather_routing.c b/projects/WEAtHeR/weather_routing.c index 8c354b0215..3e572a96cd 100644 --- a/projects/WEAtHeR/weather_routing.c +++ b/projects/WEAtHeR/weather_routing.c @@ -1,26 +1,31 @@ #include #include -#include #include +#include + #include "weather_protocol.h" #include "weather_routing.h" +#define ENABLE_DEBUG +#include + +uint8_t gossip_probability; + static source_timestamp_t sources[MAX_SOURCES]; static uint8_t update_sources(uint8_t id, time_t timestamp) { uint8_t i; + + DEBUG("updating sources list\n"); for (i = 0; i < MAX_SOURCES; i++) { /* source id found */ if (sources[i].id == id) { + DEBUG("source already known, comparing timestamps: %04lX : %04lX\n", sources[i].timestamp, timestamp); /* more current timestamp received, updating */ if (sources[i].timestamp < timestamp) { sources[i].timestamp = timestamp; return 1; } - /* older, but still valid timestamp, not updating */ - else if (sources[i].timestamp < timestamp + MAX_INTERVAL) { - return 1; - } /* timestamp too old, discard this packet */ else { puts("Timestamp too old, not routing"); @@ -29,6 +34,7 @@ static uint8_t update_sources(uint8_t id, time_t timestamp) { } /* source id not yet stored creating new entry */ else if (!sources[i].id) { + puts("got to know a new source"); sources[i].id = id; sources[i].timestamp = timestamp; return 1; @@ -40,20 +46,31 @@ static uint8_t update_sources(uint8_t id, time_t timestamp) { void route_packet(void* msg, int msg_size) { weather_packet_header_t *header = (weather_packet_header_t*) msg; + weather_data_pkt_t* wdp = NULL; + int state = 0; + if (header->type == WEATHER_DATA) { - weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg; + wdp = (weather_data_pkt_t*) msg; if (!update_sources(wdp->header.src, wdp->timestamp)) { return; } } - if ((100.0 * rand()/(double) RAND_MAX) <= FLOODING_PROB) { + if ((100.0 * rand()/(double) RAND_MAX) <= gossip_probability) { printf("Broadcasting packet..."); - if (cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)msg, msg_size)) { + /* if broadcasting weather data, append current hop */ + if (wdp != NULL) { + if (wdp->hop_counter < MAX_HOP_LIST) { + wdp->hops[wdp->hop_counter] = cc1100_get_address(); + wdp->hop_counter++; + } + } + state = cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)msg, msg_size); + if (state > 0) { puts("successful!"); } else { - puts("failed!"); + printf("failed with code %i!\n", state); } } } diff --git a/sys/shell/cc1100.c b/sys/shell/cc1100.c index 47901d7344..b9542e3b72 100644 --- a/sys/shell/cc1100.c +++ b/sys/shell/cc1100.c @@ -1,27 +1,43 @@ #include +#include +#include #include #ifdef MODULE_CC110X -void _cc1100_get_address_handler(char *str) { - radio_address_t addr = cc1100_get_address(); - printf("cc1100 address: %i\n", addr); +void _cc110x_get_set_address_handler(char *addr) { + int16_t a; + + a = atoi(addr+5); + if (strlen(addr) > 5) { + printf("[cc110x] Setting address %i ... ", a); + cc1100_set_address((radio_address_t)a); + if (cc1100_get_address() == (radio_address_t)a) { + puts("[OK]"); + } else { + puts("Error!"); + } + } + else { + printf("[cc1100] Got address: %i\n", cc1100_get_address()); + } } -void _cc1100_set_address_handler(char *str) { - int addr; - int res = sscanf(str, "cc1100_set_address %i", &addr); - if (res == 1) { - cc1100_set_address((radio_address_t)addr); - printf("Setting cc1100 address to %i: ", addr); - if (cc1100_get_address() == (radio_address_t)addr) { +void _cc110x_get_set_channel_handler(char *addr) { + int16_t a; + + a = atoi(addr+5); + if (strlen(addr) > 5) { + printf("[cc110x] Setting channel %i...", a); + cc1100_set_channel(a); + if (cc1100_get_channel() == a) { puts("OK"); } else { puts("Error!"); } - } else { - puts("usage: cc1100_set_address
"); + } + else { + printf("[cc1100] Got address: %i\n", cc1100_get_channel()); } } - #endif diff --git a/sys/shell/id.c b/sys/shell/id.c index 414997bac5..3807484ff3 100644 --- a/sys/shell/id.c +++ b/sys/shell/id.c @@ -8,7 +8,9 @@ void _id_handler(char *id) { newid = atoi(id+3); if (strlen(id) < 3) { +#ifdef MODULE_CONFIG printf("Current id: %u\n", sysconfig.id); +#endif } else { printf("Setting new id %lu\n", newid); diff --git a/sys/shell/shell_commands.c b/sys/shell/shell_commands.c index dd5372b99a..6023faf2a9 100644 --- a/sys/shell/shell_commands.c +++ b/sys/shell/shell_commands.c @@ -24,8 +24,8 @@ extern void _reset_current_handler(char* unused); #endif #ifdef MODULE_CC110X -extern void _cc110x_get_address_handler(char *unused); -extern void _cc110x_set_address_handler(char *ptr); +extern void _cc110x_get_set_address_handler(char *addr); +extern void _cc110x_get_set_channel_handler(char *addr); #endif #ifdef MODULE_TRANSCEIVER @@ -56,8 +56,8 @@ const shell_command_t _shell_command_list[] = { {"rstcur", "Resets coulomb counter.", _reset_current_handler}, #endif #ifdef MODULE_CC110X - {"cc110x_get_address", "", _cc110x_get_address_handler}, - {"cc110x_set_address", "", _cc110x_set_address_handler}, + {"addr", "Gets or sets the address for the CC1100 transceiver", _cc110x_get_set_address_handler}, + {"chan", "Gets or sets the channel for the CC1100 transceiver", _cc110x_get_set_channel_handler}, #endif #ifdef MODULE_TRANSCEIVER #ifdef MODULE_CC110X_NG