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

started adding at86rf231 driver

at86rf231 TX and RX

driver is using vtimer instead of hwtimer_ functions, TO CHECK

vtimer debug function prototype fix
This commit is contained in:
Alaeddine WESLATI 2013-07-12 12:31:16 +02:00
parent a02e00b68b
commit 11bb09b7f8
15 changed files with 855 additions and 8 deletions

View File

@ -35,6 +35,13 @@ ifneq (,$(findstring cc2420,$(USEMODULE)))
endif
endif
ifneq (,$(findstring at86rf231,$(USEMODULE)))
ifeq (,$(findstring transceiver,$(USEMODULE)))
USEMODULE += transceiver
USEMODULE += ieee802154
endif
endif
ifneq (,$(findstring sixlowpan,$(USEMODULE)))
ifeq (,$(findstring ieee802154,$(USEMODULE)))
USEMODULE += ieee802154

View File

@ -92,3 +92,6 @@ term:
doc:
make -BC $(RIOTBASE) doc
debug:
$(DEBUGGER) $(DEBUGGER_FLAGS)

View File

@ -20,6 +20,9 @@ ifneq (,$(findstring cc110x,$(USEMODULE)))
DIRS += cc110x
endif
endif
ifneq (,$(findstring at86rf231,$(USEMODULE)))
DIRS += at86rf231
endif
ifneq (,$(findstring gps_ublox,$(USEMODULE)))
DIRS += gps_ublox
endif

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 =at86rf231
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 ;

View File

@ -0,0 +1,160 @@
/**
* at86rf231.c - Implementation of at86rf231 functions.
* Copyright (C) 2013 Alaeddine Weslati <alaeddine.weslati@inria.fr>
*
* This source code is licensed under the GNU Lesser General Public License,
* Version 2. See the file LICENSE for more details.
*/
#include <at86rf231.h>
//#define ENABLE_DEBUG
#include <debug.h>
static uint16_t radio_pan;
static uint8_t radio_channel;
static uint16_t radio_address;
static uint64_t radio_address_long;
int transceiver_pid;
void at86rf231_init(int tpid)
{
transceiver_pid = tpid;
at86rf231_gpio_spi_interrupts_init();
at86rf231_reset();
// TODO : Enable addr decode, auto ack, auto crc
// and configure security, power, channel, pan
at86rf231_switch_to_rx();
}
void at86rf231_switch_to_rx(void)
{
at86rf231_disable_interrupts();
// Send a FORCE TRX OFF command
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__FORCE_TRX_OFF);
// Reset IRQ to TRX END only
at86rf231_reg_write(AT86RF231_REG__IRQ_MASK, AT86RF231_IRQ_STATUS_MASK__TRX_END);
// Read IRQ to clear it
at86rf231_reg_read(AT86RF231_REG__IRQ_STATUS);
// Enable IRQ interrupt
at86rf231_enable_interrupts();
// Start RX
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__RX_ON);
// wait until it is on RX_ON state
uint8_t status;
uint8_t max_wait = 100; // TODO : move elsewhere, this is in 10us
do
{
status = at86rf231_get_status();
vtimer_usleep(10);
if (!--max_wait)
{
printf("at86rf231 : ERROR : could not enter RX_ON mode");
break;
}
}
while ((status & AT86RF231_TRX_STATUS_MASK__TRX_STATUS) != AT86RF231_TRX_STATUS__RX_ON);
}
void at86rf231_rx_irq(void)
{
at86rf231_rx_handler();
}
uint16_t at86rf231_set_address(uint16_t address)
{
radio_address = address;
at86rf231_reg_write(AT86RF231_REG__SHORT_ADDR_0, (uint8_t)(0x0F & radio_address));
at86rf231_reg_write(AT86RF231_REG__SHORT_ADDR_1, (uint8_t)(radio_address >> 8));
return radio_address;
}
uint16_t at86rf231_get_address(void)
{
return radio_address;
}
uint64_t at86rf231_set_address_long(uint64_t address)
{
radio_address_long = address;
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_0, (uint8_t)(0x0F & radio_address));
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_1, (uint8_t)(radio_address >> 8));
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_2, (uint8_t)(radio_address >> 16));
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_3, (uint8_t)(radio_address >> 24));
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_4, (uint8_t)(radio_address >> 32));
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_5, (uint8_t)(radio_address >> 40));
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_6, (uint8_t)(radio_address >> 48));
at86rf231_reg_write(AT86RF231_REG__IEEE_ADDR_7, (uint8_t)(radio_address >> 56));
return radio_address_long;
}
uint64_t at86rf231_get_address_long(void)
{
return radio_address_long;
}
uint16_t at86rf231_set_pan(uint16_t pan)
{
radio_pan = pan;
at86rf231_reg_write(AT86RF231_REG__PAN_ID_0, (uint8_t)(0x0F & radio_pan));
at86rf231_reg_write(AT86RF231_REG__PAN_ID_1, (uint8_t)(radio_pan >> 8));
return radio_pan;
}
uint16_t at86rf231_get_pan(void)
{
return radio_pan;
}
uint8_t at86rf231_set_channel(uint8_t channel)
{
radio_channel = channel;
if (channel < RF86RF231_MIN_CHANNEL ||
channel > RF86RF231_MAX_CHANNEL) {
radio_channel = RF86RF231_MAX_CHANNEL;
}
at86rf231_reg_write(AT86RF231_REG__PHY_CC_CCA, AT86RF231_PHY_CC_CCA_DEFAULT__CCA_MODE | radio_channel);
return radio_channel;
}
uint8_t at86rf231_get_channel(void)
{
return radio_channel;
//return at86rf231_reg_read(AT86RF231_REG__PHY_CC_CCA) & 0x0F;
}
void at86rf231_set_monitor(uint8_t mode)
{
// TODO
}
void at86rf231_swap_fcf_bytes(uint8_t *buf)
{
uint8_t tmp;
tmp = buf[1];
buf[1] = buf[2];
buf[2] = tmp;
}

View File

@ -0,0 +1,74 @@
#include <at86rf231.h>
#include <at86rf231_arch.h>
#include <transceiver.h>
#include <msg.h>
//#define ENABLE_DEBUG
#include <debug.h>
at86rf231_packet_t at86rf231_rx_buffer[AT86RF231_RX_BUF_SIZE];
uint8_t buffer[AT86RF231_RX_BUF_SIZE][AT86RF231_MAX_PKT_LENGTH];
volatile uint8_t rx_buffer_next;
void at86rf231_rx_handler(void)
{
uint8_t lqi, fcs_rssi;
// read packet length
at86rf231_read_fifo(&at86rf231_rx_buffer[rx_buffer_next].length, 1);
// read psdu, read packet with length as first byte and lqi as last byte.
uint8_t *buf = buffer[rx_buffer_next];
at86rf231_read_fifo(buf, at86rf231_rx_buffer[rx_buffer_next].length);
at86rf231_swap_fcf_bytes(buf);
// read lqi which is appended after the psdu
lqi = buf[at86rf231_rx_buffer[rx_buffer_next].length-1];
// read fcs and rssi, from a register
fcs_rssi = at86rf231_reg_read(AT86RF231_REG__PHY_RSSI);
// build package
at86rf231_rx_buffer[rx_buffer_next].lqi = lqi;
// RSSI has no meaning here, it should be read during packet reception.
at86rf231_rx_buffer[rx_buffer_next].rssi = fcs_rssi & 0x0F; // bit[4:0]
// bit7, boolean, 1 FCS valid, 0 FCS not valid
at86rf231_rx_buffer[rx_buffer_next].crc = (fcs_rssi >> 7) & 0x01;
if(at86rf231_rx_buffer[rx_buffer_next].crc == 0) {
DEBUG("Got packet with invalid crc.\n");
return;
}
read_802154_frame(&buf[1], &at86rf231_rx_buffer[rx_buffer_next].frame,
at86rf231_rx_buffer[rx_buffer_next].length-2);
if(at86rf231_rx_buffer[rx_buffer_next].frame.fcf.frame_type != 2) {
#ifdef ENABLE_DEBUG
print_802154_fcf_frame(&at86rf231_rx_buffer[rx_buffer_next].frame);
#endif
/* notify transceiver thread if any */
if (transceiver_pid) {
msg_t m;
m.type = (uint16_t) RCV_PKT_AT86RF231;
m.content.value = rx_buffer_next;
msg_send_int(&m, transceiver_pid);
}
} else {
#ifdef ENABLE_DEBUG
DEBUG("GOT ACK for SEQ %u\n", at86rf231_rx_buffer[rx_buffer_next].frame.seq_nr);
print_802154_fcf_frame(&at86rf231_rx_buffer[rx_buffer_next].frame);
#endif
}
// shift to next buffer element
if (++rx_buffer_next == AT86RF231_RX_BUF_SIZE) {
rx_buffer_next = 0;
}
// Read IRQ to clear it
at86rf231_reg_read(AT86RF231_REG__IRQ_STATUS);
}

View File

@ -0,0 +1,66 @@
#include <at86rf231_spi.h>
#include <at86rf231_arch.h>
#include <at86rf231_settings.h>
void at86rf231_reg_write(uint8_t addr, uint8_t value)
{
// Start the SPI transfer
at86rf231_spi_select();
// Send first byte being the command and address
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_REG | AT86RF231_ACCESS_WRITE | addr);
// Send value
at86rf231_spi_transfer_byte(value);
// End the SPI transfer
at86rf231_spi_unselect();
}
uint8_t at86rf231_reg_read(uint8_t addr)
{
uint8_t value;
// Start the SPI transfer
at86rf231_spi_select();
// Send first byte being the command and address
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_REG | AT86RF231_ACCESS_READ | addr);
// Send value
value = at86rf231_spi_transfer_byte(0);
// End the SPI transfer
at86rf231_spi_unselect();
return value;
}
void at86rf231_read_fifo(uint8_t* data, uint8_t length)
{
// Start the SPI transfer
at86rf231_spi_select();
// Send Frame Buffer Write access
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_FRAMEBUFFER | AT86RF231_ACCESS_READ);
at86rf231_spi_transfer(0, data, length);
// End the SPI transfer
at86rf231_spi_unselect();
}
void at86rf231_write_fifo(const uint8_t* data, uint8_t length)
{
// Start the SPI transfer
at86rf231_spi_select();
// Send Frame Buffer Write access
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_FRAMEBUFFER | AT86RF231_ACCESS_WRITE);
at86rf231_spi_transfer(data, 0, length);
// End the SPI transfer
at86rf231_spi_unselect();
}

View File

@ -0,0 +1,106 @@
#include <at86rf231.h>
#include <at86rf231_arch.h>
static void at86rf231_xmit(uint8_t *data, uint8_t length);
static void at86rf231_gen_pkt(uint8_t *buf, at86rf231_packet_t *packet);
static uint8_t sequenz_nr;
int16_t at86rf231_send(at86rf231_packet_t *packet)
{
// 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)(at86rf231_get_address() >> 8);
packet->frame.src_addr[0] = (uint8_t)(at86rf231_get_address() & 0xFF);
} else if (packet->frame.fcf.src_addr_m == 3) {
packet->frame.src_addr[7] = (uint8_t)(at86rf231_get_address_long() >> 56);
packet->frame.src_addr[6] = (uint8_t)(at86rf231_get_address_long() >> 48);
packet->frame.src_addr[5] = (uint8_t)(at86rf231_get_address_long() >> 40);
packet->frame.src_addr[4] = (uint8_t)(at86rf231_get_address_long() >> 32);
packet->frame.src_addr[3] = (uint8_t)(at86rf231_get_address_long() >> 24);
packet->frame.src_addr[2] = (uint8_t)(at86rf231_get_address_long() >> 16);
packet->frame.src_addr[1] = (uint8_t)(at86rf231_get_address_long() >> 8);
packet->frame.src_addr[0] = (uint8_t)(at86rf231_get_address_long() & 0xFF);
}
packet->frame.src_pan_id = at86rf231_get_pan();
packet->frame.seq_nr = sequenz_nr;
sequenz_nr += 1;
// calculate size of the frame (payload + FCS) */
packet->length = get_802154_hdr_len(&packet->frame) + packet->frame.payload_len + 2;
if(packet->length > AT86RF231_MAX_PKT_LENGTH) {
return -1;
}
// FCS is added in hardware
uint8_t pkt[packet->length-2];
/* generate pkt */
at86rf231_gen_pkt(pkt, packet);
// transmit packet
at86rf231_xmit(pkt, packet->length-2);
}
static void at86rf231_xmit(uint8_t *data, uint8_t length)
{
// Go to state PLL_ON
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__PLL_ON);
// wait until it is on PLL_ON state
uint8_t status;
uint8_t max_wait = 100; // TODO : move elsewhere, this is in 10us
do
{
status = at86rf231_get_status();
vtimer_usleep(10);
if (!--max_wait)
{
printf("at86rf231 : ERROR : could not enter PLL_ON mode");
break;
}
}
while ((status & AT86RF231_TRX_STATUS_MASK__TRX_STATUS) != AT86RF231_TRX_STATUS__PLL_ON);
// copy the packet to the radio FIFO
at86rf231_write_fifo(data, length);
// Start TX
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__TX_START);
}
/**
* @brief Static function to generate byte array from at86rf231 packet.
*
*/
static void at86rf231_gen_pkt(uint8_t *buf, at86rf231_packet_t *packet)
{
uint8_t index, offset;
index = init_802154_frame(&packet->frame, &buf[1]);
// add length for at86rf231
buf[0] = packet->length;
index++;
offset = index;
while(index < packet->length-2) {
buf[index] = packet->frame.payload[index-offset];
index += 1;
}
at86rf231_swap_fcf_bytes(buf);
}

View File

@ -0,0 +1,64 @@
#ifndef AT86RF231_H_
#define AT86RF231_H_
#include <stdio.h>
#include <stdint.h>
#include <ieee802154/ieee802154_frame.h>
#include <at86rf231_settings.h>
#define AT86RF231_MAX_PKT_LENGTH 127
#define AT86RF231_MAX_DATA_LENGTH 118
/**
* Structure to represent a at86rf231 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 */
/* @} */
} at86rf231_packet_t;
void at86rf231_init(int tpid);
//void at86rf231_reset(void);
void at86rf231_rx(void);
void at86rf231_rx_handler(void);
int16_t at86rf231_send(at86rf231_packet_t *packet);
uint8_t at86rf231_set_channel(uint8_t channel);
uint8_t at86rf231_get_channel(void);
uint16_t at86rf231_set_pan(uint16_t pan);
uint16_t at86rf231_get_pan(void);
uint16_t at86rf231_set_address(uint16_t address);
uint16_t at86rf231_get_address(void);
uint64_t at86rf231_get_address_long(void);
uint64_t at86rf231_set_address_long(uint64_t address);
void at86rf231_set_monitor(uint8_t mode);
void at86rf231_swap_fcf_bytes(uint8_t *buf);
enum
{
RF86RF231_MAX_TX_LENGTH = 125,
RF86RF231_MAX_RX_LENGTH = 127,
RF86RF231_MIN_CHANNEL = 11,
RF86RF231_MAX_CHANNEL = 26
};
extern at86rf231_packet_t at86rf231_rx_buffer[AT86RF231_RX_BUF_SIZE];
#endif

View File

@ -0,0 +1,21 @@
#ifndef AT86RF231_ARCH_H_
#define AT86RF231_ARCH_H_
#include <stdint.h>
void at86rf231_gpio_spi_interrupts_init(void);
void at86rf231_reset(void);
uint8_t at86rf231_get_status(void);
void at86rf231_switch_to_rx(void);
void at86rf231_spi_select(void);
void at86rf231_spi_unselect(void);
uint8_t at86rf231_spi_transfer_byte(uint8_t byte);
void at86rf231_init_interrupts(void);
void at86rf231_enable_interrupts(void);
void at86rf231_disable_interrupts(void);
#endif

View File

@ -0,0 +1,221 @@
#ifndef AT86AT86RF231_SETTINGS_H
#define AT86AT86RF231_SETTINGS_H
#define AT86RF231_RX_BUF_SIZE 3
enum at86rf231_access
{
AT86RF231_ACCESS_REG = 0x80,
AT86RF231_ACCESS_FRAMEBUFFER = 0x20,
AT86RF231_ACCESS_SRAM = 0x00,
AT86RF231_ACCESS_READ = 0x00,
AT86RF231_ACCESS_WRITE = 0x40,
};
enum at86rf231_register
{
AT86RF231_REG__TRX_STATUS = 0x01,
AT86RF231_REG__TRX_STATE = 0x02,
AT86RF231_REG__TRX_CTRL_0 = 0x03,
AT86RF231_REG__TRX_CTRL_1 = 0x04,
AT86RF231_REG__PHY_TX_PWR = 0x05,
AT86RF231_REG__PHY_RSSI = 0x06,
AT86RF231_REG__PHY_ED_LEVEL = 0x07,
AT86RF231_REG__PHY_CC_CCA = 0x08,
AT86RF231_REG__CCA_THRES = 0x09,
AT86RF231_REG__RX_CTRL = 0x0A,
AT86RF231_REG__SFD_VALUE = 0x0B,
AT86RF231_REG__TRX_CTRL_2 = 0x0C,
AT86RF231_REG__ANT_DIV = 0x0D,
AT86RF231_REG__IRQ_MASK = 0x0E,
AT86RF231_REG__IRQ_STATUS = 0x0F,
AT86RF231_REG__VREG_CTRL = 0x10,
AT86RF231_REG__BATMON = 0x11,
AT86RF231_REG__XOSC_CTRL = 0x12,
AT86RF231_REG__RX_SYN = 0x15,
AT86RF231_REG__XAH_CTRL_1 = 0x17,
AT86RF231_REG__FTN_CTRL = 0x18,
AT86RF231_REG__PLL_CF = 0x1A,
AT86RF231_REG__PLL_DCU = 0x1B,
AT86RF231_REG__PART_NUM = 0x1C,
AT86RF231_REG__VERSION_NUM = 0x1D,
AT86RF231_REG__MAN_ID_0 = 0x1E,
AT86RF231_REG__MAN_ID_1 = 0x1F,
AT86RF231_REG__SHORT_ADDR_0 = 0x20,
AT86RF231_REG__SHORT_ADDR_1 = 0x21,
AT86RF231_REG__PAN_ID_0 = 0x22,
AT86RF231_REG__PAN_ID_1 = 0x23,
AT86RF231_REG__IEEE_ADDR_0 = 0x24,
AT86RF231_REG__IEEE_ADDR_1 = 0x25,
AT86RF231_REG__IEEE_ADDR_2 = 0x26,
AT86RF231_REG__IEEE_ADDR_3 = 0x27,
AT86RF231_REG__IEEE_ADDR_4 = 0x28,
AT86RF231_REG__IEEE_ADDR_5 = 0x29,
AT86RF231_REG__IEEE_ADDR_6 = 0x2A,
AT86RF231_REG__IEEE_ADDR_7 = 0x2B,
AT86RF231_REG__XAH_CTRL_0 = 0x2C,
AT86RF231_REG__CSMA_SEED_0 = 0x2D,
AT86RF231_REG__CSMA_SEED_1 = 0x2E,
AT86RF231_REG__CSMA_BE = 0x2F,
AT86RF231_REG__TST_CTRL_DIGI = 0x36,
};
enum
{
AT86RF231_TRX_CTRL_0_MASK__PAD_IO = 0xC0,
AT86RF231_TRX_CTRL_0_MASK__PAD_IO_CLKM = 0x30,
AT86RF231_TRX_CTRL_0_MASK__CLKM_SHA_SEL = 0x08,
AT86RF231_TRX_CTRL_0_MASK__CLKM_CTRL = 0x07,
AT86RF231_TRX_CTRL_0_DEFAULT__PAD_IO = 0x00,
AT86RF231_TRX_CTRL_0_DEFAULT__PAD_IO_CLKM = 0x10,
AT86RF231_TRX_CTRL_0_DEFAULT__CLKM_SHA_SEL = 0x08,
AT86RF231_TRX_CTRL_0_DEFAULT__CLKM_CTRL = 0x01,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__OFF = 0x00,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__1MHz = 0x01,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__2MHz = 0x02,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__4MHz = 0x03,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__8MHz = 0x04,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__16MHz = 0x05,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__250kHz = 0x06,
AT86RF231_TRX_CTRL_0_CLKM_CTRL__62_5kHz = 0x07,
};
enum
{
AT86RF231_TRX_CTRL_1_MASK__PA_EXT_EN = 0x80,
AT86RF231_TRX_CTRL_1_MASK__IRQ_2_EXT_EN = 0x40,
AT86RF231_TRX_CTRL_1_MASK__TX_AUTO_CRC_ON = 0x20,
AT86RF231_TRX_CTRL_1_MASK__RX_BL_CTRL = 0x10,
AT86RF231_TRX_CTRL_1_MASK__SPI_CMD_MODE = 0x0C,
AT86RF231_TRX_CTRL_1_MASK__IRQ_MASK_MODE = 0x02,
AT86RF231_TRX_CTRL_1_MASK__IRQ_POLARITY = 0x01,
};
enum
{
AT86RF231_TRX_CTRL_2_MASK__RX_SAFE_MODE = 0x80,
AT86RF231_TRX_CTRL_2_MASK__OQPSK_DATA_RATE = 0x03,
};
enum
{
AT86RF231_IRQ_STATUS_MASK__BAT_LOW = 0x80,
AT86RF231_IRQ_STATUS_MASK__TRX_UR = 0x40,
AT86RF231_IRQ_STATUS_MASK__AMI = 0x20,
AT86RF231_IRQ_STATUS_MASK__CCA_ED_DONE = 0x10,
AT86RF231_IRQ_STATUS_MASK__TRX_END = 0x08,
AT86RF231_IRQ_STATUS_MASK__RX_START = 0x04,
AT86RF231_IRQ_STATUS_MASK__PLL_UNLOCK = 0x02,
AT86RF231_IRQ_STATUS_MASK__PLL_LOCK = 0x01,
};
enum at86rf231_trx_status
{
AT86RF231_TRX_STATUS_MASK__CCA_DONE = 0x80,
AT86RF231_TRX_STATUS_MASK__CCA_STATUS = 0x40,
AT86RF231_TRX_STATUS_MASK__TRX_STATUS = 0x1F,
AT86RF231_TRX_STATUS__P_ON = 0x00,
AT86RF231_TRX_STATUS__BUSY_RX = 0x01,
AT86RF231_TRX_STATUS__BUSY_TX = 0x02,
AT86RF231_TRX_STATUS__RX_ON = 0x06,
AT86RF231_TRX_STATUS__TRX_OFF = 0x08,
AT86RF231_TRX_STATUS__PLL_ON = 0x09,
AT86RF231_TRX_STATUS__SLEEP = 0x0F,
AT86RF231_TRX_STATUS__BUSY_RX_AACK = 0x11,
AT86RF231_TRX_STATUS__BUSY_TX_ARET = 0x12,
AT86RF231_TRX_STATUS__RX_AACK_ON = 0x16,
AT86RF231_TRX_STATUS__TX_ARET_ON = 0x19,
AT86RF231_TRX_STATUS__RX_ON_NOCLK = 0x1C,
AT86RF231_TRX_STATUS__RX_AACK_ON_NOCLK = 0x1D,
AT86RF231_TRX_STATUS__BUSY_RX_AACK_NOCLK = 0x1E,
AT86RF231_TRX_STATUS__STATE_TRANSITION_IN_PROGRESS = 0x1F,
};
enum at86rf231_trx_state
{
AT86RF231_TRX_STATE__NOP = 0x00,
AT86RF231_TRX_STATE__TX_START = 0x02,
AT86RF231_TRX_STATE__FORCE_TRX_OFF = 0x03,
AT86RF231_TRX_STATE__FORCE_PLL_ON = 0x04,
AT86RF231_TRX_STATE__RX_ON = 0x06,
AT86RF231_TRX_STATE__TRX_OFF = 0x08,
AT86RF231_TRX_STATE__PLL_ON = 0x09,
AT86RF231_TRX_STATE__RX_AACK_ON = 0x16,
AT86RF231_TRX_STATE__TX_ARET_ON = 0x19,
};
enum at86rf231_phy_cc_cca
{
AT86RF231_PHY_CC_CCA_MASK__CCA_REQUEST = 0x80,
AT86RF231_PHY_CC_CCA_MASK__CCA_MODE = 0x60,
AT86RF231_PHY_CC_CCA_MASK__CHANNEL = 0x1F,
AT86RF231_PHY_CC_CCA_DEFAULT__CCA_MODE = 0x20,
};
enum at86rf231_phy_tx_pwr
{
AT86RF231_PHY_TX_PWR_MASK__PA_BUF_LT = 0xC0,
AT86RF231_PHY_TX_PWR_MASK__PA_LT = 0x30,
AT86RF231_PHY_TX_PWR_MASK__TX_PWR = 0x0F,
AT86RF231_PHY_TX_PWR_DEFAULT__PA_BUF_LT = 0xC0,
AT86RF231_PHY_TX_PWR_DEFAULT__PA_LT = 0x00,
AT86RF231_PHY_TX_PWR_DEFAULT__TX_PWR = 0x00,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__3dBm = 0x00,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__2_8dBm = 0x01,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__2_3dBm = 0x02,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__1_8dBm = 0x03,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__1_3dBm = 0x04,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__0_7dBm = 0x05,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__0dBm = 0x06,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m1dBm = 0x07,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m2dBm = 0x08,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m3dBm = 0x09,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m4dBm = 0x0A,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m5dBm = 0x0B,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m7dBm = 0x0C,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m9dBm = 0x0D,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m12dBm = 0x0E,
AT86RF231_PHY_TX_PWR_TX_PWR_VALUE__m17dBm = 0x0F,
};
enum at86rf231_phy_rssi
{
AT86RF231_PHY_RSSI_MASK__RX_CRC_VALID = 0x80,
AT86RF231_PHY_RSSI_MASK__RND_VALUE = 0x60,
AT86RF231_PHY_RSSI_MASK__RSSI = 0x1F,
};
enum at86rf231_xosc_ctrl
{
AT86RF231_XOSC_CTRL__XTAL_MODE_CRYSTAL = 0xF0,
AT86RF231_XOSC_CTRL__XTAL_MODE_EXTERNAL = 0xF0,
};
enum
{
AT86RF231_TIMING__VCC_TO_P_ON = 330,
AT86RF231_TIMING__SLEEP_TO_TRX_OFF = 380,
AT86RF231_TIMING__TRX_OFF_TO_PLL_ON = 110,
AT86RF231_TIMING__TRX_OFF_TO_RX_ON = 110,
AT86RF231_TIMING__PLL_ON_TO_BUSY_TX = 16,
AT86RF231_TIMING__RESET = 100,
AT86RF231_TIMING__RESET_TO_TRX_OFF = 37,
};
#endif

View File

@ -0,0 +1,9 @@
#ifndef AT86RF231_SPI_H_
#define AT86RF231_SPI_H_
#include <stdint.h>
uint8_t at86rf231_reg_read(uint8_t addr);
void at86rf231_reg_write(uint8_t addr, uint8_t value);
#endif

View File

@ -27,11 +27,12 @@
/**
* @brief All supported transceivers
*/
#define TRANSCEIVER_NONE (0x0) ///< Invalid
#define TRANSCEIVER_CC1100 (0x01) ///< CC110X transceivers
#define TRANSCEIVER_CC1020 (0x02) ///< CC1020 transceivers
#define TRANSCEIVER_CC2420 (0x04) ///< CC2420 transceivers
#define TRANSCEIVER_MC1322X (0x08) ///< MC1322X transceivers
#define TRANSCEIVER_NONE (0x0) ///< Invalid
#define TRANSCEIVER_CC1100 (0x01) ///< CC110X transceivers
#define TRANSCEIVER_CC1020 (0x02) ///< CC1020 transceivers
#define TRANSCEIVER_CC2420 (0x04) ///< CC2420 transceivers
#define TRANSCEIVER_MC1322X (0x08) ///< MC1322X transceivers
#define TRANSCEIVER_AT86RF231 (0x08) ///< AT86RF231 transceivers
/**
* @brief Data type for transceiver specification
@ -47,6 +48,7 @@ enum transceiver_msg_type_t {
RCV_PKT_CC1100, ///< packet was received by CC1100 transceiver
RCV_PKT_CC2420, ///< packet was received by CC2420 transceiver
RCV_PKT_MC1322X, ///< packet was received by mc1322x transceiver
RCV_PKT_AT86RF231, ///< packet was received by AT86RF231 transceiver
/* Message types for transceiver <-> upper layer communication */
PKT_PENDING, ///< packet pending in transceiver buffer

View File

@ -94,7 +94,7 @@ int vtimer_remove(vtimer_t *t);
/**
* @brief Prints a vtimer_t
*/
void vtimer_print(vtimer_t *t);
static void vtimer_print(vtimer_t *t);
/**
* @brief Prints the vtimer shortterm queue (use for debug purposes)

View File

@ -50,6 +50,14 @@
#define PAYLOAD_SIZE (CC2420_MAX_DATA_LENGTH)
#endif
#endif
#ifdef MODULE_AT86RF231
#include <at86rf231.h>
#if (AT86RF231_MAX_DATA_LENGTH > PAYLOAD_SIZE)
#undef PAYLOAD_SIZE
#define PAYLOAD_SIZE (AT86RF231_MAX_DATA_LENGTH)
#endif
#endif
#ifdef MODULE_MC1322X
#include <mc1322x.h>
@ -103,6 +111,8 @@ void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol,
void receive_cc1100_packet(radio_packet_t *trans_p);
#elif MODULE_CC2420
static void receive_cc2420_packet(radio_packet_t *trans_p);
#elif MODULE_AT86RF231
void receive_at86rf231_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);
@ -139,7 +149,7 @@ void transceiver_init(transceiver_type_t t)
reg[i].transceivers = TRANSCEIVER_NONE;
reg[i].pid = 0;
}
if (t & (TRANSCEIVER_CC1100 | TRANSCEIVER_CC2420)) {
if (t & (TRANSCEIVER_CC1100 | TRANSCEIVER_CC2420 | TRANSCEIVER_AT86RF231)) {
transceivers |= t;
}
else if (t & TRANSCEIVER_MC1322X) {
@ -174,6 +184,11 @@ int transceiver_start(void)
DEBUG("Transceiver started for CC2420\n");
cc2420_init(transceiver_pid);
}
#elif MODULE_AT86RF231
else if(transceivers & TRANSCEIVER_AT86RF231) {
DEBUG("Transceiver started for AT86RF231\n");
at86rf231_init(transceiver_pid);
}
#endif
#ifdef MODULE_MC1322X
else if (transceivers & TRANSCEIVER_MC1322X) {
@ -234,6 +249,9 @@ void run(void)
case RCV_PKT_CC2420:
receive_packet(m.type, m.content.value);
break;
case RCV_PKT_AT86RF231:
receive_packet(m.type, m.content.value);
break;
case SND_PKT:
response = send_packet(cmd->transceivers, cmd->data);
m.content.value = response;
@ -335,6 +353,9 @@ static void receive_packet(uint16_t type, uint8_t pos)
case RCV_PKT_MC1322X:
t = TRANSCEIVER_MC1322X;
break;
case RCV_PKT_AT86RF231:
t = TRANSCEIVER_AT86RF231;
break;
default:
t = TRANSCEIVER_NONE;
break;
@ -373,6 +394,11 @@ static void receive_packet(uint16_t type, uint8_t pos)
else if (type == RCV_PKT_CC2420) {
#ifdef MODULE_CC2420
receive_cc2420_packet(trans_p);
#endif
}
else if (type == RCV_PKT_AT86RF231) {
#ifdef MODULE_AT86RF231
receive_at86rf231_packet(trans_p);
#endif
}
else {
@ -476,7 +502,25 @@ void receive_mc1322x_packet(radio_packet_t *trans_p) {
}
#endif
#ifdef MODULE_AT86RF231
void receive_at86rf231_packet(radio_packet_t *trans_p) {
DEBUG("Handling AT86RF231 packet\n");
dINT();
at86rf231_packet_t p = at86rf231_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, AT86RF231_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 * AT86RF231_MAX_DATA_LENGTH]);
DEBUG("Content: %s\n", trans_p->data);
}
#endif
/*------------------------------------------------------------------------------------*/
/*
* @brief Sends a radio packet to the receiver
@ -505,6 +549,10 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt)
cc2420_packet_t cc2420_pkt;
#endif
#ifdef MODULE_AT86RF231
at86rf231_packet_t at86rf231_pkt;
#endif
switch (t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
@ -549,6 +597,23 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt)
memcpy(maca_pkt->data, p.data, p.length);
maca_set_tx_packet( maca_pkt );
res = 1;
break;
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
at86rf231_pkt.frame.payload_len = p.length;
at86rf231_pkt.frame.dest_addr[1] = (uint8_t)(p.dst >> 8);
at86rf231_pkt.frame.dest_addr[0] = (uint8_t)(p.dst & 0xFF);
at86rf231_pkt.frame.dest_pan_id = at86rf231_get_pan();
at86rf231_pkt.frame.fcf.dest_addr_m = 2;
at86rf231_pkt.frame.fcf.src_addr_m = 2;
at86rf231_pkt.frame.fcf.ack_req = 0;
at86rf231_pkt.frame.fcf.sec_enb = 0;
at86rf231_pkt.frame.fcf.frame_type = 1;
at86rf231_pkt.frame.fcf.frame_pend = 0;
at86rf231_pkt.frame.payload = p.data;
res = at86rf231_send(&at86rf231_pkt);
break;
#endif
default:
puts("Unknown transceiver");
@ -586,6 +651,9 @@ static int16_t set_channel(transceiver_type_t t, void *channel)
#ifdef MODULE_MC1322X
maca_set_channel(c);
return c; ///< TODO: should be changed! implement get channel
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
return at86rf231_set_channel(c);
#endif
default:
return -1;
@ -614,6 +682,10 @@ static int16_t get_channel(transceiver_type_t t)
#endif
case TRANSCEIVER_MC1322X:
///< TODO:implement return maca_get_channel();
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
return at86rf231_get_channel();
#endif
default:
return -1;
}
@ -634,6 +706,10 @@ static uint16_t set_pan(transceiver_type_t t, void *pan) {
case TRANSCEIVER_CC2420:
#ifdef MODULE_CC2420
return cc2420_set_pan(c);
#endif
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
return at86rf231_set_pan(c);
#endif
default:
/* get rid of compiler warning about unused variable */
@ -654,6 +730,10 @@ static uint16_t get_pan(transceiver_type_t t) {
case TRANSCEIVER_CC2420:
#ifdef MODULE_CC2420
return cc2420_get_pan();
#endif
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
return at86rf231_get_pan();
#endif
default:
return -1;
@ -683,6 +763,10 @@ static int16_t get_address(transceiver_type_t t)
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_get_address();
#endif
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
return at86rf231_get_address();
#endif
default:
return -1;
@ -715,6 +799,10 @@ static int16_t set_address(transceiver_type_t t, void *address)
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_set_address(addr);
#endif
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
return at86rf231_set_address(addr);
#endif
default:
return -1;
@ -738,6 +826,10 @@ static void set_monitor(transceiver_type_t t, void *mode)
case TRANSCEIVER_CC2420:
#ifdef MODULE_CC2420
cc2420_set_monitor(*((uint8_t*) mode));
#endif
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
at86rf231_set_monitor(*((uint8_t*) mode));
#endif
break;
default:
@ -777,6 +869,12 @@ static void switch_to_rx(transceiver_type_t t)
cc2420_switch_to_rx();
#endif
break;
case TRANSCEIVER_AT86RF231:
#ifdef MODULE_AT86RF231
at86rf231_switch_to_rx();
#endif
break;
default:
break;
}