diff --git a/Jamrules b/Jamrules index 8dbb5f62c7..13a6088f0c 100644 --- a/Jamrules +++ b/Jamrules @@ -73,3 +73,4 @@ HDRS += [ FPath $(TOP) projects $(PROJECT) ] ; # drivers HDRS += [ FPath $(TOP) drivers include ] ; HDRS += [ FPath $(TOP) drivers cc110x ] ; +HDRS += [ FPath $(TOP) drivers cc110x_ng ] ; diff --git a/drivers/cc110x_ng/cc1100.c b/drivers/cc110x_ng/cc1100.c index 87cf951bc0..85ea601d2b 100644 --- a/drivers/cc110x_ng/cc1100.c +++ b/drivers/cc110x_ng/cc1100.c @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include @@ -25,11 +25,12 @@ cc1100_statistic_t cc1100_statistic; volatile cc1100_flags rflags; ///< Radio control flags volatile uint8_t radio_state = RADIO_UNKNOWN; ///< Radio state -volatile uint8_t cc1100_rx_buffer_next; ///< Next packet in RX queue +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 /* internal function prototypes */ static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length); @@ -41,8 +42,10 @@ static void write_register(uint8_t r, uint8_t value); /*---------------------------------------------------------------------------*/ // Radio Driver API /*---------------------------------------------------------------------------*/ -void cc1100_init(void) { - cc1100_rx_buffer_next = 0; +void cc1100_init(int tpid) { + transceiver_pid = tpid; + + rx_buffer_next = 0; /* Initialize SPI */ cc1100_spi_init(); @@ -95,7 +98,7 @@ void cc1100_rx_handler(void) { rflags.MAN_WOR = 0; cc1100_statistic.packets_in++; - res = receive_packet((uint8_t*)&(cc1100_rx_buffer[cc1100_rx_buffer_next].packet), sizeof(cc1100_packet_t)); + 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. @@ -106,8 +109,8 @@ void cc1100_rx_handler(void) { cc1100_statistic.packets_in_while_tx++; return; } - cc1100_rx_buffer[cc1100_rx_buffer_next].rssi = rflags.RSSI; - cc1100_rx_buffer[cc1100_rx_buffer_next].lqi = rflags.LQI; + 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 @@ -118,13 +121,15 @@ void cc1100_rx_handler(void) { hwtimer_wait(IDLE_TO_RX_TIME); radio_state = RADIO_RX; - if (++cc1100_rx_buffer_next == RX_BUF_SIZE) { - cc1100_rx_buffer_next = 0; + if (++rx_buffer_next == RX_BUF_SIZE) { + rx_buffer_next = 0; + } + if (transceiver_pid) { + msg m; + m.type = (uint16_t) RCV_PKT; + m.content.value = TRANSCEIVER_CC1100; + msg_send_int(&m, transceiver_pid); } - msg m; - m.type = (uint16_t) RCV_PKT; - m.content.ptr = NULL; - msg_send_int(&m, transceiver_pid); return; } else @@ -156,6 +161,10 @@ void cc1100_rx_handler(void) { } } +uint8_t cc1100_get_buffer_pos(void) { + return (rx_buffer_next-1); +} + uint8_t cc1100_set_address(radio_address_t address) { if ((address < MIN_UID) || (address > MAX_UID)) { return 0; diff --git a/drivers/cc110x_ng/cc1100.h b/drivers/cc110x_ng/cc1100_ng.h similarity index 97% rename from drivers/cc110x_ng/cc1100.h rename to drivers/cc110x_ng/cc1100_ng.h index 90f327592e..cc42454fc9 100644 --- a/drivers/cc110x_ng/cc1100.h +++ b/drivers/cc110x_ng/cc1100_ng.h @@ -83,12 +83,12 @@ enum radio_mode { extern rx_buffer_t cc1100_rx_buffer[]; -extern volatile uint8_t cc1100_rx_buffer_next; - -void cc1100_init(void); +void cc1100_init(int transceiver_pid); void cc1100_rx_handler(void); +uint8_t cc1100_get_buffer_pos(void); + void cc1100_setup_rx_mode(void); void cc1100_switch_to_rx(void); void cc1100_wakeup_from_rx(void); diff --git a/drivers/cc110x_ng/cc1100_spi.c b/drivers/cc110x_ng/cc1100_spi.c index 010f31a5ed..0eaa70d572 100644 --- a/drivers/cc110x_ng/cc1100_spi.c +++ b/drivers/cc110x_ng/cc1100_spi.c @@ -44,7 +44,7 @@ and the mailinglist (subscription via web site) #include -#include +#include #include #include #include diff --git a/sys/Jamfile b/sys/Jamfile index f236e498ea..a8ff40a5c0 100644 --- a/sys/Jamfile +++ b/sys/Jamfile @@ -35,7 +35,7 @@ Module auto_init : auto_init.c ; Module chardev_thread : chardev_thread.c : ringbuffer ; Module uart0 : uart0.c : ringbuffer chardev_thread ; -Module transceiver : transceiver.c : oneway_malloc ; +Module transceiver : transceiver.c ; SubInclude TOP sys net ; SubInclude TOP sys lib ; diff --git a/sys/include/transceiver.h b/sys/include/transceiver.h index 4a60a42fe5..b8a44a91fb 100644 --- a/sys/include/transceiver.h +++ b/sys/include/transceiver.h @@ -1,6 +1,8 @@ #ifndef TRANSCEIVER_H #define TRANSCEIVER_H +#include + /* Packets to buffer */ #define TRANSCEIVER_BUFFER_SIZE (10) /* Stack size for transceiver thread */ @@ -13,20 +15,27 @@ * @brief Message types for transceiver interface */ enum transceiver_msg_type_t { + /* Packet types for driver <-> transceiver communication */ RCV_PKT, ///< packet was received + + /* Packet types for transceiver <-> upper layer communication */ + PKT_PENDING, ///< packet pending in transceiver buffer SND_PKT, ///< request for sending a packet SND_ACK, ///< request for sending an acknowledgement - SWITCH_RX, ///< switch receiver to RX sate - POWERDOWN, ///< power down receiver + SWITCH_RX, ///< switch transceiver to RX sate + POWERDOWN, ///< power down transceiver + + /* Error messages */ + ENOBUFFER, }; /** * @brief All supported transceivers */ typedef enum { - NONE, ///< Invalid - CC1100, ///< CC110X transceivers - CC1020 ///< CC1020 transceivers + TRANSCEIVER_NONE, ///< Invalid + TRANSCEIVER_CC1100, ///< CC110X transceivers + TRANSCEIVER_CC1020 ///< CC1020 transceivers } transceiver_type_t; /** @@ -42,7 +51,6 @@ typedef struct { radio_packet_t *packet; } send_packet_t; -extern int transceiver_pid; extern void *transceiver_rx_buffer; /** @@ -55,7 +63,7 @@ void transceiver_init(transceiver_type_t transceivers); /** * @brief Runs the transceiver thread */ -void transceiver_start(void); +int transceiver_start(void); /** * @brief register a thread for events from certain transceivers diff --git a/sys/transceiver.c b/sys/transceiver.c index 5c11f7fd72..85d4b6b4d6 100644 --- a/sys/transceiver.c +++ b/sys/transceiver.c @@ -1,21 +1,34 @@ #include #include -#include +#include + +#include +#include #include +#define PAYLOAD_SIZE (0) + /* supported transceivers */ -#include +#ifdef MODULE_CC110X_NG +#include +#if (CC1100_MAX_DATA_LENGTH > PAYLOAD_SIZE) + #undef PAYLOAD_SIZE + #define PAYLOAD_SIZE (CC1100_MAX_DATA_LENGTH;) +#endif +#endif + +//#define ENABLE_DEBUG (1) +#include /* used transceiver types */ -uint8_t transceivers = NONE; -int transceiver_pid = EINVAL; +transceiver_type_t transceivers = TRANSCEIVER_NONE; registered_t reg[TRANSCEIVER_MAX_REGISTERED]; /* packet buffers */ radio_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE]; -uint8_t *cc1100_data_buffer; +uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE]; static volatile uint8_t rx_buffer_pos = 0; static volatile uint8_t transceiver_buffer_pos = 0; @@ -24,42 +37,47 @@ static volatile uint8_t transceiver_buffer_pos = 0; const char transceiver_stack[TRANSCEIVER_STACK_SIZE]; /* function prototypes */ -void run(void); -void receive_packet(transceiver_type_t t); +static void run(void); +static void receive_packet(transceiver_type_t t); +static void receive_cc1100_packet(radio_packet_t *trans_p); +static uint8_t send_packet(transceiver_type_t t, radio_packet_t *pkt); void transceiver_init(transceiver_type_t t) { uint8_t i; for (i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) { - reg[i].transceiver = NULL; - reg[i].pid = NULL; + reg[i].transceivers = TRANSCEIVER_NONE; + reg[i].pid = 0; } - if (t & CC1100) { - transceiver |= t; - cc1100_init(); - cc1100_data_buffer = malloc(TRANSCEIVER_BUFFER_SIZE * CC100_MAX_DATA_LENGTH); + if (t & TRANSCEIVER_CC1100) { + transceivers |= t; } else { puts("Invalid transceiver type"); } } -void transceiver_start(void) { - transceiver_pid = thread_create(transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST | CREATE_SLEEPING, run, "Transceiver"); - if (transceiver_pid < 0) { +int transceiver_start(void) { + int pid = thread_create((char*) transceiver_stack, TRANSCEIVER_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST | CREATE_SLEEPING, run, "Transceiver"); + if (pid < 0) { puts("Error creating transceiver thread"); } + else if (transceivers & TRANSCEIVER_CC1100) { + cc1100_init(pid); + } + return pid; } uint8_t transceiver_register(transceiver_type_t t, int pid) { uint8_t i; - for (i = 0; ((i < TRANSCEIVER_MAX_REGISTERED) && (reg[i].transceiver != NULL)); i++); + for (i = 0; ((i < TRANSCEIVER_MAX_REGISTERED) && (reg[i].transceivers != TRANSCEIVER_NONE)); i++); if (i >= TRANSCEIVER_MAX_REGISTERED) { return ENOMEM; } else { - reg[i].transceiver = t: + reg[i].transceivers |= t; reg[i].pid = pid; + return 1; } } @@ -68,15 +86,16 @@ uint8_t transceiver_register(transceiver_type_t t, int pid) { /*------------------------------------------------------------------------------------*/ void run(void) { msg m; + send_packet_t *spkt; while (1) { msg_receive(&m); - switch (m) { + switch (m.type) { case RCV_PKT: - receive_packet(); + receive_packet(m.content.value); break; case SND_PKT: - send_packet_t spkt = (send_packet_t*) m.cotent.ptr; - send_packet(spkt.transceiver, spkt.packet); + spkt = (send_packet_t*) m.content.ptr; + send_packet(spkt->transceivers, spkt->packet); break; default: DEBUG("Unknown message received\n"); @@ -86,36 +105,60 @@ void run(void) { } -void receive_packet(transceiver_type_t t) { +static void receive_packet(transceiver_type_t t) { uint8_t i = 0; msg m; - - if (t & CC1100) { - dINT(); - rx_buffer_pos = cc1100_rx_buffer_next - 1; - cc1100_packet_t p = cc1100_rx_buffer[rx_buffer_pos].packet; - radio_info_t info = cc1100_rx_buffer[rx_buffer_pos].info; - radio_packet_t trans_p = transceiver_buffer[transceiver_buffer_pos]; - - trans_p.src = p.phy_src; - trans_p.dst = p.address; - trans_p.rssi = info.rssi; - trans_p.lqi = info.lqi; - trans_p.length = p.length; - memcpy(cc1100_data_buffer[transceiver_buffer_pos], p.data, CC1100_MAX_DATA_LENGTH); - eINT(); - - while (reg[i].transceiver != NULL) { - if (reg[i].transceiver & t) { - msg_send(&m, reg[i].pid, false); - } - i++: - } + + transceiver_buffer_pos = 0; + while ((transceiver_buffer[transceiver_buffer_pos].processing) && (transceiver_buffer_pos < TRANSCEIVER_BUFFER_SIZE)) + { + transceiver_buffer_pos++; + } + if (transceiver_buffer_pos >= TRANSCEIVER_BUFFER_SIZE) { + m.type = ENOBUFFER; + m.content.value = t; } else { - puts("Invalid transceiver type"); + radio_packet_t trans_p = transceiver_buffer[transceiver_buffer_pos]; + m.type = PKT_PENDING; + + if (t & TRANSCEIVER_CC1100) { + receive_cc1100_packet(&trans_p); + } + else { + puts("Invalid transceiver type"); + return; + } + } + + 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++; } } -uint8_t send_packet(transceiver_type_t t, radio_packet_t *pkt) { +static void receive_cc1100_packet(radio_packet_t *trans_p) { + /* disable interrupts while copying packet */ + dINT(); + rx_buffer_pos = cc1100_get_buffer_pos(); + 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; + memcpy((void*) &(cc1100_data_buffer[transceiver_buffer_pos]), p.data, CC1100_MAX_DATA_LENGTH); + 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) { + + return res; }