Browse Source

Merge branch 'wsn430'

Conflicts:
	core/include/queue.h
	core/queue.c
	cpu/msp430-common/hwtimer_cpu.c
	cpu/msp430x16x/hwtimer_msp430.c
	sys/lib/hashtable.c
	sys/net/ieee802154/ieee802154_frame.c
	sys/shell/commands/sc_cc110x_ng.c
	sys/transceiver/transceiver.c
	sys/vtimer/vtimer.c
dev/timer
Oliver Hahm 10 years ago
parent
commit
57cc002c67
  1. 13
      Makefile.dep
  2. 5
      core/include/queue.h
  3. 5
      core/queue.c
  4. 7
      cpu/msp430-common/hwtimer_cpu.c
  5. 2
      cpu/msp430-common/include/hwtimer_cpu.h
  6. 43
      cpu/msp430x16x/hwtimer_msp430.c
  7. 3
      drivers/Makefile
  8. 9
      drivers/cc110x_ng/Makefile
  9. 13
      drivers/cc2420/Makefile
  10. 179
      drivers/cc2420/cc2420.c
  11. 73
      drivers/cc2420/cc2420_rx.c
  12. 104
      drivers/cc2420/cc2420_spi.c
  13. 112
      drivers/cc2420/cc2420_tx.c
  14. 241
      drivers/cc2420/include/cc2420.h
  15. 123
      drivers/cc2420/include/cc2420_arch.h
  16. 107
      drivers/cc2420/include/cc2420_settings.h
  17. 92
      drivers/cc2420/include/cc2420_spi.h
  18. 8
      sys/Makefile
  19. 4
      sys/lib/hashtable.c
  20. 4
      sys/net/ieee802154/Makefile
  21. 33
      sys/net/ieee802154/ieee802154_frame.c
  22. 0
      sys/net/ieee802154/ieee802154_frame.h
  23. 2
      sys/net/sixlowpan/sixlowborder.c
  24. 2
      sys/net/sixlowpan/sixlowmac.c
  25. 2
      sys/net/sixlowpan/sixlowpan.c
  26. 4
      sys/shell/commands/Makefile
  27. 4
      sys/shell/commands/sc_cc110x_ng.c
  28. 115
      sys/shell/commands/sc_cc2420.c
  29. 19
      sys/shell/commands/shell_commands.c
  30. 2
      sys/transceiver/Makefile
  31. 179
      sys/transceiver/transceiver.c
  32. 23
      sys/vtimer/vtimer.c

13
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

5
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);

5
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);
}
/*

7
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)

2
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

43
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();
}

3
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

9
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

13
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 ;

179
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;
}

73
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;
}
}

104
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;
}

112
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);
}

241
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

123
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);

107
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

92
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

8
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 ;

4
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);

4
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

33
sys/net/sixlowpan/ieee802154_frame.c → 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;