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

added driver for cc2420

also added cc2420 to transceiver and added cc2420 shell commands
This commit is contained in:
Milan Babel 2013-05-02 08:45:47 +02:00
parent 2f5ed66756
commit db1fc96ffe
17 changed files with 1367 additions and 30 deletions

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

13
drivers/cc2420/Makefile Normal file
View File

@ -0,0 +1,13 @@
INCLUDES = -I$(RIOTBASE)/sys/include -I../../net -I../include -I../../lib -I../../../.. -I../../../cpu/ -I$(RIOTBASE)/core/include -I../../ -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_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

@ -10,8 +10,11 @@
#define TRANSCEIVER_STACK_SIZE (512)
#endif
#ifdef MODULE_CC2420
#define PAYLOAD_SIZE (118)
#else
#define PAYLOAD_SIZE (58)
#endif
/* The maximum of threads to register */
#define TRANSCEIVER_MAX_REGISTERED (4)
@ -26,6 +29,7 @@ enum transceiver_msg_type_t {
/* Message types for driver <-> transceiver communication */
RCV_PKT_CC1020, ///< packet was received by CC1020 transceiver
RCV_PKT_CC1100, ///< packet was received by CC1100 transceiver
RCV_PKT_CC2420, ///< packet was received by CC2420 transceiver
/* Message types for transceiver <-> upper layer communication */
PKT_PENDING, ///< packet pending in transceiver buffer
@ -38,6 +42,8 @@ enum transceiver_msg_type_t {
GET_ADDRESS, ///< Get the radio address
SET_ADDRESS, ///< Set the radio address
SET_MONITOR, ///< Set transceiver to monitor mode (disable address checking)
GET_PAN, ///< Get current pan
SET_PAN, ///< Set a new pan
/* debug message types */
DBG_IGN, ///< add a physical address to the ignore list
@ -52,7 +58,8 @@ enum transceiver_msg_type_t {
typedef enum {
TRANSCEIVER_NONE, ///< Invalid
TRANSCEIVER_CC1100, ///< CC110X transceivers
TRANSCEIVER_CC1020 ///< CC1020 transceivers
TRANSCEIVER_CC1020, ///< CC1020 transceivers
TRANSCEIVER_CC2420 ///< CC2420 transceivers
} transceiver_type_t;
/**

View File

@ -10,15 +10,16 @@ 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.frame_type << 5) |
(frame->fcf.sec_enb << 4) |
(frame->fcf.frame_pend << 3) |
(frame->fcf.ack_req << 2) |
(frame->fcf.panid_comp << 1));
buf[index] = ((frame->fcf.dest_addr_m << 2) |
(frame->fcf.frame_ver << 4) |
(frame->fcf.src_addr_m << 6));
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 */
@ -118,17 +119,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

@ -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/ieee802154/
SRC += sc_cc2420.c
endif
ifneq (,$(findstring cc110x,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/drivers/cc110x/
SRC += sc_cc1100.c

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

@ -43,6 +43,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);
@ -87,6 +97,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

@ -25,6 +25,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>
@ -69,12 +77,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);
@ -96,7 +109,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 {
@ -110,15 +123,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;
}
@ -164,6 +185,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;
@ -194,6 +218,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:
printf("Transceiver PID: %i (%p), rx_buffer_next: %u\n", transceiver_pid, &transceiver_pid, rx_buffer_next);
@ -238,6 +270,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;
@ -263,8 +298,13 @@ 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
#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 {
@ -328,7 +368,26 @@ 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
@ -349,6 +408,10 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) {
cc110x_packet_t cc110x_pkt;
#endif
#ifdef MODULE_CC2420
cc2420_packet_t cc2420_pkt;
#endif
switch (t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
@ -357,7 +420,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) {
DEBUG("snd_ret (%u) = %i\n", p.length, snd_ret);
@ -368,6 +431,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;
@ -390,8 +469,12 @@ 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;
@ -410,8 +493,51 @@ 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:
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;
@ -430,8 +556,12 @@ 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;
@ -452,8 +582,12 @@ 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;
@ -471,6 +605,11 @@ static void set_monitor(transceiver_type_t t, void *mode) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
cc110x_set_monitor(*((uint8_t*) mode));
#endif
break;
case TRANSCEIVER_CC2420:
#ifdef MODULE_CC2420
cc2420_set_monitor(*((uint8_t*) mode));
#endif
break;
default:
@ -496,6 +635,11 @@ static void switch_to_rx(transceiver_type_t t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
cc110x_switch_to_rx();
#endif
break;
case TRANSCEIVER_CC2420:
#ifdef MODULE_CC2420
cc2420_switch_to_rx();
#endif
break;
default: