mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
* NOTE: simple packet exchange using cc110x_ng seems to work now
* added TX functions to cc110x_ng driver and transceiver module * split up cc1100_ng functions to more files * added address asignment and request functions to driver and transceiver module
This commit is contained in:
parent
d378ee1930
commit
29cb64a37e
@ -29,5 +29,5 @@ SubDir TOP drivers cc110x_ng ;
|
||||
|
||||
HDRS += $(TOP)/drivers/cc110x_ng ;
|
||||
|
||||
Module cc110x_ng : cc1100.c cc1100-defaultSettings.c cc1100_spi.c : board_cc1100 swtimer gpioint ;
|
||||
Module cc110x_ng : cc1100.c cc1100-rx.c cc1100-tx.c cc1100-defaultSettings.c cc1100_spi.c : board_cc1100 swtimer gpioint ;
|
||||
|
||||
|
@ -137,19 +137,5 @@ uint8_t pa_table[] = { ///< PATABLE with available output powers
|
||||
0xC3 ///< +10 dBm
|
||||
}; // If PATABLE is changed in size, adjust MAX_OUTPUT_POWER definition in CC1100 interface!
|
||||
|
||||
static int8_t pa_table_dBm[] = { ///< Values of the PATABLE in dBm
|
||||
-52,
|
||||
-30,
|
||||
-20,
|
||||
-15,
|
||||
-10,
|
||||
-5,
|
||||
-1,
|
||||
0,
|
||||
5,
|
||||
7,
|
||||
9,
|
||||
10
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
153
drivers/cc110x_ng/cc1100-rx.c
Normal file
153
drivers/cc110x_ng/cc1100-rx.c
Normal file
@ -0,0 +1,153 @@
|
||||
#include <cc1100_ng.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100-config.h>
|
||||
#include <cc1100-defaultSettings.h>
|
||||
#include <cc1100_spi.h>
|
||||
|
||||
#include <hwtimer.h>
|
||||
#include <msg.h>
|
||||
#include <transceiver.h>
|
||||
|
||||
#include <board.h>
|
||||
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length);
|
||||
static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length);
|
||||
|
||||
rx_buffer_t cc1100_rx_buffer[RX_BUF_SIZE]; ///< RX buffer
|
||||
volatile uint8_t rx_buffer_next; ///< Next packet in RX queue
|
||||
|
||||
void cc1100_rx_handler(void) {
|
||||
uint8_t res = 0;
|
||||
|
||||
// Possible packet received, RX -> IDLE (0.1 us)
|
||||
rflags.CAA = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
cc1100_statistic.packets_in++;
|
||||
|
||||
res = receive_packet((uint8_t*)&(cc1100_rx_buffer[rx_buffer_next].packet), sizeof(cc1100_packet_t));
|
||||
if (res) {
|
||||
// If we are sending a burst, don't accept packets.
|
||||
// Only ACKs are processed (for stopping the burst).
|
||||
// Same if state machine is in TX lock.
|
||||
if (radio_state == RADIO_SEND_BURST || rflags.TX)
|
||||
{
|
||||
cc1100_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
cc1100_rx_buffer[rx_buffer_next].rssi = rflags.RSSI;
|
||||
cc1100_rx_buffer[rx_buffer_next].lqi = rflags.LQI;
|
||||
|
||||
// Valid packet. After a wake-up, the radio should be in IDLE.
|
||||
// So put CC1100 to RX for WOR_TIMEOUT (have to manually put
|
||||
// the radio back to sleep/WOR).
|
||||
cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal
|
||||
cc1100_spi_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME (until end of packet)
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
radio_state = RADIO_RX;
|
||||
|
||||
/* notify transceiver thread if any */
|
||||
if (transceiver_pid) {
|
||||
msg m;
|
||||
m.type = (uint16_t) RCV_PKT_CC1100;
|
||||
m.content.value = rx_buffer_next;
|
||||
msg_send_int(&m, transceiver_pid);
|
||||
}
|
||||
|
||||
/* shift to next buffer element */
|
||||
if (++rx_buffer_next == RX_BUF_SIZE) {
|
||||
rx_buffer_next = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No ACK received so TOF is unpredictable
|
||||
rflags.TOF = 0;
|
||||
|
||||
// CRC false or RX buffer full -> clear RX FIFO in both cases
|
||||
cc1100_spi_strobe(CC1100_SIDLE); // Switch to IDLE (should already be)...
|
||||
cc1100_spi_strobe(CC1100_SFRX); // ...for flushing the RX FIFO
|
||||
|
||||
// If packet interrupted this nodes send call,
|
||||
// don't change anything after this point.
|
||||
if (radio_state == RADIO_AIR_FREE_WAITING)
|
||||
{
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
return;
|
||||
}
|
||||
// If currently sending, exit here (don't go to RX/WOR)
|
||||
if (radio_state == RADIO_SEND_BURST)
|
||||
{
|
||||
cc1100_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
|
||||
// No valid packet, so go back to RX/WOR as soon as possible
|
||||
cc1100_switch_to_rx();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t status[2];
|
||||
uint8_t packetLength = 0;
|
||||
|
||||
/* Any bytes available in RX FIFO? */
|
||||
if ((cc1100_spi_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) {
|
||||
LED_GREEN_TOGGLE;
|
||||
// Read length byte (first byte in RX FIFO)
|
||||
packetLength = cc1100_spi_read_reg(CC1100_RXFIFO);
|
||||
// Read data from RX FIFO and store in rxBuffer
|
||||
if (packetLength <= length)
|
||||
{
|
||||
// Put length byte at first position in RX Buffer
|
||||
rxBuffer[0] = packetLength;
|
||||
|
||||
// Read the rest of the packet
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength);
|
||||
|
||||
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)status, 2);
|
||||
|
||||
// Store RSSI value of packet
|
||||
rflags.RSSI = status[I_RSSI];
|
||||
|
||||
// MSB of LQI is the CRC_OK bit
|
||||
rflags.CRC = (status[I_LQI] & CRC_OK) >> 7;
|
||||
if (!rflags.CRC) {
|
||||
cc1100_statistic.packets_in_crc_fail++;
|
||||
}
|
||||
|
||||
// Bit 0-6 of LQI indicates the link quality (LQI)
|
||||
rflags.LQI = status[I_LQI] & LQI_EST;
|
||||
|
||||
return rflags.CRC;
|
||||
}
|
||||
/* too many bytes in FIFO */
|
||||
else {
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* no bytes in RX FIFO */
|
||||
else {
|
||||
LED_RED_TOGGLE;
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t pkt_len_cfg = cc1100_spi_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG;
|
||||
if (pkt_len_cfg == VARIABLE_PKTLEN)
|
||||
{
|
||||
return receive_packet_variable(rxBuffer, length);
|
||||
}
|
||||
// Fixed packet length not supported.
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
77
drivers/cc110x_ng/cc1100-tx.c
Normal file
77
drivers/cc110x_ng/cc1100-tx.c
Normal file
@ -0,0 +1,77 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cc1100_ng.h>
|
||||
#include <cc1100-defaultSettings.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100-arch.h>
|
||||
#include <cc1100_spi.h>
|
||||
|
||||
#include <irq.h>
|
||||
|
||||
#include <board.h>
|
||||
|
||||
uint8_t cc1100_send(cc1100_packet_t *packet) {
|
||||
puts("Going to send\n");
|
||||
volatile uint32_t abort_count;
|
||||
uint8_t size;
|
||||
/* TODO: burst sending */
|
||||
radio_state = RADIO_SEND_BURST;
|
||||
rflags.LL_ACK = 0;
|
||||
|
||||
/*
|
||||
* Number of bytes to send is:
|
||||
* length of phy payload (packet->length)
|
||||
* + size of length field (1 byte)
|
||||
*/
|
||||
size = packet->length + 1;
|
||||
|
||||
// The number of bytes to be transmitted must be smaller
|
||||
// or equal to PACKET_LENGTH (62 bytes). So the receiver
|
||||
// can put the whole packet in its RX-FIFO (with appended
|
||||
// packet status bytes).
|
||||
if (size > PACKET_LENGTH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
packet->phy_src = cc1100_get_address();
|
||||
|
||||
// Disables RX interrupt etc.
|
||||
cc1100_before_send();
|
||||
|
||||
// But CC1100 in IDLE mode to flush the FIFO
|
||||
cc1100_spi_strobe(CC1100_SIDLE);
|
||||
// Flush TX FIFO to be sure it is empty
|
||||
cc1100_spi_strobe(CC1100_SFTX);
|
||||
// Write packet into TX FIFO
|
||||
cc1100_spi_writeburst_reg(CC1100_TXFIFO, (char*) packet, size);
|
||||
// Switch to TX mode
|
||||
abort_count = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_strobe(CC1100_STX);
|
||||
// Wait for GDO2 to be set -> sync word transmitted
|
||||
while (cc1100_get_gdo2() == 0) {
|
||||
abort_count++;
|
||||
if (abort_count > CC1100_SYNC_WORD_TX_TIME) {
|
||||
// Abort waiting. CC1100 maybe in wrong mode
|
||||
// e.g. sending preambles for always
|
||||
puts("[CC1100 TX] fatal error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
restoreIRQ(cpsr);
|
||||
// Wait for GDO2 to be cleared -> end of packet
|
||||
while (cc1100_get_gdo2() != 0);
|
||||
|
||||
// Experimental - TOF Measurement
|
||||
cc1100_after_send();
|
||||
cc1100_statistic.raw_packets_out++;
|
||||
|
||||
// Store number of transmission retries
|
||||
rflags.TX = 0;
|
||||
|
||||
// Go to mode after TX (CONST_RX -> RX, WOR -> WOR)
|
||||
cc1100_switch_to_rx();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cc1100_ng.h>
|
||||
#include <cc1100-arch.h>
|
||||
#include <cc1100-config.h>
|
||||
@ -7,15 +5,10 @@
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100_spi.h>
|
||||
|
||||
#include <transceiver.h>
|
||||
#include <hwtimer.h>
|
||||
#include <msg.h>
|
||||
|
||||
//#define ENABLE_DEBUG (1)
|
||||
#include <debug.h>
|
||||
#include <board.h>
|
||||
|
||||
#define RX_BUF_SIZE (10)
|
||||
|
||||
/* some externals */
|
||||
extern uint8_t pa_table[]; ///< PATABLE with available output powers
|
||||
@ -23,22 +16,17 @@ extern uint8_t pa_table_index; ///< Current PATABLE Index
|
||||
|
||||
/* global variables */
|
||||
|
||||
rx_buffer_t cc1100_rx_buffer[RX_BUF_SIZE]; ///< RX buffer
|
||||
cc1100_statistic_t cc1100_statistic;
|
||||
|
||||
volatile cc1100_flags rflags; ///< Radio control flags
|
||||
volatile uint8_t radio_state = RADIO_UNKNOWN; ///< Radio state
|
||||
|
||||
static volatile uint8_t rx_buffer_next; ///< Next packet in RX queue
|
||||
|
||||
static uint8_t radio_address; ///< Radio address
|
||||
static uint8_t radio_channel; ///< Radio channel
|
||||
|
||||
static int transceiver_pid; ///< the transceiver thread pid
|
||||
int transceiver_pid; ///< the transceiver thread pid
|
||||
|
||||
/* internal function prototypes */
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length);
|
||||
static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length);
|
||||
static int rd_set_mode(int mode);
|
||||
static void reset(void);
|
||||
static void power_up_reset(void);
|
||||
@ -100,84 +88,15 @@ void cc1100_gdo2_irq(void) {
|
||||
cc1100_rx_handler();
|
||||
}
|
||||
|
||||
void cc1100_rx_handler(void) {
|
||||
uint8_t res = 0;
|
||||
|
||||
// Possible packet received, RX -> IDLE (0.1 us)
|
||||
rflags.CAA = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
cc1100_statistic.packets_in++;
|
||||
|
||||
res = receive_packet((uint8_t*)&(cc1100_rx_buffer[rx_buffer_next].packet), sizeof(cc1100_packet_t));
|
||||
if (res) {
|
||||
// If we are sending a burst, don't accept packets.
|
||||
// Only ACKs are processed (for stopping the burst).
|
||||
// Same if state machine is in TX lock.
|
||||
if (radio_state == RADIO_SEND_BURST || rflags.TX)
|
||||
{
|
||||
cc1100_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
cc1100_rx_buffer[rx_buffer_next].rssi = rflags.RSSI;
|
||||
cc1100_rx_buffer[rx_buffer_next].lqi = rflags.LQI;
|
||||
|
||||
// Valid packet. After a wake-up, the radio should be in IDLE.
|
||||
// So put CC1100 to RX for WOR_TIMEOUT (have to manually put
|
||||
// the radio back to sleep/WOR).
|
||||
cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal
|
||||
cc1100_spi_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME (until end of packet)
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
radio_state = RADIO_RX;
|
||||
|
||||
/* notify transceiver thread if any */
|
||||
if (transceiver_pid) {
|
||||
msg m;
|
||||
m.type = (uint16_t) RCV_PKT_CC1100;
|
||||
m.content.value = rx_buffer_next;
|
||||
msg_send_int(&m, transceiver_pid);
|
||||
}
|
||||
|
||||
/* shift to next buffer element */
|
||||
if (++rx_buffer_next == RX_BUF_SIZE) {
|
||||
rx_buffer_next = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No ACK received so TOF is unpredictable
|
||||
rflags.TOF = 0;
|
||||
|
||||
// CRC false or RX buffer full -> clear RX FIFO in both cases
|
||||
cc1100_spi_strobe(CC1100_SIDLE); // Switch to IDLE (should already be)...
|
||||
cc1100_spi_strobe(CC1100_SFRX); // ...for flushing the RX FIFO
|
||||
|
||||
// If packet interrupted this nodes send call,
|
||||
// don't change anything after this point.
|
||||
if (radio_state == RADIO_AIR_FREE_WAITING)
|
||||
{
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
return;
|
||||
}
|
||||
// If currently sending, exit here (don't go to RX/WOR)
|
||||
if (radio_state == RADIO_SEND_BURST)
|
||||
{
|
||||
cc1100_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
|
||||
// No valid packet, so go back to RX/WOR as soon as possible
|
||||
cc1100_switch_to_rx();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t cc1100_get_buffer_pos(void) {
|
||||
return (rx_buffer_next-1);
|
||||
}
|
||||
|
||||
uint8_t cc1100_set_address(radio_address_t address) {
|
||||
radio_address_t cc1100_get_address() {
|
||||
return radio_address;
|
||||
}
|
||||
|
||||
radio_address_t cc1100_set_address(radio_address_t address) {
|
||||
if ((address < MIN_UID) || (address > MAX_UID)) {
|
||||
return 0;
|
||||
}
|
||||
@ -188,7 +107,7 @@ uint8_t cc1100_set_address(radio_address_t address) {
|
||||
}
|
||||
|
||||
radio_address = id;
|
||||
return 0;
|
||||
return radio_address;
|
||||
}
|
||||
|
||||
void cc1100_setup_rx_mode(void) {
|
||||
@ -277,7 +196,6 @@ char* cc1100_state_to_text(uint8_t state) {
|
||||
|
||||
|
||||
void cc1100_print_config(void) {
|
||||
char buf[8];
|
||||
printf("Current radio state: %s\r\n", cc1100_state_to_text(radio_state));
|
||||
printf("Current MARC state: %s\r\n", cc1100_get_marc_state());
|
||||
printf("Current channel number: %u\r\n", radio_channel);
|
||||
@ -289,9 +207,10 @@ void switch_to_pwd(void) {
|
||||
radio_state = RADIO_PWD;
|
||||
}
|
||||
|
||||
uint8_t cc1100_set_channel(uint8_t channr) {
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int16_t cc1100_set_channel(uint8_t channr) {
|
||||
uint8_t state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
if (state != 1) && ((channr > MAX_CHANNR)) {
|
||||
if ((state != 1) && (channr > MAX_CHANNR)) {
|
||||
return 0;
|
||||
}
|
||||
write_register(CC1100_CHANNR, channr*10);
|
||||
@ -299,72 +218,10 @@ uint8_t cc1100_set_channel(uint8_t channr) {
|
||||
return radio_channel;
|
||||
}
|
||||
|
||||
uint8_t cc1100_get_channel(void) {
|
||||
int16_t cc1100_get_channel(void) {
|
||||
return radio_channel;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Internal functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t status[2];
|
||||
uint8_t packetLength = 0;
|
||||
|
||||
/* Any bytes available in RX FIFO? */
|
||||
if ((cc1100_spi_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) {
|
||||
LED_GREEN_TOGGLE;
|
||||
// Read length byte (first byte in RX FIFO)
|
||||
packetLength = cc1100_spi_read_reg(CC1100_RXFIFO);
|
||||
// Read data from RX FIFO and store in rxBuffer
|
||||
if (packetLength <= length)
|
||||
{
|
||||
// Put length byte at first position in RX Buffer
|
||||
rxBuffer[0] = packetLength;
|
||||
|
||||
// Read the rest of the packet
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength);
|
||||
|
||||
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)status, 2);
|
||||
|
||||
// Store RSSI value of packet
|
||||
rflags.RSSI = status[I_RSSI];
|
||||
|
||||
// MSB of LQI is the CRC_OK bit
|
||||
rflags.CRC = (status[I_LQI] & CRC_OK) >> 7;
|
||||
if (!rflags.CRC) {
|
||||
cc1100_statistic.packets_in_crc_fail++;
|
||||
}
|
||||
|
||||
// Bit 0-6 of LQI indicates the link quality (LQI)
|
||||
rflags.LQI = status[I_LQI] & LQI_EST;
|
||||
|
||||
return rflags.CRC;
|
||||
}
|
||||
/* too many bytes in FIFO */
|
||||
else {
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* no bytes in RX FIFO */
|
||||
else {
|
||||
LED_RED_TOGGLE;
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t pkt_len_cfg = cc1100_spi_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG;
|
||||
if (pkt_len_cfg == VARIABLE_PKTLEN)
|
||||
{
|
||||
return receive_packet_variable(rxBuffer, length);
|
||||
}
|
||||
// Fixed packet length not supported.
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// CC1100 reset functionality
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <stdint.h>
|
||||
#include <cc1100-config.h>
|
||||
|
||||
#define RX_BUF_SIZE (10)
|
||||
|
||||
#define CC1100_MAX_DATA_LENGTH (58)
|
||||
|
||||
#define CC1100_BROADCAST_ADDRESS (0x00) ///< CC1100 broadcast address
|
||||
@ -19,6 +21,9 @@
|
||||
#define MIN_OUTPUT_POWER (0) ///< Minimum output power value
|
||||
#define MAX_OUTPUT_POWER (11) ///< Maximum output power value
|
||||
|
||||
#define PACKET_LENGTH (0x3E) ///< Packet length = 62 Bytes.
|
||||
#define CC1100_SYNC_WORD_TX_TIME (90000) // loop count (max. timeout ~ 15 ms) to wait for
|
||||
// sync word to be transmitted (GDO2 from low to high)
|
||||
/**
|
||||
* @name Defines used as state values for state machine
|
||||
* @{
|
||||
@ -83,10 +88,19 @@ enum radio_mode {
|
||||
|
||||
extern rx_buffer_t cc1100_rx_buffer[];
|
||||
|
||||
extern volatile uint8_t rx_buffer_next; ///< Next packet in RX queue
|
||||
|
||||
extern volatile uint8_t radio_state; ///< Radio state
|
||||
extern cc1100_statistic_t cc1100_statistic;
|
||||
|
||||
int transceiver_pid; ///< the transceiver thread pid
|
||||
|
||||
void cc1100_init(int transceiver_pid);
|
||||
|
||||
void cc1100_rx_handler(void);
|
||||
|
||||
uint8_t cc1100_send(cc1100_packet_t *pkt);
|
||||
|
||||
uint8_t cc1100_get_buffer_pos(void);
|
||||
|
||||
void cc1100_setup_rx_mode(void);
|
||||
@ -95,8 +109,11 @@ void cc1100_wakeup_from_rx(void);
|
||||
void cc1100_switch_to_pwd(void);
|
||||
|
||||
void cc1100_disable_interrupts(void);
|
||||
uint8_t cc1100_set_channel(uint8_t channr);
|
||||
uint8_t cc1100_get_channel(void);
|
||||
int16_t cc1100_set_channel(uint8_t channr);
|
||||
int16_t cc1100_get_channel(void);
|
||||
|
||||
radio_address_t cc1100_set_address(radio_address_t addr);
|
||||
radio_address_t cc1100_get_address(void);
|
||||
|
||||
void cc1100_print_config(void);
|
||||
#endif
|
||||
|
@ -12,12 +12,12 @@
|
||||
#define RADIO_STACK_SIZE (4096)
|
||||
|
||||
int transceiver_pid;
|
||||
int radio_pid;
|
||||
char shell_stack_buffer[SHELL_STACK_SIZE];
|
||||
char radio_stack_buffer[RADIO_STACK_SIZE];
|
||||
|
||||
void trans_chan(char *chan);
|
||||
void trans_register(char *unused);
|
||||
void trans_addr(char *addr);
|
||||
void trans_send(char *mesg);
|
||||
|
||||
msg mesg;
|
||||
transceiver_command_t tcmd;
|
||||
@ -25,28 +25,58 @@ transceiver_command_t tcmd;
|
||||
shell_t shell;
|
||||
const shell_command_t sc[] = {
|
||||
{"tchan", "Set the channel for cc1100", trans_chan},
|
||||
{"treg", "Register application for CC1100", trans_register},
|
||||
{"taddr", "Set the address for cc1100", trans_addr},
|
||||
{"tsnd", "Sends a CC1100 packet", trans_send},
|
||||
{NULL, NULL, NULL}};
|
||||
|
||||
void trans_chan(char *chan) {
|
||||
unsigned int c;
|
||||
int c;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &c;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
if (sscanf(chan, "tchan %u", &c)) {
|
||||
printf("Trying to set channel %u\n", c);
|
||||
if (sscanf(chan, "tchan %i", &c) > 0) {
|
||||
printf("Trying to set channel %i\n", c);
|
||||
mesg.type = SET_CHANNEL;
|
||||
}
|
||||
else {
|
||||
mesg.type = GET_CHANNEL;
|
||||
}
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
printf("Got channel: %hu\n", c);
|
||||
printf("Got channel: %i\n", c);
|
||||
}
|
||||
|
||||
void trans_register(char *unused) {
|
||||
transceiver_register(TRANSCEIVER_CC1100, radio_pid);
|
||||
void trans_addr(char *addr) {
|
||||
int a;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &a;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
if (sscanf(addr, "taddr %i", &a) > 0) {
|
||||
printf("Trying to set address %i\n", a);
|
||||
mesg.type = SET_ADDRESS;
|
||||
}
|
||||
else {
|
||||
mesg.type = GET_ADDRESS;
|
||||
}
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
printf("Got address: %i\n", a);
|
||||
}
|
||||
|
||||
void trans_send(char *text) {
|
||||
radio_packet_t p;
|
||||
uint32_t response;
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &p;
|
||||
|
||||
p.length = 10;
|
||||
p.dst = 5;
|
||||
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
msg_send_receive(&mesg, &mesg, transceiver_pid);
|
||||
response = mesg.content.value;
|
||||
printf("Packet send: %lu\n", response);
|
||||
}
|
||||
|
||||
void shell_runner(void) {
|
||||
@ -65,12 +95,12 @@ void radio(void) {
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
thread_create(shell_stack_buffer, SHELL_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, shell_runner, "shell");
|
||||
int radio_pid;
|
||||
thread_create(shell_stack_buffer, SHELL_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, shell_runner, "shell");
|
||||
radio_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE, PRIORITY_MAIN-2, CREATE_STACKTEST, radio, "radio");
|
||||
transceiver_init(TRANSCEIVER_CC1100);
|
||||
transceiver_pid = transceiver_start();
|
||||
extern void cc1100_set_channel(uint8_t c);
|
||||
cc1100_set_channel(6);
|
||||
transceiver_init(TRANSCEIVER_CC1100);
|
||||
transceiver_pid = transceiver_start();
|
||||
transceiver_register(TRANSCEIVER_CC1100, radio_pid);
|
||||
|
||||
while (1) {
|
||||
// LED_GREEN_TOGGLE;
|
||||
|
@ -27,6 +27,8 @@ enum transceiver_msg_type_t {
|
||||
POWERDOWN, ///< power down transceiver
|
||||
GET_CHANNEL, ///< Get current channel
|
||||
SET_CHANNEL, ///< Set a new channel
|
||||
GET_ADDRESS, ///< Get the radio address
|
||||
SET_ADDRESS, ///< Set the radio address
|
||||
|
||||
/* Error messages */
|
||||
ENOBUFFER,
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <msg.h>
|
||||
|
||||
#include <transceiver.h>
|
||||
#include <radio/types.h>
|
||||
|
||||
#define PAYLOAD_SIZE (0)
|
||||
|
||||
@ -21,29 +22,38 @@
|
||||
#define ENABLE_DEBUG (1)
|
||||
#include <debug.h>
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/* used transceiver types */
|
||||
transceiver_type_t transceivers = TRANSCEIVER_NONE;
|
||||
|
||||
/* registered upper layer threads */
|
||||
registered_t reg[TRANSCEIVER_MAX_REGISTERED];
|
||||
|
||||
/* packet buffers */
|
||||
radio_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE];
|
||||
uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE];
|
||||
|
||||
uint32_t response; ///< response bytes for messages to upper layer threads
|
||||
|
||||
static volatile uint8_t rx_buffer_pos = 0;
|
||||
static volatile uint8_t transceiver_buffer_pos = 0;
|
||||
|
||||
/* transceiver stack */
|
||||
char transceiver_stack[TRANSCEIVER_STACK_SIZE];
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/* function prototypes */
|
||||
static void run(void);
|
||||
static void receive_packet(uint16_t type, uint8_t pos);
|
||||
static void receive_cc1100_packet(radio_packet_t *trans_p);
|
||||
static uint8_t send_packet(transceiver_type_t t, void *pkt);
|
||||
static uint8_t get_channel(transceiver_type_t t);
|
||||
static uint8_t set_channel(transceiver_type_t t, void *channel);
|
||||
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);
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/* Transceiver init */
|
||||
void transceiver_init(transceiver_type_t t) {
|
||||
uint8_t i;
|
||||
for (i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) {
|
||||
@ -58,6 +68,7 @@ void transceiver_init(transceiver_type_t t) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Start the transceiver thread */
|
||||
int transceiver_start(void) {
|
||||
int pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN-3, CREATE_STACKTEST, run, "Transceiver");
|
||||
if (pid < 0) {
|
||||
@ -70,6 +81,7 @@ int transceiver_start(void) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* Register an upper layer thread */
|
||||
uint8_t transceiver_register(transceiver_type_t t, int pid) {
|
||||
uint8_t i;
|
||||
for (i = 0; ((reg[i].pid != pid) &&
|
||||
@ -90,12 +102,19 @@ uint8_t transceiver_register(transceiver_type_t t, int pid) {
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/* Internal functions */
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* @brief The main thread run, receiving and processing messages in an infinite
|
||||
* loop
|
||||
*/
|
||||
void run(void) {
|
||||
msg m;
|
||||
transceiver_command_t *cmd;
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m);
|
||||
/* only makes sense for messages for upper layers */
|
||||
cmd = (transceiver_command_t*) m.content.ptr;
|
||||
DEBUG("Transceiver: Message received\n");
|
||||
switch (m.type) {
|
||||
case RCV_PKT_CC1020:
|
||||
@ -103,17 +122,24 @@ void run(void) {
|
||||
receive_packet(m.type, m.content.value);
|
||||
break;
|
||||
case SND_PKT:
|
||||
cmd = (transceiver_command_t*) m.content.ptr;
|
||||
send_packet(cmd->transceivers, cmd->data);
|
||||
response = send_packet(cmd->transceivers, cmd->data);
|
||||
m.content.value = response;
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
case GET_CHANNEL:
|
||||
cmd = (transceiver_command_t*) m.content.ptr;
|
||||
*((uint8_t*) cmd->data) = get_channel(cmd->transceivers);
|
||||
*((int16_t*) cmd->data) = get_channel(cmd->transceivers);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
case SET_CHANNEL:
|
||||
cmd = (transceiver_command_t*) m.content.ptr;
|
||||
*((uint8_t*) cmd->data) = set_channel(cmd->transceivers, cmd->data);
|
||||
*((int16_t*) cmd->data) = set_channel(cmd->transceivers, cmd->data);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
case GET_ADDRESS:
|
||||
*((int16_t*) cmd->data) = get_address(cmd->transceivers);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
case SET_ADDRESS:
|
||||
*((int16_t*) cmd->data) = set_address(cmd->transceivers, cmd->data);
|
||||
msg_reply(&m, &m);
|
||||
break;
|
||||
default:
|
||||
@ -123,7 +149,14 @@ void run(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* @brief Processes a packet received by any transceiver device
|
||||
*
|
||||
* @param type The message type to determine which device has received the
|
||||
* packet
|
||||
* @param pos The current device driver's buffer position
|
||||
*/
|
||||
static void receive_packet(uint16_t type, uint8_t pos) {
|
||||
uint8_t i = 0;
|
||||
transceiver_type_t t;
|
||||
@ -181,6 +214,11 @@ static void receive_packet(uint16_t type, uint8_t pos) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief process packets from CC1100
|
||||
*
|
||||
* @param trans_p The current entry in the transceiver buffer
|
||||
*/
|
||||
static void receive_cc1100_packet(radio_packet_t *trans_p) {
|
||||
DEBUG("Handling CC1100 packet\n");
|
||||
/* disable interrupts while copying packet */
|
||||
@ -199,13 +237,47 @@ static void receive_cc1100_packet(radio_packet_t *trans_p) {
|
||||
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* @brief Sends a radio packet to the receiver
|
||||
*
|
||||
* @param t The transceiver device
|
||||
* @param pkt Generic pointer to the packet
|
||||
*
|
||||
* @return 1 on success, 0 otherwise
|
||||
*/
|
||||
static uint8_t send_packet(transceiver_type_t t, void *pkt) {
|
||||
uint8_t res = 0;
|
||||
radio_packet_t p = *((radio_packet_t*) pkt);
|
||||
cc1100_packet_t cc1100_pkt;
|
||||
|
||||
switch (t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
/* TODO: prepare and send packet here */
|
||||
cc1100_pkt.length = p.length;
|
||||
cc1100_pkt.address = p.dst;
|
||||
cc1100_pkt.flags = 0;
|
||||
memcpy(cc1100_pkt.data, p.data, p.length);
|
||||
|
||||
res = cc1100_send(&cc1100_pkt);
|
||||
break;
|
||||
default:
|
||||
puts("Unknown transceiver");
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint8_t set_channel(transceiver_type_t t, void *channel) {
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* @brief Sets the radio channel for any transceiver device
|
||||
*
|
||||
* @param t The transceiver device
|
||||
* @param channel The channel to be set
|
||||
*
|
||||
* @return The radio channel AFTER calling the set command, -1 on error
|
||||
*/
|
||||
static int16_t set_channel(transceiver_type_t t, void *channel) {
|
||||
uint8_t c = *((uint8_t*) channel);
|
||||
switch (t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
@ -215,7 +287,14 @@ static uint8_t set_channel(transceiver_type_t t, void *channel) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t get_channel(transceiver_type_t t) {
|
||||
/*
|
||||
* @brief Get the radio channel of any transceiver device
|
||||
*
|
||||
* @param t The transceiver device
|
||||
*
|
||||
* @return The current radio channel of the transceiver, -1 on error
|
||||
*/
|
||||
static int16_t get_channel(transceiver_type_t t) {
|
||||
switch (t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
return cc1100_get_channel();
|
||||
@ -223,3 +302,37 @@ static uint8_t get_channel(transceiver_type_t t) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* @brief Get the current address of transceiver device
|
||||
*
|
||||
* @param t The transciever device
|
||||
*
|
||||
* @return The configured address of the device, -1 on error
|
||||
*/
|
||||
static int16_t get_address(transceiver_type_t t) {
|
||||
switch (t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
return cc1100_get_address();
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Set the address of the transceiver device
|
||||
*
|
||||
* @param t The transceiver device
|
||||
* @param address Generic pointer to the address to set
|
||||
*
|
||||
* @return The new radio address of the device
|
||||
*/
|
||||
static int16_t set_address(transceiver_type_t t, void *address) {
|
||||
radio_address_t addr = *((radio_address_t*) address);
|
||||
switch (t) {
|
||||
case TRANSCEIVER_CC1100:
|
||||
return cc1100_set_address(addr);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user