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