00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
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
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
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
00091
00092
00093
00094
00095 static const void *pending_data;
00096
00097
00098
00099
00100 unsigned char tr1001_rxbuf[RXBUFSIZE];
00101
00102
00103
00104
00105 static unsigned short tr1001_rxlen = 0;
00106
00107
00108
00109
00110 volatile unsigned char tr1001_rxstate = RXSTATE_READY;
00111
00112 static uint16_t rxcrc, rxcrctmp;
00113
00114
00115
00116
00117 struct tr1001_hdr {
00118 uint8_t len[2];
00119
00120 };
00121
00122
00123
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
00139
00140
00141
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(...)
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
00186
00187 static void
00188 txook(void)
00189 {
00190 P3SEL = 0xf0;
00191 P5OUT |= 0x40;
00192 P5OUT &= 0x7f;
00193 }
00194
00195
00196
00197
00198 static void
00199 rxon(void)
00200 {
00201 P3SEL = 0xe0;
00202 P5OUT |= 0xc0;
00203
00204
00205 ME1 |= URXE0;
00206
00207
00208 IE1 |= URXIE0;
00209
00210 }
00211
00212
00213
00214
00215 static void
00216 rxoff(void)
00217 {
00218 P5OUT &= 0x3f;
00219
00220
00221 ME1 &= ~URXE0;
00222
00223
00224 IE1 &= ~URXIE0;
00225 }
00226
00227
00228
00229
00230 static void
00231 rxclear(void)
00232 {
00233 tr1001_rxstate = RXSTATE_READY;
00234 }
00235
00236
00237
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
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
00275
00276
00277
00278 static void
00279 send(unsigned char b)
00280 {
00281 clock_time_t start;
00282
00283 start = clock_time();
00284
00285
00286 while((IFG1 & UTXIFG0) == 0) {
00287
00288 if((clock_time_t)(clock_time() - start) > (clock_time_t)CLOCK_SECOND) {
00289 break;
00290 }
00291 }
00292
00293
00294 TXBUF0 = b;
00295 }
00296
00297
00298
00299
00300
00301
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
00334 if(p > 100) {
00335 p = 100;
00336 }
00337
00338
00339
00340 P2OUT &= 0xDF;
00341 P2OUT &= 0xBF;
00342 for(i = 0; i < 102; ++i) {
00343 P2OUT &= 0xEF;
00344 P2OUT |= 0x10;
00345 }
00346
00347
00348
00349
00350 P2OUT |= 0x20;
00351 for(i = 0; i < p; ++i) {
00352 P2OUT &= 0xEF;
00353 P2OUT |= 0x10;
00354 }
00355 P2OUT |= 0x40;
00356 }
00357
00358 int
00359 tr1001_init(void)
00360 {
00361 PT_INIT(&rxhandler_pt);
00362
00363 onoroff = OFF;
00364
00365 UCTL0 = CHAR;
00366 UTCTL0 = SSEL1;
00367
00368 tr1001_set_speed(TR1001_19200);
00369
00370 ME1 |= UTXE0 + URXE0;
00371
00372
00373 IE1 |= URXIE0;
00374
00375 timer_set(&rxtimer, CLOCK_SECOND / 4);
00376
00377
00378 tr1001_on();
00379 tr1001_set_txpower(100);
00380
00381
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
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
00432 rxclear();
00433
00434
00435 PT_WAIT_UNTIL(&rxhandler_pt, incoming_byte == SYNCH1);
00436
00437 tr1001_rxstate = RXSTATE_RECEIVING;
00438
00439
00440 PT_WAIT_WHILE(&rxhandler_pt, incoming_byte == SYNCH1);
00441
00442
00443
00444 if(incoming_byte != SYNCH2) {
00445 PT_RESTART(&rxhandler_pt);
00446 }
00447
00448
00449 tmp_sstrength = 0;
00450 tmp_count = 0;
00451
00452
00453 rxcrc = 0xffff;
00454
00455 gcr_init();
00456 GCRLOG("RECV: ");
00457
00458
00459 for(tmppos = 0; tmppos < TR1001_HDRLEN; ++tmppos) {
00460
00461
00462 do {
00463 PT_YIELD(&rxhandler_pt);
00464 GCRLOG("(%02x) ", incoming_byte);
00465
00466 gcr_decode(incoming_byte);
00467
00468
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
00480 rxcrc = crc16_add(rxtmp, rxcrc);
00481 }
00482
00483
00484 tr1001_rxlen = ((((struct tr1001_hdr *)tr1001_rxbuf)->len[0] << 8) +
00485 ((struct tr1001_hdr *)tr1001_rxbuf)->len[1]);
00486
00487
00488
00489 if(tmppos + tr1001_rxlen > sizeof(tr1001_rxbuf)) {
00490 RIMESTATS_ADD(toolong);
00491 PT_RESTART(&rxhandler_pt);
00492 }
00493
00494
00495 for(; tmppos < tr1001_rxlen + TR1001_HDRLEN; ++tmppos) {
00496
00497
00498 do {
00499 PT_YIELD(&rxhandler_pt);
00500 GCRLOG("(%02x)", incoming_byte);
00501
00502 gcr_decode(incoming_byte);
00503
00504
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
00518 rxcrc = crc16_add(rxtmp, rxcrc);
00519 }
00520
00521
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
00542
00543
00544 RIMESTATS_ADD(llrx);
00545 process_poll(&tr1001_process);
00546
00547
00548
00549
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
00594
00595
00596 clock_delay(random_rand() & 0x3ff);
00597
00598
00599
00600
00601
00602
00603 while(tr1001_rxstate == RXSTATE_RECEIVING &&
00604 !timer_expired(&rxtimer)) {
00605
00606 clock_delay(random_rand() & 0x7ff);
00607 }
00608
00609
00610
00611 txook();
00612
00613
00614
00615
00616 clock_delay(200);
00617
00618
00619
00620 for(i = 0; i < 20; ++i) {
00621 send(0xaa);
00622 }
00623
00624
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
00639 crc16 = sendx_crc16(len >> 8, crc16);
00640 crc16 = sendx_crc16(len & 0xff, crc16);
00641
00642
00643 for(i = 0; i < len; ++i) {
00644 crc16 = sendx_crc16(((uint8_t *)packet)[i], crc16);
00645 }
00646
00647
00648 sendx(crc16 >> 8);
00649 sendx(crc16 & 0xff);
00650
00651
00652 if (!gcr_finished()) {
00653 sendx(0);
00654 }
00655
00656 GCRLOG("\n");
00657
00658
00659 send(0x33);
00660 send(0xcc);
00661 send(0x33);
00662 send(0xcc);
00663
00664
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
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
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
00731 return 0;
00732 }
00733
00734 PROCESS_THREAD(tr1001_process, ev, data)
00735 {
00736 int len;
00737 PROCESS_BEGIN();
00738
00739
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
00761 UBR00 = 0x80;
00762 UBR10 = 0x00;
00763 UMCTL0 = 0x00;
00764 } else if(speed == TR1001_38400) {
00765
00766 UBR00 = 0x40;
00767 UBR10 = 0x00;
00768 UMCTL0 = 0x00;
00769 } else if(speed == TR1001_57600) {
00770 UBR00 = 0x2a;
00771 UBR10 = 0x00;
00772 UMCTL0 = 0x5b;
00773 } else if(speed == TR1001_115200) {
00774 UBR00 = 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