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 "lib/me.h"
00056 #include "lib/crc16.h"
00057 #include "net/tr1001-drv.h"
00058
00059 #include <io.h>
00060 #include <signal.h>
00061 #include <string.h>
00062
00063 #define RXSTATE_READY 0
00064 #define RXSTATE_RECEVING 1
00065 #define RXSTATE_FULL 2
00066
00067 #define SYNCH1 0x3c
00068 #define SYNCH2 0x03
00069
00070 #if TR1001_STATISTICS
00071 static unsigned short sstrength_dropped,
00072 sstrength_max, sstrength_min, tmp_sstrength_max, tmp_sstrength_min;
00073
00074 static unsigned short packets_err;
00075
00076 static unsigned short packets_ok;
00077 #endif
00078
00079
00080
00081
00082
00083 #define RXBUFSIZE UIP_BUFSIZE
00084 unsigned char tr1001_rxbuf[RXBUFSIZE];
00085
00086
00087
00088
00089 static unsigned short tr1001_rxlen = 0;
00090
00091
00092
00093
00094 volatile unsigned char tr1001_rxstate = RXSTATE_READY;
00095
00096 static u16_t rxcrc, rxcrctmp;
00097
00098
00099
00100
00101 struct tr1001_hdr {
00102 u8_t len[2];
00103
00104 };
00105
00106
00107
00108
00109 #define TR1001_HDRLEN sizeof(struct tr1001_hdr)
00110
00111 #define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00112
00113 #define OFF 0
00114 #define ON 1
00115 static u8_t onoroff = ON;
00116
00117 #define NUM_SYNCHBYTES 4
00118
00119 void tr1001_default_rxhandler(unsigned char c);
00120 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char c));
00121 static struct pt rxhandler_pt;
00122
00123
00124
00125
00126
00127
00128
00129 static struct timer rxtimer;
00130
00131 static unsigned short tmp_sstrength, sstrength;
00132
00133 #include <stdio.h>
00134 #define LOG(...)
00135
00136
00137 #if TR1001_STATISTICS
00138 #define PACKET_DROPPED(bytes) do { \
00139 if(packets_err < ~0) {\
00140 packets_err++;\
00141 }\
00142 sstrength_dropped = ((bytes) == 0 ? 0 : ((tmp_sstrength / (bytes)) << 1));\
00143 } while(0)
00144 #define PACKET_ACCEPTED() do {\
00145 if(packets_ok < ~0) {\
00146 packets_ok++;\
00147 }\
00148 } while(0);
00149 #else
00150 #define PACKET_DROPPED(bytes)
00151 #define PACKET_ACCEPTED()
00152 #endif
00153
00154
00155
00156
00157 static void
00158 txook(void)
00159 {
00160 P3SEL = 0xf0;
00161 P5OUT |= 0x40;
00162 P5OUT &= 0x7f;
00163 }
00164
00165
00166
00167
00168 static void
00169 rxon(void)
00170 {
00171 P3SEL = 0xe0;
00172 P5OUT |= 0xc0;
00173
00174
00175 ME1 |= URXE0;
00176
00177
00178 IE1 |= URXIE0;
00179
00180 }
00181
00182
00183
00184
00185 static void
00186 rxoff(void)
00187 {
00188 P5OUT &= 0x3f;
00189
00190
00191 ME1 &= ~URXE0;
00192
00193
00194 IE1 &= ~URXIE0;
00195 }
00196
00197
00198
00199
00200 static void
00201 rxclear(void)
00202 {
00203 tr1001_rxstate = RXSTATE_READY;
00204 }
00205
00206
00207
00208
00209
00210 void
00211 radio_off(void)
00212 {
00213 onoroff = OFF;
00214 rxoff();
00215 rxclear();
00216 }
00217
00218
00219
00220
00221
00222 void
00223 radio_on(void)
00224 {
00225 onoroff = ON;
00226 rxon();
00227 rxclear();
00228 }
00229
00230
00231
00232
00233
00234
00235 static void
00236 send(unsigned char b)
00237 {
00238 clock_time_t start;
00239
00240 start = clock_time();
00241
00242
00243 while((IFG1 & UTXIFG0) == 0) {
00244
00245 if((clock_time_t)(clock_time() - start) > (clock_time_t)CLOCK_SECOND) {
00246 break;
00247 }
00248 }
00249
00250
00251 TXBUF0 = b;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260 static void
00261 send2(unsigned char b)
00262 {
00263 u16_t m;
00264 m = me_encode(b);
00265 send(m >> 8);
00266 send(m & 0xff);
00267 }
00268 static u16_t
00269 send2_crc16(unsigned char b, u16_t crcacc)
00270 {
00271 u16_t m;
00272 m = me_encode(b);
00273 send(m >> 8);
00274 send(m & 0xff);
00275 return crc16_add(b, crcacc);
00276 }
00277
00278 void
00279 tr1001_set_txpower(unsigned char p)
00280 {
00281 int i;
00282
00283
00284 if(p > 100) {
00285 p = 100;
00286 }
00287
00288
00289
00290 P2OUT &= 0xDF;
00291 P2OUT &= 0xBF;
00292 for(i = 0; i < 102; ++i) {
00293 P2OUT &= 0xEF;
00294 P2OUT |= 0x10;
00295 }
00296
00297
00298
00299
00300 P2OUT |= 0x20;
00301 for(i = 0; i < p; ++i) {
00302 P2OUT &= 0xEF;
00303 P2OUT |= 0x10;
00304 }
00305 P2OUT |= 0x40;
00306 }
00307
00308 void
00309 tr1001_init(void)
00310 {
00311
00312 PT_INIT(&rxhandler_pt);
00313
00314 #if TR1001_STATISTICS
00315 packets_ok = packets_err = 0;
00316 sstrength_dropped = 0;
00317 sstrength_min = 0xFFFF;
00318 sstrength_max = 0;
00319 #endif
00320
00321 UCTL0 = CHAR;
00322 UTCTL0 = SSEL1;
00323
00324 tr1001_set_speed(TR1001_19200);
00325
00326 ME1 |= UTXE0 + URXE0;
00327
00328
00329 IE1 |= URXIE0;
00330
00331 timer_set(&rxtimer, CLOCK_SECOND / 4);
00332
00333
00334 radio_on();
00335 tr1001_set_txpower(100);
00336
00337
00338 rxclear();
00339
00340 }
00341
00342 interrupt (UART0RX_VECTOR)
00343 tr1001_rxhandler(void)
00344 {
00345 tr1001_default_rxhandler_pt(RXBUF0);
00346 }
00347
00348 static void
00349 dump_packet(int len)
00350 {
00351 int i;
00352 for(i = 0; i < len; ++i) {
00353 LOG("%d: 0x%02x\n", i, tr1001_rxbuf[i]);
00354 }
00355 }
00356
00357 PT_THREAD(tr1001_default_rxhandler_pt(unsigned char incoming_byte))
00358 {
00359 static unsigned char rxtmp, tmppos;
00360
00361 if(timer_expired(&rxtimer) && tr1001_rxstate != RXSTATE_FULL) {
00362 PT_INIT(&rxhandler_pt);
00363 }
00364
00365 timer_restart(&rxtimer);
00366
00367 if(tr1001_rxstate == RXSTATE_RECEVING) {
00368 unsigned short signal = radio_sensor_signal;
00369 tmp_sstrength += (signal >> 2);
00370 if(signal < tmp_sstrength_min) {
00371 tmp_sstrength_min = signal;
00372 }
00373 if(signal > tmp_sstrength_max) {
00374 tmp_sstrength_max = signal;
00375 }
00376 }
00377
00378 PT_BEGIN(&rxhandler_pt);
00379
00380 while(1) {
00381
00382
00383 rxclear();
00384
00385
00386 PT_WAIT_UNTIL(&rxhandler_pt, incoming_byte == SYNCH1);
00387
00388 tr1001_rxstate = RXSTATE_RECEVING;
00389
00390
00391 PT_WAIT_WHILE(&rxhandler_pt, incoming_byte == SYNCH1);
00392
00393
00394
00395 if(incoming_byte != SYNCH2) {
00396 PT_RESTART(&rxhandler_pt);
00397 }
00398
00399
00400 tmp_sstrength = 0;
00401 tmp_sstrength_max = 0;
00402 tmp_sstrength_min = 0xFFFF;
00403
00404
00405 rxcrc = 0xffff;
00406
00407
00408 for(tmppos = 0; tmppos < TR1001_HDRLEN; ++tmppos) {
00409
00410
00411 PT_YIELD(&rxhandler_pt);
00412
00413
00414
00415 if(!me_valid(incoming_byte)) {
00416 beep_beep(1000);
00417 LOG("Incorrect manchester in header at byte %d/1\n", tmppos);
00418 PACKET_DROPPED(tmppos);
00419 PT_RESTART(&rxhandler_pt);
00420 }
00421
00422 rxtmp = me_decode8(incoming_byte);
00423
00424
00425 PT_YIELD(&rxhandler_pt);
00426
00427 if(!me_valid(incoming_byte)) {
00428 beep_beep(1000);
00429 LOG("Incorrect manchester in header at byte %d/2\n", tmppos);
00430 PACKET_DROPPED(tmppos + 1);
00431 PT_RESTART(&rxhandler_pt);
00432 }
00433
00434
00435
00436
00437 tr1001_rxbuf[tmppos] = (rxtmp << 4) | me_decode8(incoming_byte);
00438
00439
00440 rxcrc = crc16_add(tr1001_rxbuf[tmppos], rxcrc);
00441
00442
00443 }
00444
00445
00446 tr1001_rxlen = ((((struct tr1001_hdr *)tr1001_rxbuf)->len[0] << 8) +
00447 ((struct tr1001_hdr *)tr1001_rxbuf)->len[1]);
00448
00449
00450
00451 if(tmppos + tr1001_rxlen > sizeof(tr1001_rxbuf)) {
00452 PACKET_DROPPED(tmppos);
00453 PT_RESTART(&rxhandler_pt);
00454 }
00455
00456
00457 for(; tmppos < tr1001_rxlen + TR1001_HDRLEN; ++tmppos) {
00458 PT_YIELD(&rxhandler_pt);
00459
00460 if(!me_valid(incoming_byte)) {
00461 LOG("Incorrect manchester 0x%02x at byte %d/1\n", incoming_byte,
00462 tmppos - TR1001_HDRLEN);
00463 beep_beep(1000);
00464 PACKET_DROPPED(tmppos);
00465 PT_RESTART(&rxhandler_pt);
00466 }
00467
00468 rxtmp = me_decode8(incoming_byte);
00469
00470 PT_YIELD(&rxhandler_pt);
00471
00472 if(!me_valid(incoming_byte)) {
00473 LOG("Incorrect manchester at byte %d/2\n", tmppos - TR1001_HDRLEN);
00474 beep_beep(1000);
00475 PACKET_DROPPED(tmppos + 1);
00476 PT_RESTART(&rxhandler_pt);
00477 }
00478
00479 tr1001_rxbuf[tmppos] = (rxtmp << 4) | me_decode8(incoming_byte);
00480 rxcrc = crc16_add(tr1001_rxbuf[tmppos], rxcrc);
00481
00482 }
00483
00484
00485 for(tmppos = 0; tmppos < 4; ++tmppos) {
00486
00487 PT_YIELD(&rxhandler_pt);
00488
00489 if(!me_valid(incoming_byte)) {
00490 beep_beep(1000);
00491 PACKET_DROPPED(tr1001_rxlen + TR1001_HDRLEN);
00492 PT_RESTART(&rxhandler_pt);
00493 }
00494
00495 rxcrctmp = (rxcrctmp << 4) | me_decode8(incoming_byte);
00496 }
00497
00498 if(rxcrctmp == rxcrc) {
00499
00500
00501
00502 PACKET_ACCEPTED();
00503 tr1001_drv_request_poll();
00504 LPM_AWAKE();
00505
00506
00507
00508
00509 tr1001_rxstate = RXSTATE_FULL;
00510 PT_WAIT_UNTIL(&rxhandler_pt, tr1001_rxstate != RXSTATE_FULL);
00511
00512 } else {
00513 LOG("Incorrect CRC");
00514 beep_beep(1000);
00515 PACKET_DROPPED(tr1001_rxlen + TR1001_HDRLEN);
00516 }
00517 }
00518 PT_END(&rxhandler_pt);
00519 }
00520
00521
00522
00523
00524
00525
00526
00527 static void
00528 prepare_transmission(int synchbytes)
00529 {
00530 int i;
00531
00532
00533 clock_delay(random_rand() & 0x3ff);
00534
00535
00536
00537
00538
00539
00540 while(tr1001_rxstate == RXSTATE_RECEVING &&
00541 !timer_expired(&rxtimer)) {
00542
00543 clock_delay(random_rand() & 0x7ff);
00544 }
00545
00546
00547
00548 txook();
00549
00550
00551
00552
00553 clock_delay(200);
00554
00555
00556
00557
00558
00559 for(i = 0; i < 20; ++i) {
00560 send(0xaa);
00561 }
00562
00563
00564 send(0xff);
00565
00566 for(i = 0; i < synchbytes; ++i) {
00567 send(SYNCH1);
00568 }
00569 send(SYNCH2);
00570
00571 }
00572
00573 u8_t
00574 tr1001_send(u8_t *packet, u16_t len)
00575 {
00576 int i;
00577 u16_t crc16;
00578
00579 LOG("tr1001_send: sending %d bytes\n", len);
00580
00581
00582 prepare_transmission(NUM_SYNCHBYTES);
00583
00584 crc16 = 0xffff;
00585
00586
00587 crc16 = send2_crc16(len >> 8, crc16);
00588 crc16 = send2_crc16(len & 0xff, crc16);
00589
00590
00591 for(i = 0; i < len; ++i) {
00592 crc16 = send2_crc16(packet[i], crc16);
00593 }
00594
00595
00596 send2(crc16 >> 8);
00597 send2(crc16 & 0xff);
00598
00599
00600 send(0x33);
00601 send(0xcc);
00602 send(0x33);
00603 send(0xcc);
00604
00605
00606 if(onoroff == ON) {
00607 rxon();
00608 rxclear();
00609 } else {
00610 rxoff();
00611 rxclear();
00612 }
00613
00614 return UIP_FW_OK;
00615 }
00616
00617 unsigned short
00618 tr1001_poll(void)
00619 {
00620 unsigned short tmplen;
00621
00622 if(tr1001_rxstate == RXSTATE_FULL) {
00623
00624 dump_packet(tr1001_rxlen + 2);
00625
00626 tmplen = tr1001_rxlen;
00627
00628 if(tmplen > UIP_BUFSIZE - (UIP_LLH_LEN - TR1001_HDRLEN)) {
00629 tmplen = UIP_BUFSIZE - (UIP_LLH_LEN - TR1001_HDRLEN);
00630 }
00631
00632 memcpy(&uip_buf[UIP_LLH_LEN], &tr1001_rxbuf[TR1001_HDRLEN],
00633 tmplen);
00634
00635
00636 sstrength = (tmp_sstrength / (TR1001_HDRLEN + tr1001_rxlen + 2)) << 1;
00637 sstrength_max = tmp_sstrength_max;
00638 sstrength_min = tmp_sstrength_min;
00639
00640 rxclear();
00641
00642 LOG("tr1001_poll: got %d bytes\n", tmplen);
00643
00644 return tmplen;
00645 }
00646 return 0;
00647 }
00648
00649 void
00650 tr1001_set_speed(unsigned char speed)
00651 {
00652
00653 if(speed == TR1001_19200) {
00654
00655 UBR00 = 0x80;
00656 UBR10 = 0x00;
00657 UMCTL0 = 0x00;
00658 } else if(speed == TR1001_38400) {
00659
00660 UBR00 = 0x40;
00661 UBR10 = 0x00;
00662 UMCTL0 = 0x00;
00663 } else if(speed == TR1001_57600) {
00664 UBR00 = 0x2a;
00665 UBR10 = 0x00;
00666 UMCTL0 = 0x5b;
00667 } else if(speed == TR1001_115200) {
00668 UBR00 = 0x15;
00669 UBR10 = 0x00;
00670 UMCTL0 = 0x4a;
00671 } else {
00672 tr1001_set_speed(TR1001_19200);
00673 }
00674 }
00675
00676 unsigned short
00677 tr1001_sstrength(void)
00678 {
00679 return sstrength;
00680 }
00681
00682 #if TR1001_STATISTICS
00683 unsigned short
00684 tr1001_packets_ok(void)
00685 {
00686 return packets_ok;
00687 }
00688 #endif
00689
00690 #if TR1001_STATISTICS
00691 unsigned short
00692 tr1001_packets_dropped(void)
00693 {
00694 return packets_err;
00695 }
00696 #endif
00697
00698 #if TR1001_STATISTICS
00699 void
00700 tr1001_clear_packets(void)
00701 {
00702 packets_ok = packets_err = 0;
00703 }
00704 #endif
00705
00706 #if TR1001_STATISTICS
00707 unsigned short
00708 tr1001_sstrength_value(unsigned int type)
00709 {
00710 switch(type) {
00711 case TR1001_SSTRENGTH_DROPPED:
00712 return sstrength_dropped;
00713 case TR1001_SSTRENGTH_MAX:
00714 return sstrength_max;
00715 case TR1001_SSTRENGTH_MIN:
00716 return sstrength_min < sstrength_max ? sstrength_min : 0;
00717 default:
00718 return 0;
00719 }
00720 }
00721 #endif
00722
00723
00724