Loading...
Searching...
No Matches
kw41zrf_intern.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2017 SKF AB
3 * SPDX-FileCopyrightText: 2016 Phytec Messtechnik GmbH
4 * SPDX-License-Identifier: LGPL-2.1-only
5 */
6
7#pragma once
8
18
19#include <stdint.h>
20#include "kw41zrf.h"
21/* For XCVSEQ_IDLE */
22#include "kw41zrf_getset.h"
23/* For ZLL CPU registers */
24#include "cpu.h"
25
26/* When the transceiver is not in DSM, this power mode will be blocked. */
27#define KW41ZRF_PM_BLOCKER KINETIS_PM_VLPS
28
29/* Set to 1 to use on board LEDs to show RX/TX activity */
30#ifndef KW41ZRF_ENABLE_LEDS
31# define KW41ZRF_ENABLE_LEDS (0)
32#endif
33
34#if KW41ZRF_ENABLE_LEDS
35/* For LED macros */
36# include "board.h"
37# if !defined(KW41ZRF_LED_RX_ON)
38# if defined(LED0_ON)
39# define KW41ZRF_LED_RX_ON LED0_ON
40# define KW41ZRF_LED_RX_OFF LED0_OFF
41# else /* defined(LED0_ON) */
42# define KW41ZRF_LED_RX_ON
43# define KW41ZRF_LED_RX_OFF
44# endif /* defined(LED0_ON) */
45# endif /* !defined(KW41ZRF_LED_RX_ON) */
46# if !defined(KW41ZRF_LED_TX_ON)
47# if defined(LED1_ON)
48/* Separate TX LED */
49# define KW41ZRF_LED_TX_ON LED1_ON
50# define KW41ZRF_LED_TX_OFF LED1_OFF
51# elif defined(LED0_ON)
52/* Combined RX+TX in one LED */
53# define KW41ZRF_LED_TX_ON LED0_ON
54# define KW41ZRF_LED_TX_OFF LED0_OFF
55# else /* defined(LEDx_ON) */
56# define KW41ZRF_LED_TX_ON
57# define KW41ZRF_LED_TX_OFF
58# endif /* defined(LEDx_ON) */
59# endif /* !defined(KW41ZRF_LED_TX_ON) */
60# if !defined(KW41ZRF_LED_NDSM_ON)
61# if defined(LED2_ON)
62# define KW41ZRF_LED_NDSM_ON LED2_ON
63# define KW41ZRF_LED_NDSM_OFF LED2_OFF
64# else /* defined(LEDx_ON) */
65# define KW41ZRF_LED_NDSM_ON
66# define KW41ZRF_LED_NDSM_OFF
67# endif /* defined(LEDx_ON) */
68# endif /* !defined(KW41ZRF_LED_NDSM_ON) */
69# if !defined(KW41ZRF_LED_IRQ_ON)
70# if defined(LED3_ON)
71# define KW41ZRF_LED_IRQ_ON LED3_ON
72# define KW41ZRF_LED_IRQ_OFF LED3_OFF
73# else /* defined(LEDx_ON) */
74# define KW41ZRF_LED_IRQ_ON
75# define KW41ZRF_LED_IRQ_OFF
76# endif /* defined(LEDx_ON) */
77# endif /* !defined(KW41ZRF_LED_IRQ_ON) */
78#else /* KW41ZRF_ENABLE_LEDS */
79# define KW41ZRF_LED_NDSM_ON
80# define KW41ZRF_LED_NDSM_OFF
81# define KW41ZRF_LED_TX_ON
82# define KW41ZRF_LED_TX_OFF
83# define KW41ZRF_LED_RX_ON
84# define KW41ZRF_LED_RX_OFF
85# define KW41ZRF_LED_IRQ_ON
86# define KW41ZRF_LED_IRQ_OFF
87#endif /* KW41ZRF_ENABLE_LEDS */
88
89#ifdef __cplusplus
90extern "C" {
91#endif
92
100
105 KW41ZRF_TIMEBASE_500000HZ = 0b010,
106 KW41ZRF_TIMEBASE_250000HZ = 0b011,
107 KW41ZRF_TIMEBASE_125000HZ = 0b100,
108 KW41ZRF_TIMEBASE_62500HZ = 0b101,
109 KW41ZRF_TIMEBASE_31250HZ = 0b110,
110 KW41ZRF_TIMEBASE_15625HZ = 0b111,
112
116static inline void kw41zrf_mask_irqs(void)
117{
118 NVIC_DisableIRQ(Radio_1_IRQn);
119 NVIC_ClearPendingIRQ(Radio_1_IRQn);
120}
121
125static inline void kw41zrf_unmask_irqs(void)
126{
127 KW41ZRF_LED_IRQ_OFF;
128 NVIC_EnableIRQ(Radio_1_IRQn);
129}
130
139void kw41zrf_set_irq_callback(void (*cb)(void *arg), void *arg);
140
148
158
168void kw41zrf_set_sequence(kw41zrf_t *dev, uint32_t seq);
169
177static inline uint8_t kw41zrf_get_sequence(kw41zrf_t *dev)
178{
179 (void)dev;
180 return (ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK) >> ZLL_PHY_CTRL_XCVSEQ_SHIFT;
181}
182
188static inline void kw41zrf_abort_sequence(kw41zrf_t *dev)
189{
190 (void) dev;
191 /* Writing IDLE to XCVSEQ aborts any ongoing sequence */
192 ZLL->PHY_CTRL = (ZLL->PHY_CTRL &
193 ~(ZLL_PHY_CTRL_XCVSEQ_MASK |
194 ZLL_PHY_CTRL_TC3TMOUT_MASK | ZLL_PHY_CTRL_TMRTRIGEN_MASK)) |
195 ZLL_PHY_CTRL_XCVSEQ(XCVSEQ_IDLE) | ZLL_PHY_CTRL_SEQMSK_MASK;
196 /* Spin until the sequence manager has acknowledged the sequence abort, this
197 * should not take many cycles */
198 while (!(ZLL->SEQ_CTRL_STS & ZLL_SEQ_CTRL_STS_SEQ_IDLE_MASK)) {}
199
200 /* Clear interrupt flags */
201 uint32_t irqsts = ZLL->IRQSTS;
202 ZLL->IRQSTS = irqsts;
203}
204
211static inline void kw41zrf_set_sequence_abort(kw41zrf_t *dev, uint32_t seq)
212{
214 kw41zrf_set_sequence(dev, seq);
215}
216
223static inline uint32_t kw41zrf_is_dsm(void)
224{
225 return (RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK);
226}
227
234static inline void kw41zrf_timer_load(kw41zrf_t *dev, uint32_t value)
235{
236 (void) dev;
237 ZLL->EVENT_TMR = ZLL_EVENT_TMR_EVENT_TMR(value) | ZLL_EVENT_TMR_EVENT_TMR_LD_MASK;
238}
239
247static inline uint32_t kw41zrf_timer_get(kw41zrf_t *dev)
248{
249 (void) dev;
250 return (ZLL->EVENT_TMR & ZLL_EVENT_TMR_EVENT_TMR_MASK) >> ZLL_EVENT_TMR_EVENT_TMR_SHIFT;
251}
252
260static inline void kw41zrf_timer_set(kw41zrf_t *dev, volatile uint32_t *cmp_reg, uint32_t timeout)
261{
262 uint32_t now = kw41zrf_timer_get(dev);
263
264 *cmp_reg = now + timeout;
265}
266
279{
280 ZLL->TMR_PRESCALE = (ZLL->TMR_PRESCALE & ~ZLL_TMR_PRESCALE_TMR_PRESCALE_MASK) |
281 ZLL_TMR_PRESCALE_TMR_PRESCALE(tb);
282 kw41zrf_timer_load(dev, 0);
283}
284
296static inline uint32_t kw41zrf_get_timestamp(kw41zrf_t *dev)
297{
298 (void) dev;
299 return ZLL->TIMESTAMP;
300}
301
308static inline uint8_t kw41zrf_ack_requested(kw41zrf_t *dev)
309{
310 (void) dev;
311 return (ZLL->PHY_CTRL & ZLL_PHY_CTRL_RXACKRQD_MASK);
312}
313
314#ifdef __cplusplus
315}
316#endif
317
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.
static uint8_t kw41zrf_get_sequence(kw41zrf_t *dev)
Get the current state of device.
kw41zrf_timer_timebase
Timebase settings.
static uint8_t kw41zrf_ack_requested(kw41zrf_t *dev)
Returns if the transmitted frame needs an ACK afterwards.
static void kw41zrf_set_sequence_abort(kw41zrf_t *dev, uint32_t seq)
Abort current sequence and set new sequence state.
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.
Device descriptor for KW41ZRF radio devices.
Definition kw41zrf.h:110