kw41zrf_intern.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 SKF AB
3  * Copyright (C) 2016 Phytec Messtechnik GmbH
4  *
5  * This file is subject to the terms and conditions of the GNU Lesser
6  * General Public License v2.1. See the file LICENSE in the top level
7  * directory for more details.
8  */
9 
20 #ifndef KW41ZRF_INTERN_H
21 #define KW41ZRF_INTERN_H
22 
23 #include <stdint.h>
24 #include "kw41zrf.h"
25 /* For XCVSEQ_IDLE */
26 #include "kw41zrf_getset.h"
27 /* For ZLL CPU registers */
28 #include "cpu.h"
29 
30 /* When the transceiver is not in DSM, this power mode will be blocked. */
31 #define KW41ZRF_PM_BLOCKER KINETIS_PM_VLPS
32 
33 /* Set to 1 to use on board LEDs to show RX/TX activity */
34 #ifndef KW41ZRF_ENABLE_LEDS
35 #define KW41ZRF_ENABLE_LEDS (0)
36 #endif
37 
38 #if KW41ZRF_ENABLE_LEDS
39 /* For LED macros */
40 #include "board.h"
41 #if !defined(KW41ZRF_LED_RX_ON)
42 #if defined(LED0_ON)
43 #define KW41ZRF_LED_RX_ON LED0_ON
44 #define KW41ZRF_LED_RX_OFF LED0_OFF
45 #else /* defined(LED0_ON) */
46 #define KW41ZRF_LED_RX_ON
47 #define KW41ZRF_LED_RX_OFF
48 #endif /* defined(LED0_ON) */
49 #endif /* !defined(KW41ZRF_LED_RX_ON) */
50 #if !defined(KW41ZRF_LED_TX_ON)
51 #if defined(LED1_ON)
52 /* Separate TX LED */
53 #define KW41ZRF_LED_TX_ON LED1_ON
54 #define KW41ZRF_LED_TX_OFF LED1_OFF
55 #elif defined(LED0_ON)
56 /* Combined RX+TX in one LED */
57 #define KW41ZRF_LED_TX_ON LED0_ON
58 #define KW41ZRF_LED_TX_OFF LED0_OFF
59 #else /* defined(LEDx_ON) */
60 #define KW41ZRF_LED_TX_ON
61 #define KW41ZRF_LED_TX_OFF
62 #endif /* defined(LEDx_ON) */
63 #endif /* !defined(KW41ZRF_LED_TX_ON) */
64 #if !defined(KW41ZRF_LED_NDSM_ON)
65 #if defined(LED2_ON)
66 #define KW41ZRF_LED_NDSM_ON LED2_ON
67 #define KW41ZRF_LED_NDSM_OFF LED2_OFF
68 #else /* defined(LEDx_ON) */
69 #define KW41ZRF_LED_NDSM_ON
70 #define KW41ZRF_LED_NDSM_OFF
71 #endif /* defined(LEDx_ON) */
72 #endif /* !defined(KW41ZRF_LED_NDSM_ON) */
73 #if !defined(KW41ZRF_LED_IRQ_ON)
74 #if defined(LED3_ON)
75 #define KW41ZRF_LED_IRQ_ON LED3_ON
76 #define KW41ZRF_LED_IRQ_OFF LED3_OFF
77 #else /* defined(LEDx_ON) */
78 #define KW41ZRF_LED_IRQ_ON
79 #define KW41ZRF_LED_IRQ_OFF
80 #endif /* defined(LEDx_ON) */
81 #endif /* !defined(KW41ZRF_LED_IRQ_ON) */
82 #else /* KW41ZRF_ENABLE_LEDS */
83 #define KW41ZRF_LED_NDSM_ON
84 #define KW41ZRF_LED_NDSM_OFF
85 #define KW41ZRF_LED_TX_ON
86 #define KW41ZRF_LED_TX_OFF
87 #define KW41ZRF_LED_RX_ON
88 #define KW41ZRF_LED_RX_OFF
89 #define KW41ZRF_LED_IRQ_ON
90 #define KW41ZRF_LED_IRQ_OFF
91 #endif /* KW41ZRF_ENABLE_LEDS */
92 
93 #ifdef __cplusplus
94 extern "C" {
95 #endif
96 
100 typedef enum {
104 
109  KW41ZRF_TIMEBASE_500000HZ = 0b010,
110  KW41ZRF_TIMEBASE_250000HZ = 0b011,
111  KW41ZRF_TIMEBASE_125000HZ = 0b100,
112  KW41ZRF_TIMEBASE_62500HZ = 0b101,
113  KW41ZRF_TIMEBASE_31250HZ = 0b110,
114  KW41ZRF_TIMEBASE_15625HZ = 0b111,
116 
120 static inline void kw41zrf_mask_irqs(void)
121 {
122  NVIC_DisableIRQ(Radio_1_IRQn);
123  NVIC_ClearPendingIRQ(Radio_1_IRQn);
124 }
125 
129 static inline void kw41zrf_unmask_irqs(void)
130 {
131  KW41ZRF_LED_IRQ_OFF;
132  NVIC_EnableIRQ(Radio_1_IRQn);
133 }
134 
143 void kw41zrf_set_irq_callback(void (*cb)(void *arg), void *arg);
144 
152 
162 
169 void kw41zrf_set_sequence(kw41zrf_t *dev, uint32_t seq);
170 
176 static inline void kw41zrf_abort_sequence(kw41zrf_t *dev)
177 {
178  (void) dev;
179  /* Writing IDLE to XCVSEQ aborts any ongoing sequence */
180  ZLL->PHY_CTRL = (ZLL->PHY_CTRL &
181  ~(ZLL_PHY_CTRL_XCVSEQ_MASK |
182  ZLL_PHY_CTRL_TC3TMOUT_MASK | ZLL_PHY_CTRL_TMRTRIGEN_MASK)) |
183  ZLL_PHY_CTRL_XCVSEQ(XCVSEQ_IDLE) | ZLL_PHY_CTRL_SEQMSK_MASK;
184  /* Spin until the sequence manager has acknowledged the sequence abort, this
185  * should not take many cycles */
186  while (!(ZLL->SEQ_CTRL_STS & ZLL_SEQ_CTRL_STS_SEQ_IDLE_MASK)) {}
187 
188  /* Clear interrupt flags */
189  uint32_t irqsts = ZLL->IRQSTS;
190  ZLL->IRQSTS = irqsts;
191 }
192 
199 static inline uint32_t kw41zrf_is_dsm(void)
200 {
201  return (RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK);
202 }
203 
210 static inline void kw41zrf_timer_load(kw41zrf_t *dev, uint32_t value)
211 {
212  (void) dev;
213  ZLL->EVENT_TMR = ZLL_EVENT_TMR_EVENT_TMR(value) | ZLL_EVENT_TMR_EVENT_TMR_LD_MASK;
214 }
215 
223 static inline uint32_t kw41zrf_timer_get(kw41zrf_t *dev)
224 {
225  (void) dev;
226  return (ZLL->EVENT_TMR & ZLL_EVENT_TMR_EVENT_TMR_MASK) >> ZLL_EVENT_TMR_EVENT_TMR_SHIFT;
227 }
228 
236 static inline void kw41zrf_timer_set(kw41zrf_t *dev, volatile uint32_t *cmp_reg, uint32_t timeout)
237 {
238  uint32_t now = kw41zrf_timer_get(dev);
239 
240  *cmp_reg = now + timeout;
241 }
242 
255 {
256  ZLL->TMR_PRESCALE = (ZLL->TMR_PRESCALE & ~ZLL_TMR_PRESCALE_TMR_PRESCALE_MASK) |
257  ZLL_TMR_PRESCALE_TMR_PRESCALE(tb);
258  kw41zrf_timer_load(dev, 0);
259 }
260 
272 static inline uint32_t kw41zrf_get_timestamp(kw41zrf_t *dev)
273 {
274  (void) dev;
275  return ZLL->TIMESTAMP;
276 }
277 
278 #ifdef __cplusplus
279 }
280 #endif
281 
282 #endif /* KW41ZRF_INTERN_H */
283 
kw41zrf_mask_irqs
static void kw41zrf_mask_irqs(void)
Mask all transceiver interrupts.
Definition: kw41zrf_intern.h:120
kw41zrf_set_irq_callback
void kw41zrf_set_irq_callback(void(*cb)(void *arg), void *arg)
Set the callback function for the radio ISR.
kw41zrf.h
Interface definition for the kw41zrf driver.
KW41ZRF_POWER_IDLE
@ KW41ZRF_POWER_IDLE
All parts powered.
Definition: kw41zrf_intern.h:101
kw41zrf_get_timestamp
static uint32_t kw41zrf_get_timestamp(kw41zrf_t *dev)
Returns timestamp of the beginning of the most recently received packet.
Definition: kw41zrf_intern.h:272
kw41zrf_timer_set
static void kw41zrf_timer_set(kw41zrf_t *dev, volatile uint32_t *cmp_reg, uint32_t timeout)
Set a timeout value for the given compare register of the Event Timer.
Definition: kw41zrf_intern.h:236
kw41zrf_unmask_irqs
static void kw41zrf_unmask_irqs(void)
Unmask all transceiver interrupts.
Definition: kw41zrf_intern.h:129
kw41zrf_timer_timebase
kw41zrf_timer_timebase
Timebase settings.
Definition: kw41zrf_intern.h:108
kw41zrf_timer_get
static uint32_t kw41zrf_timer_get(kw41zrf_t *dev)
Get current event timer counter value.
Definition: kw41zrf_intern.h:223
kw41zrf_timer_load
static void kw41zrf_timer_load(kw41zrf_t *dev, uint32_t value)
Set event timer counter value.
Definition: kw41zrf_intern.h:210
kw41zrf_timer_timebase_t
enum kw41zrf_timer_timebase kw41zrf_timer_timebase_t
Timebase settings.
kw41zrf_abort_sequence
static void kw41zrf_abort_sequence(kw41zrf_t *dev)
Abort the current autosequence.
Definition: kw41zrf_intern.h:176
kw41zrf_getset.h
get/set interfaces for kw41zrf driver
kw41zrf_powermode_t
kw41zrf_powermode_t
KW41Z transceiver power modes.
Definition: kw41zrf_intern.h:100
kw41zrf_set_sequence
void kw41zrf_set_sequence(kw41zrf_t *dev, uint32_t seq)
Set sequence state of device.
KW41ZRF_POWER_DSM
@ KW41ZRF_POWER_DSM
Deep sleep mode.
Definition: kw41zrf_intern.h:102
kw41zrf_t
Device descriptor for KW41ZRF radio devices.
Definition: kw41zrf.h:102
kw41zrf_can_switch_to_idle
int kw41zrf_can_switch_to_idle(kw41zrf_t *dev)
Determine if the transceiver is busy doing TX or RX.
kw41zrf_is_dsm
static uint32_t kw41zrf_is_dsm(void)
Check if the radio is in deep sleep mode.
Definition: kw41zrf_intern.h:199
kw41zrf_set_power_mode
void kw41zrf_set_power_mode(kw41zrf_t *dev, kw41zrf_powermode_t pm)
Set power mode for device.
kw41zrf_timer_init
static void kw41zrf_timer_init(kw41zrf_t *dev, kw41zrf_timer_timebase_t tb)
Initialize the Event Timer Block (up counter)
Definition: kw41zrf_intern.h:254