diff --git a/Makefile.dep b/Makefile.dep index 00844b493307a0f88d825f3bd3b6cd4313dde126..2e13d5e40ef4e878c4ff4adc47e7946a6d437b0e 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -21,3 +21,16 @@ ifneq (,$(findstring cc110x_ng,$(USEMODULE))) USEMODULE += hwtimer endif endif + +ifneq (,$(findstring cc2420,$(USEMODULE))) + ifeq (,$(findstring transceiver,$(USEMODULE))) + USEMODULE += transceiver + USEMODULE += ieee802154 + endif +endif + +ifneq (,$(findstring sixlowpan,$(USEMODULE))) + ifeq (,$(findstring ieee802154,$(USEMODULE))) + USEMODULE += ieee802154 + endif +endif diff --git a/core/include/queue.h b/core/include/queue.h index 422cff6cd2e09066c0472aac75d31ea165629fc3..ba4104828241257ad9a2bbbc5b1cee0540103540 100644 --- a/core/include/queue.h +++ b/core/include/queue.h @@ -9,10 +9,13 @@ #ifndef __QUEUE_H #define __QUEUE_H +#include <stdlib.h> +#include <stdint.h> + typedef struct queue_node_t { struct queue_node_t *next; unsigned int data; - unsigned int priority; + uint32_t priority; } queue_node_t; queue_node_t *queue_remove_head(queue_node_t *root); diff --git a/core/queue.c b/core/queue.c index 91483b8bf6fa9505c165660d54336a67a0628eeb..1090dd8a06d5cd866b072af5e2ba67350053e16e 100644 --- a/core/queue.c +++ b/core/queue.c @@ -15,6 +15,7 @@ */ #include <stddef.h> +#include <inttypes.h> #include "queue.h" @@ -104,13 +105,13 @@ void queue_print(queue_node_t *node) while (node->next != NULL) { node = node->next; - printf("Data: %u Priority: %u\n", node->data, node->priority); + printf("Data: %u Priority: %"PRIu32"\n", node->data, node->priority); } } void queue_print_node(queue_node_t *node) { - printf("Data: %u Priority: %u Next: %u\n", (unsigned int)node->data, node->priority, (unsigned int)node->next); + printf("Data: %u Priority: %"PRIu32" Next: %u\n", (unsigned int)node->data, node->priority, (unsigned int)node->next); } /* diff --git a/cpu/msp430-common/hwtimer_cpu.c b/cpu/msp430-common/hwtimer_cpu.c index 9fcd305a45cc01af5285fcf366f4578999bbcc7b..7a511b269fb9abbb21346bd79346cd91947c0c7d 100644 --- a/cpu/msp430-common/hwtimer_cpu.c +++ b/cpu/msp430-common/hwtimer_cpu.c @@ -22,6 +22,8 @@ License. See the file LICENSE in the top level directory for more details. void (*int_handler)(int); extern void timerA_init(void); +uint16_t overflow_interrupt[ARCH_MAXTIMERS+1]; +uint16_t timer_round; static void TA0_disable_interrupt(short timer) { @@ -66,6 +68,7 @@ void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) { timerA_init(); int_handler = handler; + TA0_enable_interrupt(0); } void hwtimer_arch_enable_interrupt(void) @@ -90,7 +93,9 @@ void hwtimer_arch_set(unsigned long offset, short timer) void hwtimer_arch_set_absolute(unsigned long value, short timer) { - TA0_set(value, timer); + uint16_t small_value = value % 0xFFFF; + overflow_interrupt[timer] = (uint16_t)(value >> 16); + TA0_set(small_value,timer); } void hwtimer_arch_unset(short timer) diff --git a/cpu/msp430-common/include/hwtimer_cpu.h b/cpu/msp430-common/include/hwtimer_cpu.h index 872b584307752ff1287031950e03da897b35e785..1eea5df49124026b5317245523f84bb798759023 100644 --- a/cpu/msp430-common/include/hwtimer_cpu.h +++ b/cpu/msp430-common/include/hwtimer_cpu.h @@ -37,6 +37,6 @@ License. See the file LICENSE in the top level directory for more details. #endif #define HWTIMER_SPEED 32768 -#define HWTIMER_MAXTICKS (0xFFFF) +#define HWTIMER_MAXTICKS (0xFFFFFFFF) #endif // __HWTIMER_CPU_H diff --git a/cpu/msp430x16x/hwtimer_msp430.c b/cpu/msp430x16x/hwtimer_msp430.c index 85410a78726885f18d72c6e85b6b9ed4b4ee2f13..3a4a3a91cef6e01a26838333140ae84e54b4d18f 100644 --- a/cpu/msp430x16x/hwtimer_msp430.c +++ b/cpu/msp430x16x/hwtimer_msp430.c @@ -7,33 +7,36 @@ static uint32_t ticks = 0; extern void (*int_handler)(int); extern void TA0_unset(short timer); +extern uint16_t overflow_interrupt[ARCH_MAXTIMERS+1]; +extern uint16_t timer_round; void timerA_init(void) { - ticks = 0; // Set tick counter value to 0 - TA0CTL = TASSEL_1 + TACLR; // Clear the timer counter, set ACLK - TA0CTL &= ~TAIFG; // Clear the IFG - TA0CTL &= ~TAIE; // Clear the IFG - volatile unsigned int *ccr = &TA0CCR0; - volatile unsigned int *ctl = &TA0CCTL0; + volatile unsigned int *ccr; + volatile unsigned int *ctl; + ticks = 0; // Set tick counter value to 0 + timer_round = 0; // Set to round 0 + TA0CTL = TASSEL_1 + TACLR; // Clear the timer counter, set ACLK + TA0CTL &= ~TAIFG; // Clear the IFG + TA0CTL &= ~TAIE; // Clear the IFG for (int i = 0; i < ARCH_MAXTIMERS; i++) { + ccr = &TA0CCR0 + (i); + ctl = &TA0CCTL0 + (i); *ccr = 0; *ctl &= ~(CCIFG); *ctl &= ~(CCIE); } - ITA0CTL |= MC_2; + TA0CTL |= MC_2; } interrupt(TIMERA0_VECTOR) __attribute__((naked)) timer_isr_ccr0(void) { __enter_isr(); - - TA0_unset(0); - int_handler(0); - + timer_round += 1; __exit_isr(); + } interrupt(TIMERA1_VECTOR) __attribute__((naked)) timer_isr(void) @@ -43,16 +46,14 @@ interrupt(TIMERA1_VECTOR) __attribute__((naked)) timer_isr(void) short taiv = TA0IV; if (taiv & TAIFG) { - // puts("msp430/hwtimer_cpu TAIFG set!"); - // TA0CTL &= ~TAIFG; - // ticks += 0xFFFF; + } else { + + short timer = (taiv/2); + if(overflow_interrupt[timer] == timer_round) + { + TA0_unset(timer); + int_handler(timer); + } } - else { - - short timer = (taiv / 2); - TA0_unset(timer); - int_handler(timer); - } - __exit_isr(); } diff --git a/drivers/Makefile b/drivers/Makefile index 273d1e00279171c6e9acf8a378ddd5728d083d05..d4371e5b0b19a8129fd598cca8952d5d5d2bb969 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -4,6 +4,9 @@ DIRS= ifneq (,$(findstring powermon,$(USEMODULE))) DIRS += powermon endif +ifneq (,$(findstring cc2420,$(USEMODULE))) + DIRS += cc2420 +endif ifneq (,$(findstring sht11,$(USEMODULE))) DIRS += sht11 endif diff --git a/drivers/cc110x_ng/Makefile b/drivers/cc110x_ng/Makefile index f5f3820efc86eff405cfe983b2584ee258b5dc94..d36acedc19db20a7f2f29123a8a628fd63cb28b0 100644 --- a/drivers/cc110x_ng/Makefile +++ b/drivers/cc110x_ng/Makefile @@ -3,13 +3,16 @@ MODULE =cc110x_ng DIRS = ifneq (,$(findstring msb-430h,$(BOARD))) - DIRS += spi + DIRS += spi endif ifneq (,$(findstring msba2,$(BOARD))) - DIRS += spi + DIRS += spi +endif +ifneq (,$(findstring wsn430-v1_3b,$(BOARD))) + DIRS += spi endif ifneq (,$(findstring native,$(BOARD))) - DIRS += spi + DIRS += spi endif all: $(BINDIR)$(MODULE).a diff --git a/drivers/cc2420/Makefile b/drivers/cc2420/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e4c0b6297e621a9135ce1e472f7b8838592fc0af --- /dev/null +++ b/drivers/cc2420/Makefile @@ -0,0 +1,13 @@ +INCLUDES = -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/sys/net -I$(RIOTBASE)/core/include -Iinclude/ -I$(RIOTBASE)/sys/net/ieee802154/ +MODULE =cc2420 + +DIRS = + +all: $(BINDIR)$(MODULE).a + @for i in $(DIRS) ; do $(MAKE) -C $$i ; done ; + +include $(RIOTBASE)/Makefile.base + +clean:: + @for i in $(DIRS) ; do $(MAKE) -C $$i clean ; done ; + diff --git a/drivers/cc2420/cc2420.c b/drivers/cc2420/cc2420.c new file mode 100644 index 0000000000000000000000000000000000000000..0e877b7439cb70478deb2401589040aac8316dc1 --- /dev/null +++ b/drivers/cc2420/cc2420.c @@ -0,0 +1,179 @@ +/** + * cc2420.c - Implementation of cc2420 functions. + * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de> + * + * This source code is licensed under the GNU Lesser General Public License, + * Version 2. See the file LICENSE for more details. + */ + +#include <cc2420.h> +#include <cc2420_spi.h> +#include <cc2420_settings.h> +#include <cc2420_arch.h> +#include <hwtimer.h> + +//#define ENABLE_DEBUG +#include <debug.h> + +static uint16_t radio_channel; +static uint16_t radio_address; +static uint64_t radio_address_long; +static uint16_t radio_pan; + +/* Radio driver API */ + +int transceiver_pid; + +void cc2420_init(int tpid) +{ + uint16_t reg; + transceiver_pid = tpid; + + cc2420_spi_init(); + hwtimer_wait(CC2420_WAIT_TIME); + cc2420_reset(); + + cc2420_strobe(CC2420_STROBE_XOSCON); //enable crystal + + while((cc2420_strobe(NOBYTE) & 0x40) == 0); //wait for crystal to be stable + hwtimer_wait(CC2420_WAIT_TIME); + + reg = cc2420_read_reg(CC2420_REG_MDMCTRL0); + reg |= CC2420_ADR_DECODE; //enable adr decode + reg |= CC2420_AUTOACK; //enable auto ack + reg |= CC2420_AUTOCRC; //enable auto crc + reg &= ~(CC2420_RES_FRM_MODE); //disable reserved frames + cc2420_write_reg(CC2420_REG_MDMCTRL0, reg); + + /* Change default values as recomended in the data sheet, */ + /* RX bandpass filter = 1.3uA. */ + reg = cc2420_read_reg(CC2420_REG_RXCTRL1); + reg |= CC2420_RXBPF_LOCUR; + cc2420_write_reg(CC2420_REG_RXCTRL1, reg); + + /* Set the FIFOP threshold to maximum. */ + cc2420_write_reg(CC2420_REG_IOCFG0, 127); + + /* Turn off "Security enable" (page 32). */ + reg = cc2420_read_reg(CC2420_REG_SECCTRL0); + reg &= ~CC2420_RXFIFO_PROTECTION; + cc2420_write_reg(CC2420_REG_SECCTRL0, reg); + + /* set output power to 0dbm */ + cc2420_write_reg(CC2420_REG_TXCTRL, 0xA0FF); + + cc2420_set_channel(CC2420_DEFAULT_CHANNR); + cc2420_set_pan(0x1111); + DEBUG("CC2420 initialized and set to channel %i and pan %i\n", radio_channel, radio_pan); + cc2420_init_interrupts(); + cc2420_switch_to_rx(); + +} + +void cc2420_switch_to_rx(void) { + cc2420_strobe(CC2420_STROBE_RFOFF); + cc2420_strobe(CC2420_STROBE_FLUSHRX); + cc2420_strobe(CC2420_STROBE_FLUSHRX); + cc2420_strobe(CC2420_STROBE_RXON); +} + +void cc2420_rxoverflow_irq(void) +{ + cc2420_strobe(CC2420_STROBE_FLUSHRX); + //Datasheets says do this twice... + cc2420_strobe(CC2420_STROBE_FLUSHRX); +} + +void cc2420_rx_irq(void) +{ + cc2420_rx_handler(); +} + +void cc2420_set_monitor(uint8_t mode) +{ + uint16_t reg; + reg = cc2420_read_reg(CC2420_REG_MDMCTRL0); + if(mode) { + reg &= ~CC2420_ADR_DECODE; + } else { + reg |= CC2420_ADR_DECODE; + } + cc2420_write_reg(CC2420_REG_MDMCTRL0, reg); +} + +int16_t cc2420_set_channel(uint16_t chan) +{ + if(chan < 11 || chan > 26) { + DEBUG("Invalid channel %i set. Valid channels are 11 through 26\n",chan); + return -1; + } + radio_channel = chan; + chan = 357 + (5 * (radio_channel-11)); //calculation from p.50 + cc2420_write_reg(CC2420_REG_FSCTRL, chan); + return radio_channel; +} + +uint16_t cc2420_get_channel(void) +{ + return radio_channel; +} + +uint16_t cc2420_set_address(uint16_t addr) +{ + uint8_t buf[2]; + radio_address = addr; + buf[0] = (uint8_t)(addr & 0xFF); + buf[1] = (uint8_t)(addr >> 8); + cc2420_write_ram(CC2420_RAM_SHORTADR, buf, 2); + cc2420_set_address_long(0x00FF & addr); + return radio_address; +} + +uint64_t cc2420_set_address_long(uint64_t addr) +{ + uint8_t buf[8]; + radio_address_long = addr; + buf[0] = (uint8_t)(addr & 0xFF); + buf[1] = (uint8_t)(addr >> 8); + buf[2] = (uint8_t)(addr >> 16); + buf[3] = (uint8_t)(addr >> 24); + buf[4] = (uint8_t)(addr >> 32); + buf[5] = (uint8_t)(addr >> 40); + buf[6] = (uint8_t)(addr >> 48); + buf[7] = (uint8_t)(addr >> 56); + cc2420_write_ram(CC2420_RAM_IEEEADR, buf, 8); + return radio_address_long; +} + +uint16_t cc2420_get_address(void) +{ + return radio_address; +} + +uint64_t cc2420_get_address_long(void) +{ + return radio_address_long; +} + +uint16_t cc2420_set_pan(uint16_t pan) +{ + uint8_t buf[2]; + radio_pan = pan; + buf[0] = (uint8_t)(pan & 0xFF); + buf[1] = (uint8_t)(pan >> 8); + cc2420_write_ram(CC2420_RAM_PANID, buf, 2); + return radio_pan; +} + +uint16_t cc2420_get_pan(void) +{ + return radio_pan; +} + +void cc2420_swap_fcf_bytes(uint8_t *buf) +{ + uint8_t tmp; + tmp = buf[0]; + buf[0] = buf[1]; + buf[1] = tmp; +} diff --git a/drivers/cc2420/cc2420_rx.c b/drivers/cc2420/cc2420_rx.c new file mode 100644 index 0000000000000000000000000000000000000000..51b6c1801b987f11d3175f937ee8b0dbf8ef3b76 --- /dev/null +++ b/drivers/cc2420/cc2420_rx.c @@ -0,0 +1,73 @@ +/** + * cc2420_rx.c - Implementation of receiving cc2420 functions. + * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de> + * + * This source code is licensed under the GNU Lesser General Public License, + * Version 2. See the file LICENSE for more details. + */ + +#include <stdio.h> + +#include <cc2420.h> +#include <cc2420_settings.h> +#include <cc2420_arch.h> +#include <cc2420_spi.h> +#include <ieee802154_frame.h> + +#include <transceiver.h> +#include <msg.h> +#include <debug.h> + +cc2420_packet_t cc2420_rx_buffer[CC2420_RX_BUF_SIZE]; +volatile uint8_t rx_buffer_next; + +void cc2420_rx_handler(void) +{ + uint8_t rssi_crc_lqi[2]; + + /* read length */ + cc2420_read_fifo(&cc2420_rx_buffer[rx_buffer_next].length, 1); + + /* read packet without rssi, crc and lqi */ + uint8_t buf[cc2420_rx_buffer[rx_buffer_next].length-2]; + cc2420_read_fifo(buf, cc2420_rx_buffer[rx_buffer_next].length-2); + + cc2420_swap_fcf_bytes(buf); + /* read rssi, lqi and crc */ + cc2420_read_fifo(rssi_crc_lqi, 2); + + /* build package */ + cc2420_rx_buffer[rx_buffer_next].rssi = (int8_t)(rssi_crc_lqi[0]); + cc2420_rx_buffer[rx_buffer_next].lqi = (uint8_t)(rssi_crc_lqi[1] & 0x7F); + cc2420_rx_buffer[rx_buffer_next].crc = (uint8_t)((rssi_crc_lqi[1] & 0x80) >> 7); + + if(cc2420_rx_buffer[rx_buffer_next].crc == 0) { + DEBUG("Got packet with invalid crc.\n"); + return; + } + read_802154_frame(buf, + &cc2420_rx_buffer[rx_buffer_next].frame, + cc2420_rx_buffer[rx_buffer_next].length-2); + if(cc2420_rx_buffer[rx_buffer_next].frame.fcf.frame_type != 2) { +#ifdef DEBUG + print_802154_fcf_frame(&cc2420_rx_buffer[rx_buffer_next].frame); +#endif + /* notify transceiver thread if any */ + if (transceiver_pid) { + msg_t m; + m.type = (uint16_t) RCV_PKT_CC2420; + m.content.value = rx_buffer_next; + msg_send_int(&m, transceiver_pid); + } + } else { +#ifdef DEBUG + DEBUG("GOT ACK for SEQ %u\n", cc2420_rx_buffer[rx_buffer_next].frame.seq_nr); + print_802154_fcf_frame(&cc2420_rx_buffer[rx_buffer_next].frame); +#endif + } + + /* shift to next buffer element */ + if (++rx_buffer_next == CC2420_RX_BUF_SIZE) { + rx_buffer_next = 0; + } +} diff --git a/drivers/cc2420/cc2420_spi.c b/drivers/cc2420/cc2420_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..653955a9ca2abb9834a5f7f3943b389b5028d38b --- /dev/null +++ b/drivers/cc2420/cc2420_spi.c @@ -0,0 +1,104 @@ +/** + * cc2420_spi.c - Implementation of SPI cc2420 functions. + * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de> + * + * This source code is licensed under the GNU Lesser General Public License, + * Version 2. See the file LICENSE for more details. + */ + +#include <cc2420_spi.h> +#include <cc2420_arch.h> + +#include <cc2420_settings.h> +#include <irq.h> + +/* reg */ +void cc2420_write_reg(uint8_t addr, uint16_t value) { + unsigned int cpsr = disableIRQ(); + cc2420_spi_select(); + cc2420_txrx(addr | CC2420_WRITE_ACCESS); + cc2420_txrx((uint8_t) (value >> 8)); + cc2420_txrx((uint8_t) (value & 0xFF)); + cc2420_spi_unselect(); + restoreIRQ(cpsr); +} + +uint16_t cc2420_read_reg(uint8_t addr) { + uint16_t result; + unsigned int cpsr = disableIRQ(); + cc2420_spi_select(); + cc2420_txrx(addr | CC2420_READ_ACCESS); + result = cc2420_txrx(NOBYTE); + result = result << 8; + result = cc2420_txrx(NOBYTE); + cc2420_spi_unselect(); + restoreIRQ(cpsr); + return result; +} + +uint8_t cc2420_strobe(uint8_t c) { + uint8_t result; + unsigned int cpsr = disableIRQ(); + cc2420_spi_select(); + result = cc2420_txrx(c); + cc2420_spi_unselect(); + restoreIRQ(cpsr); + return result; +} + +/* ram */ +uint16_t cc2420_read_ram(uint16_t addr, uint8_t* buffer, uint16_t len) { + uint16_t i; + unsigned int cpsr = disableIRQ(); + cc2420_spi_select(); + cc2420_txrx(CC2420_RAM_ACCESS | (addr & 0x7F)); + cc2420_txrx(((addr >> 1) & 0xC0) | CC2420_RAM_READ_ACCESS); + for (i = 0; i < len; i++) { + buffer[i] = cc2420_txrx(NOBYTE); + } + cc2420_spi_unselect(); + restoreIRQ(cpsr); + return i; +} + +uint16_t cc2420_write_ram(uint16_t addr, uint8_t* buffer, uint16_t len) { + uint16_t i; + unsigned int cpsr = disableIRQ(); + cc2420_spi_select(); + cc2420_txrx(CC2420_RAM_ACCESS | (addr & 0x7F)); + cc2420_txrx(((addr >> 1) & 0xC0) | CC2420_RAM_WRITE_ACCESS); + for (i = 0; i < len; i++) { + cc2420_txrx(buffer[i]); + } + cc2420_spi_unselect(); + restoreIRQ(cpsr); + return i; +} + +/* fifo */ + +uint16_t cc2420_write_fifo(uint8_t* data, uint16_t data_length) { + uint16_t i; + unsigned int cpsr = disableIRQ(); + cc2420_spi_select(); + cc2420_txrx(CC2420_REG_TXFIFO | CC2420_WRITE_ACCESS); + for (i = 0; i < data_length; i++) { + cc2420_txrx(data[i]); + } + cc2420_spi_unselect(); + restoreIRQ(cpsr); + return i; +} + +uint16_t cc2420_read_fifo(uint8_t* data, uint16_t data_length) { + uint16_t i; + unsigned int cpsr = disableIRQ(); + cc2420_spi_select(); + cc2420_txrx(CC2420_REG_RXFIFO | CC2420_READ_ACCESS); + for (i = 0; i < data_length; i++) { + data[i] = cc2420_txrx(NOBYTE); + } + cc2420_spi_unselect(); + restoreIRQ(cpsr); + return i; +} diff --git a/drivers/cc2420/cc2420_tx.c b/drivers/cc2420/cc2420_tx.c new file mode 100644 index 0000000000000000000000000000000000000000..e97418468b26da8ed5e2a9691e6f3bf39234339f --- /dev/null +++ b/drivers/cc2420/cc2420_tx.c @@ -0,0 +1,112 @@ +/** + * cc2420_rx.c - Implementation of transmitting cc2420 functions. + * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de> + * + * This source code is licensed under the GNU Lesser General Public License, + * Version 2. See the file LICENSE for more details. + */ + +#include <stdio.h> + +#include <cc2420.h> +#include <cc2420_spi.h> +#include <cc2420_settings.h> +#include <cc2420_arch.h> +#include <ieee802154_frame.h> + +#include <irq.h> + +static void cc2420_gen_pkt(uint8_t *buf, cc2420_packet_t *packet); + +static uint8_t sequenz_nr; + +int16_t cc2420_send(cc2420_packet_t *packet) +{ + volatile uint32_t abort_count; + + /* Set missing frame information */ + packet->frame.fcf.frame_ver = 0; + if(packet->frame.src_pan_id == packet->frame.dest_pan_id) { + packet->frame.fcf.panid_comp = 1; + } else { + packet->frame.fcf.panid_comp = 0; + } + + if(packet->frame.fcf.src_addr_m == 2) { + packet->frame.src_addr[1] = (uint8_t)(cc2420_get_address() >> 8); + packet->frame.src_addr[0] = (uint8_t)(cc2420_get_address() & 0xFF); + } else if (packet->frame.fcf.src_addr_m == 3) { + packet->frame.src_addr[7] = (uint8_t)(cc2420_get_address_long() >> 56); + packet->frame.src_addr[6] = (uint8_t)(cc2420_get_address_long() >> 48); + packet->frame.src_addr[5] = (uint8_t)(cc2420_get_address_long() >> 40); + packet->frame.src_addr[4] = (uint8_t)(cc2420_get_address_long() >> 32); + packet->frame.src_addr[3] = (uint8_t)(cc2420_get_address_long() >> 24); + packet->frame.src_addr[2] = (uint8_t)(cc2420_get_address_long() >> 16); + packet->frame.src_addr[1] = (uint8_t)(cc2420_get_address_long() >> 8); + packet->frame.src_addr[0] = (uint8_t)(cc2420_get_address_long() & 0xFF); + } + packet->frame.src_pan_id = cc2420_get_pan(); + packet->frame.seq_nr = sequenz_nr; + + sequenz_nr += 1; + + /* calculate size of the package (header + payload + fcs) */ + packet->length = get_802154_hdr_len(&packet->frame) + packet->frame.payload_len + 2; + + if(packet->length > CC2420_MAX_PKT_LENGTH) { + return -1; + } + /* FCS is added in hardware */ + uint8_t pkt[packet->length-2]; + + /* generate pkt */ + cc2420_gen_pkt(pkt, packet); + + /* idle & flush tx */ + cc2420_strobe(CC2420_STROBE_RFOFF); + cc2420_strobe(CC2420_STROBE_FLUSHTX); + + /* write length and packet to fifo */ + cc2420_write_fifo(&packet->length, 1); + cc2420_write_fifo(pkt, packet->length-2); + + unsigned int cpsr = disableIRQ(); + cc2420_strobe(CC2420_STROBE_TXON); + + // Wait for SFD to be set -> sync word transmitted + while (cc2420_get_sfd() == 0) { + abort_count++; + if (abort_count > CC2420_SYNC_WORD_TX_TIME) { + // Abort waiting. CC2420 maybe in wrong mode + // e.g. sending preambles for always + puts("[CC2420 TX] fatal error\n"); + packet->length = 0; + break; + } + } + printf("SEQ: %u\n", packet->frame.seq_nr); + restoreIRQ(cpsr); + + /* wait for packet to be send */ + while (cc2420_get_sfd() != 0); + + cc2420_switch_to_rx(); + return packet->length; +} + +/** + * @brief Static function to generate byte array from cc2420 packet. + * + */ + +static void cc2420_gen_pkt(uint8_t *buf, cc2420_packet_t *packet) +{ + uint8_t index, offset; + index = init_802154_frame(&packet->frame, buf); + offset = index; + while(index < packet->length-2) { + buf[index] = packet->frame.payload[index-offset]; + index += 1; + } + cc2420_swap_fcf_bytes(buf); +} diff --git a/drivers/cc2420/include/cc2420.h b/drivers/cc2420/include/cc2420.h new file mode 100644 index 0000000000000000000000000000000000000000..bf2d6c6bc2469ba9f496756ac1c6960bb4a9c6e1 --- /dev/null +++ b/drivers/cc2420/include/cc2420.h @@ -0,0 +1,241 @@ +/** + * cc2420.h - Definitions for CC2420 functions. + * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de> + * + * This source code is licensed under the GNU Lesser General Public License, + * Version 2. See the file LICENSE for more details. + */ + + +/** + * @ingroup CC2420 + * @{ + * @file + * @brief Definitions for CC2420 functions + * @author Milan Babel <babel@inf.fu-berlin.de> + * + */ + +/** + * @brief Definition of the cc2420 layer 0 protocol + * <pre> +--------------------------------------------------------------------------- +| | | | | | | | +| Length | FCF | Seq No. |Address | PhySrc | Data | FCS | +| | | | | | | | +--------------------------------------------------------------------------- + 1 byte 2 bytes 1 byte 2/8 bytes 2/8 bytes <=118 bytes 2 bytes + +A 5 byte SHR will be generated and added in hardware. +SHR contains a preable sequence and a start of delimiter, + +Length does not contain SHR and Length, +first bit of length has to be 0 (length has only 7bit) + +Address fields can be in total between 4 and 20 bytes +FCS contain a hardware generated CRC sum with the polynom x^16+x^12+x^5+1 +When receiving a package FCS will be checked by hardware, the first FCS byte will be replaced by RSSI, +followed by a CRC OK bit and the unsigned 7 bit correlation value. +FCF: + Bit | Meaning + -------------------- + 0-2 | Frame Type + 3 | Security Enabled + 4 | Frame Pending + 5 | Acknowledge request + 6 | PAN ID Compression Field + 7-9 | Reserved + 10-11 | Destination addressing mode + 12-13 | Reserved + 14-15 | Source addressing mode + +For the cc2420 bit 0 is the most right bit and bit 15 is the most left bit. +But the 2 FCF bytes have to be transmitted littel endian (byte 15 to 8 first than 7 to 0) + +Addressing mode value: + + Bit | Meaning + --------------------- + 00 | PAN identifier and address field are not present. + 01 | Reserved. + 10 | Address field contains a 16 bit short address. + 11 | Address field contains a 64 bit extended address. + +Frame type value: + + Bit | Meaning + --------------------- + 000 | Beacon + 001 | Data + 010 | Acknowledgment + 011 | MAC command + 1xx | Reserved + </pre> +*/ + +#ifndef CC2420_H +#define CC2420_H + +#include <ieee802154/ieee802154_frame.h> +#include <cc2420_settings.h> + +#define CC2420_MAX_PKT_LENGTH 127 +#define CC2420_MAX_DATA_LENGTH (118) + +#define CC2420_BROADCAST_ADDRESS (0xFFFF) + +#define CC2420_MAX_UID (0xFFFE) +#define CC2420_MIN_UID (0x0000) + +/** + * Structure to represent a cc2420 packet. + */ +typedef struct __attribute__ ((packed)) { + /* @{ */ + uint8_t length; /** < the length of the frame of the frame including fcs*/ + ieee802154_frame_t frame; /** < the ieee802154 frame */ + int8_t rssi; /** < the rssi value */ + uint8_t crc; /** < 1 if crc was successfull, 0 otherwise */ + uint8_t lqi; /** < the link quality indicator */ + /* @} */ +} cc2420_packet_t; + +/** + * @brief Init the cc2420. + * + * @param[in] tpid The PID of the transceiver thread. + */ + +void cc2420_init(int tpid); + +/** + * @brief Turns monitor mode on off. + * + * @param[in] mode The desired mode, 1 for on; 0 for off. + */ +void cc2420_set_monitor(uint8_t mode); + +/** + * @brief Switchs the cc2420 into receive mode. + * + */ +void cc2420_switch_to_rx(void); + +/** + * @brief Set the channel of the cc2420. + * + * @param[in] chan The desired channel, valid channels are from 11 to 26. + * + * @return The tuned channel after calling, or -1 on error. + */ +int16_t cc2420_set_channel(uint16_t chan); + +/** + * @brief Get the channel of the cc2420. + * + * @return The tuned channel. + */ +uint16_t cc2420_get_channel(void); + +/** + * @brief Sets the short address of the cc2420. + * + * @param[in] addr The desired address. + * + * @return The set address after calling. + */ +uint16_t cc2420_set_address(uint16_t addr); + +/** + * @brief Gets the current short address of the cc2420. + * + * @return The current short address. + * + */ +uint16_t cc2420_get_address(void); + +/** + * @brief Sets the IEEE long address of the cc2420. + * + * @param[in] addr The desired address. + * + * @return The set address after calling. + */ +uint64_t cc2420_set_address_long(uint64_t addr); + +/** + * @brief Gets the current IEEE long address of the cc2420. + * + * @return The current IEEE long address. + * + */ +uint64_t cc2420_get_address_long(void); + +/** + * @brief Sets the pan ID of the cc2420. + * + * @param[in] pan The desired pan ID. + * + * @return The set pan ID after calling. + */ +uint16_t cc2420_set_pan(uint16_t pan); + +/** + * @brief Gets the current IEEE long address of the cc2420. + * + * @return The current IEEE long address. + * + */ +uint16_t cc2420_get_pan(void); + + +/** + * @brief Interrupt handler, gets fired when a RX overflow happens. + * + */ +void cc2420_rxoverflow_irq(void); + +/** + * @brief Interrupt handler, gets fired when bytes in the RX FIFO are present. + * + */ +void cc2420_rx_irq(void); + + +/** + * @brief RX handler, process data from the RX FIFO. + * + */ +void cc2420_rx_handler(void); + +/** + * @brief Send function, sends a cc2420_packet_t over the air. + * + * @param[in] *packet The Packet which will be send. + * + * @return The count of bytes which are send or -1 on error + * + */ +int16_t cc2420_send(cc2420_packet_t *packet); + +/** + * @brief Changes the byte order of the two fcf bytes in a buffer. + * + * @param[in] *buf The Packet to swap. + * + */ +void cc2420_swap_fcf_bytes(uint8_t *buf); + +/** + * The PID of the transceiver thread. + */ +extern int transceiver_pid; + +/* + * RX Packet Buffer, read from the transceiver, filled by the cc2420_rx_handler. + */ +extern cc2420_packet_t cc2420_rx_buffer[CC2420_RX_BUF_SIZE]; + + +#endif + diff --git a/drivers/cc2420/include/cc2420_arch.h b/drivers/cc2420/include/cc2420_arch.h new file mode 100644 index 0000000000000000000000000000000000000000..a206ecb399f9dd8a57d0b29de9051e551c002133 --- /dev/null +++ b/drivers/cc2420/include/cc2420_arch.h @@ -0,0 +1,123 @@ +/****************************************************************************** +Copyright 2013, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of RIOT. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation version 2 of the License. + +RIOT is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @file + * @ingroup CC2420 + * @brief CC2420 dependend functions + * + * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Heiko Will <hwill@inf.fu-berlin.de> + * @author Milan Babel <babel@inf.fu-berlin.de> + * @version $Revision: 1775 $ + * + * @note $Id: arch_cc110x.h 1775 2010-01-26 09:37:03Z hillebra $ + */ + +#include <stdint.h> + +/** + * @brief SPI tx and rx function. + * + * @param[in] c byte which should be transmitted. + * + * @return Byte which was received after transmitting. + * + */ +uint8_t cc2420_txrx(uint8_t c); + +/** + * @brief Gets the status of the sfd pin. + * + * @return Status of the sfd pin. + * + */ +uint8_t cc2420_get_sfd(void); + +/** + * @brief Does a hardware reset of the cc2420. + * + */ +void cc2420_reset(void); + +/** + * @brief Init the SPI interface. + * + */ +void cc2420_spi_init(void); + +/** + * @brief Selects the cc2420 on the spi bus. + * + */ +void cc2420_spi_select(void); + +/** + * @brief Unselects the cc2420 on the spi bus. + * + */ +void cc2420_spi_unselect(void); + +/** + * @brief Enable interrupts on the GDO0 pin. + * + */ +void cc2420_gdo0_enable(void); + +/** + * @brief Disable interrupts on the GDO0 pin. + * + */ +void cc2420_gdo0_disable(void); + +/** + * @brief Enable interrupts on the GDO2 pin. + * + */ +void cc2420_gdo2_enable(void); + +/** + * @brief Disable interrupts on the GDO2 pin. + * + */ +void cc2420_gdo2_disable(void); + +/** + * @brief Init interrupts. + * + */ +void cc2420_init_interrupts(void); + +/** + * @brief Function called before send to disable interrupts. + * + */ +void cc2420_before_send(void); + +/** + * @brief Function called after send to reenable interrupts. + * + */ +void cc2420_after_send(void); diff --git a/drivers/cc2420/include/cc2420_settings.h b/drivers/cc2420/include/cc2420_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..18fcf3ac2203862c61e51e2e45df0e709e1dacd9 --- /dev/null +++ b/drivers/cc2420/include/cc2420_settings.h @@ -0,0 +1,107 @@ +/** + * cc2420_settings.h - Definitions and settings for the CC2420. + * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de> + * + * This source code is licensed under the GNU Lesser General Public License, + * Version 2. See the file LICENSE for more details. + */ + + +/** + * @ingroup CC2420 + * @{ + * @file + * @brief Definitions and settings for the CC2420 + * @author Milan Babel <babel@inf.fu-berlin.de> + * + */ +#ifndef CC2420_SETTINGS_H +#define CC2420_SETTINGS_H + +/* Access addresses */ +#define CC2420_READ_ACCESS 0x40 +#define CC2420_WRITE_ACCESS 0x00 + +#define CC2420_RAM_ACCESS 0x80 +#define CC2420_RAM_READ_ACCESS 0x20 +#define CC2420_RAM_WRITE_ACCESS 0x00 + +#define CC2420_REG_TXFIFO 0x3E +#define CC2420_REG_RXFIFO 0x3F + +/* RAM addresses */ +#define CC2420_RAM_SHORTADR 0x16A +#define CC2420_RAM_PANID 0x168 +#define CC2420_RAM_IEEEADR 0x160 + +/* Strobe command addresses */ +#define CC2420_STROBE_NOP 0x00 +#define CC2420_STROBE_XOSCON 0x01 +#define CC2420_STROBE_TXCAL 0x02 +#define CC2420_STROBE_RXON 0x03 +#define CC2420_STROBE_TXON 0x04 +#define CC2420_STROBE_TXONCCA 0x05 +#define CC2420_STROBE_RFOFF 0x06 +#define CC2420_STROBE_XOSCOFF 0x07 +#define CC2420_STROBE_FLUSHRX 0x08 +#define CC2420_STROBE_FLUSHTX 0x09 +#define CC2420_STROBE_ACK 0x0A +#define CC2420_STROBE_ACKPEND 0x0B +#define CC2420_STROBE_RXDEC 0x0C +#define CC2420_STROBE_TXENC 0x0D +#define CC2420_STROBE_AES 0x0E + +/* Register command addresses */ +#define CC2420_REG_MAIN 0x10 +#define CC2420_REG_MDMCTRL0 0x11 + #define CC2420_ADR_DECODE 0x800 + #define CC2420_RES_FRM_MODE 0x2000 + #define CC2420_PAN_COORD 0x1000 + #define CC2420_AUTOCRC 0x20 + #define CC2420_AUTOACK 0x10 +#define CC2420_REG_MDMCTRL1 0x12 +#define CC2420_REG_RSSI 0x13 + #define CC2420_CCATHR_MASK 0xFF00 + #define CC2420_RSSI_MASK 0xFF +#define CC2420_REG_SYNCWORD 0x14 +#define CC2420_REG_TXCTRL 0x15 + #define CC2420_PALEVEL_MASK 0x1F +#define CC2420_REG_RXCTRL0 0x16 +#define CC2420_REG_RXCTRL1 0x17 + #define CC2420_RXBPF_LOCUR 0x2000 +#define CC2420_REG_FSCTRL 0x18 + #define CC2420_FREQ_MASK 0x3FF +#define CC2420_REG_SECCTRL0 0x19 + #define CC2420_RXFIFO_PROTECTION 0x200 +#define CC2420_REG_SECCTRL1 0x1A +#define CC2420_REG_BATTMON 0x1B +#define CC2420_REG_IOCFG0 0x1C + #define CC2420_FIFOPTHR_MASK 0x7F +#define CC2420_REG_IOCFG1 0x1D +#define CC2420_REG_MANFIDL 0x1E +#define CC2420_REG_MANFIDH 0x1F +#define CC2420_REG_FSMTC 0x20 +#define CC2420_REG_MANAND 0x21 +#define CC2420_REG_MANOR 0x22 +#define CC2420_REG_AGCCTRL 0x23 +#define CC2420_REG_AGCTST0 0x24 +#define CC2420_REG_AGCTST1 0x25 +#define CC2420_REG_AGCTST2 0x26 +#define CC2420_REG_FSTST0 0x27 +#define CC2420_REG_FSTST1 0x28 +#define CC2420_REG_FSTST2 0x29 +#define CC2420_REG_FSTST3 0x2A +#define CC2420_REG_RXBPFTST 0x2B +#define CC2420_REG_FSMSTATE 0x2C +#define CC2420_REG_ADCTST 0x2D +#define CC2420_REG_DACTST 0x2E +#define CC2420_REG_TOPTST 0x2F + +#define NOBYTE 0x0 + +/* Settings */ +#define CC2420_DEFAULT_CHANNR 18 +#define CC2420_SYNC_WORD_TX_TIME 900000 +#define CC2420_RX_BUF_SIZE 3 +#define CC2420_WAIT_TIME 500 +#endif diff --git a/drivers/cc2420/include/cc2420_spi.h b/drivers/cc2420/include/cc2420_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..b590b7908c40c77139228bb5222b20bc306c6799 --- /dev/null +++ b/drivers/cc2420/include/cc2420_spi.h @@ -0,0 +1,92 @@ +/** + * cc2420_spi.h - Definition of CC2420 SPI functions. + * Copyright (C) 2013 Milan Babel <babel@inf.fu-berlin.de> + * + * This source code is licensed under the GNU Lesser General Public License, + * Version 2. See the file LICENSE for more details. + */ + + +/** + * @ingroup CC2420 + * @{ + * @file + * @brief Definition of CC2420 SPI functions + * @author Milan Babel <babel@inf.fu-berlin.de> + * + */ +#ifndef CC2420_SPI_H +#define CC2420_SPI_H + +#include <stdio.h> + +/** + * @brief Writes a byte to the cc2420 register. + * + * @param[in] addr The address of the register to write. + * @param[in] value The value to write in the register. + */ +void cc2420_write_reg(uint8_t addr, uint16_t value); + +/** + * @brief Reads a byte from the cc2420 register. + * + * @param[in] addr The address of the register to read. + * + * @return The value in the register. + */ +uint16_t cc2420_read_reg(uint8_t addr); + +/** + * @brief Sends a strobe command to the cc2420. + * + * @param[in] c The strobe command to send. + * + * @return The result of the strobe command. + */ +uint8_t cc2420_strobe(uint8_t c); + + +/** + * @brief Reads multiple bytes from the cc2420 ram. + * + * @param[in] addr The ram address to read. + * @param[out] buffer A buffer to store the value of the ram. + * @param[in] len The count of bytes which should be read. + * + * @return The number of bytes read. + */ +uint16_t cc2420_read_ram(uint16_t addr, uint8_t* buffer, uint16_t len); + +/** + * @brief Writes multiple bytes to the cc2420 ram. + * + * @param[in] addr The ram address to write. + * @param[in] buffer A buffer with the value to write to the ram. + * @param[in] len The count of bytes which should be written. + * + * @return The number of bytes written. + */ +uint16_t cc2420_write_ram(uint16_t addr, uint8_t* buffer, uint16_t len); + +/** + * @brief Writes multiple bytes to the cc2420 fifo. + * + * @param[in] data A buffer with the value to write to the fifo. + * @param[in] data_length The count of bytes which should be written. + * + * @return The number of bytes written. + */ +uint16_t cc2420_write_fifo(uint8_t* data, uint16_t data_length); + +/** + * @brief Reads multiple bytes from the cc2420 fifo. + * + * @param[out] data A buffer to store the value of the fifo. + * @param[in] data_length The count of bytes which should be read. + * + * @return The number of bytes read. + */ +uint16_t cc2420_read_fifo(uint8_t* data, uint16_t data_length); + +#endif diff --git a/sys/Makefile b/sys/Makefile index 1332d17a16cc400154cde62f66f16b9378776515..d4da789e995cdb954b0e3c47f4fddfd44b55ee79 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -7,9 +7,6 @@ endif ifneq (,$(findstring config,$(USEMODULE))) DIRS += config endif -ifneq (,$(findstring net,$(USEMODULE))) - DIRS += net -endif ifneq (,$(findstring lib,$(USEMODULE))) DIRS += lib endif @@ -80,6 +77,9 @@ ifneq (,$(findstring sixlowpan,$(USEMODULE))) DIRS += net/sixlowpan DIRS += net/sixlowpan/rpl endif +ifneq (,$(findstring ieee802154,$(USEMODULE))) + DIRS += net/ieee802154 +endif all: $(BINDIR)$(MODULE).a @for i in $(DIRS) ; do $(MAKE) -C $$i ; done ; @@ -90,5 +90,3 @@ include $(RIOTBASE)/Makefile.base clean:: @for i in $(DIRS) ; do $(MAKE) -C $$i clean ; done ; - - diff --git a/sys/lib/hashtable.c b/sys/lib/hashtable.c index c89c9cecdf9adf89068cfbd7386d2f173b0e9538..7bfcf8bae1ef36d65d0bdbdfdfec2509f78bdc0a 100644 --- a/sys/lib/hashtable.c +++ b/sys/lib/hashtable.c @@ -35,7 +35,7 @@ create_hashtable(uint32_t minsize, unsigned int pindex, size = primes[0]; /* Check requested hashtable isn't too large */ - if (minsize > (1u << 30)) { + if (minsize > (1UL << 30)) { return NULL; } @@ -76,7 +76,7 @@ hash(struct hashtable *h, void *k) { /* Aim to protect against poor hash functions by adding logic here * - logic taken from java 1.4 hashtable source */ - unsigned int i = h->hashfn(k); + uint32_t i = h->hashfn(k); i += ~(i << 9); i ^= ((i >> 14) | (i << 18)); /* >>> */ i += (i << 4); diff --git a/sys/net/ieee802154/Makefile b/sys/net/ieee802154/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7dce69248eb8e2eab2366c49d09161d715d27712 --- /dev/null +++ b/sys/net/ieee802154/Makefile @@ -0,0 +1,4 @@ +MODULE:=$(shell basename $(CURDIR)) +INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/net + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/sixlowpan/ieee802154_frame.c b/sys/net/ieee802154/ieee802154_frame.c similarity index 89% rename from sys/net/sixlowpan/ieee802154_frame.c rename to sys/net/ieee802154/ieee802154_frame.c index 44228b2c3425fae0a817fbc85f2b8995919c35c8..1417734a7e4e81dd12112bd23b376beda7e01e08 100644 --- a/sys/net/sixlowpan/ieee802154_frame.c +++ b/sys/net/ieee802154/ieee802154_frame.c @@ -27,16 +27,17 @@ uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf) { /* Frame Control Field - 802.15.4 - 2006 - 7.2.1.1 */ uint8_t index = 0; + + buf[index] = ((frame->fcf.dest_addr_m << 2) | + (frame->fcf.frame_ver << 4) | + (frame->fcf.src_addr_m << 6)); - buf[index] = ((frame->fcf.frame_type << 5) | - (frame->fcf.sec_enb << 4) | - (frame->fcf.frame_pend << 3) | - (frame->fcf.ack_req << 2) | - (frame->fcf.panid_comp << 1)); index++; - buf[index] = ((frame->fcf.dest_addr_m << 4) | - (frame->fcf.frame_ver << 2) | - (frame->fcf.src_addr_m)); + buf[index] = ((frame->fcf.frame_type) | + (frame->fcf.sec_enb << 3) | + (frame->fcf.frame_pend << 4) | + (frame->fcf.ack_req << 5) | + (frame->fcf.panid_comp << 6)); index++; /* Sequence Number - 802.15.4 - 2006 - 7.2.1.2 */ @@ -145,17 +146,17 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len) uint8_t index = 0; uint8_t hdrlen; - frame->fcf.frame_type = (buf[index] >> 5) & 0x07; - frame->fcf.sec_enb = (buf[index] >> 4) & 0x01; - frame->fcf.frame_pend = (buf[index] >> 3) & 0x01; - frame->fcf.ack_req = (buf[index] >> 2) & 0x01; - frame->fcf.panid_comp = (buf[index] >> 1) & 0x01; + frame->fcf.dest_addr_m = (buf[index] >> 2) & 0x03; + frame->fcf.frame_ver = (buf[index] >> 4) & 0x03; + frame->fcf.src_addr_m = (buf[index] >> 6) & 0x03; index++; - frame->fcf.dest_addr_m = (buf[index] >> 4) & 0x03; - frame->fcf.frame_ver = (buf[index] >> 2) & 0x03; - frame->fcf.src_addr_m = buf[index] & 0x03; + frame->fcf.frame_type = (buf[index]) & 0x07; + frame->fcf.sec_enb = (buf[index] >> 3) & 0x01; + frame->fcf.frame_pend = (buf[index] >> 4) & 0x01; + frame->fcf.ack_req = (buf[index] >> 5) & 0x01; + frame->fcf.panid_comp = (buf[index] >> 6) & 0x01; //print_802154_fcf_frame(frame); diff --git a/sys/net/sixlowpan/ieee802154_frame.h b/sys/net/ieee802154/ieee802154_frame.h similarity index 100% rename from sys/net/sixlowpan/ieee802154_frame.h rename to sys/net/ieee802154/ieee802154_frame.h diff --git a/sys/net/sixlowpan/sixlowborder.c b/sys/net/sixlowpan/sixlowborder.c index 5abc53128013194f2c6bfaa18e0ab901772b8cf9..51d41c5ed1791840a05c992e24847af936106561 100644 --- a/sys/net/sixlowpan/sixlowborder.c +++ b/sys/net/sixlowpan/sixlowborder.c @@ -27,7 +27,7 @@ #include <board_uart0.h> #include "bordermultiplex.h" -#include "ieee802154_frame.h" +#include "ieee802154/ieee802154_frame.h" #include "flowcontrol.h" #include "sixlowborder.h" #include "sixlowip.h" diff --git a/sys/net/sixlowpan/sixlowmac.c b/sys/net/sixlowpan/sixlowmac.c index e8d277c53594d108c9521ef5ad8241d7a278f196..deef901235c1dfa9570f7037548fd91bf5216f9c 100644 --- a/sys/net/sixlowpan/sixlowmac.c +++ b/sys/net/sixlowpan/sixlowmac.c @@ -34,7 +34,7 @@ #include "radio/radio.h" #include "transceiver.h" #include "vtimer.h" -#include "ieee802154_frame.h" +#include "ieee802154/ieee802154_frame.h" #include "net_help/net_help.h" char radio_stack_buffer[RADIO_STACK_SIZE]; diff --git a/sys/net/sixlowpan/sixlowpan.c b/sys/net/sixlowpan/sixlowpan.c index 37bc30456fc3c87e78b756634dfe6b7f2de5feb2..2c93b9e5e59c6cd4710f54c789a3b91b5caadeac 100644 --- a/sys/net/sixlowpan/sixlowpan.c +++ b/sys/net/sixlowpan/sixlowpan.c @@ -37,7 +37,7 @@ #include "sixlowip.h" #include "sixlownd.h" #include "transceiver.h" -#include "ieee802154_frame.h" +#include "ieee802154/ieee802154_frame.h" #include "sys/net/destiny/in.h" #include "sys/net/net_help/net_help.h" diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 8fc4103d227ef4d2391bbc00dfb77f05d8ad5204..8ab148c8d93f158692bc0acada010b931865a5e8 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -5,6 +5,10 @@ ifneq (,$(findstring cc110x_ng,$(USEMODULE))) INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include/ SRC += sc_cc110x_ng.c endif +ifneq (,$(findstring cc2420,$(USEMODULE))) + INCLUDES += -I$(RIOTBASE)/drivers/cc2420/include/ -I$(RIOTBASE)/sys/net/ + SRC += sc_cc2420.c +endif ifneq (,$(findstring cc110x,$(USEMODULE))) INCLUDES += -I$(RIOTBASE)/drivers/cc110x/ SRC += sc_cc1100.c diff --git a/sys/shell/commands/sc_cc110x_ng.c b/sys/shell/commands/sc_cc110x_ng.c index 0f383c52a1fbf6de0a74789c0b2150fb2490570d..83850c90a731220b5260c163b98dba6cd22d85e4 100644 --- a/sys/shell/commands/sc_cc110x_ng.c +++ b/sys/shell/commands/sc_cc110x_ng.c @@ -94,8 +94,8 @@ void _cc110x_ng_send_handler(char *pkt) p.length = strlen(text_msg) + 1; p.dst = addr; mesg.type = SND_PKT; - mesg.content.ptr = (char *) &tcmd; - printf("[cc110x] Sending packet of length %u to %hu: %s\n", p.length, p.dst, (char *) p.data); + mesg.content.ptr = (char *)&tcmd; + printf("[cc110x] Sending packet of length %u to %u: %s\n", p.length, p.dst, (char*) p.data); msg_send_receive(&mesg, &mesg, transceiver_pid); response = mesg.content.value; printf("[cc110x] Packet sent: %" PRIu32 "\n", response); diff --git a/sys/shell/commands/sc_cc2420.c b/sys/shell/commands/sc_cc2420.c new file mode 100644 index 0000000000000000000000000000000000000000..7da2dd717674c1fba154ef3ce371dce5ce6e4932 --- /dev/null +++ b/sys/shell/commands/sc_cc2420.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <transceiver.h> +#include <cc2420.h> +#include <msg.h> + +#define TEXT_SIZE CC2420_MAX_DATA_LENGTH + +char text_msg[TEXT_SIZE]; +msg_t mesg; +transceiver_command_t tcmd; + +void _cc2420_get_set_address_handler(char *addr) { + uint16_t a; + + tcmd.transceivers = TRANSCEIVER_CC2420; + tcmd.data = &a; + mesg.content.ptr = (char*) &tcmd; + a = atoi(addr+5); + if (strlen(addr) > 5) { + printf("[cc2420] Trying to set address %i\n", a); + mesg.type = SET_ADDRESS; + } + else { + mesg.type = GET_ADDRESS; + } + msg_send_receive(&mesg, &mesg, transceiver_pid); + printf("[cc2420] Got address: %i\n", a); +} + +void _cc2420_get_set_channel_handler(char *chan) { + int16_t c; + + tcmd.transceivers = TRANSCEIVER_CC2420; + tcmd.data = &c; + mesg.content.ptr = (char*) &tcmd; + c = atoi(chan+5); + if (strlen(chan) > 5) { + printf("[cc2420] Trying to set channel %i\n", c); + mesg.type = SET_CHANNEL; + } + else { + mesg.type = GET_CHANNEL; + } + msg_send_receive(&mesg, &mesg, transceiver_pid); + printf("[cc2420] Got channel: %i\n", c); +} + +void _cc2420_get_set_pan_handler(char *pan) { + uint16_t p; + + tcmd.transceivers = TRANSCEIVER_CC2420; + tcmd.data = &p; + mesg.content.ptr = (char*) &tcmd; + p = atoi(pan+4); + if (strlen(pan) > 4) { + printf("[cc2420] Trying to set pan %i\n", p); + mesg.type = SET_PAN; + } + else { + mesg.type = GET_PAN; + } + msg_send_receive(&mesg, &mesg, transceiver_pid); + printf("[cc2420] Got pan: %i\n", p); +} + +void _cc2420_send_handler(char *pkt) { + radio_packet_t p; + uint32_t response; + uint16_t addr; + char *tok; + + tcmd.transceivers = TRANSCEIVER_CC2420; + tcmd.data = &p; + + tok = strtok(pkt+7, " "); + if (tok) { + addr = atoi(tok); + tok = strtok(NULL, " "); + if (tok) { + memset(text_msg, 0, TEXT_SIZE); + memcpy(text_msg, tok, strlen(tok)); + /* if (sscanf(pkt, "txtsnd %hu %s", &(addr), text_msg) == 2) {*/ + p.data = (uint8_t*) text_msg; + p.length = strlen(text_msg) + 1; + p.dst = addr; + mesg.type = SND_PKT; + mesg.content.ptr = (char*) &tcmd; + printf("[cc2420] Sending packet of length %u to %u: %s\n", p.length, p.dst, (char*) p.data); + msg_send_receive(&mesg, &mesg, transceiver_pid); + response = mesg.content.value; + printf("[cc2420] Packet sent: %lu\n", response); + return; + } + } + puts("Usage:\ttxtsnd <ADDR> <MSG>"); +} + +void _cc2420_monitor_handler(char *mode) { + unsigned int m; + + tcmd.transceivers = TRANSCEIVER_CC2420; + tcmd.data = &m; + mesg.content.ptr = (char*) &tcmd; + m = atoi(mode+8); + if (strlen(mode) > 8) { + printf("Setting monitor mode: %u\n", m); + mesg.type = SET_MONITOR; + msg_send(&mesg, transceiver_pid, 1); + } + else { + puts("Usage:\nmonitor <MODE>"); + } +} diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index cfa0bcfa4c1b1cffbf53d9549ed7819f3cc1b490..e075bf36d581c27caaddd09603d8e0445b1668e0 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -60,6 +60,16 @@ extern void _cc110x_ng_monitor_handler(char *mode); #endif #endif +#ifdef MODULE_TRANSCEIVER +#ifdef MODULE_CC2420 +extern void _cc2420_get_set_address_handler(char *addr); +extern void _cc2420_get_set_channel_handler(char *chan); +extern void _cc2420_get_set_pan_handler(char *pan); +extern void _cc2420_send_handler(char *pkt); +extern void _cc2420_monitor_handler(char *mode); +#endif +#endif + #ifdef MODULE_MCI extern void _get_sectorsize(char *unused); extern void _get_blocksize(char *unused); @@ -104,6 +114,15 @@ const shell_command_t _shell_command_list[] = { {"monitor", "Enables or disables address checking for the CC1100 transceiver", _cc110x_ng_monitor_handler}, #endif #endif +#ifdef MODULE_TRANSCEIVER +#ifdef MODULE_CC2420 + {"addr", "Gets or sets the address for the CC2420 transceiver", _cc2420_get_set_address_handler}, + {"chan", "Gets or sets the channel for the CC2420 transceiver", _cc2420_get_set_channel_handler}, + {"pan", "Gets or sets the pan id for the CC2420 transceiver", _cc2420_get_set_pan_handler}, + {"txtsnd", "Sends a text message to a given node via the C2420 transceiver", _cc2420_send_handler}, + {"monitor", "Enables or disables address checking for the CC2420 transceiver", _cc2420_monitor_handler}, +#endif +#endif #ifdef MODULE_MCI {DISK_READ_SECTOR_CMD, "Reads the specified sector of inserted memory card", _read_sector}, {DISK_READ_BYTES_CMD, "Reads the specified bytes from inserted memory card", _read_bytes}, diff --git a/sys/transceiver/Makefile b/sys/transceiver/Makefile index 3d01f44b6d9b2ea5621f404d2bfa6ddd175e74c2..f3718a1d15faf2acb0b79ba1d57e1899725dd9df 100644 --- a/sys/transceiver/Makefile +++ b/sys/transceiver/Makefile @@ -1,4 +1,4 @@ -INCLUDES = -I../include -I$(RIOTBAE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I../lib -I$(RIOTCPU)/$(CPU)/include -I../net -I../../core/include +INCLUDES = -I../include -I$(RIOTBAE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I../lib -I$(RIOTCPU)/$(CPU)/include -I../net -I../../core/include -I$(RIOTBASE)/drivers/cc2420/include -I$(RIOTBASE)/sys/net/ieee802154/ MODULE =transceiver include $(MAKEBASE)/Makefile.base diff --git a/sys/transceiver/transceiver.c b/sys/transceiver/transceiver.c index 773da55659be1e497f9358a2134da6da441ff47b..f19e60666098174aa720115ac457cab88c96496c 100644 --- a/sys/transceiver/transceiver.c +++ b/sys/transceiver/transceiver.c @@ -43,6 +43,14 @@ #endif #endif +#ifdef MODULE_CC2420 +#include <cc2420.h> +#if (CC2420_MAX_DATA_LENGTH > PAYLOAD_SIZE) + #undef PAYLOAD_SIZE + #define PAYLOAD_SIZE (CC2420_MAX_DATA_LENGTH) +#endif +#endif + //#define ENABLE_DEBUG (1) #include <debug.h> @@ -87,12 +95,17 @@ static void receive_cc110x_packet(radio_packet_t *trans_p); #elif MODULE_CC110X void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol, packet_info_t *packet_info); void receive_cc1100_packet(radio_packet_t *trans_p); +#elif MODULE_CC2420 +static void receive_cc2420_packet(radio_packet_t *trans_p); #endif static uint8_t send_packet(transceiver_type_t t, void *pkt); static int16_t get_channel(transceiver_type_t t); static int16_t set_channel(transceiver_type_t t, void *channel); static int16_t get_address(transceiver_type_t t); static int16_t set_address(transceiver_type_t t, void *address); +static uint16_t get_pan(transceiver_type_t t); +static uint16_t set_pan(transceiver_type_t t, void *pan); + static void set_monitor(transceiver_type_t t, void *mode); static void powerdown(transceiver_type_t t); static void switch_to_rx(transceiver_type_t t); @@ -120,8 +133,7 @@ void transceiver_init(transceiver_type_t t) reg[i].transceivers = TRANSCEIVER_NONE; reg[i].pid = 0; } - - if (t & TRANSCEIVER_CC1100) { + if (t & (TRANSCEIVER_CC1100 || TRANSCEIVER_CC2420)) { transceivers |= t; } else { @@ -137,16 +149,23 @@ int transceiver_start(void) if (transceiver_pid < 0) { puts("Error creating transceiver thread"); } +#ifdef MODULE_CC110X_NG else if (transceivers & TRANSCEIVER_CC1100) { DEBUG("Transceiver started for CC1100\n"); -#ifdef MODULE_CC110X_NG cc110x_init(transceiver_pid); -#else + } +#elif MODULE_CC110X + else if (transceivers & TRANSCEIVER_CC1100) { + DEBUG("Transceiver started for CC1100\n"); cc1100_init(); cc1100_set_packet_monitor(cc1100_packet_monitor); -#endif } - +#elif MODULE_CC2420 + else if(transceivers & TRANSCEIVER_CC2420) { + DEBUG("Transceiver started for CC2420\n"); + cc2420_init(transceiver_pid); + } +#endif return transceiver_pid; } @@ -197,7 +216,9 @@ void run(void) case RCV_PKT_CC1100: receive_packet(m.type, m.content.value); break; - + case RCV_PKT_CC2420: + receive_packet(m.type, m.content.value); + break; case SND_PKT: response = send_packet(cmd->transceivers, cmd->data); m.content.value = response; @@ -235,6 +256,14 @@ void run(void) case SWITCH_RX: switch_to_rx(cmd->transceivers); break; + case GET_PAN: + *((int16_t*) cmd->data) = get_pan(cmd->transceivers); + msg_reply(&m, &m); + break; + case SET_PAN: + *((int16_t*) cmd->data) = set_pan(cmd->transceivers, cmd->data); + msg_reply(&m, &m); + break; #ifdef DBG_IGNORE case DBG_IGN: @@ -285,7 +314,9 @@ static void receive_packet(uint16_t type, uint8_t pos) case RCV_PKT_CC1100: t = TRANSCEIVER_CC1100; break; - + case RCV_PKT_CC2420: + t = TRANSCEIVER_CC2420; + break; default: t = TRANSCEIVER_NONE; break; @@ -311,9 +342,14 @@ static void receive_packet(uint16_t type, uint8_t pos) if (type == RCV_PKT_CC1100) { #ifdef MODULE_CC110X_NG - receive_cc110x_packet(trans_p); -#else + receive_cc110x_packet(trans_p); +#elif MODULE_CC110X receive_cc1100_packet(trans_p); +#endif + } + else if (type == RCV_PKT_CC2420) { +#ifdef MODULE_CC2420 + receive_cc2420_packet(trans_p); #endif } else { @@ -383,6 +419,25 @@ void receive_cc1100_packet(radio_packet_t *trans_p) #endif +#ifdef MODULE_CC2420 +void receive_cc2420_packet(radio_packet_t *trans_p) { + DEBUG("Handling CC2420 packet\n"); + dINT(); + cc2420_packet_t p = cc2420_rx_buffer[rx_buffer_pos]; + trans_p->src = (uint16_t)((p.frame.src_addr[1] << 8) | p.frame.src_addr[0]); + trans_p->dst = (uint16_t)((p.frame.dest_addr[1] << 8)| p.frame.dest_addr[0]); + trans_p->rssi = p.rssi; + trans_p->lqi = p.lqi; + trans_p->length = p.frame.payload_len; + memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.frame.payload, CC2420_MAX_DATA_LENGTH); + eINT(); + + DEBUG("Packet %p was from %u to %u, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length); + trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC2420_MAX_DATA_LENGTH]); + DEBUG("Content: %s\n", trans_p->data); +} +#endif + /*------------------------------------------------------------------------------------*/ /* * @brief Sends a radio packet to the receiver @@ -404,7 +459,11 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) cc110x_packet_t cc110x_pkt; #endif - switch(t) { +#ifdef MODULE_CC2420 + cc2420_packet_t cc2420_pkt; +#endif + + switch (t) { case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG cc110x_pkt.length = p.length + CC1100_HEADER_LENGTH; @@ -412,7 +471,7 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) cc110x_pkt.flags = 0; memcpy(cc110x_pkt.data, p.data, p.length); res = cc110x_send(&cc110x_pkt); -#else +#elif MODULE_CC110X memcpy(cc1100_pkt, p.data, p.length); if ((snd_ret = cc1100_send_csmaca(p.dst, 4, 0, (char *) cc1100_pkt, p.length)) < 0) { @@ -425,7 +484,22 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) #endif break; - +#ifdef MODULE_CC2420 + case TRANSCEIVER_CC2420: + cc2420_pkt.frame.payload_len = p.length; + cc2420_pkt.frame.dest_addr[1] = (uint8_t)(p.dst >> 8); + cc2420_pkt.frame.dest_addr[0] = (uint8_t)(p.dst & 0xFF); + cc2420_pkt.frame.dest_pan_id = cc2420_get_pan(); + cc2420_pkt.frame.fcf.dest_addr_m = 2; + cc2420_pkt.frame.fcf.src_addr_m = 2; + cc2420_pkt.frame.fcf.ack_req = 0; + cc2420_pkt.frame.fcf.sec_enb = 0; + cc2420_pkt.frame.fcf.frame_type = 1; + cc2420_pkt.frame.fcf.frame_pend = 0; + cc2420_pkt.frame.payload = p.data; + res = cc2420_send(&cc2420_pkt); + break; +#endif default: puts("Unknown transceiver"); break; @@ -451,10 +525,13 @@ static int16_t set_channel(transceiver_type_t t, void *channel) case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_set_channel(c); -#else +#elif MODULE_CC110X return cc1100_set_channel(c); #endif - + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + return cc2420_set_channel(c); +#endif default: return -1; } @@ -473,10 +550,54 @@ static int16_t get_channel(transceiver_type_t t) case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_get_channel(); -#else +#elif MODULE_CC110X return cc1100_get_channel(); #endif + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + return cc2420_get_channel(); +#endif + default: + return -1; + } +} + +/*------------------------------------------------------------------------------------*/ +/* + * @brief Sets the pan for the CC2420 transceiver device + * + * @param t The transceiver device + * @param channel The channel to be set + * + * @return The pan AFTER calling the set command, -1 on error + */ +static uint16_t set_pan(transceiver_type_t t, void *pan) { + uint16_t c = *((uint16_t*) pan); + switch (t) { + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + return cc2420_set_pan(c); +#endif + default: + /* get rid of compiler warning about unused variable */ + (void) c; + return -1; + } +} +/* + * @brief Get the pan for the cc2420 transceiver device + * + * @param t The transceiver device + * + * @return The current pan of the transceiver, -1 on error + */ +static uint16_t get_pan(transceiver_type_t t) { + switch (t) { + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + return cc2420_get_pan(); +#endif default: return -1; } @@ -495,10 +616,13 @@ static int16_t get_address(transceiver_type_t t) case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_get_address(); -#else +#elif MODULE_CC110X return cc1100_get_address(); #endif - + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + return cc2420_get_address(); +#endif default: return -1; } @@ -520,10 +644,13 @@ static int16_t set_address(transceiver_type_t t, void *address) case TRANSCEIVER_CC1100: #ifdef MODULE_CC110X_NG return cc110x_set_address(addr); -#else +#elif MODULE_CC110X return cc1100_set_address(addr); #endif - + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + return cc2420_set_address(addr); +#endif default: return -1; } @@ -543,7 +670,11 @@ static void set_monitor(transceiver_type_t t, void *mode) cc110x_set_monitor(*((uint8_t *)mode)); #endif break; - + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + cc2420_set_monitor(*((uint8_t*) mode)); +#endif + break; default: break; } @@ -572,7 +703,11 @@ static void switch_to_rx(transceiver_type_t t) cc110x_switch_to_rx(); #endif break; - + case TRANSCEIVER_CC2420: +#ifdef MODULE_CC2420 + cc2420_switch_to_rx(); +#endif + break; default: break; } diff --git a/sys/vtimer/vtimer.c b/sys/vtimer/vtimer.c index a453db816741154b4b0e7fba83f712f8d4fbcdcd..cd22840adcfe1f19e5a51fc90d5867f66047df08 100644 --- a/sys/vtimer/vtimer.c +++ b/sys/vtimer/vtimer.c @@ -16,11 +16,11 @@ #include <debug.h> -#define VTIMER_THRESHOLD 20U -#define VTIMER_BACKOFF 10U +#define VTIMER_THRESHOLD 20UL +#define VTIMER_BACKOFF 10UL #define SECONDS_PER_TICK (4096U) -#define MICROSECONDS_PER_TICK (4096U * 1000000) +#define MICROSECONDS_PER_TICK (4096UL * 1000000) void vtimer_callback(void *ptr); void vtimer_tick(void *ptr); @@ -64,16 +64,16 @@ static int update_shortterm(void) hwtimer_next_absolute = shortterm_queue_root.next->priority; - unsigned int next = hwtimer_next_absolute + longterm_tick_start; - unsigned int now = hwtimer_now(); + uint32_t next = hwtimer_next_absolute + longterm_tick_start; + uint32_t now = HWTIMER_TICKS_TO_US(hwtimer_now()); - if ((next - VTIMER_THRESHOLD - now) > MICROSECONDS_PER_TICK) { - next = now + VTIMER_BACKOFF; + if((next - HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now) > MICROSECONDS_PER_TICK ) { + next = now + HWTIMER_TICKS_TO_US(VTIMER_BACKOFF); } + + hwtimer_id = hwtimer_set_absolute(HWTIMER_TICKS(next), vtimer_callback, NULL); - hwtimer_id = hwtimer_set_absolute(next, vtimer_callback, NULL); - - DEBUG("update_shortterm: Set hwtimer to %lu (now=%lu)\n", hwtimer_next_absolute + longterm_tick_start, hwtimer_now()); + DEBUG("update_shortterm: Set hwtimer to %lu (now=%lu)\n", next, HWTIMER_TICKS_TO_US(hwtimer_now())); return 0; } @@ -169,6 +169,7 @@ static int vtimer_set(vtimer_t *timer) normalize_to_tick(&(timer->absolute)); DEBUG("vtimer_set(): Absolute: %lu %lu\n", timer->absolute.seconds, timer->absolute.microseconds); + DEBUG("vtimer_set(): NOW: %lu %lu\n", now.seconds, now.microseconds); int result = 0; @@ -217,6 +218,8 @@ int vtimer_init() int state = disableIRQ(); seconds = 0; + longterm_tick_start = 0; + longterm_tick_timer.action = vtimer_tick; longterm_tick_timer.arg = NULL;