2010-11-19 20:10:09 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <errno.h>
|
2010-11-23 11:37:13 +01:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <thread.h>
|
|
|
|
#include <msg.h>
|
2010-11-19 20:10:09 +01:00
|
|
|
|
|
|
|
#include <transceiver.h>
|
|
|
|
|
2010-11-23 11:37:13 +01:00
|
|
|
#define PAYLOAD_SIZE (0)
|
|
|
|
|
2010-11-19 20:10:09 +01:00
|
|
|
/* supported transceivers */
|
2010-11-23 11:37:13 +01:00
|
|
|
#ifdef MODULE_CC110X_NG
|
|
|
|
#include <cc1100_ng.h>
|
|
|
|
#if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE)
|
|
|
|
#undef PAYLOAD_SIZE
|
2010-11-24 11:20:27 +01:00
|
|
|
#define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH)
|
2010-11-23 11:37:13 +01:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2010-11-24 11:20:27 +01:00
|
|
|
#define ENABLE_DEBUG (1)
|
2010-11-23 11:37:13 +01:00
|
|
|
#include <debug.h>
|
2010-11-19 20:10:09 +01:00
|
|
|
|
2010-11-21 14:00:24 +01:00
|
|
|
/* used transceiver types */
|
2010-11-23 11:37:13 +01:00
|
|
|
transceiver_type_t transceivers = TRANSCEIVER_NONE;
|
2010-11-21 14:00:24 +01:00
|
|
|
|
|
|
|
registered_t reg[TRANSCEIVER_MAX_REGISTERED];
|
|
|
|
|
|
|
|
/* packet buffers */
|
2010-11-19 20:10:09 +01:00
|
|
|
radio_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE];
|
2010-11-23 11:37:13 +01:00
|
|
|
uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE];
|
2010-11-19 20:10:09 +01:00
|
|
|
|
|
|
|
static volatile uint8_t rx_buffer_pos = 0;
|
|
|
|
static volatile uint8_t transceiver_buffer_pos = 0;
|
|
|
|
|
2010-11-21 14:00:24 +01:00
|
|
|
/* transceiver stack */
|
2010-11-24 11:20:27 +01:00
|
|
|
char transceiver_stack[TRANSCEIVER_STACK_SIZE];
|
2010-11-19 20:10:09 +01:00
|
|
|
|
2010-11-21 14:00:24 +01:00
|
|
|
/* function prototypes */
|
2010-11-23 11:37:13 +01:00
|
|
|
static void run(void);
|
2010-11-24 11:20:27 +01:00
|
|
|
static void receive_packet(uint16_t type, uint8_t pos);
|
2010-11-23 11:37:13 +01:00
|
|
|
static void receive_cc1100_packet(radio_packet_t *trans_p);
|
|
|
|
static uint8_t send_packet(transceiver_type_t t, radio_packet_t *pkt);
|
2010-11-19 20:10:09 +01:00
|
|
|
|
|
|
|
void transceiver_init(transceiver_type_t t) {
|
2010-11-21 14:00:24 +01:00
|
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) {
|
2010-11-23 11:37:13 +01:00
|
|
|
reg[i].transceivers = TRANSCEIVER_NONE;
|
|
|
|
reg[i].pid = 0;
|
2010-11-21 14:00:24 +01:00
|
|
|
}
|
2010-11-23 11:37:13 +01:00
|
|
|
if (t & TRANSCEIVER_CC1100) {
|
|
|
|
transceivers |= t;
|
2010-11-21 14:00:24 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
puts("Invalid transceiver type");
|
2010-11-19 20:10:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-23 11:37:13 +01:00
|
|
|
int transceiver_start(void) {
|
2010-11-24 11:20:27 +01:00
|
|
|
int pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN-3, CREATE_STACKTEST, run, "Transceiver");
|
2010-11-23 11:37:13 +01:00
|
|
|
if (pid < 0) {
|
2010-11-19 20:10:09 +01:00
|
|
|
puts("Error creating transceiver thread");
|
|
|
|
}
|
2010-11-23 11:37:13 +01:00
|
|
|
else if (transceivers & TRANSCEIVER_CC1100) {
|
2010-11-24 11:20:27 +01:00
|
|
|
DEBUG("Transceiver started for CC1100\n");
|
2010-11-23 11:37:13 +01:00
|
|
|
cc1100_init(pid);
|
|
|
|
}
|
|
|
|
return pid;
|
2010-11-19 20:10:09 +01:00
|
|
|
}
|
|
|
|
|
2010-11-21 14:00:24 +01:00
|
|
|
uint8_t transceiver_register(transceiver_type_t t, int pid) {
|
|
|
|
uint8_t i;
|
2010-11-24 11:20:27 +01:00
|
|
|
for (i = 0; ((reg[i].pid != pid) &&
|
|
|
|
(i < TRANSCEIVER_MAX_REGISTERED) &&
|
|
|
|
(reg[i].transceivers != TRANSCEIVER_NONE)); i++);
|
2010-11-21 14:00:24 +01:00
|
|
|
|
|
|
|
if (i >= TRANSCEIVER_MAX_REGISTERED) {
|
|
|
|
return ENOMEM;
|
|
|
|
}
|
|
|
|
else {
|
2010-11-23 11:37:13 +01:00
|
|
|
reg[i].transceivers |= t;
|
2010-11-21 14:00:24 +01:00
|
|
|
reg[i].pid = pid;
|
2010-11-24 11:20:27 +01:00
|
|
|
DEBUG("Thread %i registered for %i\n", reg[i].pid, reg[i].transceivers);
|
2010-11-23 11:37:13 +01:00
|
|
|
return 1;
|
2010-11-21 14:00:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------------------*/
|
|
|
|
/* Internal functions */
|
|
|
|
/*------------------------------------------------------------------------------------*/
|
2010-11-19 20:10:09 +01:00
|
|
|
void run(void) {
|
|
|
|
msg m;
|
2010-11-23 11:37:13 +01:00
|
|
|
send_packet_t *spkt;
|
2010-11-24 11:20:27 +01:00
|
|
|
|
2010-11-19 20:10:09 +01:00
|
|
|
while (1) {
|
2010-11-24 11:20:27 +01:00
|
|
|
DEBUG("Waiting for messages\n");
|
|
|
|
/* TODO: check here if message was lost, while handling the last */
|
2010-11-19 20:10:09 +01:00
|
|
|
msg_receive(&m);
|
2010-11-24 11:20:27 +01:00
|
|
|
DEBUG("Transceiver: Message received\n");
|
2010-11-23 11:37:13 +01:00
|
|
|
switch (m.type) {
|
2010-11-24 11:20:27 +01:00
|
|
|
case RCV_PKT_CC1020:
|
|
|
|
case RCV_PKT_CC1100:
|
|
|
|
receive_packet(m.type, m.content.value);
|
2010-11-19 20:10:09 +01:00
|
|
|
break;
|
2010-11-21 14:00:24 +01:00
|
|
|
case SND_PKT:
|
2010-11-23 11:37:13 +01:00
|
|
|
spkt = (send_packet_t*) m.content.ptr;
|
|
|
|
send_packet(spkt->transceivers, spkt->packet);
|
2010-11-21 14:00:24 +01:00
|
|
|
break;
|
2010-11-19 20:10:09 +01:00
|
|
|
default:
|
|
|
|
DEBUG("Unknown message received\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-24 11:20:27 +01:00
|
|
|
static void receive_packet(uint16_t type, uint8_t pos) {
|
2010-11-21 14:00:24 +01:00
|
|
|
uint8_t i = 0;
|
2010-11-24 11:20:27 +01:00
|
|
|
transceiver_type_t t;
|
|
|
|
rx_buffer_pos = pos;
|
2010-11-21 14:00:24 +01:00
|
|
|
msg m;
|
2010-11-24 11:20:27 +01:00
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case RCV_PKT_CC1020:
|
|
|
|
t = TRANSCEIVER_CC1020;
|
|
|
|
break;
|
|
|
|
case RCV_PKT_CC1100:
|
|
|
|
t = TRANSCEIVER_CC1100;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
t = TRANSCEIVER_NONE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* search first free position in transceiver buffer */
|
2010-11-23 11:37:13 +01:00
|
|
|
while ((transceiver_buffer[transceiver_buffer_pos].processing) && (transceiver_buffer_pos < TRANSCEIVER_BUFFER_SIZE))
|
|
|
|
{
|
|
|
|
transceiver_buffer_pos++;
|
|
|
|
}
|
2010-11-24 11:20:27 +01:00
|
|
|
/* no buffer left */
|
2010-11-23 11:37:13 +01:00
|
|
|
if (transceiver_buffer_pos >= TRANSCEIVER_BUFFER_SIZE) {
|
2010-11-24 11:20:27 +01:00
|
|
|
/* inform upper layers of lost packet */
|
2010-11-23 11:37:13 +01:00
|
|
|
m.type = ENOBUFFER;
|
|
|
|
m.content.value = t;
|
|
|
|
}
|
2010-11-24 11:20:27 +01:00
|
|
|
/* copy packet and handle it */
|
2010-11-23 11:37:13 +01:00
|
|
|
else {
|
2010-11-21 14:00:24 +01:00
|
|
|
radio_packet_t trans_p = transceiver_buffer[transceiver_buffer_pos];
|
2010-11-23 11:37:13 +01:00
|
|
|
m.type = PKT_PENDING;
|
|
|
|
|
2010-11-24 11:20:27 +01:00
|
|
|
if (type == RCV_PKT_CC1100) {
|
2010-11-23 11:37:13 +01:00
|
|
|
receive_cc1100_packet(&trans_p);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
puts("Invalid transceiver type");
|
|
|
|
return;
|
2010-11-21 14:00:24 +01:00
|
|
|
}
|
2010-11-19 20:10:09 +01:00
|
|
|
}
|
2010-11-23 11:37:13 +01:00
|
|
|
|
2010-11-24 11:20:27 +01:00
|
|
|
/* finally notify waiting upper layers
|
|
|
|
* this is done non-blocking, so packets can get lost */
|
2010-11-23 11:37:13 +01:00
|
|
|
while (reg[i].transceivers != TRANSCEIVER_NONE) {
|
|
|
|
if (reg[i].transceivers & t) {
|
|
|
|
m.content.value = transceiver_buffer_pos;
|
|
|
|
msg_send(&m, reg[i].pid, false);
|
|
|
|
}
|
|
|
|
i++;
|
2010-11-21 14:00:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-23 11:37:13 +01:00
|
|
|
static void receive_cc1100_packet(radio_packet_t *trans_p) {
|
|
|
|
/* disable interrupts while copying packet */
|
|
|
|
dINT();
|
|
|
|
cc1100_packet_t p = cc1100_rx_buffer[rx_buffer_pos].packet;
|
|
|
|
|
|
|
|
trans_p->src = p.phy_src;
|
|
|
|
trans_p->dst = p.address;
|
|
|
|
trans_p->rssi = cc1100_rx_buffer[rx_buffer_pos].rssi;
|
|
|
|
trans_p->lqi = cc1100_rx_buffer[rx_buffer_pos].lqi;
|
|
|
|
trans_p->length = p.length;
|
2010-11-24 11:20:27 +01:00
|
|
|
memcpy((void*) &(data_buffer[transceiver_buffer_pos]), p.data, CC1100_MAX_DATA_LENGTH);
|
2010-11-23 11:37:13 +01:00
|
|
|
eINT();
|
|
|
|
|
|
|
|
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint8_t send_packet(transceiver_type_t t, radio_packet_t *pkt) {
|
2010-11-24 11:20:27 +01:00
|
|
|
uint8_t res = 0;
|
2010-11-23 11:37:13 +01:00
|
|
|
return res;
|
2010-11-19 20:10:09 +01:00
|
|
|
}
|