nrfxlib API 3.3.99
Loading...
Searching...
No Matches
nrf_802154_hw_utils.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
42#ifndef NRF_802154_HW_UTILS_H_
43#define NRF_802154_HW_UTILS_H_
44
45#include <nrfx.h>
46
47#ifdef __STATIC_INLINE__
48#undef __STATIC_INLINE__
49#endif /* __STATIC_INLINE__ */
50
51#ifdef NRF_802154_HW_UTILS_DECLARE_ONLY
52#define __STATIC_INLINE__
53#else /* NRF_802154_HW_UTILS_DECLARE_ONLY */
54#define __STATIC_INLINE__ __STATIC_INLINE
55#endif /* NRF_802154_HW_UTILS_DECLARE_ONLY */
56
57#define RADIO_BASE ((uintptr_t)NRF_RADIO)
58#define FICR_BASE ((uintptr_t)NRF_FICR)
59
60#define FICR_REG_RESET_VALUE 0xFFFFFFFFUL
61#define IS_FICR_REG_SET(_ficr_reg) ((_ficr_reg) != FICR_REG_RESET_VALUE)
62
71__STATIC_INLINE__ uint32_t nrf_802154_hw_offset_read(uintptr_t base_addr, uint32_t offset);
72
80__STATIC_INLINE__ void nrf_802154_hw_offset_write(uintptr_t base_addr,
81 uint32_t offset,
82 uint32_t value);
83
84#ifndef RADIO_POWER_POWER_Msk
88__STATIC_INLINE__ void nrf_802154_hw_reset_radio_tasks_events(void);
89#endif /* RADIO_POWER_POWER_Msk */
90
91#if NRF53_ERRATA_158_ENABLE_WORKAROUND
102__STATIC_INLINE__ void yopan_158_workaround(void);
103#endif /* NRF53_ERRATA_158_ENABLE_WORKAROUND */
104
105#if NRF53_ERRATA_117_ENABLE_WORKAROUND
111__STATIC_INLINE__ void errata_117_apply(void);
112#endif /* NRF53_ERRATA_117_ENABLE_WORKAROUND */
113
114#if NRF54L_ERRATA_6_ENABLE_WORKAROUND
120__STATIC_INLINE__ void mltpan_6_apply(void);
121#endif /* NRF54L_ERRATA_6_ENABLE_WORKAROUND */
122
123#if NRF52_CONFIGURATION_254_ENABLE
129__STATIC_INLINE__ void device_config_254_apply_tx(void);
130#endif /* NRF52_CONFIGURATION_254_ENABLE */
131
132#ifndef NRF_802154_HW_UTILS_DECLARE_ONLY
133
134__STATIC_INLINE__ uint32_t nrf_802154_hw_offset_read(uintptr_t base_addr, uint32_t offset)
135{
136 return *(volatile uint32_t *)(base_addr + offset);
137}
138
139__STATIC_INLINE__ void nrf_802154_hw_offset_write(uintptr_t base_addr,
140 uint32_t offset,
141 uint32_t value)
142{
143 volatile uint32_t * p_register_address = (volatile uint32_t *)(base_addr + offset);
144
145 *p_register_address = value;
146}
147
148#ifndef RADIO_POWER_POWER_Msk
149
150__STATIC_INLINE__ void nrf_802154_hw_reset_radio_tasks_events(void)
151{
152 /* SUBSCRIBE registers */
153 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN);
154 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN);
155 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_START);
156 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_STOP);
157 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
158 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RSSISTART);
159 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_BCSTART);
160 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_BCSTOP);
161 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_EDSTART);
162 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_EDSTOP);
163 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_CCASTART);
164 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_CCASTOP);
165
166 /* EVENT registers */
167 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
168 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
169 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PAYLOAD);
170 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
171 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
172 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMATCH);
173 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMISS);
174 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH);
175 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
176 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR);
177 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_FRAMESTART);
178 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_EDEND);
179 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_EDSTOPPED);
180 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE);
181 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY);
182 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCASTOPPED);
183 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST);
184 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_TXREADY);
185 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RXREADY);
186 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_MHRMATCH);
187 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
188 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CTEPRESENT);
189
190 /* PUBLISH registers */
191 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
192 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
193 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_PAYLOAD);
194 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
195 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
196 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMATCH);
197 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMISS);
198 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH);
199 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
200 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR);
201 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_FRAMESTART);
202 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_EDEND);
203 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_EDSTOPPED);
204 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE);
205 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY);
206 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCASTOPPED);
207 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST);
208 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_TXREADY);
209 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_RXREADY);
210 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_MHRMATCH);
211 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
212 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CTEPRESENT);
213
214 /* INTEN registers */
215 nrf_radio_int_disable(NRF_RADIO, 0xFFFFFFFFUL);
216}
217
218#endif /* RADIO_POWER_POWER_Msk */
219
220#if NRF53_ERRATA_158_ENABLE_WORKAROUND
221
223__STATIC_INLINE__ void yopan_158_workaround(void)
224{
225 const uint32_t radio_address_mask = 0xFFFFF000UL;
226 const uint32_t ficr_trim_registers_count = 32UL;
227
228 /* Copy all the trimming values from FICR into the target addresses. Trim until one ADDR
229 is not initialized. */
230 for (uint32_t index = 0; index < ficr_trim_registers_count; index++)
231 {
232 if (((volatile uint32_t *)((volatile uintptr_t)NRF_FICR_NS->TRIMCNF[index].ADDR &
233 (uintptr_t)radio_address_mask) == (uint32_t *)NRF_RADIO))
234 {
235 *((volatile uint32_t *)NRF_FICR_NS->TRIMCNF[index].ADDR) =
236 NRF_FICR_NS->TRIMCNF[index].DATA;
237 }
238 }
239}
240
241#endif /* NRF53_ERRATA_158_ENABLE_WORKAROUND */
242
243#if NRF53_ERRATA_117_ENABLE_WORKAROUND
244
245__STATIC_INLINE__ void errata_117_apply(void)
246{
247#ifndef CONFIG_SOC_SERIES_BSIM_NRFXX
248
249 /* Register at 0x01FF0084. */
250 uint32_t ficr_reg = nrf_802154_hw_offset_read(FICR_BASE, 0x84UL);
251
252 /* Register at 0x41008588. */
253 nrf_802154_hw_offset_write(RADIO_BASE, 0x588UL, ficr_reg);
254
255#endif /* CONFIG_SOC_SERIES_BSIM_NRFXX */
256}
257
258#endif /* NRF53_ERRATA_117_ENABLE_WORKAROUND */
259
260#if NRF54L_ERRATA_6_ENABLE_WORKAROUND
261
262__STATIC_INLINE__ void mltpan_6_apply(void)
263{
264#ifndef CONFIG_SOC_SERIES_BSIM_NRFXX
265
266 /* Apply MLTPAN-6 */
268
269#endif /* CONFIG_SOC_SERIES_BSIM_NRFXX */
270}
271
272#endif /* NRF54L_ERRATA_6_ENABLE_WORKAROUND */
273
274#if NRF52_CONFIGURATION_254_ENABLE
275
281__STATIC_INLINE__ void device_config_254_apply_tx(void)
282{
283 /* Trim values for FTPAN-254 */
284 uint32_t ficr_reg1 = nrf_802154_hw_offset_read(FICR_BASE, 0x0330UL);
285 uint32_t ficr_reg2 = nrf_802154_hw_offset_read(FICR_BASE, 0x0334UL);
286 uint32_t ficr_reg3 = nrf_802154_hw_offset_read(FICR_BASE, 0x0338UL);
287
288 /* Check if the device is fixed by testing every FICR register's value separately. */
289 if (IS_FICR_REG_SET(ficr_reg1))
290 {
291 nrf_802154_hw_offset_write(RADIO_BASE, 0x074cUL, ficr_reg1);
292 }
293
294 if (IS_FICR_REG_SET(ficr_reg2))
295 {
296 nrf_802154_hw_offset_write(RADIO_BASE, 0x0584UL, ficr_reg2);
297 }
298
299 if (IS_FICR_REG_SET(ficr_reg3))
300 {
301 nrf_802154_hw_offset_write(RADIO_BASE, 0x0588UL, ficr_reg3);
302 }
303}
304
305#endif /* NRF52_CONFIGURATION_254_ENABLE */
306
307#endif /* NRF_802154_HW_UTILS_DECLARE_ONLY */
308
309#endif /* NRF_802154_HW_UTILS_H_ */
__STATIC_INLINE void nrf_802154_hw_offset_write(uintptr_t base_addr, uint32_t offset, uint32_t value)
Write to peripheral register at a given offset.
Definition nrf_802154_hw_utils.h:139
#define RADIO_BASE
Definition nrf_802154_hw_utils.h:57
__STATIC_INLINE uint32_t nrf_802154_hw_offset_read(uintptr_t base_addr, uint32_t offset)
Read peripheral register at a given offset.
Definition nrf_802154_hw_utils.h:134
__STATIC_INLINE void nrf_802154_hw_reset_radio_tasks_events(void)
Reset radio PUBLISH, SUBSCRIBE, EVENTS and INTEN registers.
Definition nrf_802154_hw_utils.h:150
#define FICR_BASE
Definition nrf_802154_hw_utils.h:58
#define IS_FICR_REG_SET(_ficr_reg)
Definition nrf_802154_hw_utils.h:61