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-esb.h"
00054 
00055 #include "dev/tr1001.h"
00056 #include "dev/radio-sensor.h"
00057 #include "lib/me.h"
00058 #include "lib/crc16.h"
00059 #include "net/netstack.h"
00060 #include "net/rime/rimestats.h"
00061 
00062 #include <io.h>
00063 #include <signal.h>
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 interrupt (UART0RX_VECTOR)
00381      tr1001_rxhandler(void)
00382 {
00383   ENERGEST_ON(ENERGEST_TYPE_IRQ);
00384   tr1001_default_rxhandler_pt(RXBUF0);
00385   if(tr1001_rxstate == RXSTATE_FULL) {
00386     LPM4_EXIT;
00387   }
00388   ENERGEST_OFF(ENERGEST_TYPE_IRQ);
00389 }
00390 /*---------------------------------------------------------------------------*/
00391 #if DEBUG
00392 static void
00393 dump_packet(int len)
00394 {
00395   int i;
00396   for(i = 0; i < len; ++i) {
00397     LOG("%d: 0x%02x\n", i, tr1001_rxbuf[i]);
00398   }
00399 }
00400 #endif /* DEBUG */
00401 /*---------------------------------------------------------------------------*/
00402 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char incoming_byte))
00403 {
00404   static unsigned char rxtmp, tmppos;
00405 
00406   if(timer_expired(&rxtimer) && tr1001_rxstate != RXSTATE_FULL) {
00407     PT_INIT(&rxhandler_pt);
00408   }
00409 
00410   timer_restart(&rxtimer);
00411 
00412   if(tr1001_rxstate == RXSTATE_RECEIVING) {
00413     unsigned short signal = radio_sensor.value(0);
00414     tmp_sstrength += (signal >> 2);
00415     tmp_count++;
00416   }
00417 
00418   PT_BEGIN(&rxhandler_pt);
00419 
00420   while(1) {
00421 
00422     /* Reset reception state. */
00423     rxclear();
00424 
00425     /* Wait until we receive the first syncronization byte. */
00426     PT_WAIT_UNTIL(&rxhandler_pt, incoming_byte == SYNCH1);
00427 
00428     tr1001_rxstate = RXSTATE_RECEIVING;
00429 
00430     /* Read all incoming syncronization bytes. */
00431     PT_WAIT_WHILE(&rxhandler_pt, incoming_byte == SYNCH1);
00432 
00433     /* We should receive the second synch byte by now, otherwise we'll
00434        restart the protothread. */
00435     if(incoming_byte != SYNCH2) {
00436       PT_RESTART(&rxhandler_pt);
00437     }
00438 
00439     /* Start signal strength measurement */
00440     tmp_sstrength = 0;
00441     tmp_count = 0;
00442 
00443     /* Reset the CRC. */
00444     rxcrc = 0xffff;
00445 
00446     /* Read packet header. */
00447     for(tmppos = 0; tmppos < TR1001_HDRLEN; ++tmppos) {
00448 
00449       /* Wait for the first byte of the packet to arrive. */
00450       PT_YIELD(&rxhandler_pt);
00451 
00452       /* If the incoming byte isn't a valid Manchester encoded byte,
00453          we start again from the beginning. */
00454       if(!me_valid(incoming_byte)) {
00455         BEEP_BEEP(1000);
00456         LOG("Incorrect manchester in header at byte %d/1\n", tmppos);
00457         RIMESTATS_ADD(badsynch);
00458         PT_RESTART(&rxhandler_pt);
00459       }
00460 
00461       rxtmp = me_decode8(incoming_byte);
00462 
00463       /* Wait for the next byte to arrive. */
00464       PT_YIELD(&rxhandler_pt);
00465 
00466       if(!me_valid(incoming_byte)) {
00467         BEEP_BEEP(1000);
00468         LOG("Incorrect manchester in header at byte %d/2\n", tmppos);
00469         RIMESTATS_ADD(badsynch);
00470         PT_RESTART(&rxhandler_pt);
00471       }
00472 
00473       /* Put together the two bytes into a single Manchester decoded
00474          byte. */
00475 
00476       tr1001_rxbuf[tmppos] = (rxtmp << 4) | me_decode8(incoming_byte);
00477 
00478       /* Calculate the CRC. */
00479       rxcrc = crc16_add(tr1001_rxbuf[tmppos], rxcrc);
00480 
00481 
00482     }
00483 
00484     /* Since we've got the header, we can grab the length from it. */
00485     tr1001_rxlen = ((((struct tr1001_hdr *)tr1001_rxbuf)->len[0] << 8) +
00486                     ((struct tr1001_hdr *)tr1001_rxbuf)->len[1]);
00487 
00488     /* If the length is longer than we can handle, we'll start from
00489        the beginning. */
00490     if(tmppos + tr1001_rxlen > sizeof(tr1001_rxbuf)) {
00491       RIMESTATS_ADD(toolong);
00492       PT_RESTART(&rxhandler_pt);
00493     }
00494 
00495     /* Read packet data. */
00496     for(; tmppos < tr1001_rxlen + TR1001_HDRLEN; ++tmppos) {
00497       PT_YIELD(&rxhandler_pt);
00498 
00499       if(!me_valid(incoming_byte)) {
00500         LOG("Incorrect manchester 0x%02x at byte %d/1\n", incoming_byte,
00501             tmppos - TR1001_HDRLEN);
00502         BEEP_BEEP(1000);
00503         RIMESTATS_ADD(badsynch);
00504         PT_RESTART(&rxhandler_pt);
00505       }
00506 
00507       rxtmp = me_decode8(incoming_byte);
00508 
00509       PT_YIELD(&rxhandler_pt);
00510 
00511       if(!me_valid(incoming_byte)) {
00512         LOG("Incorrect manchester at byte %d/2\n", tmppos - TR1001_HDRLEN);
00513         BEEP_BEEP(1000);
00514         RIMESTATS_ADD(badsynch);
00515         PT_RESTART(&rxhandler_pt);
00516       }
00517 
00518       tr1001_rxbuf[tmppos] = (rxtmp << 4) | me_decode8(incoming_byte);
00519       rxcrc = crc16_add(tr1001_rxbuf[tmppos], rxcrc);
00520 
00521     }
00522 
00523     /* Read the frame CRC. */
00524     for(tmppos = 0; tmppos < 4; ++tmppos) {
00525 
00526       PT_YIELD(&rxhandler_pt);
00527 
00528       if(!me_valid(incoming_byte)) {
00529         BEEP_BEEP(1000);
00530         RIMESTATS_ADD(badsynch);
00531         PT_RESTART(&rxhandler_pt);
00532       }
00533 
00534       rxcrctmp = (rxcrctmp << 4) | me_decode8(incoming_byte);
00535     }
00536 
00537     if(rxcrctmp == rxcrc) {
00538       /* A full packet has been received and the CRC checks out. We'll
00539          request the driver to take care of the incoming data. */
00540 
00541       RIMESTATS_ADD(llrx);
00542       process_poll(&tr1001_process);
00543 
00544       /* We'll set the receive state flag to signal that a full frame
00545          is present in the buffer, and we'll wait until the buffer has
00546          been taken care of. */
00547       tr1001_rxstate = RXSTATE_FULL;
00548       PT_WAIT_UNTIL(&rxhandler_pt, tr1001_rxstate != RXSTATE_FULL);
00549 
00550     } else {
00551       LOG("Incorrect CRC\n");
00552       BEEP_BEEP(1000);
00553       RIMESTATS_ADD(badcrc);
00554     }
00555   }
00556   PT_END(&rxhandler_pt);
00557 }
00558 /*---------------------------------------------------------------------------*/
00559 static int
00560 prepare_packet(const void *data, unsigned short len)
00561 {
00562   pending_data = data;
00563   return 0;
00564 }
00565 /*---------------------------------------------------------------------------*/
00566 static int
00567 transmit_packet(unsigned short len)
00568 {
00569   int ret = RADIO_TX_ERR;
00570   if(pending_data != NULL) {
00571     ret = tr1001_send(pending_data, len);
00572     pending_data = NULL;
00573   }
00574   return ret;
00575 }
00576 /*---------------------------------------------------------------------------*/
00577 int
00578 tr1001_send(const void *packet, unsigned short len)
00579 {
00580   int i;
00581   uint16_t crc16;
00582 
00583   LOG("tr1001_send: sending %d bytes\n", len);
00584 
00585   if(onoroff == ON) {
00586     ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
00587   }
00588   ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
00589 
00590   /* Prepare the transmission. */
00591 
00592   /* Delay the transmission for a short random duration. */
00593   clock_delay(random_rand() & 0x3ff);
00594 
00595 
00596   /* Check that we don't currently are receiving a packet, and if so
00597      we wait until the reception has been completed. Reception is done
00598      with interrupts so it is OK for us to wait in a while() loop. */
00599 
00600   while(tr1001_rxstate == RXSTATE_RECEIVING &&
00601         !timer_expired(&rxtimer)) {
00602     /* Delay the transmission for a short random duration. */
00603     clock_delay(random_rand() & 0x7ff);
00604   }
00605 
00606 
00607   /* Turn on OOK mode with transmission. */
00608   txook();
00609 
00610   /* According to the datasheet, the transmitter must wait for 12 us
00611      in order to settle. Empirical tests show that is it better to
00612      wait for something like 283 us... */
00613   clock_delay(200);
00614 
00615 
00616   /* Transmit preamble and synch bytes. */
00617   for(i = 0; i < 20; ++i) {
00618     send(0xaa);
00619   }
00620   /*  send(0xaa);
00621       send(0xaa);*/
00622   send(0xff);
00623 
00624   for(i = 0; i < NUM_SYNCHBYTES; ++i) {
00625     send(SYNCH1);
00626   }
00627   send(SYNCH2);
00628 
00629   crc16 = 0xffff;
00630 
00631   /* Send packet header. */
00632   crc16 = send2_crc16(len >> 8, crc16);
00633   crc16 = send2_crc16(len & 0xff, crc16);
00634 
00635   /* Send packet data. */
00636   for(i = 0; i < len; ++i) {
00637     crc16 = send2_crc16(((uint8_t *)packet)[i], crc16);
00638   }
00639 
00640   /* Send CRC */
00641   send2(crc16 >> 8);
00642   send2(crc16 & 0xff);
00643 
00644   /* Send trailing bytes. */
00645   send(0x33);
00646   send(0xcc);
00647   send(0x33);
00648   send(0xcc);
00649 
00650   /* Turn on (or off) reception again. */
00651   if(onoroff == ON) {
00652     ENERGEST_ON(ENERGEST_TYPE_LISTEN);
00653     rxon();
00654     rxclear();
00655   } else {
00656     rxoff();
00657     rxclear();
00658   }
00659 
00660   ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
00661   RIMESTATS_ADD(lltx);
00662 
00663   return RADIO_TX_OK;
00664 }
00665 /*---------------------------------------------------------------------------*/
00666 int
00667 tr1001_read(void *buf, unsigned short bufsize)
00668 {
00669   unsigned short tmplen;
00670 
00671   if(tr1001_rxstate == RXSTATE_FULL) {
00672 
00673 #if DEBUG
00674     dump_packet(tr1001_rxlen + 2);
00675 #endif /* DEBUG */
00676 
00677     tmplen = tr1001_rxlen;
00678 
00679     if(tmplen > bufsize) {
00680       LOG("tr1001_read: too large packet: %d/%d bytes\n", tmplen, bufsize);
00681       rxclear();
00682       RIMESTATS_ADD(toolong);
00683       return -1;
00684     }
00685 
00686     memcpy(buf, &tr1001_rxbuf[TR1001_HDRLEN], tmplen);
00687 
00688     /* header + content + CRC */
00689     sstrength = (tmp_count ? ((tmp_sstrength / tmp_count) << 2) : 0);
00690 
00691     rxclear();
00692 
00693     LOG("tr1001_read: got %d bytes\n", tmplen);
00694 
00695     return tmplen;
00696   }
00697   return 0;
00698 }
00699 /*---------------------------------------------------------------------------*/
00700 static int
00701 receiving_packet(void)
00702 {
00703   return tr1001_rxstate == RXSTATE_RECEIVING &&
00704     !timer_expired(&rxtimer);
00705 }
00706 /*---------------------------------------------------------------------------*/
00707 static int
00708 pending_packet(void)
00709 {
00710   return tr1001_rxstate == RXSTATE_FULL;
00711 }
00712 /*---------------------------------------------------------------------------*/
00713 static int
00714 channel_clear(void)
00715 {
00716   /* TODO add CCA functionality */
00717   return 0;
00718 }
00719 /*---------------------------------------------------------------------------*/
00720 PROCESS_THREAD(tr1001_process, ev, data)
00721 {
00722   int len;
00723   PROCESS_BEGIN();
00724 
00725   /* Reset reception state now that the process is ready to receive data. */
00726   rxclear();
00727 
00728   while(1) {
00729     PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
00730     packetbuf_clear();
00731     len = tr1001_read(packetbuf_dataptr(), PACKETBUF_SIZE);
00732     if(len > 0) {
00733       packetbuf_set_datalen(len);
00734       NETSTACK_RDC.input();
00735     }
00736   }
00737 
00738   PROCESS_END();
00739 }
00740 /*---------------------------------------------------------------------------*/
00741 void
00742 tr1001_set_speed(unsigned char speed)
00743 {
00744 
00745   if(speed == TR1001_19200) {
00746     /* Set TR1001 to 19200 */
00747     UBR00 = 0x80;                         /* 2,457MHz/19200 = 128 -> 0x80 */
00748     UBR10 = 0x00;                         /* */
00749     UMCTL0 = 0x00;                        /* no modulation  */
00750   } else if(speed == TR1001_38400) {
00751     /* Set TR1001 to 38400 */
00752     UBR00 = 0x40;                         /* 2,457MHz/38400 = 64 -> 0x40 */
00753     UBR10 = 0x00;                         /* */
00754     UMCTL0 = 0x00;                        /* no modulation  */
00755   } else if(speed == TR1001_57600) {
00756     UBR00 = 0x2a;                         /* 2,457MHz/57600 = 42.7 -> 0x2A */
00757     UBR10 = 0x00;                         /* */
00758     UMCTL0 = 0x5b;                        /* */
00759   } else if(speed == TR1001_115200) {
00760     UBR00 = 0x15;                         /* 2,457MHz/115200 = 21.4 -> 0x15 */
00761     UBR10 = 0x00;                         /* */
00762     UMCTL0 = 0x4a;                        /* */
00763   } else {
00764     tr1001_set_speed(TR1001_19200);
00765   }
00766 }
00767 /*---------------------------------------------------------------------------*/
00768 unsigned short
00769 tr1001_sstrength(void)
00770 {
00771   return sstrength;
00772 }
00773 /*---------------------------------------------------------------------------*/
00774 /** @} */
00775 /** @} */

Generated on Mon Apr 11 14:23:44 2011 for Contiki 2.5 by  doxygen 1.6.1