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