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