cc2538_rf.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016 MUTEX NZ Ltd.
3  * SPDX-FileCopyrightText: 2015 Loci Controls Inc.
4  * SPDX-License-Identifier: LGPL-2.1-only
5  */
6 
7 #pragma once
8 
20 #include <stdbool.h>
21 
22 #include "board.h"
23 #include "cc2538_rfcore.h"
24 
25 #include "net/ieee802154.h"
26 #include "kernel_defines.h"
27 
28 #include "net/ieee802154/radio.h"
29 
30 #include "net/netopt.h"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #define CC2538_AUTOCRC_LEN (2)
37 #define CC2538_RF_FIFO_SIZE (128)
38 #define CC2538_PACKET_LENGTH_SIZE (1)
39 #define CC2538_LENGTH_BYTE_MASK (0x7F)
41 #define CC2538_RF_MAX_DATA_LEN (CC2538_RF_FIFO_SIZE - CC2538_PACKET_LENGTH_SIZE)
42 
43 /* TODO: Move these to sys/include/net/ieee802154.h somehow */
44 /* IEEE 802.15.4 defined constants (2.4 GHz logical channels) */
45 #define IEEE802154_MIN_FREQ (2405)
46 #define IEEE802154_MAX_FREQ (2480)
48 #define IEEE802154_CHANNEL_SPACING (5)
50 #define IEEE802154_CHAN2FREQ(chan) ( IEEE802154_MIN_FREQ + ((chan) - IEEE802154_CHANNEL_MIN) * IEEE802154_CHANNEL_SPACING )
51 #define IEEE802154_FREQ2CHAN(freq) ( IEEE802154_CHANNEL_MIN + ((freq) - IEEE802154_MIN_FREQ) / IEEE802154_CHANNEL_SPACING )
52 /* /TODO */
53 
54 #define CC2538_MIN_FREQ (2394)
55 #define CC2538_MAX_FREQ (2507)
56 
57 #define CC2538_RF_POWER_DEFAULT (CONFIG_IEEE802154_DEFAULT_TXPOWER)
58 #define CC2538_RF_CHANNEL_DEFAULT (CONFIG_IEEE802154_DEFAULT_CHANNEL)
59 
60 #define OUTPUT_POWER_MIN (-24)
61 #define OUTPUT_POWER_MAX (7)
62 #define NUM_POWER_LEVELS ( OUTPUT_POWER_MAX - OUTPUT_POWER_MIN + 1 )
63 
64 #define CC2538_CORR_VAL_MIN (50U)
65 #define CC2538_CORR_VAL_MAX (110U)
66 #define CC2538_CORR_VAL_MASK (0x7F)
67 
68 #define CC2538_CRC_BIT_MASK (0x80)
69 
70 #define CC2538_CCA_THR_MASK (0x000000FF)
72 #define CC2538_CCA_MODE_MASK (0x18)
73 #define CC2538_CCA_MODE_POS (3U)
75 #define CC2538_CSP_SKIP_INST_MASK (0x70)
76 #define CC2538_CSP_SKIP_INST_POS (4U)
78 #define CC2538_CSP_SKIP_N_MASK (0x08)
80 #define CC2538_CSP_SKIP_COND_CCA (0x00)
81 #define CC2538_CSP_SKIP_COND_CSPZ (0x06)
82 #define CC2538_CSP_SKIP_COND_RSSI (0x07)
84 #define CC2538_SFR_MTMSEL_MASK (0x7)
85 #define CC2538_SFR_MTMSEL_TIMER_P (0x2)
86 #define CC2538_MCTRL_SYNC_MASK (0x2)
87 #define CC2538_MCTRL_RUN_MASK (0x1)
89 #define CC2538_CSP_MCU_CTRL_MASK (0x1)
91 #define CC2538_CSP_INCMAXY_MAX_MASK (0x7)
94 #define CC2538_RXENABLE_RXON_MASK (0x80)
96 #define CC2538_RSSI_OFFSET (-73)
97 #define CC2538_RF_SENSITIVITY (-97)
99 #define CC2538_ACCEPT_FT_0_BEACON (1 << 3)
100 #define CC2538_ACCEPT_FT_1_DATA (1 << 4)
101 #define CC2538_ACCEPT_FT_2_ACK (1 << 5)
102 #define CC2538_ACCEPT_FT_3_CMD (1 << 6)
103 #define CC2538_STATE_SFD_WAIT_RANGE_MIN (0x03U)
104 #define CC2538_STATE_SFD_WAIT_RANGE_MAX (0x06U)
105 #define CC2538_FRMCTRL1_PENDING_OR_MASK (0x04)
107 #define CC2538_FRMCTRL0_RX_MODE_DIS (0xC)
110 #define RFCORE_ASSERT(expr) (void)( (expr) || RFCORE_ASSERT_failure(#expr, __FUNCTION__, __LINE__) )
111 
112 #if DEVELHELP
113 #define RFCORE_WAIT_UNTIL(expr) while (!(expr)) { \
114  DEBUG("RFCORE_WAIT_UNTIL(%s) at line %u in %s()\n", #expr, __LINE__, __FUNCTION__); \
115  thread_yield(); \
116 }
117 #else
118 #define RFCORE_WAIT_UNTIL(expr) while (!(expr)) thread_yield()
119 #endif
120 
121 #define RFCORE_FLUSH_RECEIVE_FIFO() rfcore_strobe(ISFLUSHRX)
122 
123 #define ABS_DIFF(x, y) ( ((x) < (y))? ((y) - (x)) : ((x) - (y)) )
124 #define BOOLEAN(x) ( (x) != 0 )
125 #define NOT(x) ( (x) == 0 )
126 #define GET_BYTE(buffer, index) ( (unsigned char*)(buffer) )[index]
127 
128 #define BIT(n) ( 1 << (n) )
129 
130 enum {
131  FSM_STATE_IDLE = 0,
132  FSM_STATE_RX_CALIBRATION = 2,
133  FSM_STATE_TX_CALIBRATION = 32,
134 };
135 
139 enum {
140  STROBE_ERR = BIT(6),
141  TXUNDERF = BIT(5),
142  TXOVERF = BIT(4),
143  RXUNDERF = BIT(3),
144  RXOVERF = BIT(2),
145  RXABO = BIT(1),
146  NLOCK = BIT(0),
147 };
148 
152 enum {
153  SET_RXENMASK_ON_TX = BIT(0),
154  IGNORE_TX_UNDERF = BIT(1),
155  PENDING_OR = BIT(2),
156 };
157 
161 enum {
162  ENERGY_SCAN = BIT(4),
163  AUTOACK = BIT(5),
164  AUTOCRC = BIT(6),
165  APPEND_DATA_MODE = BIT(7),
166 };
167 
171 enum {
172  ACT_UNUSED = BIT(0),
173  SFD = BIT(1),
174  FIFOP = BIT(2),
175  SRC_MATCH_DONE = BIT(3),
176  SRC_MATCH_FOUND = BIT(4),
177  FRAME_ACCEPTED = BIT(5),
178  RXPKTDONE = BIT(6),
179  RXMASKZERO = BIT(7),
180 };
181 
185 enum {
186  TXACKDONE = BIT(0),
187  TXDONE = BIT(1),
188  RF_IDLE = BIT(2),
189  CSP_MANINT = BIT(3),
190  CSP_STOP = BIT(4),
191  CSP_WAIT = BIT(5),
192 };
193 
197 enum {
198  rfc_obs_sig0 = 0,
199  rfc_obs_sig1 = 1,
200  rfc_obs_sig2 = 2,
201 };
202 
206 enum {
209  rfc_sniff_data = 0x08,
211  rfc_sniff_clk = 0x09,
212  rssi_valid = 0x0c,
215  demod_cca = 0x0d,
218  sampled_cca = 0x0e,
221  sfd_sync = 0x0f,
225  tx_active = 0x10,
227  rx_active = 0x11,
229  ffctrl_fifo = 0x12,
231  ffctrl_fifop = 0x13,
237  packet_done = 0x14,
240  rfc_xor_rand_i_q = 0x16,
242  rfc_rand_q = 0x17,
244  rfc_rand_i = 0x18,
246  lock_status = 0x19,
247  pa_pd = 0x20,
248  lna_pd = 0x2a,
249  disabled = 0xff,
250 };
251 
255 #ifndef CONFIG_CC2538_RF_OBS_0
256 #define CONFIG_CC2538_RF_OBS_0 tx_active
257 #endif
258 #ifndef CONFIG_CC2538_RF_OBS_1
259 #define CONFIG_CC2538_RF_OBS_1 rx_active
260 #endif
261 #ifndef CONFIG_CC2538_RF_OBS_2
262 #define CONFIG_CC2538_RF_OBS_2 rssi_valid
263 #endif
264 
265 /* Default configuration for cc2538dk or similar */
266 #ifndef CONFIG_CC2538_RF_OBS_SIG_0_PCX
267 #define CONFIG_CC2538_RF_OBS_SIG_0_PCX 0 /* PC0 = LED_1 (red) */
268 #endif
269 #ifndef CONFIG_CC2538_RF_OBS_SIG_1_PCX
270 #define CONFIG_CC2538_RF_OBS_SIG_1_PCX 1 /* PC0 = LED_2 (red) */
271 #endif
272 #ifndef CONFIG_CC2538_RF_OBS_SIG_2_PCX
273 #define CONFIG_CC2538_RF_OBS_SIG_2_PCX 2 /* PC0 = LED_3 (red) */
274 #endif
275 #if ((CONFIG_CC2538_RF_OBS_SIG_2_PCX > 7) || \
276  (CONFIG_CC2538_RF_OBS_SIG_1_PCX > 7) || \
277  (CONFIG_CC2538_RF_OBS_SIG_0_PCX > 7))
278 #error "CONFIG_CC2538_RF_OBS_SIG_X_PCX must be between 0-7 (PC0-PC7)"
279 #endif
280 
284 typedef struct {
285  uint8_t state;
286 } cc2538_rf_t;
287 
296 
300 static inline void cc2538_rf_enable_irq(void)
301 {
302  RFCORE_XREG_RFIRQM1 = TXDONE | CSP_STOP | TXACKDONE;
304 }
305 
309 static inline void cc2538_rf_disable_irq(void)
310 {
313 }
314 
320 
328 
334 void cc2538_get_addr_long(uint8_t *addr);
335 
341 void cc2538_get_addr_short(uint8_t *addr);
342 
348 unsigned int cc2538_get_chan(void);
349 
357 
363 uint16_t cc2538_get_pan(void);
364 
371 
376 void cc2538_init(void);
377 
384 bool cc2538_is_on(void);
385 
390 void cc2538_off(void);
391 
396 bool cc2538_on(void);
397 
404 
410 void cc2538_set_addr_short(const uint8_t *addr);
411 
417 void cc2538_set_addr_long(const uint8_t *addr);
418 
424 void cc2538_set_chan(unsigned int chan);
425 
431 void cc2538_set_freq(unsigned int MHz);
432 
438 void cc2538_set_monitor(bool mode);
439 
445 void cc2538_set_pan(uint16_t pan);
446 
454 
460 void cc2538_set_tx_power(int dBm);
461 
462 #ifdef __cplusplus
463 }
464 #endif
465 
#define RFCORE_XREG_RFIRQM0
RF interrupt masks.
Definition: cc2538.h:380
#define RFCORE_XREG_RFIRQM1
RF interrupt masks.
Definition: cc2538.h:381
void cc2538_set_pan(uint16_t pan)
Set the PAN ID of the device.
void cc2538_set_addr_long(const uint8_t *addr)
Set the long address of the device.
unsigned int cc2538_get_chan(void)
Get the configured channel number of the device.
void cc2538_off(void)
Deactivate the CC2538 radio device.
bool cc2538_on(void)
Activate the CC2538 radio device.
void cc2538_rf_hal_setup(ieee802154_dev_t *hal)
Setup CC2538 in order to be used with the IEEE 802.15.4 Radio HAL.
void cc2538_irq_handler(void)
IRQ handler for RF events.
bool cc2538_channel_clear(void)
Trigger a clear channel assessment.
void cc2538_set_addr_short(const uint8_t *addr)
Set the short address of the device.
void cc2538_set_chan(unsigned int chan)
Set the channel number of the device.
static void cc2538_rf_enable_irq(void)
Enable CC2538 RF IRQs.
Definition: cc2538_rf.h:300
void cc2538_init(void)
Initialise the CC2538 radio hardware.
uint16_t cc2538_get_pan(void)
Get the configured PAN ID of the device.
void cc2538_set_tx_power(int dBm)
Set the transmission power for the device.
void cc2538_set_monitor(bool mode)
Enable/disable monitor (promiscuous) mode for the device.
@ RXPKTDONE
End of frame event.
Definition: cc2538_rf.h:178
@ SFD
Start of frame event.
Definition: cc2538_rf.h:173
void cc2538_get_addr_short(uint8_t *addr)
Get the configured short address of the device.
static void cc2538_rf_disable_irq(void)
Disable CC2538 RF IRQs.
Definition: cc2538_rf.h:309
bool cc2538_is_on(void)
Check if device is active.
bool cc2538_get_monitor(void)
Check if device is in monitor (promiscuous) mode.
void cc2538_set_state(cc2538_rf_t *dev, netopt_state_t state)
Set the state of the device.
@ rfc_rand_i
Random data output from the I channel of the receiver.
Definition: cc2538_rf.h:244
@ lna_pd
LNA power-down signal.
Definition: cc2538_rf.h:248
@ rssi_valid
Pin is high when the RSSI value has been updated at least once since RX was started.
Definition: cc2538_rf.h:212
@ packet_done
A complete frame has been received.
Definition: cc2538_rf.h:237
@ rx_active
Indicates that FFCTRL is in one of the RX states.
Definition: cc2538_rf.h:227
@ disabled
disabled
Definition: cc2538_rf.h:249
@ constant_value_0
Constant value 0.
Definition: cc2538_rf.h:207
@ sampled_cca
A sampled version of the CCA bit from demodulator.
Definition: cc2538_rf.h:218
@ rfc_xor_rand_i_q
XOR between I and Q random outputs.
Definition: cc2538_rf.h:240
@ rfc_sniff_data
Data from packet sniffer.
Definition: cc2538_rf.h:209
@ ffctrl_fifop
Pin is high when the number of bytes in the RXFIFO exceeds the programmable threshold or at least one...
Definition: cc2538_rf.h:231
@ pa_pd
Power amplifier power-down signal.
Definition: cc2538_rf.h:247
@ sfd_sync
Pin is high when a SFD has been received or transmitted.
Definition: cc2538_rf.h:221
@ demod_cca
Clear channel assessment.
Definition: cc2538_rf.h:215
@ constant_value_1
Constant value 1.
Definition: cc2538_rf.h:208
@ tx_active
Indicates that FFCTRL is in one of the TX states.
Definition: cc2538_rf.h:225
@ ffctrl_fifo
Pin is high when one or more bytes are in the RXFIFO.
Definition: cc2538_rf.h:229
@ rfc_rand_q
Random data output from the Q channel of the receiver.
Definition: cc2538_rf.h:242
@ rfc_sniff_clk
250kHz clock for packet sniffer data.
Definition: cc2538_rf.h:211
@ lock_status
1 when PLL is in lock, otherwise 0
Definition: cc2538_rf.h:246
void cc2538_set_freq(unsigned int MHz)
Set the frequency of the device.
void cc2538_get_addr_long(uint8_t *addr)
Get the configured long address of the device.
int cc2538_get_tx_power(void)
Get the configured transmission power of the device.
void cc2538_setup(cc2538_rf_t *dev)
Setup a CC2538 radio device.
CC2538 RF core interface.
netopt_state_t
Option parameter to be used with NETOPT_STATE to set or get the state of a network device or protocol...
Definition: netopt.h:893
Common macros and compiler attributes/pragmas configuration.
Definition of global configuration options.
Device descriptor for CC2538 transceiver.
Definition: cc2538_rf.h:284
uint8_t state
current state of the radio
Definition: cc2538_rf.h:285
the IEEE802.15.4 device descriptor
Definition: radio.h:414
IEEE 802.15.4 header definitions.