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