1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

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
This commit is contained in:
Oliver Hahm 2013-06-25 15:33:40 +02:00
commit 57cc002c67
32 changed files with 1441 additions and 89 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 {
} else {
short timer = (taiv / 2);
TA0_unset(timer);
int_handler(timer);
short timer = (taiv/2);
if(overflow_interrupt[timer] == timer_round)
{
TA0_unset(timer);
int_handler(timer);
}
}
__exit_isr();
}

View File

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

View File

@ -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 Normal file
View File

@ -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 Normal file
View File

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

View File

@ -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 Normal file
View File

@ -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 Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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"

View File

@ -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];

View File

@ -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"

View File

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

View File

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

View File

@ -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>");
}
}

View File

@ -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},

View File

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

View File

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

View File

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