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 #include <string.h>
00038
00039 #include "contiki.h"
00040
00041 #if defined(__AVR__)
00042 #include <avr/io.h>
00043 #elif defined(__MSP430__)
00044 #ifdef __IAR_SYSTEMS_ICC__
00045 #include <io430.h>
00046 #else
00047 #include <io.h>
00048 #endif
00049 #endif
00050
00051 #include "dev/leds.h"
00052 #include "dev/spi.h"
00053 #include "dev/cc2420.h"
00054 #include "dev/cc2420_const.h"
00055
00056 #include "net/packetbuf.h"
00057 #include "net/rime/rimestats.h"
00058 #include "net/netstack.h"
00059
00060 #include "sys/timetable.h"
00061
00062 #define WITH_SEND_CCA 1
00063
00064 #define FOOTER_LEN 2
00065
00066 #ifndef CC2420_CONF_CHECKSUM
00067 #define CC2420_CONF_CHECKSUM 0
00068 #endif
00069
00070 #ifndef CC2420_CONF_AUTOACK
00071 #define CC2420_CONF_AUTOACK 0
00072 #endif
00073
00074 #if CC2420_CONF_CHECKSUM
00075 #include "lib/crc16.h"
00076 #define CHECKSUM_LEN 2
00077 #else
00078 #define CHECKSUM_LEN 0
00079 #endif
00080
00081 #define AUX_LEN (CHECKSUM_LEN + FOOTER_LEN)
00082
00083
00084 #define FOOTER1_CRC_OK 0x80
00085 #define FOOTER1_CORRELATION 0x7f
00086
00087 #define DEBUG 0
00088 #if DEBUG
00089 #include <stdio.h>
00090 #define PRINTF(...) printf(__VA_ARGS__)
00091 #else
00092 #define PRINTF(...) do {} while (0)
00093 #endif
00094
00095 #define DEBUG_LEDS DEBUG
00096 #undef LEDS_ON
00097 #undef LEDS_OFF
00098 #if DEBUG_LEDS
00099 #define LEDS_ON(x) leds_on(x)
00100 #define LEDS_OFF(x) leds_off(x)
00101 #else
00102 #define LEDS_ON(x)
00103 #define LEDS_OFF(x)
00104 #endif
00105
00106 void cc2420_arch_init(void);
00107
00108
00109 rtimer_clock_t cc2420_time_of_arrival, cc2420_time_of_departure;
00110
00111 int cc2420_authority_level_of_sender;
00112
00113 int cc2420_packets_seen, cc2420_packets_read;
00114
00115 static uint8_t volatile pending;
00116
00117 #define BUSYWAIT_UNTIL(cond, max_time) \
00118 do { \
00119 rtimer_clock_t t0; \
00120 t0 = RTIMER_NOW(); \
00121 while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \
00122 } while(0)
00123
00124 volatile uint8_t cc2420_sfd_counter;
00125 volatile uint16_t cc2420_sfd_start_time;
00126 volatile uint16_t cc2420_sfd_end_time;
00127
00128 static volatile uint16_t last_packet_timestamp;
00129
00130 PROCESS(cc2420_process, "CC2420 driver");
00131
00132
00133
00134 int cc2420_on(void);
00135 int cc2420_off(void);
00136
00137 static int cc2420_read(void *buf, unsigned short bufsize);
00138
00139 static int cc2420_prepare(const void *data, unsigned short len);
00140 static int cc2420_transmit(unsigned short len);
00141 static int cc2420_send(const void *data, unsigned short len);
00142
00143 static int cc2420_receiving_packet(void);
00144 static int pending_packet(void);
00145 static int cc2420_cca(void);
00146
00147
00148 signed char cc2420_last_rssi;
00149 uint8_t cc2420_last_correlation;
00150
00151 const struct radio_driver cc2420_driver =
00152 {
00153 cc2420_init,
00154 cc2420_prepare,
00155 cc2420_transmit,
00156 cc2420_send,
00157 cc2420_read,
00158
00159
00160 cc2420_cca,
00161 cc2420_receiving_packet,
00162 pending_packet,
00163 cc2420_on,
00164 cc2420_off,
00165 };
00166
00167 static uint8_t receive_on;
00168
00169 static int channel;
00170
00171
00172
00173 static void
00174 getrxdata(void *buf, int len)
00175 {
00176 CC2420_READ_FIFO_BUF(buf, len);
00177 }
00178 static void
00179 getrxbyte(uint8_t *byte)
00180 {
00181 CC2420_READ_FIFO_BYTE(*byte);
00182 }
00183 static void
00184 flushrx(void)
00185 {
00186 uint8_t dummy;
00187
00188 CC2420_READ_FIFO_BYTE(dummy);
00189 CC2420_STROBE(CC2420_SFLUSHRX);
00190 CC2420_STROBE(CC2420_SFLUSHRX);
00191 }
00192
00193 static void
00194 strobe(enum cc2420_register regname)
00195 {
00196 CC2420_STROBE(regname);
00197 }
00198
00199 static unsigned int
00200 status(void)
00201 {
00202 uint8_t status;
00203 CC2420_GET_STATUS(status);
00204 return status;
00205 }
00206
00207 static uint8_t locked, lock_on, lock_off;
00208
00209 static void
00210 on(void)
00211 {
00212 CC2420_ENABLE_FIFOP_INT();
00213 strobe(CC2420_SRXON);
00214
00215 BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 100);
00216
00217 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
00218 receive_on = 1;
00219 }
00220 static void
00221 off(void)
00222 {
00223
00224 receive_on = 0;
00225
00226
00227 BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);
00228
00229 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
00230 strobe(CC2420_SRFOFF);
00231 CC2420_DISABLE_FIFOP_INT();
00232
00233 if(!CC2420_FIFOP_IS_1) {
00234 flushrx();
00235 }
00236 }
00237
00238 #define GET_LOCK() locked++
00239 static void RELEASE_LOCK(void) {
00240 if(locked == 1) {
00241 if(lock_on) {
00242 on();
00243 lock_on = 0;
00244 }
00245 if(lock_off) {
00246 off();
00247 lock_off = 0;
00248 }
00249 }
00250 locked--;
00251 }
00252
00253 static unsigned
00254 getreg(enum cc2420_register regname)
00255 {
00256 unsigned reg;
00257 CC2420_READ_REG(regname, reg);
00258 return reg;
00259 }
00260
00261 static void
00262 setreg(enum cc2420_register regname, unsigned value)
00263 {
00264 CC2420_WRITE_REG(regname, value);
00265 }
00266
00267 static void
00268 set_txpower(uint8_t power)
00269 {
00270 uint16_t reg;
00271
00272 reg = getreg(CC2420_TXCTRL);
00273 reg = (reg & 0xffe0) | (power & 0x1f);
00274 setreg(CC2420_TXCTRL, reg);
00275 }
00276
00277 #define AUTOACK (1 << 4)
00278 #define ADR_DECODE (1 << 11)
00279 #define RXFIFO_PROTECTION (1 << 9)
00280 #define CORR_THR(n) (((n) & 0x1f) << 6)
00281 #define FIFOP_THR(n) ((n) & 0x7f)
00282 #define RXBPF_LOCUR (1 << 13);
00283
00284 int
00285 cc2420_init(void)
00286 {
00287 uint16_t reg;
00288 {
00289 int s = splhigh();
00290 cc2420_arch_init();
00291 CC2420_DISABLE_FIFOP_INT();
00292 CC2420_FIFOP_INT_INIT();
00293 splx(s);
00294 }
00295
00296
00297 SET_VREG_ACTIVE();
00298
00299 SET_RESET_ACTIVE();
00300 clock_delay(127);
00301 SET_RESET_INACTIVE();
00302
00303
00304
00305
00306 strobe(CC2420_SXOSCON);
00307
00308
00309 reg = getreg(CC2420_MDMCTRL0);
00310
00311 #if CC2420_CONF_AUTOACK
00312 reg |= AUTOACK | ADR_DECODE;
00313 #else
00314 reg &= ~(AUTOACK | ADR_DECODE);
00315 #endif
00316 setreg(CC2420_MDMCTRL0, reg);
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 setreg(CC2420_MDMCTRL1, CORR_THR(20));
00328 reg = getreg(CC2420_RXCTRL1);
00329 reg |= RXBPF_LOCUR;
00330 setreg(CC2420_RXCTRL1, reg);
00331
00332
00333 setreg(CC2420_IOCFG0, FIFOP_THR(127));
00334
00335
00336 reg = getreg(CC2420_SECCTRL0);
00337 reg &= ~RXFIFO_PROTECTION;
00338 setreg(CC2420_SECCTRL0, reg);
00339
00340 cc2420_set_pan_addr(0xffff, 0x0000, NULL);
00341 cc2420_set_channel(26);
00342
00343 flushrx();
00344
00345 process_start(&cc2420_process, NULL);
00346 return 1;
00347 }
00348
00349 static int
00350 cc2420_transmit(unsigned short payload_len)
00351 {
00352 int i, txpower;
00353 uint8_t total_len;
00354 #if CC2420_CONF_CHECKSUM
00355 uint16_t checksum;
00356 #endif
00357
00358 GET_LOCK();
00359
00360 txpower = 0;
00361 if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
00362
00363 txpower = cc2420_get_txpower();
00364
00365 set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1);
00366 }
00367
00368 total_len = payload_len + AUX_LEN;
00369
00370
00371
00372
00373
00374
00375
00376
00377 #ifndef CC2420_CONF_SYMBOL_LOOP_COUNT
00378 #error CC2420_CONF_SYMBOL_LOOP_COUNT needs to be set!!!
00379 #else
00380 #define LOOP_20_SYMBOLS CC2420_CONF_SYMBOL_LOOP_COUNT
00381 #endif
00382
00383 #if WITH_SEND_CCA
00384 strobe(CC2420_SRXON);
00385 BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 10);
00386 strobe(CC2420_STXONCCA);
00387 #else
00388 strobe(CC2420_STXON);
00389 #endif
00390 for(i = LOOP_20_SYMBOLS; i > 0; i--) {
00391 if(CC2420_SFD_IS_1) {
00392 {
00393 rtimer_clock_t sfd_timestamp;
00394 sfd_timestamp = cc2420_sfd_start_time;
00395 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
00396 PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) {
00397
00398 CC2420_WRITE_RAM(&sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2);
00399 }
00400 }
00401
00402 if(!(status() & BV(CC2420_TX_ACTIVE))) {
00403
00404
00405
00406 RELEASE_LOCK();
00407 return RADIO_TX_COLLISION;
00408 }
00409 if(receive_on) {
00410 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
00411 }
00412 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
00413
00414
00415 BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);
00416
00417 #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
00418 ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2420_get_txpower());
00419 #endif
00420 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
00421 if(receive_on) {
00422 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
00423 } else {
00424
00425
00426 off();
00427 }
00428
00429 if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
00430
00431 set_txpower(txpower & 0xff);
00432 }
00433
00434 RELEASE_LOCK();
00435 return RADIO_TX_OK;
00436 }
00437 }
00438
00439
00440
00441 RIMESTATS_ADD(contentiondrop);
00442 PRINTF("cc2420: do_send() transmission never started\n");
00443
00444 if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
00445
00446 set_txpower(txpower & 0xff);
00447 }
00448
00449 RELEASE_LOCK();
00450 return RADIO_TX_COLLISION;
00451 }
00452
00453 static int
00454 cc2420_prepare(const void *payload, unsigned short payload_len)
00455 {
00456 uint8_t total_len;
00457 #if CC2420_CONF_CHECKSUM
00458 uint16_t checksum;
00459 #endif
00460 GET_LOCK();
00461
00462 PRINTF("cc2420: sending %d bytes\n", payload_len);
00463
00464 RIMESTATS_ADD(lltx);
00465
00466
00467
00468
00469
00470 strobe(CC2420_SFLUSHTX);
00471
00472 #if CC2420_CONF_CHECKSUM
00473 checksum = crc16_data(payload, payload_len, 0);
00474 #endif
00475 total_len = payload_len + AUX_LEN;
00476 CC2420_WRITE_FIFO_BUF(&total_len, 1);
00477 CC2420_WRITE_FIFO_BUF(payload, payload_len);
00478 #if CC2420_CONF_CHECKSUM
00479 CC2420_WRITE_FIFO_BUF(&checksum, CHECKSUM_LEN);
00480 #endif
00481
00482 RELEASE_LOCK();
00483 return 0;
00484 }
00485
00486 static int
00487 cc2420_send(const void *payload, unsigned short payload_len)
00488 {
00489 cc2420_prepare(payload, payload_len);
00490 return cc2420_transmit(payload_len);
00491 }
00492
00493 int
00494 cc2420_off(void)
00495 {
00496
00497 if(receive_on == 0) {
00498 return 1;
00499 }
00500
00501
00502
00503 if(locked) {
00504
00505 lock_off = 1;
00506 return 1;
00507 }
00508
00509 GET_LOCK();
00510
00511
00512
00513
00514 if(status() & BV(CC2420_TX_ACTIVE)) {
00515 lock_off = 1;
00516 } else {
00517 off();
00518 }
00519 RELEASE_LOCK();
00520 return 1;
00521 }
00522
00523 int
00524 cc2420_on(void)
00525 {
00526 if(receive_on) {
00527 return 1;
00528 }
00529 if(locked) {
00530 lock_on = 1;
00531 return 1;
00532 }
00533
00534 GET_LOCK();
00535 on();
00536 RELEASE_LOCK();
00537 return 1;
00538 }
00539
00540 int
00541 cc2420_get_channel(void)
00542 {
00543 return channel;
00544 }
00545
00546 int
00547 cc2420_set_channel(int c)
00548 {
00549 uint16_t f;
00550
00551 GET_LOCK();
00552
00553
00554
00555
00556 channel = c;
00557
00558 f = 5 * (c - 11) + 357 + 0x4000;
00559
00560
00561
00562 BUSYWAIT_UNTIL((status() & (BV(CC2420_XOSC16M_STABLE))), RTIMER_SECOND / 10);
00563
00564
00565 BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);
00566
00567 setreg(CC2420_FSCTRL, f);
00568
00569
00570
00571 if(receive_on) {
00572 strobe(CC2420_SRXON);
00573 }
00574
00575 RELEASE_LOCK();
00576 return 1;
00577 }
00578
00579 void
00580 cc2420_set_pan_addr(unsigned pan,
00581 unsigned addr,
00582 const uint8_t *ieee_addr)
00583 {
00584 uint16_t f = 0;
00585 uint8_t tmp[2];
00586
00587 GET_LOCK();
00588
00589
00590
00591
00592 BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 10);
00593
00594 tmp[0] = pan & 0xff;
00595 tmp[1] = pan >> 8;
00596 CC2420_WRITE_RAM(&tmp, CC2420RAM_PANID, 2);
00597
00598 tmp[0] = addr & 0xff;
00599 tmp[1] = addr >> 8;
00600 CC2420_WRITE_RAM(&tmp, CC2420RAM_SHORTADDR, 2);
00601 if(ieee_addr != NULL) {
00602 uint8_t tmp_addr[8];
00603
00604 for (f = 0; f < 8; f++) {
00605 tmp_addr[7 - f] = ieee_addr[f];
00606 }
00607 CC2420_WRITE_RAM(tmp_addr, CC2420RAM_IEEEADDR, 8);
00608 }
00609 RELEASE_LOCK();
00610 }
00611
00612
00613
00614
00615 #if CC2420_TIMETABLE_PROFILING
00616 #define cc2420_timetable_size 16
00617 TIMETABLE(cc2420_timetable);
00618 TIMETABLE_AGGREGATE(aggregate_time, 10);
00619 #endif
00620 int
00621 cc2420_interrupt(void)
00622 {
00623 CC2420_CLEAR_FIFOP_INT();
00624 process_poll(&cc2420_process);
00625 #if CC2420_TIMETABLE_PROFILING
00626 timetable_clear(&cc2420_timetable);
00627 TIMETABLE_TIMESTAMP(cc2420_timetable, "interrupt");
00628 #endif
00629
00630 last_packet_timestamp = cc2420_sfd_start_time;
00631 pending++;
00632 cc2420_packets_seen++;
00633 return 1;
00634 }
00635
00636 PROCESS_THREAD(cc2420_process, ev, data)
00637 {
00638 int len;
00639 PROCESS_BEGIN();
00640
00641 PRINTF("cc2420_process: started\n");
00642
00643 while(1) {
00644 PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
00645 #if CC2420_TIMETABLE_PROFILING
00646 TIMETABLE_TIMESTAMP(cc2420_timetable, "poll");
00647 #endif
00648
00649 PRINTF("cc2420_process: calling receiver callback\n");
00650
00651 packetbuf_clear();
00652 packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, last_packet_timestamp);
00653 len = cc2420_read(packetbuf_dataptr(), PACKETBUF_SIZE);
00654
00655 packetbuf_set_datalen(len);
00656
00657 NETSTACK_RDC.input();
00658 #if CC2420_TIMETABLE_PROFILING
00659 TIMETABLE_TIMESTAMP(cc2420_timetable, "end");
00660 timetable_aggregate_compute_detailed(&aggregate_time,
00661 &cc2420_timetable);
00662 timetable_clear(&cc2420_timetable);
00663 #endif
00664 }
00665
00666 PROCESS_END();
00667 }
00668
00669 static int
00670 cc2420_read(void *buf, unsigned short bufsize)
00671 {
00672 uint8_t footer[2];
00673 uint8_t len;
00674 #if CC2420_CONF_CHECKSUM
00675 uint16_t checksum;
00676 #endif
00677
00678 if(!CC2420_FIFOP_IS_1) {
00679 return 0;
00680 }
00681
00682
00683
00684
00685 pending = 0;
00686
00687 GET_LOCK();
00688
00689 cc2420_packets_read++;
00690
00691 getrxbyte(&len);
00692
00693 if(len > CC2420_MAX_PACKET_LEN) {
00694
00695 flushrx();
00696 RIMESTATS_ADD(badsynch);
00697 RELEASE_LOCK();
00698 return 0;
00699 }
00700
00701 if(len <= AUX_LEN) {
00702 flushrx();
00703 RIMESTATS_ADD(tooshort);
00704 RELEASE_LOCK();
00705 return 0;
00706 }
00707
00708 if(len - AUX_LEN > bufsize) {
00709 flushrx();
00710 RIMESTATS_ADD(toolong);
00711 RELEASE_LOCK();
00712 return 0;
00713 }
00714
00715 getrxdata(buf, len - AUX_LEN);
00716 #if CC2420_CONF_CHECKSUM
00717 getrxdata(&checksum, CHECKSUM_LEN);
00718 #endif
00719 getrxdata(footer, FOOTER_LEN);
00720
00721 #if CC2420_CONF_CHECKSUM
00722 if(checksum != crc16_data(buf, len - AUX_LEN, 0)) {
00723 PRINTF("checksum failed 0x%04x != 0x%04x\n",
00724 checksum, crc16_data(buf, len - AUX_LEN, 0));
00725 }
00726
00727 if(footer[1] & FOOTER1_CRC_OK &&
00728 checksum == crc16_data(buf, len - AUX_LEN, 0)) {
00729 #else
00730 if(footer[1] & FOOTER1_CRC_OK) {
00731 #endif
00732 cc2420_last_rssi = footer[0];
00733 cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION;
00734
00735
00736 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2420_last_rssi);
00737 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2420_last_correlation);
00738
00739 RIMESTATS_ADD(llrx);
00740
00741 } else {
00742 RIMESTATS_ADD(badcrc);
00743 len = AUX_LEN;
00744 }
00745
00746 if(CC2420_FIFOP_IS_1) {
00747 if(!CC2420_FIFO_IS_1) {
00748
00749
00750
00751 flushrx();
00752 } else {
00753
00754 process_poll(&cc2420_process);
00755 }
00756 }
00757
00758 RELEASE_LOCK();
00759
00760 if(len < AUX_LEN) {
00761 return 0;
00762 }
00763
00764 return len - AUX_LEN;
00765 }
00766
00767 void
00768 cc2420_set_txpower(uint8_t power)
00769 {
00770 GET_LOCK();
00771 set_txpower(power);
00772 RELEASE_LOCK();
00773 }
00774
00775 int
00776 cc2420_get_txpower(void)
00777 {
00778 int power;
00779 GET_LOCK();
00780 power = (int)(getreg(CC2420_TXCTRL) & 0x001f);
00781 RELEASE_LOCK();
00782 return power;
00783 }
00784
00785 int
00786 cc2420_rssi(void)
00787 {
00788 int rssi;
00789 int radio_was_off = 0;
00790
00791 if(locked) {
00792 return 0;
00793 }
00794
00795 GET_LOCK();
00796
00797 if(!receive_on) {
00798 radio_was_off = 1;
00799 cc2420_on();
00800 }
00801 BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 100);
00802
00803 rssi = (int)((signed char)getreg(CC2420_RSSI));
00804
00805 if(radio_was_off) {
00806 cc2420_off();
00807 }
00808 RELEASE_LOCK();
00809 return rssi;
00810 }
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820 int
00821 cc2420_cca_valid(void)
00822 {
00823 int valid;
00824 if(locked) {
00825 return 1;
00826 }
00827 GET_LOCK();
00828 valid = !!(status() & BV(CC2420_RSSI_VALID));
00829 RELEASE_LOCK();
00830 return valid;
00831 }
00832
00833 static int
00834 cc2420_cca(void)
00835 {
00836 int cca;
00837 int radio_was_off = 0;
00838
00839
00840
00841
00842
00843 if(locked) {
00844 return 1;
00845 }
00846
00847 GET_LOCK();
00848 if(!receive_on) {
00849 radio_was_off = 1;
00850 cc2420_on();
00851 }
00852
00853
00854 if(!receive_on) {
00855 RELEASE_LOCK();
00856 if(radio_was_off) {
00857 cc2420_off();
00858 }
00859 return 1;
00860 }
00861
00862 BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 100);
00863
00864 cca = CC2420_CCA_IS_1;
00865
00866 if(radio_was_off) {
00867 cc2420_off();
00868 }
00869 RELEASE_LOCK();
00870 return cca;
00871 }
00872
00873 int
00874 cc2420_receiving_packet(void)
00875 {
00876 return CC2420_SFD_IS_1;
00877 }
00878
00879 static int
00880 pending_packet(void)
00881 {
00882 return CC2420_FIFOP_IS_1;
00883 }
00884
00885 void
00886 cc2420_set_cca_threshold(int value)
00887 {
00888 uint16_t shifted = value << 8;
00889 GET_LOCK();
00890 setreg(CC2420_RSSI, shifted);
00891 RELEASE_LOCK();
00892 }
00893