Contiki 2.6

tr1001-gcr.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005, Swedish Institute of Computer Science
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  *
00031  * @(#)$Id: tr1001-gcr.c,v 1.15 2010/03/02 22:40:39 nifi Exp $
00032  */
00033 /**
00034  * \addtogroup esb
00035  * @{
00036  */
00037 
00038 /**
00039  * \defgroup tr1001 TR1001 radio tranciever device driver
00040  * @{
00041  */
00042 
00043 /**
00044  * \file
00045  * Device driver and packet framing for the RFM-TR1001 radio module.
00046  * \author Adam Dunkels <adam@sics.se>
00047  *
00048  * This file implements a device driver for the RFM-TR1001 radio
00049  * tranciever.
00050  *
00051  */
00052 
00053 #include "contiki.h"
00054 #include "contiki-esb.h"
00055 
00056 #include "dev/tr1001.h"
00057 #include "dev/radio-sensor.h"
00058 #include "lib/gcr.h"
00059 #include "lib/crc16.h"
00060 #include "net/netstack.h"
00061 #include "net/rime/rimestats.h"
00062 #include "isr_compat.h"
00063 
00064 #include <string.h>
00065 
00066 #ifdef TR1001_CONF_BEEP_ON_BAD_CRC
00067 #define BEEP_ON_BAD_CRC TR1001_CONF_BEEP_ON_BAD_CRC
00068 #else
00069 #define BEEP_ON_BAD_CRC 1
00070 #endif /* TR1001_CONF_BEEP_ON_BAD_CRC */
00071 
00072 #if BEEP_ON_BAD_CRC
00073 #include "dev/beep.h"
00074 #define BEEP_BEEP(t) beep_beep(t)
00075 #else
00076 #define BEEP_BEEP(t)
00077 #endif /* BEEP_ON_BAD_CRC */
00078 
00079 #define RXSTATE_READY     0
00080 #define RXSTATE_RECEIVING 1
00081 #define RXSTATE_FULL      2
00082 
00083 #define SYNCH1 0x3c
00084 #define SYNCH2 0x03
00085 
00086 #ifdef TR1001_CONF_BUFFER_SIZE
00087 #define RXBUFSIZE TR1001_CONF_BUFFER_SIZE
00088 #else
00089 #define RXBUFSIZE PACKETBUF_SIZE
00090 #endif /* TR1001_CONF_BUFFER_SIZE */
00091 
00092 /*
00093  * Pending data to send when using prepare/transmit functions.
00094  */
00095 static const void *pending_data;
00096 
00097 /*
00098  * The buffer which holds incoming data.
00099  */
00100 unsigned char tr1001_rxbuf[RXBUFSIZE];
00101 
00102 /*
00103  * The length of the packet that currently is being received.
00104  */
00105 static unsigned short tr1001_rxlen = 0;
00106 
00107 /*
00108  * The reception state.
00109  */
00110 volatile unsigned char tr1001_rxstate = RXSTATE_READY;
00111 
00112 static uint16_t rxcrc, rxcrctmp;
00113 
00114 /*
00115  * The structure of the packet header.
00116  */
00117 struct tr1001_hdr {
00118   uint8_t len[2];  /**< The 16-bit length of the packet in network byte
00119                      order. */
00120 };
00121 
00122 /*
00123  * The length of the packet header.
00124  */
00125 #define TR1001_HDRLEN sizeof(struct tr1001_hdr)
00126 
00127 #define OFF 0
00128 #define ON 1
00129 static uint8_t onoroff = OFF;
00130 
00131 #define NUM_SYNCHBYTES 4
00132 
00133 void tr1001_default_rxhandler(unsigned char c);
00134 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char c));
00135 static struct pt rxhandler_pt;
00136 
00137 /*
00138  * This timer is used to keep track of when the last byte was received
00139  * over the radio. If the inter-byte time is too large, the packet
00140  * currently being received is discarded and a new packet reception is
00141  * initiated.
00142  */
00143 static struct timer rxtimer;
00144 
00145 static unsigned short tmp_sstrength, sstrength;
00146 static unsigned short tmp_count;
00147 
00148 #define DEBUG 0
00149 #if DEBUG
00150 #include <stdio.h>
00151 #define LOG(...) printf(__VA_ARGS__)
00152 #else
00153 #define LOG(...)
00154 #endif
00155 
00156 #define GCRLOG(...) /* printf(__VA_ARGS__)*/
00157 
00158 /*---------------------------------------------------------------------------*/
00159 PROCESS(tr1001_process, "TR1001 driver");
00160 /*---------------------------------------------------------------------------*/
00161 
00162 static int prepare_packet(const void *data, unsigned short len);
00163 static int transmit_packet(unsigned short len);
00164 static int receiving_packet(void);
00165 static int pending_packet(void);
00166 static int channel_clear(void);
00167 static int tr1001_on(void);
00168 static int tr1001_off(void);
00169 
00170 const struct radio_driver tr1001_driver = {
00171   tr1001_init,
00172   prepare_packet,
00173   transmit_packet,
00174   tr1001_send,
00175   tr1001_read,
00176   channel_clear,
00177   receiving_packet,
00178   pending_packet,
00179   tr1001_on,
00180   tr1001_off
00181 };
00182 
00183 /*---------------------------------------------------------------------------*/
00184 /*
00185  * Turn on data transmission in On-Off-Keyed mode.
00186  */
00187 static void
00188 txook(void)
00189 {
00190   P3SEL = 0xf0;
00191   P5OUT |= 0x40;
00192   P5OUT &= 0x7f;
00193 }
00194 /*---------------------------------------------------------------------------*/
00195 /*
00196  * Turn on data reception for the radio tranceiver.
00197  */
00198 static void
00199 rxon(void)
00200 {
00201   P3SEL = 0xe0;
00202   P5OUT |= 0xc0;
00203 
00204   /* Enable the receiver. */
00205   ME1 |= URXE0;
00206 
00207   /* Turn on receive interrupt. */
00208   IE1 |= URXIE0;
00209 
00210 }
00211 /*---------------------------------------------------------------------------*/
00212 /*
00213  * Turn off data reception for the radio tranceiver.
00214  */
00215 static void
00216 rxoff(void)
00217 {
00218   P5OUT &= 0x3f;
00219 
00220   /* Disable the receiver. */
00221   ME1 &= ~URXE0;
00222 
00223   /* Turn off receive interrupt. */
00224   IE1 &= ~URXIE0;
00225 }
00226 /*---------------------------------------------------------------------------*/
00227 /*
00228  * Clear the recevie buffer and reset the receiver state.
00229  */
00230 static void
00231 rxclear(void)
00232 {
00233   tr1001_rxstate = RXSTATE_READY;
00234 }
00235 /*---------------------------------------------------------------------------*/
00236 /*
00237  * Turn TR1001 radio transceiver off.
00238  */
00239 /*---------------------------------------------------------------------------*/
00240 static int
00241 tr1001_off(void)
00242 {
00243   if(onoroff == OFF) {
00244     return 1;
00245   }
00246   onoroff = OFF;
00247   rxoff();
00248   rxclear();
00249 
00250   ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
00251   return 1;
00252 }
00253 /*---------------------------------------------------------------------------*/
00254 /*
00255  * Turn TR1001 radio transceiver on.
00256  */
00257 /*---------------------------------------------------------------------------*/
00258 static int
00259 tr1001_on(void)
00260 {
00261   if(onoroff == ON) {
00262     return 1;
00263   }
00264 
00265   ENERGEST_ON(ENERGEST_TYPE_LISTEN);
00266 
00267   onoroff = ON;
00268   rxon();
00269   rxclear();
00270   return 1;
00271 }
00272 /*---------------------------------------------------------------------------*/
00273 /*
00274  * Send a byte of data over the radio.
00275  *
00276  * \param b The byte to be sent.
00277  */
00278 static void
00279 send(unsigned char b)
00280 {
00281   clock_time_t start;
00282 
00283   start = clock_time();
00284 
00285   /* Wait until the USART0 TX buffer is ready. */
00286   while((IFG1 & UTXIFG0) == 0) {
00287     /* Wait no more than one second. */
00288     if((clock_time_t)(clock_time() - start) > (clock_time_t)CLOCK_SECOND) {
00289       break;
00290     }
00291   }
00292 
00293   /* Send the byte. */
00294   TXBUF0 = b;
00295 }
00296 /*---------------------------------------------------------------------------*/
00297 /*
00298  * Send a byte of data and its logical negation (all bits inverted)
00299  * over the radio.
00300  *
00301  * \param b The byte to be sent.
00302  */
00303 static void
00304 sendx(unsigned char b)
00305 {
00306   gcr_encode(b);
00307   GCRLOG("(%02x)", b);
00308 
00309   while(gcr_get_encoded(&b)) {
00310     send(b);
00311     GCRLOG("%02x ", b);
00312   }
00313 }
00314 
00315 static uint16_t
00316 sendx_crc16(unsigned char b, uint16_t crcacc)
00317 {
00318   gcr_encode(b);
00319   GCRLOG("(%02x)", b);
00320   crcacc = crc16_add(b, crcacc);
00321   while(gcr_get_encoded(&b)) {
00322     send(b);
00323     GCRLOG("C%02x ", b);
00324   }
00325   return crcacc;
00326 }
00327 /*---------------------------------------------------------------------------*/
00328 void
00329 tr1001_set_txpower(unsigned char p)
00330 {
00331   int i;
00332 
00333   /* Clamp maximum power. */
00334   if(p > 100) {
00335     p = 100;
00336   }
00337 
00338   /* First, run the potentiometer down to zero so that we know the
00339      start value of the potentiometer. */
00340   P2OUT &= 0xDF;                                /* P25 = 0 (down selected) */
00341   P2OUT &= 0xBF;                                /* P26 = 0 (chipselect on) */
00342   for(i = 0; i < 102; ++i) {
00343     P2OUT &= 0xEF;                              /* P24 = 0 (inc) */
00344     P2OUT |= 0x10;
00345   }
00346 
00347   /* Now, start to increase the value of the potentiometer until it
00348      reaches the desired value.*/
00349 
00350   P2OUT |= 0x20;                                /* P25 = 1 (up selected) */
00351   for(i = 0; i < p; ++i) {
00352     P2OUT &= 0xEF;                              /* P24 = 0 (inc) */
00353     P2OUT |= 0x10;
00354   }
00355   P2OUT |= 0x40;                                /* P26 = 1 (chipselect off) */
00356 }
00357 /*---------------------------------------------------------------------------*/
00358 int
00359 tr1001_init(void)
00360 {
00361   PT_INIT(&rxhandler_pt);
00362 
00363   onoroff = OFF;
00364 
00365   UCTL0 = CHAR;                         /* 8-bit character */
00366   UTCTL0 = SSEL1;                       /* UCLK = SMCLK */
00367 
00368   tr1001_set_speed(TR1001_19200);
00369 
00370   ME1 |= UTXE0 + URXE0;                 /* Enable USART0 TXD/RXD */
00371 
00372   /* Turn on receive interrupt. */
00373   IE1 |= URXIE0;
00374 
00375   timer_set(&rxtimer, CLOCK_SECOND / 4);
00376 
00377 
00378   tr1001_on();
00379   tr1001_set_txpower(100);
00380 
00381   /* Reset reception state. */
00382   rxclear();
00383 
00384   process_start(&tr1001_process, NULL);
00385 
00386   return 1;
00387 }
00388 /*---------------------------------------------------------------------------*/
00389 ISR(UART0RX, tr1001_rxhandler)
00390 {
00391   ENERGEST_ON(ENERGEST_TYPE_IRQ);
00392   tr1001_default_rxhandler_pt(RXBUF0);
00393   if(tr1001_rxstate == RXSTATE_FULL) {
00394     LPM4_EXIT;
00395   }
00396   ENERGEST_OFF(ENERGEST_TYPE_IRQ);
00397 }
00398 /*---------------------------------------------------------------------------*/
00399 #if DEBUG
00400 static void
00401 dump_packet(int len)
00402 {
00403   int i;
00404   for(i = 0; i < len; ++i) {
00405     LOG("%d: 0x%02x\n", i, tr1001_rxbuf[i]);
00406   }
00407 }
00408 #endif /* DEBUG */
00409 /*---------------------------------------------------------------------------*/
00410 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char incoming_byte))
00411 {
00412   static unsigned char rxtmp, tmppos;
00413 
00414   if(timer_expired(&rxtimer) && tr1001_rxstate != RXSTATE_FULL) {
00415     PT_INIT(&rxhandler_pt);
00416   }
00417 
00418   timer_restart(&rxtimer);
00419 
00420   if(tr1001_rxstate == RXSTATE_RECEIVING) {
00421     unsigned short signal = radio_sensor.value(0);
00422     tmp_sstrength += (signal >> 2);
00423     tmp_count++;
00424   }
00425 
00426   PT_BEGIN(&rxhandler_pt);
00427 
00428   while(1) {
00429 
00430     /* Reset reception state. */
00431     rxclear();
00432 
00433     /* Wait until we receive the first syncronization byte. */
00434     PT_WAIT_UNTIL(&rxhandler_pt, incoming_byte == SYNCH1);
00435 
00436     tr1001_rxstate = RXSTATE_RECEIVING;
00437 
00438     /* Read all incoming syncronization bytes. */
00439     PT_WAIT_WHILE(&rxhandler_pt, incoming_byte == SYNCH1);
00440 
00441     /* We should receive the second synch byte by now, otherwise we'll
00442        restart the protothread. */
00443     if(incoming_byte != SYNCH2) {
00444       PT_RESTART(&rxhandler_pt);
00445     }
00446 
00447     /* Start signal strength measurement */
00448     tmp_sstrength = 0;
00449     tmp_count = 0;
00450 
00451     /* Reset the CRC. */
00452     rxcrc = 0xffff;
00453 
00454     gcr_init();
00455     GCRLOG("RECV: ");
00456 
00457     /* Read packet header. */
00458     for(tmppos = 0; tmppos < TR1001_HDRLEN; ++tmppos) {
00459 
00460       /* Wait for the first byte of the packet to arrive. */
00461       do {
00462         PT_YIELD(&rxhandler_pt);
00463         GCRLOG("(%02x) ", incoming_byte);
00464 
00465         gcr_decode(incoming_byte);
00466         /* If the incoming byte isn't a valid GCR encoded byte,
00467            we start again from the beginning. */
00468         if(!gcr_valid()) {
00469           BEEP_BEEP(1000);
00470           LOG("Incorrect GCR in header at byte %d/1 %x\n", tmppos, incoming_byte);
00471           RIMESTATS_ADD(badsynch);
00472           PT_RESTART(&rxhandler_pt);
00473         }
00474       } while(!gcr_get_decoded(&rxtmp));
00475       GCRLOG("%02x ", rxtmp);
00476 
00477       tr1001_rxbuf[tmppos] = rxtmp;
00478       /* Calculate the CRC. */
00479       rxcrc = crc16_add(rxtmp, rxcrc);
00480     }
00481 
00482     /* Since we've got the header, we can grab the length from it. */
00483     tr1001_rxlen = ((((struct tr1001_hdr *)tr1001_rxbuf)->len[0] << 8) +
00484                     ((struct tr1001_hdr *)tr1001_rxbuf)->len[1]);
00485 
00486     /* If the length is longer than we can handle, we'll start from
00487        the beginning. */
00488     if(tmppos + tr1001_rxlen > sizeof(tr1001_rxbuf)) {
00489       RIMESTATS_ADD(toolong);
00490       PT_RESTART(&rxhandler_pt);
00491     }
00492 
00493     /* Read packet data. */
00494     for(; tmppos < tr1001_rxlen + TR1001_HDRLEN; ++tmppos) {
00495 
00496       /* Wait for the first byte of the packet to arrive. */
00497       do {
00498         PT_YIELD(&rxhandler_pt);
00499         GCRLOG("(%02x)", incoming_byte);
00500 
00501         gcr_decode(incoming_byte);
00502         /* If the incoming byte isn't a valid Manchester encoded byte,
00503            we start again from the beinning. */
00504         if(!gcr_valid()) {
00505           BEEP_BEEP(1000);
00506           LOG("Incorrect GCR 0x%02x at byte %d/1\n", incoming_byte,
00507               tmppos - TR1001_HDRLEN);
00508           RIMESTATS_ADD(badsynch);
00509           PT_RESTART(&rxhandler_pt);
00510         }
00511       } while(!gcr_get_decoded(&rxtmp));
00512 
00513       GCRLOG("%02x ", rxtmp);
00514 
00515       tr1001_rxbuf[tmppos] = rxtmp;
00516       /* Calculate the CRC. */
00517       rxcrc = crc16_add(rxtmp, rxcrc);
00518     }
00519 
00520     /* Read the frame CRC. */
00521     for(tmppos = 0; tmppos < 2; ++tmppos) {
00522       do {
00523         PT_YIELD(&rxhandler_pt);
00524         GCRLOG("(%02x)", incoming_byte);
00525 
00526         gcr_decode(incoming_byte);
00527         if(!gcr_valid()) {
00528           BEEP_BEEP(1000);
00529           RIMESTATS_ADD(badsynch);
00530           PT_RESTART(&rxhandler_pt);
00531         }
00532       } while(!gcr_get_decoded(&rxtmp));
00533       GCRLOG("%02x ", rxtmp);
00534 
00535       rxcrctmp = (rxcrctmp << 8) | rxtmp;
00536     }
00537     GCRLOG("\n");
00538 
00539     if(rxcrctmp == rxcrc) {
00540       /* A full packet has been received and the CRC checks out. We'll
00541          request the driver to take care of the incoming data. */
00542 
00543       RIMESTATS_ADD(llrx);
00544       process_poll(&tr1001_process);
00545 
00546       /* We'll set the receive state flag to signal that a full frame
00547          is present in the buffer, and we'll wait until the buffer has
00548          been taken care of. */
00549       tr1001_rxstate = RXSTATE_FULL;
00550       PT_WAIT_UNTIL(&rxhandler_pt, tr1001_rxstate != RXSTATE_FULL);
00551 
00552     } else {
00553       LOG("Incorrect CRC\n");
00554       BEEP_BEEP(1000);
00555       RIMESTATS_ADD(badcrc);
00556     }
00557   }
00558   PT_END(&rxhandler_pt);
00559 }
00560 /*---------------------------------------------------------------------------*/
00561 static int
00562 prepare_packet(const void *data, unsigned short len)
00563 {
00564   pending_data = data;
00565   return 0;
00566 }
00567 /*---------------------------------------------------------------------------*/
00568 static int
00569 transmit_packet(unsigned short len)
00570 {
00571   int ret = RADIO_TX_ERR;
00572   if(pending_data != NULL) {
00573     ret = tr1001_send(pending_data, len);
00574     pending_data = NULL;
00575   }
00576   return ret;
00577 }
00578 /*---------------------------------------------------------------------------*/
00579 int
00580 tr1001_send(const void *packet, unsigned short len)
00581 {
00582   int i;
00583   uint16_t crc16;
00584 
00585   LOG("tr1001_send: sending %d bytes\n", len);
00586 
00587   if(onoroff == ON) {
00588     ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
00589   }
00590   ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
00591 
00592   /* Prepare the transmission. */
00593 
00594   /* Delay the transmission for a short random duration. */
00595   clock_delay(random_rand() & 0x3ff);
00596 
00597 
00598   /* Check that we don't currently are receiving a packet, and if so
00599      we wait until the reception has been completed. Reception is done
00600      with interrupts so it is OK for us to wait in a while() loop. */
00601 
00602   while(tr1001_rxstate == RXSTATE_RECEIVING &&
00603         !timer_expired(&rxtimer)) {
00604     /* Delay the transmission for a short random duration. */
00605     clock_delay(random_rand() & 0x7ff);
00606   }
00607 
00608 
00609   /* Turn on OOK mode with transmission. */
00610   txook();
00611 
00612   /* According to the datasheet, the transmitter must wait for 12 us
00613      in order to settle. Empirical tests show that is it better to
00614      wait for something like 283 us... */
00615   clock_delay(200);
00616 
00617 
00618   /* Transmit preamble and synch bytes. */
00619   for(i = 0; i < 20; ++i) {
00620     send(0xaa);
00621   }
00622   /*  send(0xaa);
00623       send(0xaa);*/
00624   send(0xff);
00625 
00626   for(i = 0; i < NUM_SYNCHBYTES; ++i) {
00627     send(SYNCH1);
00628   }
00629   send(SYNCH2);
00630 
00631   crc16 = 0xffff;
00632 
00633   gcr_init();
00634 
00635   GCRLOG("SEND: ");
00636 
00637   /* Send packet header. */
00638   crc16 = sendx_crc16(len >> 8, crc16);
00639   crc16 = sendx_crc16(len & 0xff, crc16);
00640 
00641   /* Send packet data. */
00642   for(i = 0; i < len; ++i) {
00643     crc16 = sendx_crc16(((uint8_t *)packet)[i], crc16);
00644   }
00645 
00646   /* Send CRC */
00647   sendx(crc16 >> 8);
00648   sendx(crc16 & 0xff);
00649 
00650   /* if not encoding has sent all bytes - let it send another GCR specific */
00651   if (!gcr_finished()) {
00652     sendx(0);
00653   }
00654 
00655   GCRLOG("\n");
00656 
00657   /* Send trailing bytes. */
00658   send(0x33);
00659   send(0xcc);
00660   send(0x33);
00661   send(0xcc);
00662 
00663   /* Turn on (or off) reception again. */
00664   if(onoroff == ON) {
00665     ENERGEST_ON(ENERGEST_TYPE_LISTEN);
00666     rxon();
00667     rxclear();
00668   } else {
00669     rxoff();
00670     rxclear();
00671   }
00672 
00673   ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
00674   RIMESTATS_ADD(lltx);
00675 
00676   return RADIO_TX_OK;
00677 }
00678 /*---------------------------------------------------------------------------*/
00679 int
00680 tr1001_read(void *buf, unsigned short bufsize)
00681 {
00682   unsigned short tmplen;
00683 
00684   if(tr1001_rxstate == RXSTATE_FULL) {
00685 
00686 #if DEBUG
00687     dump_packet(tr1001_rxlen + 2);
00688 #endif /* DEBUG */
00689 
00690     tmplen = tr1001_rxlen;
00691 
00692     if(tmplen > bufsize) {
00693       LOG("tr1001_read: too large packet: %d/%d bytes\n", tmplen, bufsize);
00694       rxclear();
00695       RIMESTATS_ADD(toolong);
00696       return -1;
00697     }
00698 
00699     memcpy(buf, &tr1001_rxbuf[TR1001_HDRLEN], tmplen);
00700 
00701     /* header + content + CRC */
00702     sstrength = (tmp_count ? ((tmp_sstrength / tmp_count) << 2) : 0);
00703 
00704     rxclear();
00705 
00706     LOG("tr1001_read: got %d bytes\n", tmplen);
00707 
00708     return tmplen;
00709   }
00710   return 0;
00711 }
00712 /*---------------------------------------------------------------------------*/
00713 static int
00714 receiving_packet(void)
00715 {
00716   return tr1001_rxstate == RXSTATE_RECEIVING &&
00717     !timer_expired(&rxtimer);
00718 }
00719 /*---------------------------------------------------------------------------*/
00720 static int
00721 pending_packet(void)
00722 {
00723   return tr1001_rxstate == RXSTATE_FULL;
00724 }
00725 /*---------------------------------------------------------------------------*/
00726 static int
00727 channel_clear(void)
00728 {
00729   /* TODO add CCA functionality */
00730   return 0;
00731 }
00732 /*---------------------------------------------------------------------------*/
00733 PROCESS_THREAD(tr1001_process, ev, data)
00734 {
00735   int len;
00736   PROCESS_BEGIN();
00737 
00738   /* Reset reception state now that the process is ready to receive data. */
00739   rxclear();
00740 
00741   while(1) {
00742     PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
00743     packetbuf_clear();
00744     len = tr1001_read(packetbuf_dataptr(), PACKETBUF_SIZE);
00745     if(len > 0) {
00746       packetbuf_set_datalen(len);
00747       NETSTACK_RDC.input();
00748     }
00749   }
00750 
00751   PROCESS_END();
00752 }
00753 /*---------------------------------------------------------------------------*/
00754 void
00755 tr1001_set_speed(unsigned char speed)
00756 {
00757 
00758   if(speed == TR1001_19200) {
00759     /* Set TR1001 to 19200 */
00760     UBR00 = 0x80;                         /* 2,457MHz/19200 = 128 -> 0x80 */
00761     UBR10 = 0x00;                         /* */
00762     UMCTL0 = 0x00;                        /* no modulation  */
00763   } else if(speed == TR1001_38400) {
00764     /* Set TR1001 to 38400 */
00765     UBR00 = 0x40;                         /* 2,457MHz/38400 = 64 -> 0x40 */
00766     UBR10 = 0x00;                         /* */
00767     UMCTL0 = 0x00;                        /* no modulation  */
00768   } else if(speed == TR1001_57600) {
00769     UBR00 = 0x2a;                         /* 2,457MHz/57600 = 42.7 -> 0x2A */
00770     UBR10 = 0x00;                         /* */
00771     UMCTL0 = 0x5b;                        /* */
00772   } else if(speed == TR1001_115200) {
00773     UBR00 = 0x15;                         /* 2,457MHz/115200 = 21.4 -> 0x15 */
00774     UBR10 = 0x00;                         /* */
00775     UMCTL0 = 0x4a;                        /* */
00776   } else {
00777     tr1001_set_speed(TR1001_19200);
00778   }
00779 }
00780 /*---------------------------------------------------------------------------*/
00781 unsigned short
00782 tr1001_sstrength(void)
00783 {
00784   return sstrength;
00785 }
00786 /*---------------------------------------------------------------------------*/
00787 /** @} */
00788 /** @} */