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