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

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