Contiki-NG
Loading...
Searching...
No Matches
at86rf215.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023, ComLab, Jozef Stefan Institute - https://e6.ijs.si/
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 copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/*---------------------------------------------------------------------------*/
31/**
32 * \file
33 * AT86RF215 driver for Contiki-NG, version 0.1
34 *
35 * \author
36 * Grega Morano <grega.morano@ijs.si>
37 *
38 * \short
39 * Drivers for AT86RF215 radio, supporting only one BBC (RF core) at a
40 * time. Currently only 2.4 GHz O-QPSK modulation tested.
41 * Drivers designed to support TSCH, but CSMA works as well. Radio
42 * config can be done in at86rf215-conf.h
43 */
44/*---------------------------------------------------------------------------*/
45#include "contiki.h"
46#include "dev/radio.h"
47#include "net/netstack.h"
48#include "net/mac/tsch/tsch.h"
49
50#include "at86rf215.h"
51#include "at86rf215-arch.h"
52#include "at86rf215-conf.h"
54#include "at86rf215-def.h"
55
56#include "sys/log.h"
57/*---------------------------------------------------------------------------*/
58#define LOG_MODULE "AT86RF215"
59#define LOG_LEVEL AT86RF215_LOG_LEVEL
60/*---------------------------------------------------------------------------*/
61/**
62 * Current drivers support only one BBC (RF band) at a time. Regarding the
63 * defined frequency band, the following macros are used to select the
64 * corresponding registers.
65 *
66 * Note: The driver is not tested for the Sub-GHz band yet!
67 */
68#if AT86RF215_FREQUENCY_BAND == FREQ_BAND_24GHZ
69
70 // Radio's state register
71 #define RG_RFn_STATE RG_RF24_STATE
72 #define RG_RFn_CMD RG_RF24_CMD
73
74 // IRQ mask and state registers
75 #define RG_RFn_IRQS RG_RF24_IRQS
76 #define RG_BBCn_IRQS RG_BBC1_IRQS
77
78 // TX and RX frame buffer start and stop registers
79 #define RG_BBCn_FBRXS RG_BBC1_FBRXS
80 #define RG_BBCn_FBRXE RG_BBC1_FBRXE
81 #define RG_BBCn_FBTXS RG_BBC1_FBTXS
82 #define RG_BBCn_FBTXE RG_BBC1_FBTXE
83
84 // TX and RX frame length High and Low Bytes
85 #define RG_BBCn_RXFLL RG_BBC1_RXFLL
86 #define RG_BBCn_RXFLH RG_BBC1_RXFLH
87 #define RG_BBCn_TXFLL RG_BBC1_TXFLL
88 #define RG_BBCn_TXFLH RG_BBC1_TXFLH
89
90 // PHY control register (used for FCS valid check)
91 #define SR_BBCn_FCSOK SR_BBC1_FCSOK
92 #define SR_BBCn_FCSFE SR_BBC1_FCSFE
93 #define SR_BBCn_TXAFCS SR_BBC1_TXAFCS
94 #define SR_BBCn_FCST SR_BBC1_FCST
95 #define SR_BBCn_BBEN SR_BBC1_BBEN
96
97 // RSSI and ED registers
98 #define RG_RFn_EDV RG_RF24_EDV
99 #define RG_RFn_RSSI RG_RF24_RSSI
100
101 // TX Power
102 #define SR_RFn_TXPWR SR_RF24_TXPWR
103
104 // PHY status - UR detection
105 #define RG_BBCn_PS RG_BBC1_PS
106
107 // Frame filtering
108 #define RG_BBCn_AFC0 RG_BBC1_AFC0
109 #define RG_BBCn_MACPID0F0 RG_BBC1_MACPID0F0
110 #define RG_BBCn_MACPID1F0 RG_BBC1_MACPID1F0
111 #define RG_BBCn_MACSHA0F0 RG_BBC1_MACSHA0F0
112 #define RG_BBCn_MACSHA1F0 RG_BBC1_MACSHA1F0
113 #define RG_BBCn_MACEA0 RG_BBC1_MACEA0
114
115 // CCA
116 #define RG_RFn_EDC RG_RF24_EDC
117
118 // AACK
119 #define RG_BBCn_AMAACKTL RG_BBC1_AMAACKTL
120 #define RG_BBCn_AMAACKTH RG_BBC1_AMAACKTH
121 #define SR_BBCn_AACK SR_BBC1_AACK
122
123#else
124#error "SUB GHZ band not tested yet!"
125#endif
126
127/*---------------------------------------------------------------------------*/
128/**
129 * Contiki-NG requires that the driver stores the values of last RSSI, LQI
130 * and timestamp -> we are using at86rf215_rx_frame_t for that
131 */
132static at86rf215_rx_frame_t rx_frame;
133
134/**
135 * It is easier to store the current channel in a global variable than
136 * to read it from the radio register every time it is needed.
137*/
139
140/**
141 * The radio driver uses the following flags to keep track of the current
142 * state of the radio and IRQ events.
143*/
144volatile static at86rf215_flags_t flags;
145
146/**
147 * Radio configuration parameters according to the Contiki-NG radio API.
148*/
149static uint8_t radio_send_on_cca = 0;
150static uint8_t radio_mode_frame_filter = 0;
151static uint8_t radio_mode_aack = 0;
152static uint8_t radio_mode_poll_mode = 0;
153
154/*---------------------------------------------------------------------------*/
155/* Private functions */
156static void set_auto_ack(uint8_t enable);
157static void set_frame_filtering(uint8_t enable);
158static void set_poll_mode(uint8_t enable);
159static void set_send_on_cca(uint8_t enable);
160static void set_cca_threshold(uint8_t threshold);
161static uint8_t get_cca_threshold(void);
162static void set_pan_ID(uint16_t pan);
163static uint16_t get_pan_ID(void);
164static void set_short_addr(uint16_t addr);
165static uint16_t get_short_addr(void);
166static void set_long_addr(const uint8_t *addr, uint8_t len);
167static void get_long_addr(uint8_t *addr, uint8_t len);
168static void set_tx_power(int8_t power);
169static int8_t get_tx_power(void);
170static void set_channel(uint8_t channel);
171static uint8_t get_channel(void);
172static void set_frequency(uint16_t freq, uint8_t decimal);
173
174/*---------------------------------------------------------------------------*/
175/* HAL */
176static uint8_t regRead(uint16_t address);
177static void regWrite(uint16_t address, uint8_t data);
178static uint8_t bitRead(uint16_t address, uint8_t mask, uint8_t offset);
179static void bitWrite(uint16_t address, uint8_t mask, uint8_t offset, uint8_t value);
180static void burstRead(uint16_t address, uint8_t *data, uint16_t len);
181static void burstWrite(uint16_t address, uint8_t *data, uint16_t len);
182static void frameRead(uint8_t *frame, uint16_t *frame_len);
183static void frameWrite(uint8_t *frame, uint16_t frame_len);
184
185/*---------------------------------------------------------------------------*/
186PROCESS(at86rf215_process, "AT86RF215 radio driver");
187
188
189
190/*---------------------------------------------------------------------------*/
191/* NETSTACK API - radio driver functions */
192/*---------------------------------------------------------------------------*/
193int
194at86rf215_init(void)
195{
196 LOG_DBG("Initializing AT86RF215 radio ...\n");
197
199
200 /* Reset the radio (again) */
204
205 do {
206 LOG_DBG("Detecting radio ...\n");
207 if(regRead(RG_RF_PN) == 0x34){
208 break;
209 }
210 }while(1);
211
212 /* Radio config must be done in TRXOFF state*/
213 regWrite(RG_RFn_CMD, RF_CMD_TRXOFF);
214 while(regRead(RG_RFn_STATE) != RF_STATE_TRXOFF);
215
216 /* Enable and configure only one Base Band Core */
217#if AT86RF215_FREQUENCY_BAND == FREQ_BAND_24GHZ
218 regWrite(RG_BBC0_PC, 0x00);
219
220 /* Configure the radio based on given modulation scheme */
221 for (uint8_t i = 0; i < (sizeof(AT86RF215_RADIO_CONFIGURATION)/sizeof(at86rf215_radio_config_t)); i++) {
222 regWrite(AT86RF215_RADIO_CONFIGURATION[i].address, AT86RF215_RADIO_CONFIGURATION[i].value);
223 }
224#else
225 regWrite(RG_BBC1_PC, 0x00);
226 LOG_ERR("SUB GHZ band not tested yet!\n");
227 while(1);
228#endif
229
230#if AT86RF215_AUTO_CRC
231 /* Enable auto generation of FCS (CRC) for TX, 16-bit */
232 bitWrite(SR_BBCn_TXAFCS, 1);
233 bitWrite(SR_BBCn_FCST, AT86RF215_CRC_16BIT);
234#endif
235
236 /* Disable first level frame filter (CRC check at receive) - we do it
237 manually in at85rf215_read(). If enabled, there is no IRQ at RXFE. */
238 bitWrite(SR_BBCn_FCSFE, 0);
239
240 /* Default radio configuration (Contiki will do it again) */
241 set_frame_filtering(AT86RF215_FRAME_FILTER);
243 set_poll_mode(AT86RF215_POLL_MODE);
244 set_send_on_cca(AT86RF215_SEND_ON_CCA);
245
246 /* Configure the interrupts - active low (falling edge), masked IRQs are not shown in IRQS */
247 regWrite(RG_RF_CFG, 0x05);
248
249 /* IRQ source only from 2.4 GHz */
250#if AT86RF215_FREQUENCY_BAND == FREQ_BAND_24GHZ
251 regWrite(RG_BBC0_IRQM, 0x00);
252 regWrite(RG_RF09_IRQM, 0x00);
253 regWrite(RG_BBC1_IRQM, 0x13);
254 regWrite(RG_RF24_IRQM, 0x04);
255#endif
256
257 /* Clear all 4 IRQs */
258 uint8_t dummy __attribute__((unused));
259 dummy = regRead(RG_RF09_IRQS);
260 dummy = regRead(RG_RF24_IRQS);
261 dummy = regRead(RG_BBC0_IRQS);
262 dummy = regRead(RG_BBC1_IRQS);
263
264 flags.value = 0;
265
267
268 /* Start Contiki process which will take care of received packets (for CSMA) */
269 process_start(&at86rf215_process, NULL);
270
271 /* Go to TXPREP state */
272 regWrite(RG_RFn_CMD, RF_CMD_TXPREP);
273 while(regRead(RG_RFn_STATE) != RF_STATE_TXPREP);
274
275 return 1;
276}
277
278/*---------------------------------------------------------------------------*/
279int
280at86rf215_on(void)
281{
282 LOG_DBG("%s\n", __func__);
283 regWrite(RG_RFn_CMD, RF_CMD_RX);
284 while(regRead(RG_RFn_STATE) != RF_STATE_RX);
285 flags.RECEIVE_ON = 1;
286
287 /* Do not clear the flags in TSCH - they are cleared when they should be.
288 * We could also check the (radio_mode_poll_mode) */
289#if MAC_CONF_WITH_CSMA
290 flags.RX_START = 0;
291 flags.AMI = 0;
292 flags.PACKET_PEN = 0;
293#endif
294 return 1;
295}
296
297/*---------------------------------------------------------------------------*/
298int
299at86rf215_off(void)
300{
301 LOG_DBG("%s\n", __func__);
302 regWrite(RG_RFn_CMD, RF_CMD_TRXOFF);
303 while(regRead(RG_RFn_STATE) != RF_STATE_TRXOFF);
304 flags.RECEIVE_ON = 0;
305 return 1;
306}
307
308/*---------------------------------------------------------------------------*/
309int
310at86rf215_prepare(const void *payload, unsigned short payload_len)
311{
312 LOG_DBG("%s\n", __func__);
313
314 uint8_t buffer[127];
315
316 if(payload_len > AT86RF215_MAX_PAYLOAD_SIZE) {
317 LOG_ERR("Payload larger than radio buffer: %u > %u\n", payload_len, AT86RF215_MAX_PAYLOAD_SIZE);
318 return RADIO_TX_ERR;
319 }
320
321 /* Tranistion to TXPREP might interupt ongoing reception in CSMA MAC mode */
322 //regWrite(RG_RFn_CMD, RF_CMD_TXPREP);
323 //while(regRead(RG_RFn_STATE) != RF_STATE_TXPREP);
324
325 memcpy(buffer, payload, payload_len);
326
327 /* Add CRC if not calculated by the radio */
328#if !AT86RF215_AUTO_CRC
329 uint16_t crc = crc16_data(payload, payload_len, 0);
330 buffer[payload_len] = (uint8_t)(crc & 0x00FF);
331 buffer[payload_len + 1] = (uint8_t)((crc & 0xFF00) >> 8);
332 payload_len += 2;
333#else
334 buffer[payload_len] = 0x00;
335 buffer[payload_len + 1] = 0x00;
336 payload_len += 2;
337#endif
338
339 /* Store the buffer to the radio */
340 frameWrite(buffer, (uint16_t)(payload_len));
341
342 return RADIO_TX_OK;
343}
344
345/*---------------------------------------------------------------------------*/
346int
347at86rf215_transmit(unsigned short payload_len)
348{
349 LOG_DBG("%s\n", __func__);
350
351 regWrite(RG_RFn_CMD, RF_CMD_TXPREP);
352 while(regRead(RG_RFn_STATE) != RF_STATE_TXPREP);
353
354 flags.TX_END = 0;
355
356 /* Initiate transmission */
357 regWrite(RG_RFn_CMD, RF_CMD_TX);
358
359 /* Wait until frame is sent */
360 while(!flags.TX_END){
361 if(regRead(RG_RFn_STATE) == RF_STATE_TXPREP){
362 /* If this happens, maybe the frame was not transmitted correctly.
363 * Or it happens because of the delay before actual frame end
364 * and the delay before the TXFE IRQ is issued - the frame is
365 * still sent correctly */
366 LOG_DBG("No IRQ \n");
367 break;
368 }
369 }
370 flags.TX_END = 0;
371
372 /* Turn the radio back to RX state if needed */
373 if(flags.RECEIVE_ON){
374 at86rf215_on();
375 }
376
377 if(regRead(RG_BBCn_PS)){
378 LOG_WARN("TX - Underrun \n");
379 return RADIO_TX_ERR;
380 }
381
382 return RADIO_TX_OK;
383}
384
385/*---------------------------------------------------------------------------*/
386int
387at86rf215_send(const void *payload, unsigned short payload_len)
388{
389 LOG_DBG("%s\n", __func__);
390
391 at86rf215_prepare(payload, payload_len);
392 return at86rf215_transmit(payload_len);
393}
394
395/*---------------------------------------------------------------------------*/
396int
397at86rf215_read(void *buf, unsigned short buf_len)
398{
399 //LOG_DBG("%s\n", __func__);
400
401 uint16_t len = 0;
402 uint8_t buffer[127];
403
404 flags.PACKET_PEN = 0;
405 flags.RX_START = 0;
406 flags.AMI = 0;
407
408 frameRead(buffer, &len);
409
410 if(len < 3 || len > 127){
411 LOG_WARN("Read - invalid length \n");
412 return 0;
413 }
414
415 /* Check whether the CRC is valid and remove it from buff.
416 * If a new frame is detected in the mean time, FCSOK is set to 0 */
417 /* TODO: We can move this up - do a check before reading the frame */
418#if AT86RF215_AUTO_CRC
419 if(bitRead(SR_BBCn_FCSOK) != 1){
420 //LOG_WARN("Read - invalid CRC \n");
421 return 0;
422 }
423#else
424 uint16_t frame_crc = (uint16_t)(buffer[len-1] << 8) | (buffer[len]);
425 uint16_t crc = crc16_data(buffer, len, 0x00);
426 if(crc != frame_crc){
427 LOG_WARN("Read - wrong CRC \n");
428 return 0;
429 }
430#endif
431 len -= 2;
432
433 memcpy(buf, buffer, len);
434
435 rx_frame.rssi = (int8_t)regRead(RG_RFn_EDV);
436
437 /* TODO: AT86RF215 does not support LQI measurement */
438 rx_frame.lqi = 255;
439
440 LOG_DBG("Read %d bytes \n", len);
441
442 return len;
443}
444
445/*---------------------------------------------------------------------------*/
446int
447at86rf215_receiving_packet(void)
448{
449 /* Pooling radio IRQ state register doesn't work ok - too slow to detect
450 * that's why we never disale IRQs, not even in the pooling mode */
451 //at86rf215_bbc_irq_t bbc_irq;
452 //if (radio_mode_poll_mode) {
453 // bbc_irq.value = regRead(RG_BBC_IRQS);
454 //
455 // if(bbc_irq.IRQ1_RXFS){
456 // rx_frame.timestamp = RTIMER_NOW();
457 // LOG_DBG("Receiving packet\n");
458 // }
459 // return (bbc_irq.IRQ1_RXFS && !bbc_irq.IRQ2_RXFE);
460 //}
461 //else {
462 // return flags.RX_START;
463 //}
464
465 /* In CSMA it might happen that RXFS was triggered (which sets the
466 * RX_START flag), but the frame did not pass the frame filter. In that case,
467 * the RXFE is not trigerred and the radio is not actually receiving any
468 * packet.
469 * In TSCH the frame filter is disabled, allowing all detected
470 * frames to trigger RXFE interrupt, which clears the RX_START flag */
471
472 if(radio_mode_frame_filter){
473 if((regRead(RG_RFn_STATE) != RF_STATE_RX)){ // || (flags.AMI != 1)){
474 flags.RX_START = 0;
475 }
476 }
477
478 LOG_DBG("%s = %d \n", __func__, flags.RX_START);
479 return flags.RX_START;
480}
481/*---------------------------------------------------------------------------*/
482int
483at86rf215_pending_packet(void)
484{
485 LOG_DBG("%s = %d \n", __func__, flags.PACKET_PEN);
486
487 //at86rf215_bbc_irq_t bbc_irq;
488 //if (radio_mode_poll_mode) {
489 // bbc_irq.value = regRead(RG_BBC_IRQS);
490 //
491 // if(bbc_irq.IRQ2_RXFE){
492 // LOG_DBG("Packet pending\n");
493 // }
494 // return bbc_irq.IRQ2_RXFE;
495 //}
496 //else {
497 // return flags.PACKET_PEN;
498 //}
499
500 /* Pooling radios IRQ state register doesn't work - too slow to detect */
501 return flags.PACKET_PEN;
502}
503
504/*---------------------------------------------------------------------------*/
505int
507{
508 /**
509 * Contiki-NG CSMA mode calls the channel clear function to sense if there
510 * is an ACK in the air (besides calling receiving_packet and pending_packet)
511 * So instead of receiving an ACK, with this function (implemented from the
512 * reference manual) what we do is we put the radio to TXPREP and
513 * disable BBC to avoid packet detection to be able to measure Energy
514 * Detection value. TODO: ...
515 * So at this point, we just return 1 --> chanel not busy
516 *
517 * For TSCH, this implementation is usefull, but the CCA in TSCH is
518 * disabled by default (TSCH_CCA_ENABLED) ...
519 */
520
521 LOG_DBG("%s = ", __func__);
522 // int8_t cca;
523
524 // /* Contiki (TSCH) will put the radio to RX state -
525 // * do we need to change it before disabeling BBC? */
526 // regWrite(RG_RFn_CMD, RF_CMD_TXPREP);
527
528 // /* Disable BBC to avoid packet detection */
529 // bitWrite(SR_BBCn_BBEN, 0);
530
531 // /* Trigger the energy measurement and wait for IRQ */
532 // regWrite(RG_RFn_CMD, RF_CMD_RX);
533 // regWrite(RG_RFn_EDC, 0x01);
534 // while(!flags.CCA);
535 // flags.CCA = 0;
536
537 // /* Value from -127 to +4 */
538 // cca = regRead(RG_RFn_EDV);
539
540 // regWrite(RG_RFn_CMD, RF_CMD_TXPREP);
541 // regWrite(RG_RFn_EDC, 0x00);
542 // bitWrite(SR_BBCn_BBEN, 1);
543
544 // /* If it was in RX state (CSMA) put it back */
545 // if(flags.RECEIVE_ON){
546 // at86rf215_on();
547 // }
548
549 // LOG_DBG("%d\n", cca <= AT86RF215_CCA_THRESHOLD);
550
551 // /* Return 0 if channel is busy */
552 // return cca <= AT86RF215_CCA_THRESHOLD;
553 return 1;
554}
555
556/*---------------------------------------------------------------------------*/
557static radio_result_t
558at86rf215_get_value(radio_param_t param, radio_value_t *value)
559{
560 if (!value) return RADIO_RESULT_INVALID_VALUE;
561
562 switch (param){
564 {
565 uint8_t state = regRead(RG_RFn_STATE);
566 switch (state){
567 case RF_STATE_RX:
568 *value = RADIO_POWER_MODE_ON;
569 return RADIO_RESULT_OK;
570
571 case RF_STATE_TX:
572 case RF_STATE_TXPREP:
574 return RADIO_RESULT_OK;
575
576 default:
577 *value = RADIO_POWER_MODE_OFF;
578 return RADIO_RESULT_OK;
579 }
580 }
581
583 *value = (radio_value_t)get_channel();
584 return RADIO_RESULT_OK;
585
587 *value = (radio_value_t)get_tx_power();
588 return RADIO_RESULT_OK;
589
591 *value = (radio_value_t)get_pan_ID();
592 return RADIO_RESULT_OK;
593
595 *value = (radio_value_t)get_short_addr();
596 return RADIO_RESULT_OK;
597
599 *value = 0;
600 if (radio_mode_frame_filter) *value |= RADIO_RX_MODE_ADDRESS_FILTER;
601 if (radio_mode_aack) *value |= RADIO_RX_MODE_AUTOACK;
602 if (radio_mode_poll_mode) *value |= RADIO_RX_MODE_POLL_MODE;
603 return RADIO_RESULT_OK;
604
606 *value = 0;
608 return RADIO_RESULT_OK;
609
611 *value = (radio_value_t)get_cca_threshold();
612 return RADIO_RESULT_OK;
613
614 case RADIO_PARAM_RSSI:
615 *value = regRead(RG_RFn_RSSI);
616 return RADIO_RESULT_OK;
617
619 *value = (radio_value_t)rx_frame.rssi;
620 return RADIO_RESULT_OK;
621
623 /* Radio does not support LQI measurement */
624 *value = (radio_value_t)rx_frame.lqi;
626
628 *value = AT86RF215_RF_CHANNEL_MIN;
629 return RADIO_RESULT_OK;
630
632 *value = AT86RF215_RF_CHANNEL_MAX;
633 return RADIO_RESULT_OK;
634
636 *value = AT86RF215_OUTPUT_POWER_MIN;
637 return RADIO_RESULT_OK;
638
640 *value = AT86RF215_OUTPUT_POWER_MAX;
641 return RADIO_RESULT_OK;
642
645 return RADIO_RESULT_OK;
646
649 return RADIO_RESULT_OK;
650
653 return RADIO_RESULT_OK;
654
657 return RADIO_RESULT_OK;
658
661 return RADIO_RESULT_OK;
662
663 case RADIO_CONST_MAX_PAYLOAD_LEN:
664 *value = (radio_value_t)AT86RF215_MAX_PAYLOAD_SIZE;
665 return RADIO_RESULT_OK;
666
667 default:
669 }
670}
671
672/*---------------------------------------------------------------------------*/
673static radio_result_t
674at86rf215_set_value(radio_param_t param, radio_value_t value)
675{
676 switch (param) {
678 switch (value)
679 {
681 at86rf215_on();
682 return RADIO_RESULT_OK;
683
685 at86rf215_off();
686 return RADIO_RESULT_OK;
687
689 // TODO
690
692 // TODO
694
695 default:
697 }
698
700 set_channel(value);
701 return RADIO_RESULT_OK;
702
704 set_pan_ID(value);
705 return RADIO_RESULT_OK;
706
708 set_short_addr(value);
709 return RADIO_RESULT_OK;
710
712 set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0);
713 set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0);
714 set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0);
715 return RADIO_RESULT_OK;
716
718 set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0);
719 return RADIO_RESULT_OK;
720
722 set_tx_power(value);
723 return RADIO_RESULT_OK;
724
726 set_cca_threshold(value);
727 return RADIO_RESULT_OK;
728
730 //TODO
731
732 default:
734 }
735
736}
737
738/*---------------------------------------------------------------------------*/
739static radio_result_t
740at86rf215_get_object(radio_param_t param, void *dest, size_t size)
741{
742 if (dest == NULL) return RADIO_RESULT_ERROR;
743
744 switch (param) {
746 if (size != 8) return RADIO_RESULT_INVALID_VALUE;
747 get_long_addr((uint8_t *)dest, (uint8_t)size);
749
751 *(rtimer_clock_t *)dest = rx_frame.timestamp;
752 return RADIO_RESULT_OK;
753
754 #if MAC_CONF_WITH_TSCH
755 case RADIO_CONST_TSCH_TIMING:
756 *(const uint16_t **)dest = tsch_timeslot_timing_us_10000;
757 #endif /* MAC_CONF_WITH_TSCH */
758
759 default:
761 }
762}
763
764/*---------------------------------------------------------------------------*/
765static radio_result_t
766at86rf215_set_object(radio_param_t param, const void *src, size_t size)
767{
768 if (src == NULL) return RADIO_RESULT_ERROR;
769
770 switch (param) {
772 if (size != 8) return RADIO_RESULT_INVALID_VALUE;
773 set_long_addr((const uint8_t *)src, (uint8_t)size);
775
776 default:
778 }
779}
780
781
782/*---------------------------------------------------------------------------*/
784 .init = at86rf215_init,
785 .prepare = at86rf215_prepare,
786 .transmit = at86rf215_transmit,
787 .send = at86rf215_send,
788 .read = at86rf215_read,
789 .channel_clear = at86rf215_channel_clear,
790 .receiving_packet = at86rf215_receiving_packet,
791 .pending_packet = at86rf215_pending_packet,
792 .on = at86rf215_on,
793 .off = at86rf215_off,
794 .get_value = at86rf215_get_value,
795 .set_value = at86rf215_set_value,
796 .get_object = at86rf215_get_object,
797 .set_object = at86rf215_set_object,
798};
799
800/*---------------------------------------------------------------------------*/
801/**
802 * Interrupt service routine for the AT86RF215
803 *
804 * This function is called by the GPIO interrupt handler. The interrupt can be
805 * triggered by the radio (RF) or the baseband part (BBC). Depending on the
806 * predefined frequency band, correct register addresses are used to read the
807 * interrupt states. The states are then used to set the corresponding flags.
808 * To clear the IRQ line, all 4 interrupts registers must be read.
809 */
810void
812{
813 at86rf215_rf_irq_t rf_irq;
814 at86rf215_bbc_irq_t bbc_irq;
815
816 uint8_t dummy __attribute__((unused));
817 dummy = regRead(RG_RF09_IRQS);
818 dummy = regRead(RG_BBC0_IRQS);
819 rf_irq.value = regRead(RG_RF24_IRQS);
820 bbc_irq.value = regRead(RG_BBC1_IRQS);
821
822 /* Do not use the UART in ISR!!! Only for dev... */
823 //LOG_DBG("RF IRQ: %X\n", rf_irq.value);
824 //LOG_DBG("BBC IRQ: %X\n", bbc_irq.value);
825
826 if(rf_irq.IRQ2_TRXRDY){
827 flags.PLL_LOCK = 1;
828 }
829 if(rf_irq.IRQ5_TRXERR){
830 flags.PLL_ERR = 0;
831 LOG_WARN("PLL ERR\n"); // Not used yet
832 }
833 if(rf_irq.IRQ3_EDC){
834 flags.CCA = 1;
835 }
836
837 if(bbc_irq.IRQ1_RXFS){
838 flags.RX_START = 1;
839 flags.AMI = 0;
840 flags.TX_END = 0;
841
842 rx_frame.timestamp = RTIMER_NOW();
843 }
844 if(bbc_irq.IRQ3_RXAM){
845 flags.AMI = 1;
846 }
847 if(bbc_irq.IRQ2_RXFE){
848 flags.RX_START = 0;
849 flags.PACKET_PEN = 1;
850
851 if(!radio_mode_poll_mode){
852 process_poll(&at86rf215_process);
853 }
854 }
855 if(bbc_irq.IRQ5_TXFE){
856 flags.TX_END = 1;
857 }
858}
859
860
861/*---------------------------------------------------------------------------*/
862/**
863 * Contiki-NG process for the AT86RF215 driver.
864 *
865 * The process is started by the at86rf215_init() function and waits idle for
866 * an event. The event is triggered at the at86rf215_isr() function when the
867 * radio has received a packet. In pool mode, the upper layer has to poll the
868 * driver for new packets and therefore this process is not used.
869*/
870PROCESS_THREAD(at86rf215_process, ev, data)
871{
873
874 LOG_INFO("AT86RF215 driver process started!\n");
875
876 while(1) {
877
878 PROCESS_YIELD_UNTIL(!radio_mode_poll_mode && ev == PROCESS_EVENT_POLL);
879
880 LOG_DBG("Packet detected ... address match = %d \n", flags.AMI);
881
882 if(radio_mode_frame_filter && (flags.AMI != 1)){
883 /* Frame was not for us & radio went to TXPREP --> back to RX */
884 at86rf215_on();
885 }
886 else{
887
889 uint8_t len = at86rf215_read(packetbuf_dataptr(), PACKETBUF_SIZE);
890 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rx_frame.rssi);
891 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rx_frame.lqi);
892
893 /* Radio will go automatically to TXPREP after reception --> back to
894 * RX. But if we trun it back on right away, we might distrup the
895 * Auto ACK transmission. TODO
896 * Only RXFE irq indicates the end of Auto ACK, but we can not wait
897 * for it if the frame was broadcast and therefore the ACK is not sent */
898 at86rf215_on();
899
900 if(len) {
902 NETSTACK_MAC.input();
903 }
904 }
905
906 }
907 PROCESS_END();
908}
909
910
911
912
913
914/*---------------------------------------------------------------------------*/
915/* Private functions */
916/*---------------------------------------------------------------------------*/
917
918/*---------------------------------------------------------------------------*/
919static void
920set_send_on_cca(uint8_t enable)
921{
922 LOG_DBG("%s(%d)\n", __func__, enable);
923 radio_send_on_cca = enable;
924}
925/*---------------------------------------------------------------------------*/
926static void
927set_auto_ack(uint8_t enable)
928{
929 /**
930 * Auto ACK is sent if the frame passes all third level filtering rules,
931 * therefore frame filtering must be enabled beforehand.
932 */
933 LOG_INFO("%s(%d)\n", __func__, enable);
934
935 radio_mode_aack = enable;
936 if(enable) {
937 if(!radio_mode_frame_filter){
938 LOG_WARN("Enabeling frame filter \n");
939 set_frame_filtering(1);
940 }
941 /* TODO: Change the configuration of the ACK time delay ...
942 * CSMA_ACK_WAIT_TIME is defined in csma.h and it is equal to 400us */
943 regWrite(RG_BBCn_AMAACKTL, 0x90);
944 regWrite(RG_BBCn_AMAACKTH, 0x01);
945
946 bitWrite(SR_BBCn_AACK, 1);
947 }
948 else {
949 bitWrite(SR_BBCn_AACK, 0);
950 }
951}
952/*---------------------------------------------------------------------------*/
953static void
954set_frame_filtering(uint8_t enable)
955{
956 LOG_INFO("%s(%d)\n", __func__, enable);
957
958 radio_mode_frame_filter = enable;
959 if(enable) {
960 /* Enable frame filtering with unit #0 while keeping the promiscuous
961 mode on - we need it, so that RXFE is issued even if the frame does
962 not contain our address */
963 regWrite(RG_BBCn_AFC0, 0x11);
964 }
965 else {
966 /* Disable address frame filtering and enable promiscuous mode */
967 regWrite(RG_BBCn_AFC0, 0x10);
968 }
969 /* NOTE: that 1st level filtering (CRC check on reception) is always
970 * disabled so RXFE interupt can be generated (datasheet p. 145)*/
971}
972/*---------------------------------------------------------------------------*/
973/*
974 * In poll mode, radio interrupts should be disabled, and the radio driver
975 * never calls upper layers. TSCH will poll the driver for incoming packets.
976 *
977 * However, in this implementation, the drivers requires interrupts to be
978 * enabled to detect incoming packets and correctly obtain timestamps.
979 */
980static void
981set_poll_mode(uint8_t enable)
982{
983 LOG_INFO("%s(%d)\n", __func__, enable);
984
985 radio_mode_poll_mode = enable;
986
987 if(enable) {
988 //at86rf215_arch_disable_EXTI();
989 }
990 else {
991 //at86rf215_arch_enable_EXTI();
992 }
993}
994/*---------------------------------------------------------------------------*/
995static void
996set_cca_threshold(uint8_t threshold)
997{
998 /* CCA threshold is not stored in the radio - we could store it here as
999 * a global variable? But currently this function is never used ... */
1000}
1001/*---------------------------------------------------------------------------*/
1002static uint8_t
1003get_cca_threshold(void)
1004{
1006}
1007/*---------------------------------------------------------------------------*/
1008/*
1009 * The radio will only accept packets with matching PAN ID and address.
1010 * The address are stored in the unit #0!
1011 */
1012static uint16_t
1013get_pan_ID(void)
1014{
1015 uint16_t panid = ((uint16_t)regRead(RG_BBCn_MACPID1F0) << 8) & 0xFF00;
1016 panid |= regRead(RG_BBCn_MACPID0F0) & 0xFF;
1017 return panid;
1018}
1019/*---------------------------------------------------------------------------*/
1020static void
1021set_pan_ID(uint16_t pan)
1022{
1023 /* Store the address to unit #0 */
1024 regWrite(RG_BBCn_MACPID0F0, (uint8_t) pan & 0xFF);
1025 regWrite(RG_BBCn_MACPID1F0, (uint8_t) (pan >> 8) & 0xFF);
1026}
1027/*---------------------------------------------------------------------------*/
1028static uint16_t
1029get_short_addr(void)
1030{
1031 uint16_t addr = ((uint16_t)regRead(RG_BBCn_MACSHA1F0) << 8) & 0xFF00;
1032 addr |= regRead(RG_BBCn_MACSHA0F0) & 0xFF;
1033 return addr;
1034}
1035/*---------------------------------------------------------------------------*/
1036static void
1037set_short_addr(uint16_t addr)
1038{
1039 /* Store the address to unit #0 */
1040 regWrite(RG_BBCn_MACSHA0F0, (uint8_t) addr & 0xFF);
1041 regWrite(RG_BBCn_MACSHA1F0, (uint8_t) (addr >> 8) & 0xFF);
1042}
1043/*---------------------------------------------------------------------------*/
1044static void
1045get_long_addr(uint8_t *addr, uint8_t len)
1046{
1047 if (len > 8) len = 8;
1048 for (uint8_t i=0; i<len; i++) {
1049 addr[7 - i] = regRead(RG_BBCn_MACEA0 + i);
1050 }
1051}
1052/*---------------------------------------------------------------------------*/
1053static void
1054set_long_addr(const uint8_t *addr, uint8_t len)
1055{
1056 /* Store the address to unit #0 */
1057 if (len > 8) len = 8;
1058 for(uint8_t i=0; i<len; i++) {
1059 regWrite(RG_BBCn_MACEA0 + i, addr[7 - i]);
1060 }
1061}
1062/*---------------------------------------------------------------------------*/
1063/*
1064 * Radio accepts values from 0 to 31 (0x1F) which translates into range
1065 * -15 dBm to 15 dBm (depending on the modulation used).
1066 */
1067static void
1068set_tx_power(int8_t power)
1069{
1070 uint8_t p;
1071 if (power < AT86RF215_OUTPUT_POWER_MIN || power > AT86RF215_OUTPUT_POWER_MAX) {
1072 p = AT86RF215_OUTPUT_POWER_MAX;
1073 LOG_WARN("Invalid power setting (%d)\n", power);
1074 }
1075 else {
1076 p = power + 16;
1077 }
1078 bitWrite(SR_RFn_TXPWR, p);
1079}
1080/*---------------------------------------------------------------------------*/
1081static int8_t
1082get_tx_power(void)
1083{
1084 return (bitRead(SR_RFn_TXPWR) - 16);
1085}
1086/*---------------------------------------------------------------------------*/
1087/*
1088 * Radio supports various setups, but this function is used to set up the
1089 * channels according to IEEE 802.15.4 - TSCH. Valid channels are 11 to 26.
1090 * f = 2405 + 5 * (ch - 11) MHz
1091 */
1092static void
1093set_channel(uint8_t channel)
1094{
1095 LOG_DBG("%s(%d)\n", __func__, channel);
1096 /* Frequency should supposedly be updated in TRXOFF state (datasheet: 6.3.2).
1097 * However, if we are within the same range (the same band) it can also be
1098 * updated in TXPREP, which is faster than going to TRXOFF and than back. */
1099
1100 if(flags.RECEIVE_ON){
1101 regWrite(RG_RFn_CMD, RF_CMD_TXPREP);
1102 }
1103
1104#if AT86RF215_FREQUENCY_BAND == FREQ_BAND_24GHZ
1105
1106 if(channel < AT86RF215_RF_CHANNEL_MIN || channel > AT86RF215_RF_CHANNEL_MAX) {
1107 LOG_WARN("Invalid channel %u", channel);
1108 channel = AT86RF215_RF_CHANNEL_MIN;
1109 }
1110
1111 /* Channel spacing and center ferq are setted at the config .. select
1112 * only the channel (CNM must be written last)*/
1113 regWrite(RG_RF24_CNL, (uint8_t)(channel - 11));
1114 regWrite(RG_RF24_CNM, 0x00);
1115
1116 /* TODO: Maybe wait for PLL to settle (10 - 100 us)*/
1117 //while(!flags.PLL_LOCK);
1118 //flags.value = 0;
1119 /* Or use register to check wether the PLL is locked */
1120 //while(!bitRead(SR_RFn_PLL_LS));
1121
1122 current_channel = channel;
1123
1124 /* Turn the radio back on */
1125 if(flags.RECEIVE_ON){
1126 at86rf215_on();
1127 }
1128#else
1129 LOG_WARN("Frequency band %u not tested!", AT86RF215_FREQUENCY_BAND);
1130#endif
1131}
1132/*---------------------------------------------------------------------------*/
1133/*
1134 * Easier to store it than to read it from the radio...
1135 */
1136static uint8_t
1137get_channel(void)
1138{
1139 return current_channel;
1140}
1141/*---------------------------------------------------------------------------*/
1142/**
1143 * Set frequency via fine resolution obtion.
1144 * param freq is valid in range of 2400 to 2482 MHz.
1145 * param decimal is valid in range of 0 to 9.
1146 *
1147 * NOTE: This implementation is valid only for 2.4 GHz band!
1148 *
1149 * To set the requency to 2440.5 MHz, set: freq = 2440 and decimal = 5.
1150 * f = 2366 MHz + (26 MHz * N) / 2^16
1151 */
1152inline void
1153set_frequency(uint16_t freq, uint8_t decimal)
1154{
1155 uint32_t N = ((freq - 2366) * 65536) / 26;
1156
1157 /* Offset of 0.5 MHz is equal to 1260 */
1158 /* Decimal value of 0.1 MHz is equal to 252 */
1159 N += decimal * 252;
1160
1161 if(N > 296172){
1162 N = 296172;
1163 LOG_WARN("Freq to high\n");
1164 }
1165 else if(N < 85700){
1166 N = 85700;
1167 LOG_WARN("Freq to low\n");
1168 }
1169
1170 printf("N: %lu\n", N);
1171
1172 regWrite(RG_RF24_CNL, (uint8_t)( N & 0x00FF));
1173 regWrite(RG_RF24_CCF0L, (uint8_t)((N & 0xFF00) >> 8));
1174 regWrite(RG_RF24_CCF0H, (uint8_t)((N & 0xFF0000) >> 16));
1175 regWrite(RG_RF24_CNM, 0xC0);
1176}
1177
1178/*---------------------------------------------------------------------------*/
1179/* HAL */
1180/*---------------------------------------------------------------------------*/
1181
1182/*---------------------------------------------------------------------------*/
1183/**
1184 * Read a single register (16-bit) from the AT86RF215
1185 * Implementation of the so called single access mode
1186 */
1187static uint8_t
1188regRead(uint16_t address)
1189{
1190 uint8_t data;
1192 at86rf215_arch_spi_txrx(SPI_CMD_READ | (uint8_t)((address & 0xFF00) >> 8));
1193 at86rf215_arch_spi_txrx((uint8_t)(address & 0x00FF));
1194 data = at86rf215_arch_spi_txrx(0);
1196 return data;
1197}
1198/*---------------------------------------------------------------------------*/
1199/**
1200 * Write a single register (16-bit) to the AT86RF215
1201 */
1202static void
1203regWrite(uint16_t address, uint8_t data)
1204{
1206 at86rf215_arch_spi_txrx(SPI_CMD_WRITE |(uint8_t)((address & 0xFF00) >> 8));
1207 at86rf215_arch_spi_txrx((uint8_t)(address & 0x00FF));
1210}
1211/*---------------------------------------------------------------------------*/
1212/**
1213 * Read one ore multiple bits from the radio's register
1214 *
1215 * For params (addr, mask, offset) --> u can use SR_ defines in registermap.h
1216 */
1217static uint8_t
1218bitRead(uint16_t address, uint8_t mask, uint8_t offset){
1219 uint8_t tmp = regRead(address);
1220 return ((tmp & mask) >> offset);
1221}
1222/*---------------------------------------------------------------------------*/
1223/**
1224 * Write one ore multiple bits to the radio's register. The previous content
1225 * of the registers is not overwritten.
1226 *
1227 * For (addr, mask, offset) --> u can use SR_ defines in registermap.h
1228*/
1229static void
1230bitWrite(uint16_t address, uint8_t mask, uint8_t offset, uint8_t value){
1231 uint8_t tmp = regRead(address);
1232 tmp = (tmp & ~mask) | ((value << offset) & mask);
1233 regWrite(address, tmp);
1234}
1235/*---------------------------------------------------------------------------*/
1236/**
1237 * Read a burst of data from the AT86RF215 registers.
1238 * Implementation of so called block access mode.
1239 */
1240static void burstRead(uint16_t address, uint8_t *data, uint16_t len)
1241{
1243 at86rf215_arch_spi_txrx(SPI_CMD_READ | (uint8_t)((address & 0xFF00) >> 8));
1244 at86rf215_arch_spi_txrx((uint8_t)(address & 0x00FF));
1245
1246 for (uint8_t i = 0; i < len; i++)
1247 {
1248 data[i] = at86rf215_arch_spi_txrx(0);
1249 }
1250
1252}
1253/*---------------------------------------------------------------------------*/
1254/**
1255 * Write a burst of data to the AT86RF215 registers.
1256 * Implementation of so called block access mode.
1257 */
1258static void
1259burstWrite(uint16_t address, uint8_t *data, uint16_t len)
1260{
1261 uint8_t dummy __attribute__((unused));
1263 at86rf215_arch_spi_txrx(SPI_CMD_WRITE |(uint8_t)((address & 0xFF00) >> 8));
1264 at86rf215_arch_spi_txrx((uint8_t)(address & 0x00FF));
1265
1266 for(uint8_t i = 0; i < len; i++) {
1267 dummy = at86rf215_arch_spi_txrx(data[i]);
1268 }
1269
1271}
1272/*---------------------------------------------------------------------------*/
1273/**
1274 * Custom fuction to read a packet frame from the radio's memory
1275*/
1276static void
1277frameRead(uint8_t *frame, uint16_t *frame_len)
1278{
1279 uint8_t len_h = regRead(RG_BBCn_RXFLH);
1280 uint8_t len_l = regRead(RG_BBCn_RXFLL);
1281
1282 uint16_t len = (uint16_t)len_l | ((uint16_t) (len_h & 0x07) << 8);
1283
1284 burstRead(RG_BBCn_FBRXS, frame, len);
1285
1286 *frame_len = len;
1287}
1288/*---------------------------------------------------------------------------*/
1289/**
1290 * Custom fuction to write a packet frame to the radio's memory
1291*/
1292static void
1293frameWrite(uint8_t *frame, uint16_t frame_len)
1294{
1295 regWrite(RG_BBCn_TXFLL, (uint8_t)(frame_len & 0xFF));
1296 regWrite(RG_BBCn_TXFLH, (uint8_t)((frame_len >> 8) & 0x07));
1297
1298 burstWrite(RG_BBCn_FBTXS, frame, frame_len);
1299}
Header file for the at86rf215-arch.c - architecture dependent code.
void at86rf215_arch_clear_RSTN(void)
Release the radio from the reset mode.
void at86rf215_arch_enable_EXTI(void)
Enable the radio's IRQ line.
void at86rf215_arch_spi_select(void)
Select the radio's SPI chip select.
void at86rf215_arch_init(void)
Initialize the radio's I/O periphery.
uint8_t at86rf215_arch_spi_txrx(uint8_t b)
Transfer and receive a single byte over SPI.
void at86rf215_arch_set_RSTN(void)
Reset the radio.
void at86rf215_arch_spi_deselect(void)
Deselect the radio's SPI chip select.
Configuration file for the AT86RF215 radio drivers.
#define AT86RF215_SEND_ON_CCA
Do a CCA manually before sending a packet.
#define AT86RF215_CRC_16BIT
Select either 16-bit (1) or 32-bit (0) CRC.
#define AT86RF215_POLL_MODE
Radio poll mode - should disable interrupts and enable upper levels to poll the radio for events.
#define AT86RF215_CCA_THRESHOLD
CCA threshold in dBm.
#define AT86RF215_AUTO_ACK
If driver is used for CSMA (default)
#define AT86RF215_FRAME_FILTER
Enable/disable address filter mode, where radio only accepts frames with matching address.
#define AT86RF215_FREQUENCY_BAND
Select the Frequency band to use: 0 = Sub-GHz, 1 = 2.4 GHz.
AT86RF215 radio constants and defines.
#define AT86RF215_DELAY_BEFORE_RX
The delay between radio Rx request and start listening 1) transition to RX --> 90 us.
#define AT86RF215_BYTE_AIR_TIME
The air time for one byte in microsecond: 1 / (250kbps/8) == 32 us/byte.
#define AT86RF215_PHY_OVERHEAD
The number of header and footer bytes of overhead at the PHY layer after SFD (1 length + 2 CRC)
#define AT86RF215_DELAY_BEFORE_DETECT
The delay between the end of SFD reception and the radio returning 1 to receiving_packet().
#define AT86RF215_DELAY_BEFORE_TX
The delay between radio Tx request and SFD sent 1) transition to TXPREP --> done in prepare(),...
Registermap for the AT86RF215.
static void frameRead(uint8_t *frame, uint16_t *frame_len)
Custom fuction to read a packet frame from the radio's memory.
Definition at86rf215.c:1277
static uint8_t current_channel
It is easier to store the current channel in a global variable than to read it from the radio registe...
Definition at86rf215.c:138
static uint8_t radio_send_on_cca
Radio configuration parameters according to the Contiki-NG radio API.
Definition at86rf215.c:149
const struct radio_driver at86rf215_driver
The NETSTACK data structure for the AT86RF215 driver.
Definition at86rf215.c:783
static at86rf215_rx_frame_t rx_frame
Contiki-NG requires that the driver stores the values of last RSSI, LQI and timestamp -> we are using...
Definition at86rf215.c:132
int at86rf215_channel_clear(void)
Definition at86rf215.c:506
static uint8_t regRead(uint16_t address)
Read a single register (16-bit) from the AT86RF215 Implementation of the so called single access mode...
Definition at86rf215.c:1188
static volatile at86rf215_flags_t flags
The radio driver uses the following flags to keep track of the current state of the radio and IRQ eve...
Definition at86rf215.c:144
static void regWrite(uint16_t address, uint8_t data)
Write a single register (16-bit) to the AT86RF215.
Definition at86rf215.c:1203
static void bitWrite(uint16_t address, uint8_t mask, uint8_t offset, uint8_t value)
Write one ore multiple bits to the radio's register.
Definition at86rf215.c:1230
static void burstRead(uint16_t address, uint8_t *data, uint16_t len)
Read a burst of data from the AT86RF215 registers.
Definition at86rf215.c:1240
static void set_auto_ack(uint8_t enable)
Definition at86rf215.c:927
void at86rf215_isr(void)
Interrupt service routine for the AT86RF215.
Definition at86rf215.c:811
static void set_frequency(uint16_t freq, uint8_t decimal)
Set frequency via fine resolution obtion.
Definition at86rf215.c:1153
static void frameWrite(uint8_t *frame, uint16_t frame_len)
Custom fuction to write a packet frame to the radio's memory.
Definition at86rf215.c:1293
#define RG_RFn_STATE
Current drivers support only one BBC (RF band) at a time.
Definition at86rf215.c:71
static void burstWrite(uint16_t address, uint8_t *data, uint16_t len)
Write a burst of data to the AT86RF215 registers.
Definition at86rf215.c:1259
static uint8_t bitRead(uint16_t address, uint8_t mask, uint8_t offset)
Read one ore multiple bits from the radio's register.
Definition at86rf215.c:1218
Header file for the at86rf215.c.
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
Definition clock.c:150
static uint8_t get_channel()
Get the current operating channel.
Definition cc2538-rf.c:167
static void set_channel(uint8_t channel)
Set the current operating channel.
Definition cc2538-rf.c:177
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 packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition packetbuf.c:136
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition packetbuf.c:143
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition packetbuf.h:67
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition packetbuf.c:75
#define PROCESS(name, strname)
Declare a process.
Definition process.h:309
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition process.h:122
#define PROCESS_END()
Define the end of a process.
Definition process.h:133
void process_start(struct process *p, process_data_t data)
Start a process.
Definition process.c:121
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition process.h:275
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition process.h:180
void process_poll(struct process *p)
Request a process to be polled.
Definition process.c:366
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
Definition radio.h:451
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
Definition radio.h:461
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
Definition radio.h:474
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio.
Definition radio.h:88
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
Definition radio.h:456
@ RADIO_RESULT_ERROR
An error occurred when getting/setting the parameter, but the arguments were otherwise correct.
Definition radio.h:488
@ RADIO_RESULT_NOT_SUPPORTED
The parameter is not supported.
Definition radio.h:481
@ RADIO_RESULT_INVALID_VALUE
The value argument was incorrect.
Definition radio.h:482
@ RADIO_RESULT_OK
The parameter was set/read successfully.
Definition radio.h:480
@ RADIO_PARAM_POWER_MODE
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
Definition radio.h:119
@ RADIO_CONST_PHY_OVERHEAD
The physical layer header (PHR) + MAC layer footer (MFR) overhead in bytes.
Definition radio.h:338
@ RADIO_PARAM_RSSI
Received signal strength indicator in dBm.
Definition radio.h:218
@ RADIO_PARAM_LAST_PACKET_TIMESTAMP
Last packet timestamp, of type rtimer_clock_t.
Definition radio.h:286
@ RADIO_PARAM_LAST_RSSI
The RSSI value of the last received packet.
Definition radio.h:226
@ RADIO_CONST_BYTE_AIR_TIME
The air time of one byte in usec, e.g.
Definition radio.h:343
@ RADIO_PARAM_RX_MODE
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
Definition radio.h:173
@ RADIO_PARAM_CHANNEL
Channel used for radio communication.
Definition radio.h:134
@ RADIO_PARAM_SHR_SEARCH
For enabling and disabling the SHR search.
Definition radio.h:304
@ RADIO_PARAM_LAST_LINK_QUALITY
Link quality indicator of the last received packet.
Definition radio.h:244
@ RADIO_CONST_DELAY_BEFORE_RX
The delay in usec between turning on the radio and it being actually listening (able to hear a preamb...
Definition radio.h:355
@ RADIO_PARAM_TXPOWER
Transmission power in dBm.
Definition radio.h:192
@ RADIO_PARAM_64BIT_ADDR
Long (64 bits) address for the radio, which is used by the address filter.
Definition radio.h:263
@ RADIO_CONST_DELAY_BEFORE_TX
The delay in usec between a call to the radio API's transmit function and the end of SFD transmission...
Definition radio.h:349
@ RADIO_CONST_CHANNEL_MAX
The highest radio channel number.
Definition radio.h:316
@ RADIO_PARAM_PAN_ID
The personal area network identifier (PAN ID), which is used by the h/w frame filtering functionality...
Definition radio.h:150
@ RADIO_PARAM_CCA_THRESHOLD
Clear channel assessment threshold in dBm.
Definition radio.h:205
@ RADIO_CONST_TXPOWER_MIN
The minimum transmission power in dBm.
Definition radio.h:321
@ RADIO_CONST_CHANNEL_MIN
The lowest radio channel number.
Definition radio.h:311
@ RADIO_CONST_TXPOWER_MAX
The maximum transmission power in dBm.
Definition radio.h:326
@ RADIO_CONST_DELAY_BEFORE_DETECT
The delay in usec between the end of SFD reception for an incoming frame and the radio API starting t...
Definition radio.h:361
@ RADIO_PARAM_16BIT_ADDR
The short address (16 bits) for the radio, which is used by the h/w filter.
Definition radio.h:166
@ RADIO_PARAM_TX_MODE
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
Definition radio.h:180
@ RADIO_POWER_MODE_CARRIER_OFF
Radio powered on, but not emitting unmodulated carriers.
Definition radio.h:410
@ RADIO_POWER_MODE_OFF
Radio powered off and in the lowest possible power consumption state.
Definition radio.h:395
@ RADIO_POWER_MODE_ON
Radio powered on and able to receive frames.
Definition radio.h:400
@ RADIO_POWER_MODE_CARRIER_ON
Radio powered on and emitting unmodulated carriers.
Definition radio.h:405
@ RADIO_TX_ERR
An error occurred during transmission.
Definition radio.h:506
@ RADIO_TX_OK
TX was successful and where an ACK was requested one was received.
Definition radio.h:498
#define RTIMER_NOW()
Get the current clock time.
Definition rtimer.h:191
const tsch_timeslot_timing_usec tsch_timeslot_timing_us_10000
TSCH timing attributes and description.
Header file for the logging system.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
Definition mac.h:52
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the radio API.
void(* input)(void)
Callback for getting notified of incoming packet.
Definition mac.h:78
The structure of a Contiki-NG radio device driver.
Definition radio.h:534
int(* init)(void)
Initialise the radio hardware.
Definition radio.h:555
Main API declarations for TSCH.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition uip-nd6.c:107