Contiki 2.6

tr1001.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.c,v 1.13 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/me.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 /*---------------------------------------------------------------------------*/
00157 PROCESS(tr1001_process, "TR1001 driver");
00158 /*---------------------------------------------------------------------------*/
00159 
00160 static int prepare_packet(const void *data, unsigned short len);
00161 static int transmit_packet(unsigned short len);
00162 static int receiving_packet(void);
00163 static int pending_packet(void);
00164 static int channel_clear(void);
00165 static int tr1001_on(void);
00166 static int tr1001_off(void);
00167 
00168 const struct radio_driver tr1001_driver = {
00169   tr1001_init,
00170   prepare_packet,
00171   transmit_packet,
00172   tr1001_send,
00173   tr1001_read,
00174   channel_clear,
00175   receiving_packet,
00176   pending_packet,
00177   tr1001_on,
00178   tr1001_off
00179 };
00180 
00181 /*---------------------------------------------------------------------------*/
00182 /*
00183  * Turn on data transmission in On-Off-Keyed mode.
00184  */
00185 static void
00186 txook(void)
00187 {
00188   P3SEL = 0xf0;
00189   P5OUT |= 0x40;
00190   P5OUT &= 0x7f;
00191 }
00192 /*---------------------------------------------------------------------------*/
00193 /*
00194  * Turn on data reception for the radio tranceiver.
00195  */
00196 static void
00197 rxon(void)
00198 {
00199   P3SEL = 0xe0;
00200   P5OUT |= 0xc0;
00201 
00202   /* Enable the receiver. */
00203   ME1 |= URXE0;
00204 
00205   /* Turn on receive interrupt. */
00206   IE1 |= URXIE0;
00207 
00208 }
00209 /*---------------------------------------------------------------------------*/
00210 /*
00211  * Turn off data reception for the radio tranceiver.
00212  */
00213 static void
00214 rxoff(void)
00215 {
00216   P5OUT &= 0x3f;
00217 
00218   /* Disable the receiver. */
00219   ME1 &= ~URXE0;
00220 
00221   /* Turn off receive interrupt. */
00222   IE1 &= ~URXIE0;
00223 }
00224 /*---------------------------------------------------------------------------*/
00225 /*
00226  * Clear the recevie buffer and reset the receiver state.
00227  */
00228 static void
00229 rxclear(void)
00230 {
00231   tr1001_rxstate = RXSTATE_READY;
00232 }
00233 /*---------------------------------------------------------------------------*/
00234 /*
00235  * Turn TR1001 radio transceiver off.
00236  */
00237 /*---------------------------------------------------------------------------*/
00238 static int
00239 tr1001_off(void)
00240 {
00241   if(onoroff == OFF) {
00242     return 1;
00243   }
00244   onoroff = OFF;
00245   rxoff();
00246   rxclear();
00247 
00248   ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
00249   return 1;
00250 }
00251 /*---------------------------------------------------------------------------*/
00252 /*
00253  * Turn TR1001 radio transceiver on.
00254  */
00255 /*---------------------------------------------------------------------------*/
00256 static int
00257 tr1001_on(void)
00258 {
00259   if(onoroff == ON) {
00260     return 1;
00261   }
00262 
00263   ENERGEST_ON(ENERGEST_TYPE_LISTEN);
00264 
00265   onoroff = ON;
00266   rxon();
00267   rxclear();
00268   return 1;
00269 }
00270 /*---------------------------------------------------------------------------*/
00271 /*
00272  * Send a byte of data over the radio.
00273  *
00274  * \param b The byte to be sent.
00275  */
00276 static void
00277 send(unsigned char b)
00278 {
00279   clock_time_t start;
00280 
00281   start = clock_time();
00282 
00283   /* Wait until the USART0 TX buffer is ready. */
00284   while((IFG1 & UTXIFG0) == 0) {
00285     /* Wait no more than one second. */
00286     if((clock_time_t)(clock_time() - start) > (clock_time_t)CLOCK_SECOND) {
00287       break;
00288     }
00289   }
00290 
00291   /* Send the byte. */
00292   TXBUF0 = b;
00293 }
00294 /*---------------------------------------------------------------------------*/
00295 /*
00296  * Send a byte of data and its logical negation (all bits inverted)
00297  * over the radio.
00298  *
00299  * \param b The byte to be sent.
00300  */
00301 static void
00302 send2(unsigned char b)
00303 {
00304   uint16_t m;
00305   m = me_encode(b);
00306   send(m >> 8);
00307   send(m & 0xff);
00308 }
00309 static uint16_t
00310 send2_crc16(unsigned char b, uint16_t crcacc)
00311 {
00312   uint16_t m;
00313   m = me_encode(b);
00314   send(m >> 8);
00315   send(m & 0xff);
00316   return crc16_add(b, crcacc);
00317 }
00318 /*---------------------------------------------------------------------------*/
00319 void
00320 tr1001_set_txpower(unsigned char p)
00321 {
00322   int i;
00323 
00324   /* Clamp maximum power. */
00325   if(p > 100) {
00326     p = 100;
00327   }
00328 
00329   /* First, run the potentiometer down to zero so that we know the
00330      start value of the potentiometer. */
00331   P2OUT &= 0xDF;                                /* P25 = 0 (down selected) */
00332   P2OUT &= 0xBF;                                /* P26 = 0 (chipselect on) */
00333   for(i = 0; i < 102; ++i) {
00334     P2OUT &= 0xEF;                              /* P24 = 0 (inc) */
00335     P2OUT |= 0x10;
00336   }
00337 
00338   /* Now, start to increase the value of the potentiometer until it
00339      reaches the desired value.*/
00340 
00341   P2OUT |= 0x20;                                /* P25 = 1 (up selected) */
00342   for(i = 0; i < p; ++i) {
00343     P2OUT &= 0xEF;                              /* P24 = 0 (inc) */
00344     P2OUT |= 0x10;
00345   }
00346   P2OUT |= 0x40;                                /* P26 = 1 (chipselect off) */
00347 }
00348 /*---------------------------------------------------------------------------*/
00349 int
00350 tr1001_init(void)
00351 {
00352   PT_INIT(&rxhandler_pt);
00353 
00354   onoroff = OFF;
00355 
00356   UCTL0 = CHAR;                         /* 8-bit character */
00357   UTCTL0 = SSEL1;                       /* UCLK = SMCLK */
00358 
00359   tr1001_set_speed(TR1001_19200);
00360 
00361   ME1 |= UTXE0 + URXE0;                 /* Enable USART0 TXD/RXD */
00362 
00363   /* Turn on receive interrupt. */
00364   IE1 |= URXIE0;
00365 
00366   timer_set(&rxtimer, CLOCK_SECOND / 4);
00367 
00368 
00369   tr1001_on();
00370   tr1001_set_txpower(100);
00371 
00372   /* Reset reception state. */
00373   rxclear();
00374 
00375   process_start(&tr1001_process, NULL);
00376 
00377   return 1;
00378 }
00379 /*---------------------------------------------------------------------------*/
00380 ISR(UART0RX, tr1001_rxhandler)
00381 {
00382   ENERGEST_ON(ENERGEST_TYPE_IRQ);
00383   tr1001_default_rxhandler_pt(RXBUF0);
00384   if(tr1001_rxstate == RXSTATE_FULL) {
00385     LPM4_EXIT;
00386   }
00387   ENERGEST_OFF(ENERGEST_TYPE_IRQ);
00388 }
00389 /*---------------------------------------------------------------------------*/
00390 #if DEBUG
00391 static void
00392 dump_packet(int len)
00393 {
00394   int i;
00395   for(i = 0; i < len; ++i) {
00396     LOG("%d: 0x%02x\n", i, tr1001_rxbuf[i]);
00397   }
00398 }
00399 #endif /* DEBUG */
00400 /*---------------------------------------------------------------------------*/
00401 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char incoming_byte))
00402 {
00403   static unsigned char rxtmp, tmppos;
00404 
00405   if(timer_expired(&rxtimer) && tr1001_rxstate != RXSTATE_FULL) {
00406     PT_INIT(&rxhandler_pt);
00407   }
00408 
00409   timer_restart(&rxtimer);
00410 
00411   if(tr1001_rxstate == RXSTATE_RECEIVING) {
00412     unsigned short signal = radio_sensor.value(0);
00413     tmp_sstrength += (signal >> 2);
00414     tmp_count++;
00415   }
00416 
00417   PT_BEGIN(&rxhandler_pt);
00418 
00419   while(1) {
00420 
00421     /* Reset reception state. */
00422     rxclear();
00423 
00424     /* Wait until we receive the first syncronization byte. */
00425     PT_WAIT_UNTIL(&rxhandler_pt, incoming_byte == SYNCH1);
00426 
00427     tr1001_rxstate = RXSTATE_RECEIVING;
00428 
00429     /* Read all incoming syncronization bytes. */
00430     PT_WAIT_WHILE(&rxhandler_pt, incoming_byte == SYNCH1);
00431 
00432     /* We should receive the second synch byte by now, otherwise we'll
00433        restart the protothread. */
00434     if(incoming_byte != SYNCH2) {
00435       PT_RESTART(&rxhandler_pt);
00436     }
00437 
00438     /* Start signal strength measurement */
00439     tmp_sstrength = 0;
00440     tmp_count = 0;
00441 
00442     /* Reset the CRC. */
00443     rxcrc = 0xffff;
00444 
00445     /* Read packet header. */
00446     for(tmppos = 0; tmppos < TR1001_HDRLEN; ++tmppos) {
00447 
00448       /* Wait for the first byte of the packet to arrive. */
00449       PT_YIELD(&rxhandler_pt);
00450 
00451       /* If the incoming byte isn't a valid Manchester encoded byte,
00452          we start again from the beginning. */
00453       if(!me_valid(incoming_byte)) {
00454         BEEP_BEEP(1000);
00455         LOG("Incorrect manchester in header at byte %d/1\n", tmppos);
00456         RIMESTATS_ADD(badsynch);
00457         PT_RESTART(&rxhandler_pt);
00458       }
00459 
00460       rxtmp = me_decode8(incoming_byte);
00461 
00462       /* Wait for the next byte to arrive. */
00463       PT_YIELD(&rxhandler_pt);
00464 
00465       if(!me_valid(incoming_byte)) {
00466         BEEP_BEEP(1000);
00467         LOG("Incorrect manchester in header at byte %d/2\n", tmppos);
00468         RIMESTATS_ADD(badsynch);
00469         PT_RESTART(&rxhandler_pt);
00470       }
00471 
00472       /* Put together the two bytes into a single Manchester decoded
00473          byte. */
00474 
00475       tr1001_rxbuf[tmppos] = (rxtmp << 4) | me_decode8(incoming_byte);
00476 
00477       /* Calculate the CRC. */
00478       rxcrc = crc16_add(tr1001_rxbuf[tmppos], rxcrc);
00479 
00480 
00481     }
00482 
00483     /* Since we've got the header, we can grab the length from it. */
00484     tr1001_rxlen = ((((struct tr1001_hdr *)tr1001_rxbuf)->len[0] << 8) +
00485                     ((struct tr1001_hdr *)tr1001_rxbuf)->len[1]);
00486 
00487     /* If the length is longer than we can handle, we'll start from
00488        the beginning. */
00489     if(tmppos + tr1001_rxlen > sizeof(tr1001_rxbuf)) {
00490       RIMESTATS_ADD(toolong);
00491       PT_RESTART(&rxhandler_pt);
00492     }
00493 
00494     /* Read packet data. */
00495     for(; tmppos < tr1001_rxlen + TR1001_HDRLEN; ++tmppos) {
00496       PT_YIELD(&rxhandler_pt);
00497 
00498       if(!me_valid(incoming_byte)) {
00499         LOG("Incorrect manchester 0x%02x at byte %d/1\n", incoming_byte,
00500             tmppos - TR1001_HDRLEN);
00501         BEEP_BEEP(1000);
00502         RIMESTATS_ADD(badsynch);
00503         PT_RESTART(&rxhandler_pt);
00504       }
00505 
00506       rxtmp = me_decode8(incoming_byte);
00507 
00508       PT_YIELD(&rxhandler_pt);
00509 
00510       if(!me_valid(incoming_byte)) {
00511         LOG("Incorrect manchester at byte %d/2\n", tmppos - TR1001_HDRLEN);
00512         BEEP_BEEP(1000);
00513         RIMESTATS_ADD(badsynch);
00514         PT_RESTART(&rxhandler_pt);
00515       }
00516 
00517       tr1001_rxbuf[tmppos] = (rxtmp << 4) | me_decode8(incoming_byte);
00518       rxcrc = crc16_add(tr1001_rxbuf[tmppos], rxcrc);
00519 
00520     }
00521 
00522     /* Read the frame CRC. */
00523     for(tmppos = 0; tmppos < 4; ++tmppos) {
00524 
00525       PT_YIELD(&rxhandler_pt);
00526 
00527       if(!me_valid(incoming_byte)) {
00528         BEEP_BEEP(1000);
00529         RIMESTATS_ADD(badsynch);
00530         PT_RESTART(&rxhandler_pt);
00531       }
00532 
00533       rxcrctmp = (rxcrctmp << 4) | me_decode8(incoming_byte);
00534     }
00535 
00536     if(rxcrctmp == rxcrc) {
00537       /* A full packet has been received and the CRC checks out. We'll
00538          request the driver to take care of the incoming data. */
00539 
00540       RIMESTATS_ADD(llrx);
00541       process_poll(&tr1001_process);
00542 
00543       /* We'll set the receive state flag to signal that a full frame
00544          is present in the buffer, and we'll wait until the buffer has
00545          been taken care of. */
00546       tr1001_rxstate = RXSTATE_FULL;
00547       PT_WAIT_UNTIL(&rxhandler_pt, tr1001_rxstate != RXSTATE_FULL);
00548 
00549     } else {
00550       LOG("Incorrect CRC\n");
00551       BEEP_BEEP(1000);
00552       RIMESTATS_ADD(badcrc);
00553     }
00554   }
00555   PT_END(&rxhandler_pt);
00556 }
00557 /*---------------------------------------------------------------------------*/
00558 static int
00559 prepare_packet(const void *data, unsigned short len)
00560 {
00561   pending_data = data;
00562   return 0;
00563 }
00564 /*---------------------------------------------------------------------------*/
00565 static int
00566 transmit_packet(unsigned short len)
00567 {
00568   int ret = RADIO_TX_ERR;
00569   if(pending_data != NULL) {
00570     ret = tr1001_send(pending_data, len);
00571     pending_data = NULL;
00572   }
00573   return ret;
00574 }
00575 /*---------------------------------------------------------------------------*/
00576 int
00577 tr1001_send(const void *packet, unsigned short len)
00578 {
00579   int i;
00580   uint16_t crc16;
00581 
00582   LOG("tr1001_send: sending %d bytes\n", len);
00583 
00584   if(onoroff == ON) {
00585     ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
00586   }
00587   ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
00588 
00589   /* Prepare the transmission. */
00590 
00591   /* Delay the transmission for a short random duration. */
00592   clock_delay(random_rand() & 0x3ff);
00593 
00594 
00595   /* Check that we don't currently are receiving a packet, and if so
00596      we wait until the reception has been completed. Reception is done
00597      with interrupts so it is OK for us to wait in a while() loop. */
00598 
00599   while(tr1001_rxstate == RXSTATE_RECEIVING &&
00600         !timer_expired(&rxtimer)) {
00601     /* Delay the transmission for a short random duration. */
00602     clock_delay(random_rand() & 0x7ff);
00603   }
00604 
00605 
00606   /* Turn on OOK mode with transmission. */
00607   txook();
00608 
00609   /* According to the datasheet, the transmitter must wait for 12 us
00610      in order to settle. Empirical tests show that is it better to
00611      wait for something like 283 us... */
00612   clock_delay(200);
00613 
00614 
00615   /* Transmit preamble and synch bytes. */
00616   for(i = 0; i < 20; ++i) {
00617     send(0xaa);
00618   }
00619   /*  send(0xaa);
00620       send(0xaa);*/
00621   send(0xff);
00622 
00623   for(i = 0; i < NUM_SYNCHBYTES; ++i) {
00624     send(SYNCH1);
00625   }
00626   send(SYNCH2);
00627 
00628   crc16 = 0xffff;
00629 
00630   /* Send packet header. */
00631   crc16 = send2_crc16(len >> 8, crc16);
00632   crc16 = send2_crc16(len & 0xff, crc16);
00633 
00634   /* Send packet data. */
00635   for(i = 0; i < len; ++i) {
00636     crc16 = send2_crc16(((uint8_t *)packet)[i], crc16);
00637   }
00638 
00639   /* Send CRC */
00640   send2(crc16 >> 8);
00641   send2(crc16 & 0xff);
00642 
00643   /* Send trailing bytes. */
00644   send(0x33);
00645   send(0xcc);
00646   send(0x33);
00647   send(0xcc);
00648 
00649   /* Turn on (or off) reception again. */
00650   if(onoroff == ON) {
00651     ENERGEST_ON(ENERGEST_TYPE_LISTEN);
00652     rxon();
00653     rxclear();
00654   } else {
00655     rxoff();
00656     rxclear();
00657   }
00658 
00659   ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
00660   RIMESTATS_ADD(lltx);
00661 
00662   return RADIO_TX_OK;
00663 }
00664 /*---------------------------------------------------------------------------*/
00665 int
00666 tr1001_read(void *buf, unsigned short bufsize)
00667 {
00668   unsigned short tmplen;
00669 
00670   if(tr1001_rxstate == RXSTATE_FULL) {
00671 
00672 #if DEBUG
00673     dump_packet(tr1001_rxlen + 2);
00674 #endif /* DEBUG */
00675 
00676     tmplen = tr1001_rxlen;
00677 
00678     if(tmplen > bufsize) {
00679       LOG("tr1001_read: too large packet: %d/%d bytes\n", tmplen, bufsize);
00680       rxclear();
00681       RIMESTATS_ADD(toolong);
00682       return -1;
00683     }
00684 
00685     memcpy(buf, &tr1001_rxbuf[TR1001_HDRLEN], tmplen);
00686 
00687     /* header + content + CRC */
00688     sstrength = (tmp_count ? ((tmp_sstrength / tmp_count) << 2) : 0);
00689 
00690     rxclear();
00691 
00692     LOG("tr1001_read: got %d bytes\n", tmplen);
00693 
00694     return tmplen;
00695   }
00696   return 0;
00697 }
00698 /*---------------------------------------------------------------------------*/
00699 static int
00700 receiving_packet(void)
00701 {
00702   return tr1001_rxstate == RXSTATE_RECEIVING &&
00703     !timer_expired(&rxtimer);
00704 }
00705 /*---------------------------------------------------------------------------*/
00706 static int
00707 pending_packet(void)
00708 {
00709   return tr1001_rxstate == RXSTATE_FULL;
00710 }
00711 /*---------------------------------------------------------------------------*/
00712 static int
00713 channel_clear(void)
00714 {
00715   /* TODO add CCA functionality */
00716   return 0;
00717 }
00718 /*---------------------------------------------------------------------------*/
00719 PROCESS_THREAD(tr1001_process, ev, data)
00720 {
00721   int len;
00722   PROCESS_BEGIN();
00723 
00724   /* Reset reception state now that the process is ready to receive data. */
00725   rxclear();
00726 
00727   while(1) {
00728     PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
00729     packetbuf_clear();
00730     len = tr1001_read(packetbuf_dataptr(), PACKETBUF_SIZE);
00731     if(len > 0) {
00732       packetbuf_set_datalen(len);
00733       NETSTACK_RDC.input();
00734     }
00735   }
00736 
00737   PROCESS_END();
00738 }
00739 /*---------------------------------------------------------------------------*/
00740 void
00741 tr1001_set_speed(unsigned char speed)
00742 {
00743 
00744   if(speed == TR1001_19200) {
00745     /* Set TR1001 to 19200 */
00746     UBR00 = 0x80;                         /* 2,457MHz/19200 = 128 -> 0x80 */
00747     UBR10 = 0x00;                         /* */
00748     UMCTL0 = 0x00;                        /* no modulation  */
00749   } else if(speed == TR1001_38400) {
00750     /* Set TR1001 to 38400 */
00751     UBR00 = 0x40;                         /* 2,457MHz/38400 = 64 -> 0x40 */
00752     UBR10 = 0x00;                         /* */
00753     UMCTL0 = 0x00;                        /* no modulation  */
00754   } else if(speed == TR1001_57600) {
00755     UBR00 = 0x2a;                         /* 2,457MHz/57600 = 42.7 -> 0x2A */
00756     UBR10 = 0x00;                         /* */
00757     UMCTL0 = 0x5b;                        /* */
00758   } else if(speed == TR1001_115200) {
00759     UBR00 = 0x15;                         /* 2,457MHz/115200 = 21.4 -> 0x15 */
00760     UBR10 = 0x00;                         /* */
00761     UMCTL0 = 0x4a;                        /* */
00762   } else {
00763     tr1001_set_speed(TR1001_19200);
00764   }
00765 }
00766 /*---------------------------------------------------------------------------*/
00767 unsigned short
00768 tr1001_sstrength(void)
00769 {
00770   return sstrength;
00771 }
00772 /*---------------------------------------------------------------------------*/
00773 /** @} */
00774 /** @} */