Contiki 2.5
tr1001-gcr.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * @(#)$Id: tr1001-gcr.c,v 1.15 2010/03/02 22:40:39 nifi Exp $
32  */
33 /**
34  * \addtogroup esb
35  * @{
36  */
37 
38 /**
39  * \defgroup tr1001 TR1001 radio tranciever device driver
40  * @{
41  */
42 
43 /**
44  * \file
45  * Device driver and packet framing for the RFM-TR1001 radio module.
46  * \author Adam Dunkels <adam@sics.se>
47  *
48  * This file implements a device driver for the RFM-TR1001 radio
49  * tranciever.
50  *
51  */
52 
53 #include "contiki.h"
54 #include "contiki-esb.h"
55 
56 #include "dev/tr1001.h"
57 #include "dev/radio-sensor.h"
58 #include "lib/gcr.h"
59 #include "lib/crc16.h"
60 #include "net/netstack.h"
61 #include "net/rime/rimestats.h"
62 
63 #include <string.h>
64 
65 #ifdef TR1001_CONF_BEEP_ON_BAD_CRC
66 #define BEEP_ON_BAD_CRC TR1001_CONF_BEEP_ON_BAD_CRC
67 #else
68 #define BEEP_ON_BAD_CRC 1
69 #endif /* TR1001_CONF_BEEP_ON_BAD_CRC */
70 
71 #if BEEP_ON_BAD_CRC
72 #include "dev/beep.h"
73 #define BEEP_BEEP(t) beep_beep(t)
74 #else
75 #define BEEP_BEEP(t)
76 #endif /* BEEP_ON_BAD_CRC */
77 
78 #define RXSTATE_READY 0
79 #define RXSTATE_RECEIVING 1
80 #define RXSTATE_FULL 2
81 
82 #define SYNCH1 0x3c
83 #define SYNCH2 0x03
84 
85 #ifdef TR1001_CONF_BUFFER_SIZE
86 #define RXBUFSIZE TR1001_CONF_BUFFER_SIZE
87 #else
88 #define RXBUFSIZE PACKETBUF_SIZE
89 #endif /* TR1001_CONF_BUFFER_SIZE */
90 
91 /*
92  * Pending data to send when using prepare/transmit functions.
93  */
94 static const void *pending_data;
95 
96 /*
97  * The buffer which holds incoming data.
98  */
99 unsigned char tr1001_rxbuf[RXBUFSIZE];
100 
101 /*
102  * The length of the packet that currently is being received.
103  */
104 static unsigned short tr1001_rxlen = 0;
105 
106 /*
107  * The reception state.
108  */
109 volatile unsigned char tr1001_rxstate = RXSTATE_READY;
110 
111 static uint16_t rxcrc, rxcrctmp;
112 
113 /*
114  * The structure of the packet header.
115  */
116 struct tr1001_hdr {
117  uint8_t len[2]; /**< The 16-bit length of the packet in network byte
118  order. */
119 };
120 
121 /*
122  * The length of the packet header.
123  */
124 #define TR1001_HDRLEN sizeof(struct tr1001_hdr)
125 
126 #define OFF 0
127 #define ON 1
128 static uint8_t onoroff = OFF;
129 
130 #define NUM_SYNCHBYTES 4
131 
132 void tr1001_default_rxhandler(unsigned char c);
133 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char c));
134 static struct pt rxhandler_pt;
135 
136 /*
137  * This timer is used to keep track of when the last byte was received
138  * over the radio. If the inter-byte time is too large, the packet
139  * currently being received is discarded and a new packet reception is
140  * initiated.
141  */
142 static struct timer rxtimer;
143 
144 static unsigned short tmp_sstrength, sstrength;
145 static unsigned short tmp_count;
146 
147 #define DEBUG 0
148 #if DEBUG
149 #include <stdio.h>
150 #define LOG(...) printf(__VA_ARGS__)
151 #else
152 #define LOG(...)
153 #endif
154 
155 #define GCRLOG(...) /* printf(__VA_ARGS__)*/
156 
157 /*---------------------------------------------------------------------------*/
158 PROCESS(tr1001_process, "TR1001 driver");
159 /*---------------------------------------------------------------------------*/
160 
161 static int prepare_packet(const void *data, unsigned short len);
162 static int transmit_packet(unsigned short len);
163 static int receiving_packet(void);
164 static int pending_packet(void);
165 static int channel_clear(void);
166 static int tr1001_on(void);
167 static int tr1001_off(void);
168 
169 const struct radio_driver tr1001_driver = {
170  tr1001_init,
171  prepare_packet,
172  transmit_packet,
173  tr1001_send,
174  tr1001_read,
178  tr1001_on,
179  tr1001_off
180 };
181 
182 /*---------------------------------------------------------------------------*/
183 /*
184  * Turn on data transmission in On-Off-Keyed mode.
185  */
186 static void
187 txook(void)
188 {
189  P3SEL = 0xf0;
190  P5OUT |= 0x40;
191  P5OUT &= 0x7f;
192 }
193 /*---------------------------------------------------------------------------*/
194 /*
195  * Turn on data reception for the radio tranceiver.
196  */
197 static void
198 rxon(void)
199 {
200  P3SEL = 0xe0;
201  P5OUT |= 0xc0;
202 
203  /* Enable the receiver. */
204  ME1 |= URXE0;
205 
206  /* Turn on receive interrupt. */
207  IE1 |= URXIE0;
208 
209 }
210 /*---------------------------------------------------------------------------*/
211 /*
212  * Turn off data reception for the radio tranceiver.
213  */
214 static void
215 rxoff(void)
216 {
217  P5OUT &= 0x3f;
218 
219  /* Disable the receiver. */
220  ME1 &= ~URXE0;
221 
222  /* Turn off receive interrupt. */
223  IE1 &= ~URXIE0;
224 }
225 /*---------------------------------------------------------------------------*/
226 /*
227  * Clear the recevie buffer and reset the receiver state.
228  */
229 static void
230 rxclear(void)
231 {
232  tr1001_rxstate = RXSTATE_READY;
233 }
234 /*---------------------------------------------------------------------------*/
235 /*
236  * Turn TR1001 radio transceiver off.
237  */
238 /*---------------------------------------------------------------------------*/
239 static int
240 tr1001_off(void)
241 {
242  if(onoroff == OFF) {
243  return 1;
244  }
245  onoroff = OFF;
246  rxoff();
247  rxclear();
248 
249  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
250  return 1;
251 }
252 /*---------------------------------------------------------------------------*/
253 /*
254  * Turn TR1001 radio transceiver on.
255  */
256 /*---------------------------------------------------------------------------*/
257 static int
258 tr1001_on(void)
259 {
260  if(onoroff == ON) {
261  return 1;
262  }
263 
264  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
265 
266  onoroff = ON;
267  rxon();
268  rxclear();
269  return 1;
270 }
271 /*---------------------------------------------------------------------------*/
272 /*
273  * Send a byte of data over the radio.
274  *
275  * \param b The byte to be sent.
276  */
277 static void
278 send(unsigned char b)
279 {
280  clock_time_t start;
281 
282  start = clock_time();
283 
284  /* Wait until the USART0 TX buffer is ready. */
285  while((IFG1 & UTXIFG0) == 0) {
286  /* Wait no more than one second. */
287  if((clock_time_t)(clock_time() - start) > (clock_time_t)CLOCK_SECOND) {
288  break;
289  }
290  }
291 
292  /* Send the byte. */
293  TXBUF0 = b;
294 }
295 /*---------------------------------------------------------------------------*/
296 /*
297  * Send a byte of data and its logical negation (all bits inverted)
298  * over the radio.
299  *
300  * \param b The byte to be sent.
301  */
302 static void
303 sendx(unsigned char b)
304 {
305  gcr_encode(b);
306  GCRLOG("(%02x)", b);
307 
308  while(gcr_get_encoded(&b)) {
309  send(b);
310  GCRLOG("%02x ", b);
311  }
312 }
313 
314 static uint16_t
315 sendx_crc16(unsigned char b, uint16_t crcacc)
316 {
317  gcr_encode(b);
318  GCRLOG("(%02x)", b);
319  crcacc = crc16_add(b, crcacc);
320  while(gcr_get_encoded(&b)) {
321  send(b);
322  GCRLOG("C%02x ", b);
323  }
324  return crcacc;
325 }
326 /*---------------------------------------------------------------------------*/
327 void
328 tr1001_set_txpower(unsigned char p)
329 {
330  int i;
331 
332  /* Clamp maximum power. */
333  if(p > 100) {
334  p = 100;
335  }
336 
337  /* First, run the potentiometer down to zero so that we know the
338  start value of the potentiometer. */
339  P2OUT &= 0xDF; /* P25 = 0 (down selected) */
340  P2OUT &= 0xBF; /* P26 = 0 (chipselect on) */
341  for(i = 0; i < 102; ++i) {
342  P2OUT &= 0xEF; /* P24 = 0 (inc) */
343  P2OUT |= 0x10;
344  }
345 
346  /* Now, start to increase the value of the potentiometer until it
347  reaches the desired value.*/
348 
349  P2OUT |= 0x20; /* P25 = 1 (up selected) */
350  for(i = 0; i < p; ++i) {
351  P2OUT &= 0xEF; /* P24 = 0 (inc) */
352  P2OUT |= 0x10;
353  }
354  P2OUT |= 0x40; /* P26 = 1 (chipselect off) */
355 }
356 /*---------------------------------------------------------------------------*/
357 int
359 {
360  PT_INIT(&rxhandler_pt);
361 
362  onoroff = OFF;
363 
364  UCTL0 = CHAR; /* 8-bit character */
365  UTCTL0 = SSEL1; /* UCLK = SMCLK */
366 
367  tr1001_set_speed(TR1001_19200);
368 
369  ME1 |= UTXE0 + URXE0; /* Enable USART0 TXD/RXD */
370 
371  /* Turn on receive interrupt. */
372  IE1 |= URXIE0;
373 
374  timer_set(&rxtimer, CLOCK_SECOND / 4);
375 
376 
377  tr1001_on();
378  tr1001_set_txpower(100);
379 
380  /* Reset reception state. */
381  rxclear();
382 
383  process_start(&tr1001_process, NULL);
384 
385  return 1;
386 }
387 /*---------------------------------------------------------------------------*/
388 interrupt (UART0RX_VECTOR)
389  tr1001_rxhandler(void)
390 {
391  ENERGEST_ON(ENERGEST_TYPE_IRQ);
392  tr1001_default_rxhandler_pt(RXBUF0);
393  if(tr1001_rxstate == RXSTATE_FULL) {
394  LPM4_EXIT;
395  }
396  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
397 }
398 /*---------------------------------------------------------------------------*/
399 #if DEBUG
400 static void
401 dump_packet(int len)
402 {
403  int i;
404  for(i = 0; i < len; ++i) {
405  LOG("%d: 0x%02x\n", i, tr1001_rxbuf[i]);
406  }
407 }
408 #endif /* DEBUG */
409 /*---------------------------------------------------------------------------*/
410 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char incoming_byte))
411 {
412  static unsigned char rxtmp, tmppos;
413 
414  if(timer_expired(&rxtimer) && tr1001_rxstate != RXSTATE_FULL) {
415  PT_INIT(&rxhandler_pt);
416  }
417 
418  timer_restart(&rxtimer);
419 
420  if(tr1001_rxstate == RXSTATE_RECEIVING) {
421  unsigned short signal = radio_sensor.value(0);
422  tmp_sstrength += (signal >> 2);
423  tmp_count++;
424  }
425 
426  PT_BEGIN(&rxhandler_pt);
427 
428  while(1) {
429 
430  /* Reset reception state. */
431  rxclear();
432 
433  /* Wait until we receive the first syncronization byte. */
434  PT_WAIT_UNTIL(&rxhandler_pt, incoming_byte == SYNCH1);
435 
436  tr1001_rxstate = RXSTATE_RECEIVING;
437 
438  /* Read all incoming syncronization bytes. */
439  PT_WAIT_WHILE(&rxhandler_pt, incoming_byte == SYNCH1);
440 
441  /* We should receive the second synch byte by now, otherwise we'll
442  restart the protothread. */
443  if(incoming_byte != SYNCH2) {
444  PT_RESTART(&rxhandler_pt);
445  }
446 
447  /* Start signal strength measurement */
448  tmp_sstrength = 0;
449  tmp_count = 0;
450 
451  /* Reset the CRC. */
452  rxcrc = 0xffff;
453 
454  gcr_init();
455  GCRLOG("RECV: ");
456 
457  /* Read packet header. */
458  for(tmppos = 0; tmppos < TR1001_HDRLEN; ++tmppos) {
459 
460  /* Wait for the first byte of the packet to arrive. */
461  do {
462  PT_YIELD(&rxhandler_pt);
463  GCRLOG("(%02x) ", incoming_byte);
464 
465  gcr_decode(incoming_byte);
466  /* If the incoming byte isn't a valid GCR encoded byte,
467  we start again from the beginning. */
468  if(!gcr_valid()) {
469  BEEP_BEEP(1000);
470  LOG("Incorrect GCR in header at byte %d/1 %x\n", tmppos, incoming_byte);
471  RIMESTATS_ADD(badsynch);
472  PT_RESTART(&rxhandler_pt);
473  }
474  } while(!gcr_get_decoded(&rxtmp));
475  GCRLOG("%02x ", rxtmp);
476 
477  tr1001_rxbuf[tmppos] = rxtmp;
478  /* Calculate the CRC. */
479  rxcrc = crc16_add(rxtmp, rxcrc);
480  }
481 
482  /* Since we've got the header, we can grab the length from it. */
483  tr1001_rxlen = ((((struct tr1001_hdr *)tr1001_rxbuf)->len[0] << 8) +
484  ((struct tr1001_hdr *)tr1001_rxbuf)->len[1]);
485 
486  /* If the length is longer than we can handle, we'll start from
487  the beginning. */
488  if(tmppos + tr1001_rxlen > sizeof(tr1001_rxbuf)) {
489  RIMESTATS_ADD(toolong);
490  PT_RESTART(&rxhandler_pt);
491  }
492 
493  /* Read packet data. */
494  for(; tmppos < tr1001_rxlen + TR1001_HDRLEN; ++tmppos) {
495 
496  /* Wait for the first byte of the packet to arrive. */
497  do {
498  PT_YIELD(&rxhandler_pt);
499  GCRLOG("(%02x)", incoming_byte);
500 
501  gcr_decode(incoming_byte);
502  /* If the incoming byte isn't a valid Manchester encoded byte,
503  we start again from the beinning. */
504  if(!gcr_valid()) {
505  BEEP_BEEP(1000);
506  LOG("Incorrect GCR 0x%02x at byte %d/1\n", incoming_byte,
507  tmppos - TR1001_HDRLEN);
508  RIMESTATS_ADD(badsynch);
509  PT_RESTART(&rxhandler_pt);
510  }
511  } while(!gcr_get_decoded(&rxtmp));
512 
513  GCRLOG("%02x ", rxtmp);
514 
515  tr1001_rxbuf[tmppos] = rxtmp;
516  /* Calculate the CRC. */
517  rxcrc = crc16_add(rxtmp, rxcrc);
518  }
519 
520  /* Read the frame CRC. */
521  for(tmppos = 0; tmppos < 2; ++tmppos) {
522  do {
523  PT_YIELD(&rxhandler_pt);
524  GCRLOG("(%02x)", incoming_byte);
525 
526  gcr_decode(incoming_byte);
527  if(!gcr_valid()) {
528  BEEP_BEEP(1000);
529  RIMESTATS_ADD(badsynch);
530  PT_RESTART(&rxhandler_pt);
531  }
532  } while(!gcr_get_decoded(&rxtmp));
533  GCRLOG("%02x ", rxtmp);
534 
535  rxcrctmp = (rxcrctmp << 8) | rxtmp;
536  }
537  GCRLOG("\n");
538 
539  if(rxcrctmp == rxcrc) {
540  /* A full packet has been received and the CRC checks out. We'll
541  request the driver to take care of the incoming data. */
542 
543  RIMESTATS_ADD(llrx);
544  process_poll(&tr1001_process);
545 
546  /* We'll set the receive state flag to signal that a full frame
547  is present in the buffer, and we'll wait until the buffer has
548  been taken care of. */
549  tr1001_rxstate = RXSTATE_FULL;
550  PT_WAIT_UNTIL(&rxhandler_pt, tr1001_rxstate != RXSTATE_FULL);
551 
552  } else {
553  LOG("Incorrect CRC\n");
554  BEEP_BEEP(1000);
555  RIMESTATS_ADD(badcrc);
556  }
557  }
558  PT_END(&rxhandler_pt);
559 }
560 /*---------------------------------------------------------------------------*/
561 static int
562 prepare_packet(const void *data, unsigned short len)
563 {
564  pending_data = data;
565  return 0;
566 }
567 /*---------------------------------------------------------------------------*/
568 static int
569 transmit_packet(unsigned short len)
570 {
571  int ret = RADIO_TX_ERR;
572  if(pending_data != NULL) {
573  ret = tr1001_send(pending_data, len);
574  pending_data = NULL;
575  }
576  return ret;
577 }
578 /*---------------------------------------------------------------------------*/
579 int
580 tr1001_send(const void *packet, unsigned short len)
581 {
582  int i;
583  uint16_t crc16;
584 
585  LOG("tr1001_send: sending %d bytes\n", len);
586 
587  if(onoroff == ON) {
588  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
589  }
590  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
591 
592  /* Prepare the transmission. */
593 
594  /* Delay the transmission for a short random duration. */
595  clock_delay(random_rand() & 0x3ff);
596 
597 
598  /* Check that we don't currently are receiving a packet, and if so
599  we wait until the reception has been completed. Reception is done
600  with interrupts so it is OK for us to wait in a while() loop. */
601 
602  while(tr1001_rxstate == RXSTATE_RECEIVING &&
603  !timer_expired(&rxtimer)) {
604  /* Delay the transmission for a short random duration. */
605  clock_delay(random_rand() & 0x7ff);
606  }
607 
608 
609  /* Turn on OOK mode with transmission. */
610  txook();
611 
612  /* According to the datasheet, the transmitter must wait for 12 us
613  in order to settle. Empirical tests show that is it better to
614  wait for something like 283 us... */
615  clock_delay(200);
616 
617 
618  /* Transmit preamble and synch bytes. */
619  for(i = 0; i < 20; ++i) {
620  send(0xaa);
621  }
622  /* send(0xaa);
623  send(0xaa);*/
624  send(0xff);
625 
626  for(i = 0; i < NUM_SYNCHBYTES; ++i) {
627  send(SYNCH1);
628  }
629  send(SYNCH2);
630 
631  crc16 = 0xffff;
632 
633  gcr_init();
634 
635  GCRLOG("SEND: ");
636 
637  /* Send packet header. */
638  crc16 = sendx_crc16(len >> 8, crc16);
639  crc16 = sendx_crc16(len & 0xff, crc16);
640 
641  /* Send packet data. */
642  for(i = 0; i < len; ++i) {
643  crc16 = sendx_crc16(((uint8_t *)packet)[i], crc16);
644  }
645 
646  /* Send CRC */
647  sendx(crc16 >> 8);
648  sendx(crc16 & 0xff);
649 
650  /* if not encoding has sent all bytes - let it send another GCR specific */
651  if (!gcr_finished()) {
652  sendx(0);
653  }
654 
655  GCRLOG("\n");
656 
657  /* Send trailing bytes. */
658  send(0x33);
659  send(0xcc);
660  send(0x33);
661  send(0xcc);
662 
663  /* Turn on (or off) reception again. */
664  if(onoroff == ON) {
665  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
666  rxon();
667  rxclear();
668  } else {
669  rxoff();
670  rxclear();
671  }
672 
673  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
674  RIMESTATS_ADD(lltx);
675 
676  return RADIO_TX_OK;
677 }
678 /*---------------------------------------------------------------------------*/
679 int
680 tr1001_read(void *buf, unsigned short bufsize)
681 {
682  unsigned short tmplen;
683 
684  if(tr1001_rxstate == RXSTATE_FULL) {
685 
686 #if DEBUG
687  dump_packet(tr1001_rxlen + 2);
688 #endif /* DEBUG */
689 
690  tmplen = tr1001_rxlen;
691 
692  if(tmplen > bufsize) {
693  LOG("tr1001_read: too large packet: %d/%d bytes\n", tmplen, bufsize);
694  rxclear();
695  RIMESTATS_ADD(toolong);
696  return -1;
697  }
698 
699  memcpy(buf, &tr1001_rxbuf[TR1001_HDRLEN], tmplen);
700 
701  /* header + content + CRC */
702  sstrength = (tmp_count ? ((tmp_sstrength / tmp_count) << 2) : 0);
703 
704  rxclear();
705 
706  LOG("tr1001_read: got %d bytes\n", tmplen);
707 
708  return tmplen;
709  }
710  return 0;
711 }
712 /*---------------------------------------------------------------------------*/
713 static int
714 receiving_packet(void)
715 {
716  return tr1001_rxstate == RXSTATE_RECEIVING &&
717  !timer_expired(&rxtimer);
718 }
719 /*---------------------------------------------------------------------------*/
720 static int
721 pending_packet(void)
722 {
723  return tr1001_rxstate == RXSTATE_FULL;
724 }
725 /*---------------------------------------------------------------------------*/
726 static int
727 channel_clear(void)
728 {
729  /* TODO add CCA functionality */
730  return 0;
731 }
732 /*---------------------------------------------------------------------------*/
733 PROCESS_THREAD(tr1001_process, ev, data)
734 {
735  int len;
736  PROCESS_BEGIN();
737 
738  /* Reset reception state now that the process is ready to receive data. */
739  rxclear();
740 
741  while(1) {
742  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
743  packetbuf_clear();
745  if(len > 0) {
747  NETSTACK_RDC.input();
748  }
749  }
750 
751  PROCESS_END();
752 }
753 /*---------------------------------------------------------------------------*/
754 void
755 tr1001_set_speed(unsigned char speed)
756 {
757 
758  if(speed == TR1001_19200) {
759  /* Set TR1001 to 19200 */
760  UBR00 = 0x80; /* 2,457MHz/19200 = 128 -> 0x80 */
761  UBR10 = 0x00; /* */
762  UMCTL0 = 0x00; /* no modulation */
763  } else if(speed == TR1001_38400) {
764  /* Set TR1001 to 38400 */
765  UBR00 = 0x40; /* 2,457MHz/38400 = 64 -> 0x40 */
766  UBR10 = 0x00; /* */
767  UMCTL0 = 0x00; /* no modulation */
768  } else if(speed == TR1001_57600) {
769  UBR00 = 0x2a; /* 2,457MHz/57600 = 42.7 -> 0x2A */
770  UBR10 = 0x00; /* */
771  UMCTL0 = 0x5b; /* */
772  } else if(speed == TR1001_115200) {
773  UBR00 = 0x15; /* 2,457MHz/115200 = 21.4 -> 0x15 */
774  UBR10 = 0x00; /* */
775  UMCTL0 = 0x4a; /* */
776  } else {
777  tr1001_set_speed(TR1001_19200);
778  }
779 }
780 /*---------------------------------------------------------------------------*/
781 unsigned short
783 {
784  return sstrength;
785 }
786 /*---------------------------------------------------------------------------*/
787 /** @} */
788 /** @} */