Contiki 3.x
rf230bb.c
1 /*
2  * Copyright (c) 2007, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Additional fixes for AVR contributed by:
6  *
7  * David Kopf dak664@embarqmail.com
8  * Ivan Delamer delamer@ieee.com
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the Institute nor the names of its contributors
19  * may be used to endorse or promote products derived from this software
20  * without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * This file is part of the Contiki operating system.
35  *
36  */
37 /*
38  * This code is almost device independent and should be easy to port.
39  * Ported to Atmel RF230 21Feb2010 by dak
40  */
41 
42 #include <stdio.h>
43 #include <string.h>
44 
45 #include "contiki.h"
46 
47 #if defined(__AVR__)
48 #include <avr/io.h>
49 
50 //_delay_us has the potential to use floating point which brings the 256 byte clz table into RAM
51 //#include <util/delay.h>
52 //#define delay_us( us ) ( _delay_us( ( us ) ) )
53 //_delay_loop_2(uint16_t count) is 4 CPU cycles per iteration, up to 32 milliseconds at 8MHz
54 #include <util/delay_basic.h>
55 #define delay_us( us ) ( _delay_loop_2(1+((unsigned long long)us*F_CPU)/4000000UL) )
56 
57 #include <avr/pgmspace.h>
58 #elif defined(__MSP430__)
59 #include <io.h>
60 #endif
61 
62 #include "dev/leds.h"
63 #include "dev/spi.h"
64 #include "rf230bb.h"
65 
66 #include "net/packetbuf.h"
67 #include "net/rime/rimestats.h"
68 #include "net/netstack.h"
69 
70 #define WITH_SEND_CCA 0
71 
72 /* Timestamps have not been tested */
73 #if RF230_CONF_TIMESTAMPS
74 #include "net/rime/timesynch.h"
75 #define TIMESTAMP_LEN 3
76 #else /* RF230_CONF_TIMESTAMPS */
77 #define TIMESTAMP_LEN 0
78 #endif /* RF230_CONF_TIMESTAMPS */
79 /* Nonzero FOOTER_LEN has not been tested */
80 #define FOOTER_LEN 0
81 
82 /* RF230_CONF_CHECKSUM=0 for automatic hardware checksum */
83 #ifndef RF230_CONF_CHECKSUM
84 #define RF230_CONF_CHECKSUM 0
85 #endif
86 
87 /* Autoack setting ignored in non-extended mode */
88 #ifndef RF230_CONF_AUTOACK
89 #define RF230_CONF_AUTOACK 1
90 #endif
91 
92 /* We need to turn off autoack in promiscuous mode */
93 #if RF230_CONF_AUTOACK
94 static bool is_promiscuous;
95 #endif
96 
97 /* RF230_CONF_FRAME_RETRIES is 1 plus the number written to the hardware. */
98 /* Valid range 1-16, zero disables extended mode. */
99 #ifndef RF230_CONF_FRAME_RETRIES
100 #ifdef RF230_CONF_AUTORETRIES /* Support legacy definition. */
101 #define RF230_CONF_FRAME_RETRIES RF230_CONF_AUTORETRIES
102 #else
103 #define RF230_CONF_FRAME_RETRIES 0 /* Extended mode disabled by default. */
104 #endif
105 #endif
106 
107 /* In extended mode (FRAME_RETRIES>0) the tx routine waits for hardware
108  * processing of an expected ACK and returns RADIO_TX_OK/NOACK result.
109  * In non-extended mode the ACK is treated as a normal rx packet.
110  * If the caller needs the ACK to be returned as an rx packet,
111  * RF230_INSERTACK will generate one based on the hardware result.
112  * This is triggered when the read routine is called with a buffer
113  * length of three (the ack length).
114  * In extended nmode it can be enabled by default to support either
115  * method. In nonextended mode it would pass an extra ACK to RDCs
116  * that use the TX_OK result to signal a successful ACK.
117  * Adds 100 bytes of program flash and two bytes of RAM.
118  */
119 #if RF320_CONF_INSERTACK && RF230_CONF_FRAME_RETRIES
120 #define RF230_INSERTACK 1
121 uint8_t ack_pending,ack_seqnum;
122 #endif
123 
124 /* RF230_CONF_CSMA_RETRIES is number of random-backoff/CCA retries. */
125 /* The hardware will accept 0-7, but 802.15.4-2003 only allows 5 maximum */
126 /* In RF231/128RFA1, a value of 7 means no CSMA bebofe the Tx. */
127 /* CSMA backoffs are long and can block radio duty cycling
128  * over several channel check periods! */
129 /* Used only if RF230_CONF_FRAME_RETRIES > 0. */
130 #ifndef RF230_CONF_CSMA_RETRIES
131 #define RF230_CONF_CSMA_RETRIES 5
132 #endif
133 
134 //Automatic and manual CRC both append 2 bytes to packets
135 #if RF230_CONF_CHECKSUM || defined(RF230BB_HOOK_TX_PACKET)
136 #include "lib/crc16.h"
137 #endif
138 #define CHECKSUM_LEN 2
139 
140 /* Note the AUX_LEN is equal to the CHECKSUM_LEN in any tested configurations to date! */
141 #define AUX_LEN (CHECKSUM_LEN + TIMESTAMP_LEN + FOOTER_LEN)
142 #if AUX_LEN != CHECKSUM_LEN
143 #warning RF230 Untested Configuration!
144 #endif
145 
146 struct timestamp {
147  uint16_t time;
148  uint8_t authority_level;
149 };
150 
151 #define FOOTER1_CRC_OK 0x80
152 #define FOOTER1_CORRELATION 0x7f
153 
154 /* Leave radio on when USB powered or for testing low power protocols */
155 /* This allows DEBUGFLOW indication of packets received when the radio is "off" */
156 #if JACKDAW
157 #define RADIOALWAYSON 1
158 #else
159 #define RADIOALWAYSON 0
160 #define RADIOSLEEPSWHENOFF 1
161 #endif
162 
163 /* RS232 delays will cause 6lowpan fragment overruns! Use DEBUGFLOW instead. */
164 #define DEBUG 0
165 #if DEBUG
166 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
167 #define PRINTSHORT(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
168 #else
169 #define PRINTF(...)
170 #define PRINTSHORT(...)
171 #endif
172 #if DEBUG>1
173 /* Output format is suitable for text2pcap to convert to wireshark pcap file.
174  * Use $text2pcap -e 0x809a (these_outputs) capture.pcap
175  * Since the hardware calculates and appends the two byte checksum to Tx packets,
176  * we just add two zero bytes to the packet dump. Don't forget to enable wireshark
177  * 802.15.4 dissection even when the checksum is wrong!
178  */
179 #endif
180 
181 /* See clock.c and httpd-cgi.c for RADIOSTATS code */
182 #if AVR_WEBSERVER
183 #define RADIOSTATS 1
184 #endif
185 #if RADIOSTATS
186 uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
187 #endif
188 
189 #if RADIO_CONF_CALIBRATE_INTERVAL
190 /* Set in clock.c every 256 seconds */
191 /* The calibration is automatic when the radio turns on, so not needed when duty cycling */
192 uint8_t rf230_calibrate;
193 uint8_t rf230_calibrated; //for debugging, prints from main loop when calibration occurs
194 #endif
195 
196 /* Track flow through mac, rdc and radio drivers, see contiki-raven-main.c for example of use */
197 #if DEBUGFLOWSIZE
198 extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
199 #define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
200 #else
201 #define DEBUGFLOW(c)
202 #endif
203 
204 /* XXX hack: these will be made as Chameleon packet attributes */
205 #if RF230_CONF_TIMESTAMPS
206 rtimer_clock_t rf230_time_of_arrival, rf230_time_of_departure;
207 
208 int rf230_authority_level_of_sender;
209 
210 static rtimer_clock_t setup_time_for_transmission;
211 static unsigned long total_time_for_transmission, total_transmission_len;
212 static int num_transmissions;
213 #endif
214 
215 #if defined(__AVR_ATmega128RFA1__)
216 volatile uint8_t rf230_wakewait, rf230_txendwait, rf230_ccawait;
217 #endif
218 
219 uint8_t volatile rf230_pending;
220 
221 /* RF230 hardware delay times, from datasheet */
222 typedef enum{
223  TIME_TO_ENTER_P_ON = 510, /**< Transition time from VCC is applied to P_ON - most favorable case! */
224  TIME_P_ON_TO_TRX_OFF = 510, /**< Transition time from P_ON to TRX_OFF. */
225  TIME_SLEEP_TO_TRX_OFF = 880, /**< Transition time from SLEEP to TRX_OFF. */
226  TIME_RESET = 6, /**< Time to hold the RST pin low during reset */
227  TIME_ED_MEASUREMENT = 140, /**< Time it takes to do a ED measurement. */
228  TIME_CCA = 140, /**< Time it takes to do a CCA. */
229  TIME_PLL_LOCK = 150, /**< Maximum time it should take for the PLL to lock. */
230  TIME_FTN_TUNING = 25, /**< Maximum time it should take to do the filter tuning. */
231  TIME_NOCLK_TO_WAKE = 6, /**< Transition time from *_NOCLK to being awake. */
232  TIME_CMD_FORCE_TRX_OFF = 1, /**< Time it takes to execute the FORCE_TRX_OFF command. */
233  TIME_TRX_OFF_TO_PLL_ACTIVE = 180, /**< Transition time from TRX_OFF to: RX_ON, PLL_ON, TX_ARET_ON and RX_AACK_ON. */
234  TIME_STATE_TRANSITION_PLL_ACTIVE = 1, /**< Transition time from PLL active state to another. */
236 /*---------------------------------------------------------------------------*/
237 PROCESS(rf230_process, "RF230 driver");
238 /*---------------------------------------------------------------------------*/
239 
240 static int rf230_on(void);
241 static int rf230_off(void);
242 
243 static int rf230_read(void *buf, unsigned short bufsize);
244 
245 static int rf230_prepare(const void *data, unsigned short len);
246 static int rf230_transmit(unsigned short len);
247 static int rf230_send(const void *data, unsigned short len);
248 
249 static int rf230_receiving_packet(void);
250 static int rf230_pending_packet(void);
251 static int rf230_cca(void);
252 
253 uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
254 
255 /*---------------------------------------------------------------------------*/
256 static radio_result_t
257 get_value(radio_param_t param, radio_value_t *value)
258 {
259  return RADIO_RESULT_NOT_SUPPORTED;
260 }
261 /*---------------------------------------------------------------------------*/
262 static radio_result_t
263 set_value(radio_param_t param, radio_value_t value)
264 {
265  return RADIO_RESULT_NOT_SUPPORTED;
266 }
267 /*---------------------------------------------------------------------------*/
268 static radio_result_t
269 get_object(radio_param_t param, void *dest, size_t size)
270 {
271  return RADIO_RESULT_NOT_SUPPORTED;
272 }
273 /*---------------------------------------------------------------------------*/
274 static radio_result_t
275 set_object(radio_param_t param, const void *src, size_t size)
276 {
277  return RADIO_RESULT_NOT_SUPPORTED;
278 }
279 /*---------------------------------------------------------------------------*/
280 const struct radio_driver rf230_driver =
281  {
282  rf230_init,
283  rf230_prepare,
284  rf230_transmit,
285  rf230_send,
286  rf230_read,
287  rf230_cca,
288  rf230_receiving_packet,
289  rf230_pending_packet,
290  rf230_on,
291  rf230_off,
292  get_value,
293  set_value,
294  get_object,
295  set_object
296  };
297 
298 uint8_t RF230_receive_on;
299 static uint8_t channel;
300 
301 /* Received frames are buffered to rxframe in the interrupt routine in hal.c */
302 uint8_t rxframe_head,rxframe_tail;
303 hal_rx_frame_t rxframe[RF230_CONF_RX_BUFFERS];
304 
305 /*----------------------------------------------------------------------------*/
306 /** \brief This function return the Radio Transceivers current state.
307  *
308  * \retval P_ON When the external supply voltage (VDD) is
309  * first supplied to the transceiver IC, the
310  * system is in the P_ON (Poweron) mode.
311  * \retval BUSY_RX The radio transceiver is busy receiving a
312  * frame.
313  * \retval BUSY_TX The radio transceiver is busy transmitting a
314  * frame.
315  * \retval RX_ON The RX_ON mode enables the analog and digital
316  * receiver blocks and the PLL frequency
317  * synthesizer.
318  * \retval TRX_OFF In this mode, the SPI module and crystal
319  * oscillator are active.
320  * \retval PLL_ON Entering the PLL_ON mode from TRX_OFF will
321  * first enable the analog voltage regulator. The
322  * transceiver is ready to transmit a frame.
323  * \retval BUSY_RX_AACK The radio was in RX_AACK_ON mode and received
324  * the Start of Frame Delimiter (SFD). State
325  * transition to BUSY_RX_AACK is done if the SFD
326  * is valid.
327  * \retval BUSY_TX_ARET The radio transceiver is busy handling the
328  * auto retry mechanism.
329  * \retval RX_AACK_ON The auto acknowledge mode of the radio is
330  * enabled and it is waiting for an incomming
331  * frame.
332  * \retval TX_ARET_ON The auto retry mechanism is enabled and the
333  * radio transceiver is waiting for the user to
334  * send the TX_START command.
335  * \retval RX_ON_NOCLK The radio transceiver is listening for
336  * incomming frames, but the CLKM is disabled so
337  * that the controller could be sleeping.
338  * However, this is only true if the controller
339  * is run from the clock output of the radio.
340  * \retval RX_AACK_ON_NOCLK Same as the RX_ON_NOCLK state, but with the
341  * auto acknowledge module turned on.
342  * \retval BUSY_RX_AACK_NOCLK Same as BUSY_RX_AACK, but the controller
343  * could be sleeping since the CLKM pin is
344  * disabled.
345  * \retval STATE_TRANSITION The radio transceiver's state machine is in
346  * transition between two states.
347  */
348 //static uint8_t
349 uint8_t
351 {
353 }
354 
355 /*----------------------------------------------------------------------------*/
356 /** \brief This function checks if the radio transceiver is sleeping.
357  *
358  * \retval true The radio transceiver is in SLEEP or one of the *_NOCLK
359  * states.
360  * \retval false The radio transceiver is not sleeping.
361  */
362 #if 0
363 static bool radio_is_sleeping(void)
364 {
365  bool sleeping = false;
366 
367  /* The radio transceiver will be at SLEEP or one of the *_NOCLK states only if */
368  /* the SLP_TR pin is high. */
369  if (hal_get_slptr() != 0){
370  sleeping = true;
371  }
372 
373  return sleeping;
374 }
375 #endif
376 /*----------------------------------------------------------------------------*/
377 /** \brief This function will reset the state machine (to TRX_OFF) from any of
378  * its states, except for the SLEEP state.
379  */
380 static void
382 {
383  /* The data sheet is not clear on what happens when slptr is raised in RX on
384  * states, it "remains in the new state and returns to the preceding state
385  * when slptr is lowered". Possibly that is why there is an undocumented
386  * TIME_NOCLK_TO_WAKE delay here?
387  */
388  if (hal_get_slptr()) {
389  DEBUGFLOW('V');
391  delay_us(TIME_NOCLK_TO_WAKE);
392  }
393 
395  delay_us(TIME_CMD_FORCE_TRX_OFF);
396 }
397 /*---------------------------------------------------------------------------*/
398 static char
399 rf230_isidle(void)
400 {
401  uint8_t radio_state;
402  /* Contikimac can turn the radio off during an interrupt, so we always check
403  * slptr before doing the SPI transfer. The caller must also make this test
404  * if it could otherwise hang waiting for idle! */
405  if (hal_get_slptr()) {
406  if (RF230_receive_on) DEBUGFLOW('-');
407  return 1;
408  }
409  else {
410  radio_state = hal_subregister_read(SR_TRX_STATUS);
411  if (radio_state != BUSY_TX_ARET &&
412  radio_state != BUSY_RX_AACK &&
413  radio_state != STATE_TRANSITION &&
414  radio_state != BUSY_RX &&
415  radio_state != BUSY_TX) {
416  return(1);
417  }
418  else {
419  return(0);
420  }
421  }
422 }
423 
424 static void
425 rf230_waitidle(void)
426 {
427  /* TX_ARET with multiple csma retries can take a very long time to finish */
428  while (1) {
429  if (hal_get_slptr()) return;
430  if (rf230_isidle()) break;
431  }
432 }
433 
434 /*----------------------------------------------------------------------------*/
435 /** \brief This function will change the current state of the radio
436  * transceiver's internal state machine.
437  *
438  * \param new_state Here is a list of possible states:
439  * - RX_ON Requested transition to RX_ON state.
440  * - TRX_OFF Requested transition to TRX_OFF state.
441  * - PLL_ON Requested transition to PLL_ON state.
442  * - RX_AACK_ON Requested transition to RX_AACK_ON state.
443  * - TX_ARET_ON Requested transition to TX_ARET_ON state.
444  *
445  * \retval RADIO_SUCCESS Requested state transition completed
446  * successfully.
447  * \retval RADIO_INVALID_ARGUMENT Supplied function parameter out of bounds.
448  * \retval RADIO_WRONG_STATE Illegal state to do transition from.
449  * \retval RADIO_BUSY_STATE The radio transceiver is busy.
450  * \retval RADIO_TIMED_OUT The state transition could not be completed
451  * within resonable time.
452  */
453 static radio_status_t
454 radio_set_trx_state(uint8_t new_state)
455 {
456  uint8_t current_state;
457 
458  /*Check function parameter and current state of the radio transceiver.*/
459  if (!((new_state == TRX_OFF) ||
460  (new_state == RX_ON) ||
461  (new_state == PLL_ON) ||
462  (new_state == RX_AACK_ON) ||
463  (new_state == TX_ARET_ON))){
464  return RADIO_INVALID_ARGUMENT;
465  }
466 
467  if (hal_get_slptr()) {
468  DEBUGFLOW('W');
469  return RADIO_WRONG_STATE;
470  }
471 
472  /* Wait for radio to finish previous operation */
473  rf230_waitidle();
474  current_state = radio_get_trx_state();
475 
476  if (new_state == current_state){
477  return RADIO_SUCCESS;
478  }
479 
480 
481  /* At this point it is clear that the requested new_state is: */
482  /* TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON. */
483 
484  /* The radio transceiver can be in one of the following states: */
485  /* TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON, TX_ARET_ON. */
486  if(new_state == TRX_OFF){
487  if (hal_get_slptr()) DEBUGFLOW('K');DEBUGFLOW('K');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));
488  radio_reset_state_machine(); /* Go to TRX_OFF from any state. */
489  } else {
490  /* It is not allowed to go from RX_AACK_ON or TX_AACK_ON and directly to */
491  /* TX_AACK_ON or RX_AACK_ON respectively. Need to go via PLL_ON. */
492  /* (Old datasheets allowed other transitions, but this code complies with */
493  /* the current specification for RF230, RF231 and 128RFA1.) */
494  if (((new_state == TX_ARET_ON) && (current_state == RX_AACK_ON)) ||
495  ((new_state == RX_AACK_ON) && (current_state == TX_ARET_ON))){
496  /* First do intermediate state transition to PLL_ON. */
497  /* The final state transition is handled after the if-else if. */
500  }
501 
502  /* Any other state transition can be done directly. */
503  hal_subregister_write(SR_TRX_CMD, new_state);
504 
505  /* When the PLL is active most states can be reached in 1us. However, from */
506  /* TRX_OFF the PLL needs time to activate. */
507  if (current_state == TRX_OFF){
508  delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE);
509  } else {
511  }
512  } /* end: if(new_state == TRX_OFF) ... */
513 
514  /* Verify state transition.
515  * Radio could have already switched to an RX_BUSY state, at least in cooja.
516  * Don't know what the hardware does but this would not be an error.*/
517  current_state = radio_get_trx_state();
518  if (current_state != new_state) {
519  if (((new_state == RX_ON) && (current_state == BUSY_RX)) ||
520  ((new_state == RX_AACK_ON) && (current_state == BUSY_RX_AACK))) {
521  /* This is OK. */
522  } else {
523  DEBUGFLOW('N');DEBUGFLOW('A'+new_state);DEBUGFLOW('A'+radio_get_trx_state());DEBUGFLOW('N');
524  return RADIO_TIMED_OUT;
525  }
526  }
527 
528  return RADIO_SUCCESS;
529 }
530 
531 void
532 rf230_set_promiscuous_mode(bool isPromiscuous) {
533 #if RF230_CONF_AUTOACK
534  is_promiscuous = isPromiscuous;
535 /* TODO: Figure out when to pass promisc state to 802.15.4 */
536 // radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON);
537 #endif
538 }
539 
540 bool
541 rf230_is_ready_to_send() {
542  switch(radio_get_trx_state()) {
543  case BUSY_TX:
544  case BUSY_TX_ARET:
545  return false;
546  }
547 
548  return true;
549 }
550 
551 
552 static void
553 flushrx(void)
554 {
555  rxframe[rxframe_head].length=0;
556 }
557 /*---------------------------------------------------------------------------*/
558 static void
559 radio_on(void)
560 {
561 // ENERGEST_OFF(ENERGEST_TYPE_LISTEN);//testing
562  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
563  RF230_receive_on = 1;
564 #ifdef RF230BB_HOOK_RADIO_ON
565  RF230BB_HOOK_RADIO_ON();
566 #endif
567 
568 /* If radio is off (slptr high), turn it on */
569  if (hal_get_slptr()) {
570  ENERGEST_ON(ENERGEST_TYPE_LED_RED);
571 #if RF230BB_CONF_LEDONPORTE1
572  PORTE|=(1<<PE1); //ledon
573 #endif
574 #if defined(__AVR_ATmega128RFA1__)
575  /* Use the poweron interrupt for delay */
576  rf230_wakewait=1;
577  {
578  uint8_t sreg = SREG;
579  sei();
580  if (hal_get_slptr() == 0) DEBUGFLOW('$');
582  {
583  int i;
584  for (i=0;i<10000;i++) {
585  if (!rf230_wakewait) break;
586  }
587  if (i>=10000) {DEBUGFLOW('G');DEBUGFLOW('g');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));}
588  }
589  SREG = sreg;
590  }
591 #else
592 /* SPI based radios. The wake time depends on board capacitance.
593  * Make sure the delay is long enough, as using SPI too soon will reset the MCU!
594  * Use 2x the nominal value for safety. 1.5x is not long enough for Raven!
595  */
596 // uint8_t sreg = SREG;cli();
598  delay_us(2*TIME_SLEEP_TO_TRX_OFF);
599 // SREG=sreg;
600 #endif
601  }
602 
603 #if RF230_CONF_AUTOACK
604  // radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON);
606 #else
608 #endif
609  rf230_waitidle();
610 }
611 static void
612 radio_off(void)
613 {
614  RF230_receive_on = 0;
615  if (hal_get_slptr()) {
616  DEBUGFLOW('F');
617  return;
618  }
619 
620 #if RF230BB_CONF_LEDONPORTE1
621  PORTE&=~(1<<PE1); //ledoff
622 #endif
623 #ifdef RF230BB_HOOK_RADIO_OFF
624  RF230BB_HOOK_RADIO_OFF();
625 #endif
626 
627  /* Wait for any transmission to end */
628  rf230_waitidle();
629 
630 #if RADIOALWAYSON
631 /* Do not transmit autoacks when stack thinks radio is off */
633 #else
634  /* Force the device into TRX_OFF.
635  * First make sure an interrupt did not initiate a sleep. */
636  if (hal_get_slptr()) {
637  DEBUGFLOW('?');
638  return;
639  }
641 #if RADIOSLEEPSWHENOFF
642  /* Sleep Radio */
644  ENERGEST_OFF(ENERGEST_TYPE_LED_RED);
645 #endif
646 #endif /* RADIOALWAYSON */
647 
648  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
649 }
650 /*---------------------------------------------------------------------------*/
651 static void
652 set_txpower(uint8_t power)
653 {
654  if (power > TX_PWR_17_2DBM){
655  power=TX_PWR_17_2DBM;
656  }
657  if (hal_get_slptr()) {
658  DEBUGFLOW('f');
659  PRINTF("rf230_set_txpower:Sleeping"); //happens with cxmac
660  } else {
661  //DEBUGFLOW('g');
663  }
664 }
665 void rf230_setpendingbit(uint8_t value)
666 {
668 }
669 #if 0
670 /*----------------------------------------------------------------------------*/
671 /**
672  \brief Calibrate the internal RC oscillator
673 
674  This function calibrates the internal RC oscillator, based
675  on an external 32KHz crystal connected to TIMER2. In order to
676  verify the calibration result you can program the CKOUT fuse
677  and monitor the CPU clock on an I/O pin.
678 */
679 #define AVR_ENTER_CRITICAL_REGION( ) {uint8_t volatile saved_sreg = SREG; cli( )
680 #define AVR_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg;}
681  uint8_t osccal_original,osccal_calibrated;
682 void
684 {
685 
686  /* Calibrate RC Oscillator: The calibration routine is done by clocking TIMER2
687  * from the external 32kHz crystal while running an internal timer simultaneously.
688  * The internal timer will be clocked at the same speed as the internal RC
689  * oscillator, while TIMER2 is running at 32768 Hz. This way it is not necessary
690  * to use a timed loop, and keep track cycles in timed loop vs. optimization
691  * and compiler.
692  */
693  uint8_t osccal_original = OSCCAL;
694  volatile uint16_t temp;
695 
696  /* Start with current value, which for some MCUs could be in upper or lower range */
697 
698 // PRR0 &= ~((1 << PRTIM2)|(1 << PRTIM1)); /* Enable Timer 1 and 2 */
699 
700  TIMSK2 = 0x00; /* Disable Timer/Counter 2 interrupts. */
701  TIMSK1 = 0x00; /* Disable Timer/Counter 1 interrupts. */
702 
703  /* Enable TIMER/COUNTER 2 to be clocked from the external 32kHz clock crystal.
704  * Then wait for the timer to become stable before doing any calibration.
705  */
706  ASSR |= (1 << AS2);
707  // while (ASSR & ((1 << TCN2UB)|(1 << OCR2AUB)|(1 << TCR2AUB)|(1 << TCR2BUB))) { ; }
708  TCCR2B = 1 << CS20; /* run timer 2 at divide by 1 (32KHz) */
709 
710  delay_us(50000UL); //crystal takes significant time to stabilize
712 
713  uint8_t counter = 128;
714  bool cal_ok = false;
715  do{
716  /* wait for timer to be ready for updated config */
717  TCCR1B = 1 << CS10;
718 
719  while (ASSR & ((1 << TCN2UB)|(1 << OCR2AUB)|(1 << TCR2AUB)|(1 << TCR2BUB))) { ; }
720 
721  TCNT2 = 0x80;
722  TCNT1 = 0;
723 
724  TIFR2 = 0xFF; /* Clear TIFR2 flags (Yes, really) */
725 
726  /* Wait for TIMER/COUNTER 2 to overflow. Stop TIMER/COUNTER 1 and 2, and
727  * read the counter value of TIMER/COUNTER 1. It will now contain the
728  * number of cpu cycles elapsed within the 3906.25 microsecond period.
729  */
730  while (!(TIFR2 & (1 << TOV2))){
731  ;
732  }
733  temp = TCNT1;
734 
735  TCCR1B = 0;
736 /* Defining these as floating point introduces a lot of code and the 256 byte .clz table to RAM */
737 /* At 8 MHz we would expect 8*3906.25 = 31250 CPU clocks */
738 #define cal_upper 32812 //(31250*1.05) // 32812 = 0x802c
739 #define cal_lower 29687 //(31250*0.95) // 29687 = 0x73f7
740  /* Iteratively reduce the error to be within limits */
741  if (temp < cal_lower) {
742  /* Too slow. Put the hammer down. */
743  if (OSCCAL==0x7e) break; //stay in lowest range
744  if (OSCCAL==0xff) break;
745  OSCCAL++;
746  } else if (temp > cal_upper) {
747  /* Too fast, retard. */
748  if (OSCCAL==0x81) break; //stay in highest range
749  if (OSCCAL==0x00) break;
750  OSCCAL--;
751  } else {
752  /* The CPU clock frequency is now within +/- 0.5% of the target value. */
753  cal_ok = true;
754  }
755 
756  counter--;
757  } while ((counter != 0) && (false == cal_ok));
758 
759  osccal_calibrated=OSCCAL;
760  if (true != cal_ok) {
761  /* We failed, therefore restore previous OSCCAL value. */
762  OSCCAL = osccal_original;
763  }
764 
765  OSCCAL = osccal_original;
766  TCCR2B = 0;
767 
768  ASSR &= ~(1 << AS2);
769 
770  /* Disable both timers again to save power. */
771  // PRR0 |= (1 << PRTIM2);/* |(1 << PRTIM1); */
772 
774 }
775 #endif
776 /*---------------------------------------------------------------------------*/
777 int
778 rf230_init(void)
779 {
780  uint8_t i;
781  DEBUGFLOW('i');
782  /* Wait in case VCC just applied */
783  delay_us(TIME_TO_ENTER_P_ON);
784  /* Initialize Hardware Abstraction Layer */
785  hal_init();
786 
787  /* Calibrate oscillator */
788  // printf_P(PSTR("\nBefore calibration OSCCAL=%x\n"),OSCCAL);
789  // calibrate_rc_osc_32k();
790  // printf_P(PSTR("After calibration OSCCAL=%x\n"),OSCCAL);
791 
792  /* Set receive buffers empty and point to the first */
793  for (i=0;i<RF230_CONF_RX_BUFFERS;i++) {
794  rxframe[i].length=0;
795  }
796  rxframe_head=0;rxframe_tail=0;
797 
798  /* Do full rf230 Reset */
799  hal_set_rst_low();
801  /* On powerup a TIME_RESET delay is needed here, however on some other MCU reset
802  * (JTAG, WDT, Brownout) the radio may be sleeping. It can enter an uncertain
803  * state (sending wrong hardware FCS for example) unless the full wakeup delay
804  * is done.
805  * Wake time depends on board capacitance; use 2x the nominal delay for safety.
806  * See www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=78725
807  */
808  delay_us(2*TIME_SLEEP_TO_TRX_OFF);
809  //delay_us(TIME_RESET); /* Old impl. */
811 
812  /* Force transition to TRX_OFF */
814  delay_us(TIME_P_ON_TO_TRX_OFF);
815 
816  /* Verify that it is a supported version */
817  /* Note gcc optimizes this away if DEBUG is not set! */
818  //ATMEGA128RFA1 - version 4, ID 31
819  uint8_t tvers = hal_register_read(RG_VERSION_NUM);
820  uint8_t tmanu = hal_register_read(RG_MAN_ID_0);
821 
822  if ((tvers != RF230_REVA) && (tvers != RF230_REVB))
823  PRINTF("rf230: Unsupported version %u\n",tvers);
824  if (tmanu != SUPPORTED_MANUFACTURER_ID)
825  PRINTF("rf230: Unsupported manufacturer ID %u\n",tmanu);
826 
827  PRINTF("rf230: Version %u, ID %u\n",tvers,tmanu);
828 
829  rf230_warm_reset();
830 
831  /* Start the packet receive process */
832  process_start(&rf230_process, NULL);
833 
834  /* Leave radio in on state (?)*/
835  radio_on();
836 
837  return 1;
838 }
839 /*---------------------------------------------------------------------------*/
840 /* Used to reinitialize radio parameters without losing pan and mac address, channel, power, etc. */
841 void rf230_warm_reset(void) {
842 #if RF230_CONF_SNEEZER && JACKDAW
843  /* Take jackdaw radio out of test mode */
844 #warning Manipulating PORTB pins for RF230 Sneezer mode!
845  PORTB &= ~(1<<7);
846  DDRB &= ~(1<<7);
847 #endif
848 
849  hal_register_write(RG_IRQ_MASK, RF230_SUPPORTED_INTERRUPT_MASK);
850 
851  /* Set up number of automatic retries 0-15
852  * (0 implies PLL_ON sends instead of the extended TX_ARET mode */
854  (RF230_CONF_FRAME_RETRIES > 0) ? (RF230_CONF_FRAME_RETRIES - 1) : 0 );
855 
856  /* Set up carrier sense/clear channel assesment parameters for extended operating mode */
857  hal_subregister_write(SR_MAX_CSMA_RETRIES, RF230_CONF_CSMA_RETRIES );//highest allowed retries
858  hal_register_write(RG_CSMA_BE, 0x80); //min backoff exponent 0, max 8 (highest allowed)
859  hal_register_write(RG_CSMA_SEED_0,hal_register_read(RG_PHY_RSSI) );//upper two RSSI reg bits RND_VALUE are random in rf231
860  // hal_register_write(CSMA_SEED_1,42 );
861 
862  /* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */
863 //hal_subregister_write(SR_CCA_MODE,1); //1 is the power-on default
864 
865  /* Carrier sense threshold (not implemented in RF230 or RF231) */
866 // hal_subregister_write(SR_CCA_CS_THRES,1);
867 
868  /* Receiver sensitivity. If nonzero rf231/128rfa1 saves 0.5ma in rx mode */
869  /* Not implemented on rf230 but does not hurt to write to it */
870 #ifdef RF230_MIN_RX_POWER
871 #if RF230_MIN_RX_POWER > 84
872 #warning rf231 power threshold clipped to -48dBm by hardware register
874 #elif RF230_MIN_RX_POWER < 0
875 #error RF230_MIN_RX_POWER can not be negative!
876 #endif
877  hal_register_write(RG_RX_SYN, RF230_MIN_RX_POWER/6 + 1); //1-15 -> -90 to -48dBm
878 #endif
879 
880  /* CCA energy threshold = -91dB + 2*SR_CCA_ED_THRESH. Reset defaults to -77dB */
881  /* Use RF230 base of -91; RF231 base is -90 according to datasheet */
882 #ifdef RF230_CONF_CCA_THRES
883 #if RF230_CONF_CCA_THRES < -91
884 #warning
885 #warning RF230_CONF_CCA_THRES below hardware limit, setting to -91dBm
886 #warning
888 #elif RF230_CONF_CCA_THRES > -61
889 #warning
890 #warning RF230_CONF_CCA_THRES above hardware limit, setting to -61dBm
891 #warning
893 #else
894  hal_subregister_write(SR_CCA_ED_THRES,(RF230_CONF_CCA_THRES+91)/2);
895 #endif
896 #endif
897 
898  /* Use automatic CRC unless manual is specified */
899 #if RF230_CONF_CHECKSUM
901 #else
903 #endif
904 
905 /* Limit tx power for testing miniature Raven mesh */
906 #ifdef RF230_MAX_TX_POWER
907  set_txpower(RF230_MAX_TX_POWER); //0=3dbm 15=-17.2dbm
908 #endif
909 }
910 /*---------------------------------------------------------------------------*/
911 static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN];
912 
913 static int
914 rf230_transmit(unsigned short payload_len)
915 {
916  int txpower;
917  uint8_t total_len;
918  uint8_t tx_result;
919 #if RF230_CONF_TIMESTAMPS
920  struct timestamp timestamp;
921 #endif /* RF230_CONF_TIMESTAMPS */
922 
923  /* If radio is sleeping we have to turn it on first */
924  /* This automatically does the PLL calibrations */
925  if (hal_get_slptr()) {
926 #if defined(__AVR_ATmega128RFA1__)
927  ENERGEST_ON(ENERGEST_TYPE_LED_RED);
928 #if RF230BB_CONF_LEDONPORTE1
929  PORTE|=(1<<PE1); //ledon
930 #endif
931  rf230_wakewait=1;
933  {
934  int i;
935  for (i=0;i<10000;i++) {
936  if (!rf230_wakewait) break;
937  }
938  if (i>=10000) {DEBUGFLOW('G');DEBUGFLOW('G');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));}
939  }
940 #else
942  DEBUGFLOW('j');
943  delay_us(2*TIME_SLEEP_TO_TRX_OFF); //extra delay (2x) depends on board capacitance
944 #endif
945 
946  } else {
947 #if RADIO_CONF_CALIBRATE_INTERVAL
948  /* If nonzero, do periodic calibration. See clock.c */
949  if (rf230_calibrate) {
950  DEBUGFLOW('k');
951  hal_subregister_write(SR_PLL_CF_START,1); //takes 80us max
952  hal_subregister_write(SR_PLL_DCU_START,1); //takes 6us, concurrently
953  rf230_calibrate=0;
954  rf230_calibrated=1;
955  delay_us(80); //?
956  }
957 #endif
958  }
959 
960  /* Wait for any previous operation or state transition to finish */
961  rf230_waitidle();
962  if(RF230_receive_on) {
963  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
964  }
965  /* Prepare to transmit */
966 #if RF230_CONF_FRAME_RETRIES
968  DEBUGFLOW('t');
969 #else
971  DEBUGFLOW('T');
972 #endif
973 
974  txpower = 0;
975 
976  if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
977  /* Remember the current transmission power */
978  txpower = rf230_get_txpower();
979  /* Set the specified transmission power */
980  set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1);
981  }
982 
983  total_len = payload_len + AUX_LEN;
984 
985 #if RF230_CONF_TIMESTAMPS
986  rtimer_clock_t txtime = timesynch_time();
987 #endif /* RF230_CONF_TIMESTAMPS */
988 
989  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
990 
991 /* No interrupts across frame download! */
993 
994  /* Toggle the SLP_TR pin to initiate the frame transmission, then transfer
995  * the frame. We have about 16 us + the on-air transmission time of 40 bits
996  * (for the synchronization header) before the transceiver sends the PHR. */
999  hal_frame_write(buffer, total_len);
1000 
1002  PRINTF("rf230_transmit: %d\n", (int)total_len);
1003 
1004 #if DEBUG>1
1005 /* Note the dumped packet will have a zero checksum unless compiled with RF230_CONF_CHECKSUM
1006  * since we don't know what it will be if calculated by the hardware.
1007  */
1008  {
1009  uint8_t i;
1010  PRINTF("0000"); //Start a new wireshark packet
1011  for (i=0;i<total_len;i++) PRINTF(" %02x",buffer[i]);
1012  PRINTF("\n");
1013  }
1014 #endif
1015 
1016 #if RADIOSTATS
1017  RF230_sendpackets++;
1018 #endif
1019 
1020  /* We wait until transmission has ended so that we get an
1021  accurate measurement of the transmission time.*/
1022  rf230_waitidle();
1023 
1024  /* Get the transmission result */
1025 #if RF230_CONF_FRAME_RETRIES
1026  tx_result = hal_subregister_read(SR_TRAC_STATUS);
1027 #else
1028  tx_result=RADIO_TX_OK;
1029 #endif
1030 
1031 #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
1032  ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,rf230_get_txpower());
1033 #endif
1034 
1035  /* Restore the transmission power */
1036  if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
1037  set_txpower(txpower & 0xff);
1038  }
1039 
1040 #if RF230_CONF_TIMESTAMPS
1041  setup_time_for_transmission = txtime - timestamp.time;
1042 
1043  if(num_transmissions < 10000) {
1044  total_time_for_transmission += timesynch_time() - txtime;
1045  total_transmission_len += total_len;
1046  num_transmissions++;
1047  }
1048 
1049 #endif /* RF230_CONF_TIMESTAMPS */
1050 
1051  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
1052  if(RF230_receive_on) {
1053  DEBUGFLOW('l');
1054  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
1055  radio_on();
1056  } else {
1057 #if RADIOALWAYSON
1058  /* Enable reception */
1059  radio_on();
1060 #else
1061  radio_off();
1062  PRINTF("rf230_transmit: turning radio off\n");
1063 #endif
1064  }
1065 
1066 #if RF230_INSERTACK
1067  ack_pending = 0;
1068 #endif
1069 
1070  if (tx_result==1) { //success, data pending from addressee
1071  tx_result=RADIO_TX_OK; //handle as ordinary success
1072  }
1073 
1074  if (tx_result==RADIO_TX_OK) {
1075  RIMESTATS_ADD(lltx);
1076  if(packetbuf_attr(PACKETBUF_ATTR_RELIABLE))
1077  RIMESTATS_ADD(ackrx); //ack was requested and received
1078 #if RF230_INSERTACK
1079  /* Not PAN broadcast to FFFF, and ACK was requested and received */
1080  if (!((buffer[5]==0xff) && (buffer[6]==0xff)) && (buffer[0]&(1<<6)))
1081  ack_pending=1;
1082 #endif
1083 
1084  } else if (tx_result==3) { //CSMA channel access failure
1085  DEBUGFLOW('m');
1086  RIMESTATS_ADD(contentiondrop);
1087  PRINTF("rf230_transmit: Transmission never started\n");
1088  tx_result = RADIO_TX_COLLISION;
1089  } else if (tx_result==5) { //Expected ACK, none received
1090  DEBUGFLOW('n');
1091  tx_result = RADIO_TX_NOACK;
1092  PRINTF("rf230_transmit: ACK not received\n");
1093  RIMESTATS_ADD(badackrx); //ack was requested but not received
1094  } else if (tx_result==7) { //Invalid (Can't happen since waited for idle above?)
1095  DEBUGFLOW('o');
1096  tx_result = RADIO_TX_ERR;
1097  }
1098 
1099  return tx_result;
1100 }
1101 /*---------------------------------------------------------------------------*/
1102 static int
1103 rf230_prepare(const void *payload, unsigned short payload_len)
1104 {
1105  int ret = 0;
1106  uint8_t total_len,*pbuf;
1107 #if RF230_CONF_TIMESTAMPS
1108  struct timestamp timestamp;
1109 #endif
1110 #if RF230_CONF_CHECKSUM
1111  uint16_t checksum;
1112 #endif
1113 #if RF230_INSERTACK
1114 /* The sequence number is needed to construct the ack packet */
1115  ack_seqnum=*(((uint8_t *)payload)+2);
1116 #endif
1117 
1118  DEBUGFLOW('p');
1119 
1120 // PRINTF("rf230: sending %d bytes\n", payload_len);
1121 // PRINTSHORT("s%d ",payload_len);
1122 
1123  RIMESTATS_ADD(tx);
1124 
1125 #if RF230_CONF_CHECKSUM
1126  checksum = crc16_data(payload, payload_len, 0);
1127 #endif
1128 
1129  /* Copy payload to RAM buffer */
1130  total_len = payload_len + AUX_LEN;
1131  if (total_len > RF230_MAX_TX_FRAME_LENGTH){
1132 #if RADIOSTATS
1133  RF230_sendfail++;
1134 #endif
1135  PRINTF("rf230_prepare: packet too large (%d, max: %d)\n",total_len,RF230_MAX_TX_FRAME_LENGTH);
1136  ret = -1;
1137  goto bail;
1138  }
1139  pbuf=&buffer[0];
1140  memcpy(pbuf,payload,payload_len);
1141  pbuf+=payload_len;
1142 
1143 #if RF230_CONF_CHECKSUM
1144  memcpy(pbuf,&checksum,CHECKSUM_LEN);
1145  pbuf+=CHECKSUM_LEN;
1146 #endif
1147 
1148 #if RF230_CONF_TIMESTAMPS
1149  timestamp.authority_level = timesynch_authority_level();
1150  timestamp.time = timesynch_time();
1151  memcpy(pbuf,&timestamp,TIMESTAMP_LEN);
1152  pbuf+=TIMESTAMP_LEN;
1153 #endif
1154 /*------------------------------------------------------------*/
1155 
1156 #ifdef RF230BB_HOOK_TX_PACKET
1157 #if !RF230_CONF_CHECKSUM
1158  { // Add a checksum before we log the packet out
1159  uint16_t checksum;
1160  checksum = crc16_data(payload, payload_len, 0);
1161  memcpy(buffer+total_len-CHECKSUM_LEN,&checksum,CHECKSUM_LEN);
1162  }
1163 #endif /* RF230_CONF_CHECKSUM */
1164  RF230BB_HOOK_TX_PACKET(buffer,total_len);
1165 #endif
1166 
1167 
1168 bail:
1169  return ret;
1170 }
1171 /*---------------------------------------------------------------------------*/
1172 static int
1173 rf230_send(const void *payload, unsigned short payload_len)
1174 {
1175  int ret = 0;
1176 
1177 #ifdef RF230BB_HOOK_IS_SEND_ENABLED
1178  if(!RF230BB_HOOK_IS_SEND_ENABLED()) {
1179  goto bail;
1180  }
1181 #endif
1182 
1183  if((ret=rf230_prepare(payload, payload_len))) {
1184  PRINTF("rf230_send: Unable to send, prep failed (%d)\n",ret);
1185  goto bail;
1186  }
1187 
1188  ret = rf230_transmit(payload_len);
1189 
1190 bail:
1191 #if RADIOSTATS
1192  if (ret) RF230_sendfail++;
1193 #endif
1194  return ret;
1195 }
1196 /*---------------------------------------------------------------------------*/
1197 static int
1198 rf230_off(void)
1199 {
1200  /* Don't do anything if we are already turned off. */
1201  if(RF230_receive_on == 0) {
1202  //if (!hal_get_slptr()) DEBUGFLOW('5');
1203  return 0;
1204  }
1205  //if (hal_get_slptr()) DEBUGFLOW('6');
1206 
1207  /* If we are currently receiving a packet, we still call radio_off(),
1208  as that routine waits until Rx is complete (packet uploaded in ISR
1209  so no worries about losing it). The transmit routine may also turn
1210 + the radio off on a return to sleep. rf230_isidle checks for that. */
1211  if (!rf230_isidle()) {
1212  //DEBUGFLOW('X');DEBUGFLOW('X');DEBUGFLOW('A'+hal_subregister_read(SR_TRX_STATUS));
1213  PRINTF("rf230_off: busy receiving\r\n");
1214  //return 1;
1215  }
1216 
1217  radio_off();
1218  return 0;
1219 }
1220 /*---------------------------------------------------------------------------*/
1221 static int
1222 rf230_on(void)
1223 {
1224  if(RF230_receive_on) {
1225  //if (hal_get_slptr()) DEBUGFLOW('Q');//Cooja TODO: shows sleeping occasionally
1226  return 1;
1227  }
1228 
1229  radio_on();
1230  return 1;
1231 }
1232 /*---------------------------------------------------------------------------*/
1233 uint8_t
1234 rf230_get_channel(void)
1235 {
1236 //jackdaw reads zero channel, raven reads correct channel?
1237 //return hal_subregister_read(SR_CHANNEL);
1238  return channel;
1239 }
1240 /*---------------------------------------------------------------------------*/
1241 void
1242 rf230_set_channel(uint8_t c)
1243 {
1244  /* Wait for any transmission to end. */
1245  PRINTF("rf230: Set Channel %u\n",c);
1246  rf230_waitidle();
1247  channel=c;
1249 }
1250 /*---------------------------------------------------------------------------*/
1251 void
1252 rf230_listen_channel(uint8_t c)
1253 {
1254  /* Same as set channel but forces RX_ON state for sniffer or energy scan */
1255 // PRINTF("rf230: Listen Channel %u\n",c);
1256  rf230_set_channel(c);
1258 }
1259 /*---------------------------------------------------------------------------*/
1260 void
1261 rf230_set_pan_addr(unsigned pan,
1262  unsigned addr,
1263  const uint8_t ieee_addr[8])
1264 //rf230_set_pan_addr(uint16_t pan,uint16_t addr,uint8_t *ieee_addr)
1265 {
1266  PRINTF("rf230: PAN=%x Short Addr=%x\n",pan,addr);
1267 
1268  uint8_t abyte;
1269  abyte = pan & 0xFF;
1271  abyte = (pan >> 8*1) & 0xFF;
1273 
1274  abyte = addr & 0xFF;
1276  abyte = (addr >> 8*1) & 0xFF;
1278 
1279  if (ieee_addr != NULL) {
1280  PRINTF("MAC=%x",*ieee_addr);
1281  hal_register_write(RG_IEEE_ADDR_7, *ieee_addr++);
1282  PRINTF(":%x",*ieee_addr);
1283  hal_register_write(RG_IEEE_ADDR_6, *ieee_addr++);
1284  PRINTF(":%x",*ieee_addr);
1285  hal_register_write(RG_IEEE_ADDR_5, *ieee_addr++);
1286  PRINTF(":%x",*ieee_addr);
1287  hal_register_write(RG_IEEE_ADDR_4, *ieee_addr++);
1288  PRINTF(":%x",*ieee_addr);
1289  hal_register_write(RG_IEEE_ADDR_3, *ieee_addr++);
1290  PRINTF(":%x",*ieee_addr);
1291  hal_register_write(RG_IEEE_ADDR_2, *ieee_addr++);
1292  PRINTF(":%x",*ieee_addr);
1293  hal_register_write(RG_IEEE_ADDR_1, *ieee_addr++);
1294  PRINTF(":%x",*ieee_addr);
1295  hal_register_write(RG_IEEE_ADDR_0, *ieee_addr);
1296  PRINTF("\n");
1297  }
1298 }
1299 /*---------------------------------------------------------------------------*/
1300 /*
1301  * Interrupt leaves frame intact in FIFO.
1302  */
1303 #if RF230_CONF_TIMESTAMPS
1304 static volatile rtimer_clock_t interrupt_time;
1305 static volatile int interrupt_time_set;
1306 #endif /* RF230_CONF_TIMESTAMPS */
1307 int
1308 rf230_interrupt(void)
1309 {
1310  /* Poll the receive process, unless the stack thinks the radio is off */
1311 #if RADIOALWAYSON
1312 if (RF230_receive_on) {
1313  DEBUGFLOW('+');
1314 #endif
1315 #if RF230_CONF_TIMESTAMPS
1316  interrupt_time = timesynch_time();
1317  interrupt_time_set = 1;
1318 #endif /* RF230_CONF_TIMESTAMPS */
1319 
1320  process_poll(&rf230_process);
1321 
1322  rf230_pending = 1;
1323 
1324 #if RADIOSTATS //TODO:This will double count buffered packets
1325  RF230_receivepackets++;
1326 #endif
1327  RIMESTATS_ADD(llrx);
1328 
1329 #if RADIOALWAYSON
1330 } else {
1331  DEBUGFLOW('-');
1332  rxframe[rxframe_head].length=0;
1333 }
1334 #endif
1335  return 1;
1336 }
1337 /*---------------------------------------------------------------------------*/
1338 /* Process to handle input packets
1339  * Receive interrupts cause this process to be polled
1340  * It calls the core MAC layer which calls rf230_read to get the packet
1341  * rf230processflag can be printed in the main idle loop for debugging
1342  */
1343 #if 0
1344 uint8_t rf230processflag;
1345 #define RF230PROCESSFLAG(arg) rf230processflag=arg
1346 #else
1347 #define RF230PROCESSFLAG(arg)
1348 #endif
1349 
1350 PROCESS_THREAD(rf230_process, ev, data)
1351 {
1352  int len;
1353  PROCESS_BEGIN();
1354  RF230PROCESSFLAG(99);
1355 
1356  while(1) {
1357  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
1358  RF230PROCESSFLAG(42);
1359 
1360  packetbuf_clear();
1361 
1362  /* Turn off interrupts to avoid ISR writing to the same buffers we are reading. */
1364 
1365  len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
1366 
1367  /* Restore interrupts. */
1369  PRINTF("rf230_read: %u bytes lqi %u\n",len,rf230_last_correlation);
1370 #if DEBUG>1
1371  {
1372  uint8_t i;
1373  unsigned const char * rxdata = packetbuf_dataptr();
1374  PRINTF("0000");
1375  for (i=0;i<len+AUX_LEN;i++) PRINTF(" %02x",rxdata[i]);
1376  PRINTF("\n");
1377  }
1378 #endif
1379 
1380 
1381  RF230PROCESSFLAG(1);
1382  if(len > 0) {
1383  packetbuf_set_datalen(len);
1384  RF230PROCESSFLAG(2);
1385  NETSTACK_RDC.input();
1386  } else {
1387 #if RADIOSTATS
1388  RF230_receivefail++;
1389 #endif
1390  }
1391  }
1392 
1393  PROCESS_END();
1394 }
1395 /* Read packet that was uploaded from Radio in ISR, else return zero.
1396  * The two-byte checksum is appended but the returned length does not include it.
1397  * Frames are buffered in the interrupt routine so this routine
1398  * does not access the hardware or change its status.
1399  * However, this routine must be called with interrupts disabled to avoid ISR
1400  * writing to the same buffer we are reading.
1401  * As a result, PRINTF cannot be used in here.
1402  */
1403 /*---------------------------------------------------------------------------*/
1404 static int
1405 rf230_read(void *buf, unsigned short bufsize)
1406 {
1407  uint8_t len,*framep;
1408 #if FOOTER_LEN
1409  uint8_t footer[FOOTER_LEN];
1410 #endif
1411 #if RF230_CONF_CHECKSUM
1412  uint16_t checksum;
1413 #endif
1414 #if RF230_CONF_TIMESTAMPS
1415  struct timestamp t;
1416 #endif
1417 #if RF230_INSERTACK
1418 /* Return an ACK to the mac layer */
1419  if(ack_pending && bufsize == 3){
1420  ack_pending=0;
1421  uint8_t *buff=(uint8_t *)buf;
1422  buff[0]=2;
1423  buff[1]=0;
1424  buff[2]=ack_seqnum;
1425  return bufsize;
1426  }
1427 #endif
1428 
1429  /* The length includes the twp-byte checksum but not the LQI byte */
1430  len=rxframe[rxframe_head].length;
1431  if (len==0) {
1432 #if RADIOALWAYSON && DEBUGFLOWSIZE
1433  if (RF230_receive_on==0) {if (debugflow[debugflowsize-1]!='z') DEBUGFLOW('z');} //cxmac calls with radio off?
1434 #endif
1435  return 0;
1436  }
1437 
1438 #if RF230_CONF_TIMESTAMPS
1439  if(interrupt_time_set) {
1440  rf230_time_of_arrival = interrupt_time;
1441  interrupt_time_set = 0;
1442  } else {
1443  rf230_time_of_arrival = 0;
1444  }
1445  rf230_time_of_departure = 0;
1446 #endif /* RF230_CONF_TIMESTAMPS */
1447 
1448  if(len > RF230_MAX_TX_FRAME_LENGTH) {
1449  /* Oops, we must be out of sync. */
1450  DEBUGFLOW('u');
1451  flushrx();
1452  RIMESTATS_ADD(badsynch);
1453  return 0;
1454  }
1455 
1456  if(len <= AUX_LEN) {
1457  DEBUGFLOW('s');
1458  //PRINTF("len <= AUX_LEN\n");
1459  flushrx();
1460  RIMESTATS_ADD(tooshort);
1461  return 0;
1462  }
1463 
1464  if(len - AUX_LEN > bufsize) {
1465  DEBUGFLOW('v');
1466  //PRINTF("len - AUX_LEN > bufsize\n");
1467  flushrx();
1468  RIMESTATS_ADD(toolong);
1469  return 0;
1470  }
1471 
1472  /* Transfer the frame, stripping the footer, but copying the checksum */
1473  framep=&(rxframe[rxframe_head].data[0]);
1474  memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
1475  rf230_last_correlation = rxframe[rxframe_head].lqi;
1476 
1477  /* Clear the length field to allow buffering of the next packet */
1478  rxframe[rxframe_head].length=0;
1479  rxframe_head++;
1480  if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
1481  rxframe_head=0;
1482  }
1483  /* If another packet has been buffered, schedule another receive poll */
1484  if (rxframe[rxframe_head].length) {
1485  rf230_interrupt();
1486  }
1487  else {
1488  rf230_pending = 0;
1489  }
1490 
1491  /* Point to the checksum */
1492  framep+=len-AUX_LEN;
1493 #if RF230_CONF_CHECKSUM
1494  memcpy(&checksum,framep,CHECKSUM_LEN);
1495 #endif /* RF230_CONF_CHECKSUM */
1496  framep+=CHECKSUM_LEN;
1497 #if RF230_CONF_TIMESTAMPS
1498  memcpy(&t,framep,TIMESTAMP_LEN);
1499 #endif /* RF230_CONF_TIMESTAMPS */
1500  framep+=TIMESTAMP_LEN;
1501 #if FOOTER_LEN
1502  memcpy(footer,framep,FOOTER_LEN);
1503 #endif
1504 #if RF230_CONF_CHECKSUM
1505  if(checksum != crc16_data(buf, len - AUX_LEN, 0)) {
1506  DEBUGFLOW('w');
1507  //PRINTF("checksum failed 0x%04x != 0x%04x\n",
1508  // checksum, crc16_data(buf, len - AUX_LEN, 0));
1509  }
1510 #if FOOTER_LEN
1511  if(footer[1] & FOOTER1_CRC_OK &&
1512  checksum == crc16_data(buf, len - AUX_LEN, 0)) {
1513 #endif
1514 #endif /* RF230_CONF_CHECKSUM */
1515 
1516 /* Get the received signal strength for the packet, 0-84 dB above rx threshold */
1517 #if 0 //more general
1518  rf230_last_rssi = rf230_get_raw_rssi();
1519 #else //faster
1520 #if RF230_CONF_AUTOACK
1521  // rf230_last_rssi = hal_subregister_read(SR_ED_LEVEL); //0-84 resolution 1 dB
1522  rf230_last_rssi = hal_register_read(RG_PHY_ED_LEVEL); //0-84, resolution 1 dB
1523 #else
1524 /* last_rssi will have been set at RX_START interrupt */
1525 // rf230_last_rssi = 3*hal_subregister_read(SR_RSSI); //0-28 resolution 3 dB
1526 #endif
1527 #endif /* speed vs. generality */
1528 
1529  /* Save the smallest rssi. The display routine can reset by setting it to zero */
1530  if ((rf230_smallest_rssi==0) || (rf230_last_rssi<rf230_smallest_rssi))
1531  rf230_smallest_rssi=rf230_last_rssi;
1532 
1533  // rf230_last_correlation = rxframe[rxframe_head].lqi;
1534  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi);
1535  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation);
1536 
1537  RIMESTATS_ADD(rx);
1538 
1539 #if RF230_CONF_TIMESTAMPS
1540  rf230_time_of_departure =
1541  t.time +
1542  setup_time_for_transmission +
1543  (total_time_for_transmission * (len - 2)) / total_transmission_len;
1544 
1545  rf230_authority_level_of_sender = t.authority_level;
1546 
1547  packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, t.time);
1548 #endif /* RF230_CONF_TIMESTAMPS */
1549 
1550 #if RF230_CONF_CHECKSUM
1551 #if FOOTER_LEN
1552  } else {
1553  DEBUGFLOW('x');
1554  //PRINTF("bad crc");
1555  RIMESTATS_ADD(badcrc);
1556  len = AUX_LEN;
1557  }
1558 #endif
1559 #endif
1560 
1561 #ifdef RF230BB_HOOK_RX_PACKET
1562  RF230BB_HOOK_RX_PACKET(buf,len);
1563 #endif
1564 
1565  /* Here return just the data length. The checksum is however still in the buffer for packet sniffing */
1566  return len - AUX_LEN;
1567 }
1568 /*---------------------------------------------------------------------------*/
1569 void
1570 rf230_set_txpower(uint8_t power)
1571 {
1572  set_txpower(power);
1573 }
1574 /*---------------------------------------------------------------------------*/
1575 uint8_t
1576 rf230_get_txpower(void)
1577 {
1578  uint8_t power = TX_PWR_UNDEFINED;
1579  if (hal_get_slptr()) {
1580  PRINTF("rf230_get_txpower:Sleeping");
1581  } else {
1583  }
1584  return power;
1585 }
1586 
1587 /*---------------------------------------------------------------------------*/
1588 uint8_t
1589 rf230_get_raw_rssi(void)
1590 {
1591  uint8_t rssi,state;
1592  bool radio_was_off = 0;
1593 
1594  /*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/
1595  if(!RF230_receive_on) {
1596  radio_was_off = 1;
1597  rf230_on();
1598  }
1599 
1600 /* The energy detect register is used in extended mode (since RSSI will read 0) */
1601 /* The rssi register is multiplied by 3 to a consistent value from either register */
1602  state=radio_get_trx_state();
1603  if ((state==RX_AACK_ON) || (state==BUSY_RX_AACK)) {
1604  // rssi = hal_subregister_read(SR_ED_LEVEL); //0-84, resolution 1 dB
1605  rssi = hal_register_read(RG_PHY_ED_LEVEL); //0-84, resolution 1 dB
1606  } else {
1607 #if 0 // 3-clock shift and add is faster on machines with no hardware multiply
1608 /* avr-gcc may have an -Os bug that uses the general subroutine for multiplying by 3 */
1609  rssi = hal_subregister_read(SR_RSSI); //0-28, resolution 3 dB
1610  rssi = (rssi << 1) + rssi; //*3
1611 #else // 1 or 2 clock multiply, or compiler with correct optimization
1612  rssi = 3 * hal_subregister_read(SR_RSSI);
1613 #endif
1614 
1615  }
1616 
1617  if(radio_was_off) {
1618  rf230_off();
1619  }
1620  return rssi;
1621 }
1622 
1623 /*---------------------------------------------------------------------------*/
1624 static int
1625 rf230_cca(void)
1626 {
1627  uint8_t cca=0;
1628  uint8_t radio_was_off = 0;
1629 
1630  /* Turn radio on if necessary. If radio is currently busy return busy channel */
1631  /* This may happen when testing radio duty cycling with RADIOALWAYSON,
1632  * or because a packet just started. */
1633  if(RF230_receive_on) {
1634  if (hal_get_slptr()) { //should not be sleeping!
1635  DEBUGFLOW('<');
1636  goto busyexit;
1637  } else {
1638  if (!rf230_isidle()) {
1639  //DEBUGFLOW('2');
1640  goto busyexit;
1641  }
1642  }
1643  } else {
1644  radio_was_off = 1;
1645  rf230_on();
1646  }
1647 
1648  ENERGEST_ON(ENERGEST_TYPE_LED_YELLOW);
1649  /* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */
1650  /* Use the current mode. Note triggering a manual CCA is not recommended in extended mode */
1651 //hal_subregister_write(SR_CCA_MODE,1);
1652 
1653  /* Start the CCA, wait till done, return result */
1654  /* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */
1655 #if defined(__AVR_ATmega128RFA1__)
1656 #if 1 //interrupt method
1657  /* Disable rx transitions to busy (RX_PDT_BIT) */
1658  /* Note: for speed this resets rx threshold to the compiled default */
1659 #ifdef RF230_MIN_RX_POWER
1660  hal_register_write(RG_RX_SYN, RF230_MIN_RX_POWER/6 + 0x81);
1661 #else
1663 #endif
1664  /* Switch to RX_ON for measurement. This will wait if a packet is being received */
1666 
1667  rf230_ccawait=1;
1668 //CCA_REQUEST is supposed to trigger the interrupt but it doesn't
1669 // hal_subregister_write(SR_CCA_REQUEST,1);
1670 
1671  /* Write to ED_LEVEL register to start CCA */
1672  {
1673  uint8_t volatile saved_sreg = SREG;
1674  sei( );
1675  hal_register_write(PHY_ED_LEVEL,0);
1676  while (rf230_ccawait) {}
1677  SREG = saved_sreg;
1678  }
1679 
1680  /* Use ED register to determine result. 77dBm is poweron csma default.*/
1681 #ifdef RF230_CONF_CCA_THRES
1682  if (hal_register_read(RG_PHY_ED_LEVEL)<(91+RF230_CONF_CCA_THRES) cca=0xff;
1683 #else
1684  if (hal_register_read(RG_PHY_ED_LEVEL)<(91-77)) cca=0xff;
1685 #endif
1686 //TODO:see if the status register works!
1687 // cca=hal_register_read(RG_TRX_STATUS);
1688 #if RF230_CONF_AUTOACK
1690 #endif
1691 
1692  /* Enable packet reception */
1693 #ifdef RF230_MIN_RX_POWER
1694  hal_register_write(RG_RX_SYN, RF230_MIN_RX_POWER/6 + 0x01);
1695 #else
1697 #endif
1698 
1699 
1700 #else
1701  /* If already in receive mode can read the current ED register without delay */
1702  /* CCA energy threshold = -91dB + 2*SR_CCA_ED_THRESH. Reset defaults to -77dB */
1703 #ifdef RF230_CONF_CCA_THRES
1704  if (hal_register_read(RG_PHY_ED_LEVEL)<(91+RF230_CONF_CCA_THRES) cca=0xff;
1705 #else
1706  if (hal_register_read(RG_PHY_ED_LEVEL)<(91-77)) cca=0xff;
1707 #endif
1708 #endif
1709 
1710 
1711 #else /* RF230, RF231 */
1712  /* Don't allow interrupts! */
1713  /* Start the CCA, wait till done, return result */
1714  /* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */
1715 { uint8_t volatile saved_sreg = SREG;
1716  cli();
1717  rf230_waitidle();
1719  delay_us(TIME_CCA);
1720  while ((cca & 0x80) == 0 ) {
1721  if (hal_get_slptr()) {
1722  DEBUGFLOW('S');
1723  break;
1724  }
1726  }
1727  SREG=saved_sreg;
1728 }
1729 #endif
1730  ENERGEST_OFF(ENERGEST_TYPE_LED_YELLOW);
1731  if(radio_was_off) {
1732  rf230_off();
1733  }
1734 // if (cca & 0x40) {/*DEBUGFLOW('3')*/;} else {rf230_pending=1;DEBUGFLOW('4');}
1735  if (cca & 0x40) {
1736 // DEBUGFLOW('5');
1737  return 1;
1738  } else {
1739 // DEBUGFLOW('6');
1740  busyexit:
1741  return 0;
1742  }
1743 }
1744 /*---------------------------------------------------------------------------*/
1745 int
1746 rf230_receiving_packet(void)
1747 {
1748  uint8_t radio_state;
1749  if (hal_get_slptr()) {
1750  DEBUGFLOW('=');
1751  } else {
1752  radio_state = hal_subregister_read(SR_TRX_STATUS);
1753  if ((radio_state==BUSY_RX) || (radio_state==BUSY_RX_AACK)) {
1754 // DEBUGFLOW('8');
1755  return 1;
1756  }
1757  }
1758  return 0;
1759 }
1760 /*---------------------------------------------------------------------------*/
1761 static int
1762 rf230_pending_packet(void)
1763 {
1764 #if RF230_INSERTACK
1765  if(ack_pending == 1) return 1;
1766 #endif
1767  return rf230_pending;
1768 }
1769 /*---------------------------------------------------------------------------*/
1770 #if RF230_CONF_SNEEZER && JACKDAW
1771 /* See A.2 in the datasheet for the sequence needed.
1772  * This version for RF230 only, hence Jackdaw.
1773  * A full reset seems not necessary and allows keeping the pan address, etc.
1774  * for an easy reset back to network mode.
1775  */
1776 void rf230_start_sneeze(void) {
1777 //write buffer with random data for uniform spectral noise
1778 
1779 //uint8_t txpower = hal_register_read(0x05); //save auto_crc bit and power
1780 // hal_set_rst_low();
1781 // hal_set_slptr_low();
1782 // delay_us(TIME_RESET);
1783 // hal_set_rst_high();
1784  hal_register_write(0x0E, 0x01);
1785  hal_register_write(0x02, 0x03);
1786  hal_register_write(0x03, 0x10);
1787  // hal_register_write(0x08, 0x20+26); //channel 26
1788  hal_subregister_write(SR_CCA_MODE,1); //leave channel unchanged
1789 
1790  // hal_register_write(0x05, 0x00); //output power maximum
1791  hal_subregister_write(SR_TX_AUTO_CRC_ON, 0); //clear AUTO_CRC, leave output power unchanged
1792 
1793  hal_register_read(0x01); //should be trx-off state=0x08
1794  hal_frame_write(buffer, 127); //maximum length, random for spectral noise
1795 
1796  hal_register_write(0x36,0x0F); //configure continuous TX
1797  hal_register_write(0x3D,0x00); //Modulated frame, other options are:
1798 // hal_register_write(RG_TX_2,0x10); //CW -2MHz
1799 // hal_register_write(RG_TX_2,0x80); //CW -500KHz
1800 // hal_register_write(RG_TX_2,0xC0); //CW +500KHz
1801 
1802  DDRB |= 1<<7; //Raven USB stick has PB7 connected to the RF230 TST pin.
1803  PORTB |= 1<<7; //Raise it to enable continuous TX Test Mode.
1804 
1805  hal_register_write(0x02,0x09); //Set TRX_STATE to PLL_ON
1806  delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE);
1807  delay_us(TIME_PLL_LOCK);
1808  delay_us(TIME_PLL_LOCK);
1809  // while (hal_register_read(0x0f)!=1) {continue;} //wait for pll lock-hangs
1810  hal_register_write(0x02,0x02); //Set TRX_STATE to TX_START
1811 }
1812 #endif
#define hal_set_slptr_low()
This macro pulls the SLP_TR pin low.
Definition: hal.h:249
The requested service timed out.
Definition: radio.h:109
#define RX_ON
Constant RX_ON for sub-register SR_TRX_STATUS.
#define SR_TRX_STATUS
Access parameters for sub-register TRX_STATUS in register RG_TRX_STATUS.
Time it takes to execute the FORCE_TRX_OFF command.
Definition: radio.c:102
#define SR_PLL_DCU_START
Access parameters for sub-register PLL_DCU_START in register RG_PLL_DCU.
#define hal_get_slptr()
Read current state of the SLP_TR pin (High/Low).
Definition: hal.h:250
uint8_t lqi
LQI value for received frame.
Definition: hal.h:354
Transition time from P_ON to TRX_OFF.
Definition: radio.c:94
#define RG_IEEE_ADDR_3
Offset for register IEEE_ADDR_3.
#define RG_IRQ_MASK
Offset for register IRQ_MASK.
uint8_t hal_register_read(uint8_t address)
This function reads data from one of the radio transceiver&#39;s registers.
Definition: hal.c:304
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
#define RG_CSMA_SEED_0
Offset for register CSMA_SEED_0.
bool radio_is_sleeping(void)
This function checks if the radio transceiver is sleeping.
Definition: radio.c:776
#define RX_AACK_ON
Constant RX_AACK_ON for sub-register SR_TRX_STATUS.
#define PORTE
Peripheral PORTE base pointer.
Definition: MK60D10.h:6431
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define RG_IEEE_ADDR_5
Offset for register IEEE_ADDR_5.
#define RG_IEEE_ADDR_4
Offset for register IEEE_ADDR_4.
#define SR_TRAC_STATUS
Access parameters for sub-register TRAC_STATUS in register RG_TRX_STATE.
int timesynch_authority_level(void)
Get the current authority level of the time-synchronized time.
#define AVR_ENTER_CRITICAL_REGION()
This macro will protect the following code from interrupts.
Definition: hal.h:313
Transition time from *_NOCLK to being awake.
Definition: radio.c:101
#define RG_SHORT_ADDR_1
Offset for register SHORT_ADDR_1.
#define RG_PHY_ED_LEVEL
Offset for register PHY_ED_LEVEL.
void calibrate_rc_osc_32k(void)
Calibrate the internal RC oscillator.
Definition: radio.c:1332
#define AVR_LEAVE_CRITICAL_REGION()
This macro must always be used in conjunction with AVR_ENTER_CRITICAL_REGION so that interrupts are e...
Definition: hal.h:317
Header file for the Rime buffer (packetbuf) management
Transition time from SLEEP to TRX_OFF.
Definition: radio.c:95
#define RG_PAN_ID_0
Offset for register PAN_ID_0.
#define PORTB
Peripheral PORTB base pointer.
Definition: MK60D10.h:6419
Transition time from PLL active state to another.
Definition: radio.c:104
#define TRX_OFF
Constant TRX_OFF for sub-register SR_TRX_STATUS.
uint8_t length
Length of frame.
Definition: hal.h:352
uint8_t hal_subregister_read(uint8_t address, uint8_t mask, uint8_t position)
This function reads the value of a specific subregister.
Definition: hal.c:377
#define NULL
The null pointer.
The structure of a device driver for a radio in Contiki.
Definition: radio.h:225
#define hal_set_rst_low()
This macro pulls the RST pin low.
Definition: hal.h:256
#define SR_CHANNEL
Access parameters for sub-register CHANNEL in register RG_PHY_CC_CCA.
#define SR_CCA_MODE
Access parameters for sub-register CCA_MODE in register RG_PHY_CC_CCA.
void hal_init(void)
This function initializes the Hardware Abstraction Layer.
Definition: hal.c:133
This struct defines the rx data container.
Definition: hal.h:351
void hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position, uint8_t value)
This function writes a new value to one of the radio transceiver&#39;s subregisters.
Definition: hal.c:400
#define hal_set_rst_high()
This macro pulls the RST pin high.
Definition: hal.h:255
uint8_t data[HAL_MAX_FRAME_LENGTH]
Actual frame data.
Definition: hal.h:353
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
Definition: radio.h:88
#define BUSY_RX
Constant BUSY_RX for sub-register SR_TRX_STATUS.
#define SR_TRX_CMD
Access parameters for sub-register TRX_CMD in register RG_TRX_STATE.
Header file for a simple time synchronization mechanism
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:200
#define RG_MAN_ID_0
Offset for register MAN_ID_0.
uint8_t radio_get_trx_state(void)
This function return the Radio Transceivers current state.
Definition: radio.c:764
#define HAL_LEAVE_CRITICAL_REGION()
This macro must always be used in conjunction with HAL_ENTER_CRITICAL_REGION so that interrupts are e...
Definition: hal.h:322
Transition time from TRX_OFF to: RX_ON, PLL_ON, TX_ARET_ON and RX_AACK_ON.
Definition: radio.c:103
rtimer_clock_t timesynch_time(void)
Get the current time-synchronized time.
Maximum time it should take for the PLL to lock.
Definition: radio.c:99
#define SR_AACK_SET_PD
Access parameters for AACK_SET_PD bit in register RG_CSMA_SEED_1.
#define RG_SHORT_ADDR_0
Offset for register SHORT_ADDR_0.
#define RG_RX_SYN
Offset for register RX_SYN.
Transition time from VCC is applied to P_ON.
Definition: radio.c:93
#define SR_RSSI
Access parameters for sub-register RSSI in register RG_PHY_RSSI.
void hal_frame_write(uint8_t *write_buffer, uint8_t length)
This function will download a frame to the radio transceiver&#39;s frame buffer.
Definition: hal.c:516
The end-user tried to do an invalid state transition.
Definition: radio.h:110
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
#define STATE_TRANSITION
Constant STATE_TRANSITION for sub-register SR_TRX_STATUS.
#define hal_set_slptr_high()
This macro pulls the SLP_TR pin high.
Definition: hal.h:248
#define SR_MAX_FRAME_RETRIES
Access parameters for sub-register MAX_FRAME_RETRIES in register RG_XAH_CTRL_0.
radio_trx_timing_t
This enumeration defines the necessary timing information for the AT86RF230 radio transceiver...
Definition: radio.c:92
#define RG_IEEE_ADDR_0
Offset for register IEEE_ADDR_0.
radio_status_t
This enumeration defines the possible return values for the TAT API functions.
Definition: radio.h:105
#define SR_PLL_CF_START
Access parameters for sub-register PLL_CF_START in register RG_PLL_CF.
#define BUSY_RX_AACK
Constant BUSY_RX_AACK for sub-register SR_TRX_STATUS.
#define CMD_FORCE_TRX_OFF
Constant CMD_FORCE_TRX_OFF for sub-register SR_TRX_CMD.
#define RG_IEEE_ADDR_1
Offset for register IEEE_ADDR_1.
Time it takes to do a ED measurement.
Definition: radio.c:97
#define RF230_MAX_TX_FRAME_LENGTH
127 Byte PSDU.
Definition: radio.h:69
#define RG_CSMA_BE
Offset for register CSMA_BE.
The requested service was performed successfully.
Definition: radio.h:106
#define RG_IEEE_ADDR_7
Offset for register IEEE_ADDR_7.
#define HAL_ENTER_CRITICAL_REGION()
This macro will protect the following code from interrupts.
Definition: hal.h:318
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Definition: radio.h:258
#define RG_IEEE_ADDR_6
Offset for register IEEE_ADDR_6.
Time it takes to do a CCA.
Definition: radio.c:98
Time to hold the RST pin low during reset.
Definition: radio.c:96
#define RG_TRX_STATUS
Offset for register TRX_STATUS.
#define SR_TX_PWR
Access parameters for sub-register TX_PWR in register RG_PHY_TX_PWR.
#define BUSY_TX_ARET
Constant BUSY_TX_ARET for sub-register SR_TRX_STATUS.
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Definition: radio.h:268
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
#define TX_ARET_ON
Constant TX_ARET_ON for sub-register SR_TRX_STATUS.
#define RG_VERSION_NUM
Offset for register VERSION_NUM.
#define RG_IEEE_ADDR_2
Offset for register IEEE_ADDR_2.
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:77
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
#define PLL_ON
Constant PLL_ON for sub-register SR_TRX_STATUS.
void hal_register_write(uint8_t address, uint8_t value)
This function writes a new value to one of the radio transceiver&#39;s registers.
Definition: hal.c:342
Basic SPI macros
#define SR_TX_AUTO_CRC_ON
Access parameters for sub-register TX_AUTO_CRC_ON in register RG_PHY_TX_PWR.
Maximum time it should take to do the filter tuning.
Definition: radio.c:100
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:65
#define SR_MAX_CSMA_RETRIES
Access parameters for sub-register MAX_CSMA_RETRIES in register RG_XAH_CTRL_0.
#define RG_PAN_ID_1
Offset for register PAN_ID_1.
Header file for Rime statistics
This file contains radio driver code.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:207
One or more of the supplied function arguments are invalid.
Definition: radio.h:108
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
Definition: radio.h:274
#define SR_CCA_ED_THRES
Access parameters for sub-register CCA_ED_THRES in register RG_CCA_THRES.
Header file for the CRC16 calculcation
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition: process.h:178
radio_status_t radio_set_trx_state(uint8_t new_state)
This function will change the current state of the radio transceiver&#39;s internal state machine...
Definition: radio.c:809
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
Definition: radio.h:261
#define BUSY_TX
Constant BUSY_TX for sub-register SR_TRX_STATUS.
unsigned short crc16_data(const unsigned char *data, int len, unsigned short acc)
Calculate the CRC16 over a data area.
Definition: crc16.c:66
void radio_reset_state_machine(void)
This function will reset the state machine (to TRX_OFF) from any of its states, except for the SLEEP ...
Definition: radio.c:960
#define RG_PHY_RSSI
Offset for register PHY_RSSI.
Include file for the Contiki low-layer network stack (NETSTACK)
#define SR_CCA_REQUEST
Access parameters for sub-register CCA_REQUEST in register RG_PHY_CC_CCA.