1 /*
2 * Copyright (c) 2021 - 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 the copyright holder 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 #ifndef NRFY_TWIM_H__
35 #define NRFY_TWIM_H__
36
37 #include <nrfx.h>
38 #include <nrf_erratas.h>
39 #include <hal/nrf_twim.h>
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 typedef struct nrfy_twim_xfer_desc_t nrfy_twim_xfer_desc_t;
46
47 NRFY_STATIC_INLINE void __nrfy_internal_twim_event_enabled_clear(NRF_TWIM_Type * p_reg,
48 uint32_t mask,
49 nrf_twim_event_t event);
50
51 NRFY_STATIC_INLINE bool __nrfy_internal_twim_event_handle(NRF_TWIM_Type * p_reg,
52 uint32_t mask,
53 nrf_twim_event_t event,
54 uint32_t * p_evt_mask);
55
56 NRFY_STATIC_INLINE
57 uint32_t __nrfy_internal_twim_events_process(NRF_TWIM_Type * p_reg,
58 uint32_t mask,
59 nrfy_twim_xfer_desc_t const * p_xfer);
60
61 /**
62 * @defgroup nrfy_twim TWIM HALY
63 * @{
64 * @ingroup nrf_twim
65 * @brief Hardware access layer with cache and barrier support for managing the TWIM peripheral.
66 */
67
68 #if NRF_TWIM_HAS_ARRAY_LIST || defined(__NRFX_DOXYGEN__)
69 /** @refhal{NRF_TWIM_HAS_ARRAY_LIST} */
70 #define NRFY_TWIM_HAS_ARRAY_LIST 1
71 #else
72 #define NRFY_TWIM_HAS_ARRAY_LIST 0
73 #endif
74
75 /** @brief TWIM pins configuration structure. */
76 typedef struct
77 {
78 uint32_t scl_pin; ///< SCL pin number.
79 uint32_t sda_pin; ///< SDA pin number.
80 } nrfy_twim_pins_t;
81
82 /** @brief TWIM configuration structure. */
83 typedef struct
84 {
85 nrfy_twim_pins_t pins; ///< TWIM pins configuation.
86 nrf_twim_frequency_t frequency; ///< TWIM frequency.
87 bool skip_psel_cfg; ///< Skip pin selection configuration.
88 /**< When set to true, the driver does not modify
89 * pin select registers in the peripheral.
90 * Those registers are supposed to be set up
91 * externally before the driver is initialized.
92 * @note When both GPIO configuration and pin
93 * selection are to be skipped, the structure
94 * fields that specify pins can be omitted,
95 * as they are ignored anyway. */
96 } nrfy_twim_config_t;
97
98 /** @brief Structure describing a TWIM transfer. */
99 struct nrfy_twim_xfer_desc_t
100 {
101 uint8_t * p_buffer; ///< Pointer to transferred data.
102 size_t length; ///< Number of bytes transferred.
103 };
104
105 /**
106 * @brief Function for configuring the TWIM.
107 *
108 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
109 * @param[in] p_config Pointer to the peripheral configuration structure.
110 */
nrfy_twim_periph_configure(NRF_TWIM_Type * p_reg,nrfy_twim_config_t const * p_config)111 NRFY_STATIC_INLINE void nrfy_twim_periph_configure(NRF_TWIM_Type * p_reg,
112 nrfy_twim_config_t const * p_config)
113 {
114 if (!p_config->skip_psel_cfg)
115 {
116 nrf_twim_pins_set(p_reg, p_config->pins.scl_pin, p_config->pins.sda_pin);
117 }
118 nrf_twim_frequency_set(p_reg, p_config->frequency);
119 nrf_barrier_w();
120 }
121
122 /**
123 * @brief Function for initializing the specified TWIM interrupts.
124 *
125 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
126 * @param[in] mask Mask of interrupts to be initialized.
127 * @param[in] irq_priority Interrupt priority.
128 * @param[in] enable True if interrupts associated with the event mask are to be enabled, false otherwise.
129 */
nrfy_twim_int_init(NRF_TWIM_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)130 NRFY_STATIC_INLINE void nrfy_twim_int_init(NRF_TWIM_Type * p_reg,
131 uint32_t mask,
132 uint8_t irq_priority,
133 bool enable)
134 {
135 __nrfy_internal_twim_event_enabled_clear(p_reg, mask, NRF_TWIM_EVENT_TXSTARTED);
136 __nrfy_internal_twim_event_enabled_clear(p_reg, mask, NRF_TWIM_EVENT_RXSTARTED);
137 __nrfy_internal_twim_event_enabled_clear(p_reg, mask, NRF_TWIM_EVENT_LASTTX);
138 __nrfy_internal_twim_event_enabled_clear(p_reg, mask, NRF_TWIM_EVENT_LASTRX);
139 __nrfy_internal_twim_event_enabled_clear(p_reg, mask, NRF_TWIM_EVENT_STOPPED);
140 __nrfy_internal_twim_event_enabled_clear(p_reg, mask, NRF_TWIM_EVENT_SUSPENDED);
141 __nrfy_internal_twim_event_enabled_clear(p_reg, mask, NRF_TWIM_EVENT_ERROR);
142 nrf_barrier_w();
143
144 NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
145 NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
146 if (enable)
147 {
148 nrf_twim_int_enable(p_reg, mask);
149 }
150 nrf_barrier_w();
151 }
152
153 /**
154 * @brief Function for uninitializing the TWIM interrupts.
155 *
156 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
157 */
nrfy_twim_int_uninit(NRF_TWIM_Type * p_reg)158 NRFY_STATIC_INLINE void nrfy_twim_int_uninit(NRF_TWIM_Type * p_reg)
159 {
160 NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
161 nrf_barrier_w();
162 }
163
164 /**
165 * @brief Function for processing the specified TWIM events.
166 *
167 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
168 * @param[in] mask Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK();
169 * @param[in] p_xfer Pointer to the structure containing buffer associated with the last reception.
170 * Can be NULL.
171 *
172 * @return Mask of events that were generated and processed.
173 * To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
174 */
nrfy_twim_events_process(NRF_TWIM_Type * p_reg,uint32_t mask,nrfy_twim_xfer_desc_t const * p_xfer)175 NRFY_STATIC_INLINE uint32_t nrfy_twim_events_process(NRF_TWIM_Type * p_reg,
176 uint32_t mask,
177 nrfy_twim_xfer_desc_t const * p_xfer)
178 {
179 uint32_t evt_mask = __nrfy_internal_twim_events_process(p_reg, mask, p_xfer);
180 nrf_barrier_w();
181 return evt_mask;
182 }
183
184 /**
185 * @brief Function for setting the TWIM transaction buffer.
186 *
187 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
188 * @param[in] p_xfer Pointer to the structure containing transaction buffer.
189 */
nrfy_twim_tx_buffer_set(NRF_TWIM_Type * p_reg,nrfy_twim_xfer_desc_t const * p_xfer)190 NRFY_STATIC_INLINE void nrfy_twim_tx_buffer_set(NRF_TWIM_Type * p_reg,
191 nrfy_twim_xfer_desc_t const * p_xfer)
192 {
193 if (p_xfer->p_buffer)
194 {
195 NRFY_CACHE_WB(p_xfer->p_buffer, p_xfer->length);
196 }
197 nrf_twim_tx_buffer_set(p_reg, p_xfer->p_buffer, p_xfer->length);
198 nrf_barrier_w();
199 }
200
201 /**
202 * @brief Function for setting the TWIM reception buffer.
203 *
204 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
205 * @param[in] p_xfer Pointer to the structure containing reception buffer.
206 */
nrfy_twim_rx_buffer_set(NRF_TWIM_Type * p_reg,nrfy_twim_xfer_desc_t const * p_xfer)207 NRFY_STATIC_INLINE void nrfy_twim_rx_buffer_set(NRF_TWIM_Type * p_reg,
208 nrfy_twim_xfer_desc_t const * p_xfer)
209 {
210 nrf_twim_rx_buffer_set(p_reg, p_xfer->p_buffer, p_xfer->length);
211 nrf_barrier_w();
212 }
213
214 /**
215 * @brief Function for starting TWIM transaction.
216 *
217 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
218 * @param[in] p_xfer Pointer to the structure containing transaction buffer.
219 */
nrfy_twim_tx_start(NRF_TWIM_Type * p_reg,nrfy_twim_xfer_desc_t const * p_xfer)220 NRFY_STATIC_INLINE void nrfy_twim_tx_start(NRF_TWIM_Type * p_reg,
221 nrfy_twim_xfer_desc_t const * p_xfer)
222 {
223 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_STARTTX);
224 if (p_xfer)
225 {
226 if (p_xfer->length == 0)
227 {
228 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_STOP);
229 }
230 nrf_barrier_w();
231 uint32_t mask = NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_SUSPENDED) |
232 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_STOPPED) |
233 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_ERROR);
234 uint32_t evt_mask = 0;
235 while (!(evt_mask & (NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_SUSPENDED) |
236 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_STOPPED))))
237 {
238 evt_mask = __nrfy_internal_twim_events_process(p_reg, mask, p_xfer);
239 if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_ERROR))
240 {
241 bool lasttx_triggered = __nrfy_internal_twim_events_process(p_reg,
242 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_LASTTX),
243 NULL);
244 nrf_barrier_rw();
245 uint32_t shorts_mask = nrf_twim_shorts_get(p_reg);
246 nrf_barrier_r();
247
248 if (!(lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_STOP_MASK)))
249 {
250 // Unless LASTTX event arrived and LASTTX_STOP shortcut is active,
251 // triggering of STOP task in case of error has to be done manually.
252 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_RESUME);
253 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_STOP);
254 nrf_barrier_w();
255
256 // Mark transmission as not finished yet,
257 // as STOPPED event is expected to arrive.
258 // If LASTTX_SUSPENDED shortcut is active,
259 // NACK has been received on last byte sent
260 // and SUSPENDED event happened to be checked before ERROR,
261 // transmission will be marked as finished.
262 // In such case this flag has to be overwritten.
263 evt_mask = 0;
264 }
265
266 if (lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK))
267 {
268 // When STOP task was triggered just before SUSPEND task has taken effect,
269 // SUSPENDED event may not arrive.
270 // However if SUSPENDED arrives it always arrives after ERROR.
271 // Therefore SUSPENDED has to be cleared
272 // so it does not cause premature termination of busy loop
273 // waiting for STOPPED event to arrive.
274 (void)__nrfy_internal_twim_events_process(p_reg,
275 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_SUSPENDED),
276 p_xfer);
277 // Mark transmission as not finished yet,
278 // for same reasons as above.
279 evt_mask = 0;
280 }
281 }
282 }
283 }
284 nrf_barrier_w();
285 }
286
287 /**
288 * @brief Function for starting TWIM reception.
289 *
290 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
291 * @param[in] p_xfer Pointer to the structure containing reception buffer.
292 */
nrfy_twim_rx_start(NRF_TWIM_Type * p_reg,nrfy_twim_xfer_desc_t const * p_xfer)293 NRFY_STATIC_INLINE void nrfy_twim_rx_start(NRF_TWIM_Type * p_reg,
294 nrfy_twim_xfer_desc_t const * p_xfer)
295 {
296 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_STARTRX);
297 if (p_xfer)
298 {
299 if (p_xfer->length == 0)
300 {
301 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_STOP);
302 }
303
304 nrf_barrier_w();
305 uint32_t mask = NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_SUSPENDED) |
306 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_STOPPED) |
307 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_ERROR);
308 uint32_t evt_mask = 0;
309 while (!(evt_mask & (NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_SUSPENDED) |
310 NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_STOPPED))))
311 {
312 evt_mask = __nrfy_internal_twim_events_process(p_reg, mask, p_xfer);
313 if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_ERROR))
314 {
315 // triggering of STOP task in case of error has to be done manually.
316 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_STOP);
317 nrf_barrier_w();
318 }
319 }
320 }
321 nrf_barrier_w();
322 }
323
324 /**
325 * @brief Function for aborting the ongoing TWIM transaction.
326 *
327 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
328 * @param[in] p_xfer Pointer to the structure containing reception buffer
329 * if the abort is to be blocking. NULL for non-blocking operation.
330 */
nrfy_twim_abort(NRF_TWIM_Type * p_reg,nrfy_twim_xfer_desc_t const * p_xfer)331 NRFY_STATIC_INLINE void nrfy_twim_abort(NRF_TWIM_Type * p_reg, nrfy_twim_xfer_desc_t const * p_xfer)
332 {
333 nrf_twim_task_trigger(p_reg, NRF_TWIM_TASK_STOP);
334 if (p_xfer)
335 {
336 nrf_barrier_w();
337 uint32_t evt_mask = NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_STOPPED);
338 while (!__nrfy_internal_twim_events_process(p_reg, evt_mask, p_xfer))
339 {}
340 }
341 nrf_barrier_w();
342 }
343
344 /**
345 * @brief Function for getting TWIM pins configuration.
346 *
347 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
348 * @param[out] p_pins Pointer to the structure to be filled with TWIM pins configuration.
349 */
nrfy_twim_pins_get(NRF_TWIM_Type const * p_reg,nrfy_twim_pins_t * p_pins)350 NRFY_STATIC_INLINE void nrfy_twim_pins_get(NRF_TWIM_Type const * p_reg,
351 nrfy_twim_pins_t * p_pins)
352 {
353 nrf_barrier_rw();
354 p_pins->scl_pin = nrf_twim_scl_pin_get(p_reg);
355 p_pins->sda_pin = nrf_twim_sda_pin_get(p_reg);
356 nrf_barrier_r();
357 }
358
359 /**
360 * @brief Function for disabling TWIM with all interrupts and shortcuts.
361 *
362 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
363 */
nrfy_twim_stop(NRF_TWIM_Type * p_reg)364 NRFY_STATIC_INLINE void nrfy_twim_stop(NRF_TWIM_Type * p_reg)
365 {
366 nrf_twim_int_disable(p_reg, NRF_TWIM_ALL_INTS_MASK);
367 nrf_twim_shorts_disable(p_reg, NRF_TWIM_ALL_SHORTS_MASK);
368 #if NRF52_ERRATA_89_ENABLE_WORKAROUND
369 if (nrf52_errata_89())
370 {
371 *(volatile uint32_t *)((uint8_t *)p_reg + 0x500UL) = 9;
372 }
373 #endif
374 nrf_twim_disable(p_reg);
375 nrf_barrier_w();
376 }
377
378 #if NRFY_TWIM_HAS_ARRAY_LIST
379 /**
380 * @brief Function for enabling or disabling the TX list feature.
381 *
382 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
383 * @param[in] enable True if TX list feature is to be enabled, false otherwise.
384 */
nrfy_twim_tx_list_set(NRF_TWIM_Type * p_reg,bool enable)385 NRFY_STATIC_INLINE void nrfy_twim_tx_list_set(NRF_TWIM_Type * p_reg, bool enable)
386 {
387 if (enable)
388 {
389 nrf_twim_tx_list_enable(p_reg);
390 }
391 else
392 {
393 nrf_twim_tx_list_disable(p_reg);
394 }
395 nrf_barrier_w();
396 }
397
398 /**
399 * @brief Function for enabling or disabling the RX list feature.
400 *
401 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
402 * @param[in] enable True if RX list feature is to be enabled, false otherwise.
403 */
nrfy_twim_rx_list_set(NRF_TWIM_Type * p_reg,bool enable)404 NRFY_STATIC_INLINE void nrfy_twim_rx_list_set(NRF_TWIM_Type * p_reg, bool enable)
405 {
406 if (enable)
407 {
408 nrf_twim_rx_list_enable(p_reg);
409 }
410 else
411 {
412 nrf_twim_rx_list_disable(p_reg);
413 }
414 nrf_barrier_w();
415 }
416 #endif
417
418 /**
419 * @brief Function for setting the TWIM pins configuration.
420 *
421 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
422 * @param[out] p_pins Pointer to the TWIM pin configurartion structure.
423 */
nrfy_twim_pins_set(NRF_TWIM_Type * p_reg,nrfy_twim_pins_t const * p_pins)424 NRFY_STATIC_INLINE void nrfy_twim_pins_set(NRF_TWIM_Type * p_reg,
425 nrfy_twim_pins_t const * p_pins)
426 {
427 nrf_twim_pins_set(p_reg, p_pins->scl_pin, p_pins->sda_pin);
428 nrf_barrier_w();
429 }
430
431 /** @refhal{nrf_twim_task_trigger} */
nrfy_twim_task_trigger(NRF_TWIM_Type * p_reg,nrf_twim_task_t task)432 NRFY_STATIC_INLINE void nrfy_twim_task_trigger(NRF_TWIM_Type * p_reg,
433 nrf_twim_task_t task)
434 {
435 nrf_twim_task_trigger(p_reg, task);
436 nrf_barrier_w();
437 }
438
439 /** @refhal{nrf_twim_task_address_get} */
nrfy_twim_task_address_get(NRF_TWIM_Type const * p_reg,nrf_twim_task_t task)440 NRFY_STATIC_INLINE uint32_t nrfy_twim_task_address_get(NRF_TWIM_Type const * p_reg,
441 nrf_twim_task_t task)
442 {
443 return nrf_twim_task_address_get(p_reg, task);
444 }
445
446 /** @refhal{nrf_twim_event_clear} */
nrfy_twim_event_clear(NRF_TWIM_Type * p_reg,nrf_twim_event_t event)447 NRFY_STATIC_INLINE void nrfy_twim_event_clear(NRF_TWIM_Type * p_reg,
448 nrf_twim_event_t event)
449 {
450 nrf_twim_event_clear(p_reg, event);
451 nrf_barrier_w();
452 }
453
454 /** @refhal{nrf_twim_event_check} */
nrfy_twim_event_check(NRF_TWIM_Type const * p_reg,nrf_twim_event_t event)455 NRFY_STATIC_INLINE bool nrfy_twim_event_check(NRF_TWIM_Type const * p_reg,
456 nrf_twim_event_t event)
457 {
458 nrf_barrier_r();
459 bool check = nrf_twim_event_check(p_reg, event);
460 nrf_barrier_r();
461 return check;
462 }
463
464 /** @refhal{nrf_twim_event_address_get} */
nrfy_twim_event_address_get(NRF_TWIM_Type const * p_reg,nrf_twim_event_t event)465 NRFY_STATIC_INLINE uint32_t nrfy_twim_event_address_get(NRF_TWIM_Type const * p_reg,
466 nrf_twim_event_t event)
467 {
468 return nrf_twim_event_address_get(p_reg, event);
469 }
470
471 /** @refhal{nrf_twim_shorts_enable} */
nrfy_twim_shorts_enable(NRF_TWIM_Type * p_reg,uint32_t mask)472 NRFY_STATIC_INLINE void nrfy_twim_shorts_enable(NRF_TWIM_Type * p_reg,
473 uint32_t mask)
474 {
475 nrf_twim_shorts_enable(p_reg, mask);
476 nrf_barrier_w();
477 }
478
479 /** @refhal{nrf_twim_shorts_disable} */
nrfy_twim_shorts_disable(NRF_TWIM_Type * p_reg,uint32_t mask)480 NRFY_STATIC_INLINE void nrfy_twim_shorts_disable(NRF_TWIM_Type * p_reg,
481 uint32_t mask)
482 {
483 nrf_twim_shorts_disable(p_reg, mask);
484 nrf_barrier_w();
485 }
486
487 /** @refhal{nrf_twim_int_enable} */
nrfy_twim_int_enable(NRF_TWIM_Type * p_reg,uint32_t mask)488 NRFY_STATIC_INLINE void nrfy_twim_int_enable(NRF_TWIM_Type * p_reg,
489 uint32_t mask)
490 {
491 nrf_twim_int_enable(p_reg, mask);
492 nrf_barrier_w();
493 }
494
495 /** @refhal{nrf_twim_int_disable} */
nrfy_twim_int_disable(NRF_TWIM_Type * p_reg,uint32_t mask)496 NRFY_STATIC_INLINE void nrfy_twim_int_disable(NRF_TWIM_Type * p_reg,
497 uint32_t mask)
498 {
499 nrf_twim_int_disable(p_reg, mask);
500 nrf_barrier_w();
501 }
502
503 /** @refhal{nrf_twim_int_enable_check} */
nrfy_twim_int_enable_check(NRF_TWIM_Type const * p_reg,uint32_t mask)504 NRFY_STATIC_INLINE uint32_t nrfy_twim_int_enable_check(NRF_TWIM_Type const * p_reg, uint32_t mask)
505 {
506 nrf_barrier_rw();
507 uint32_t check = nrf_twim_int_enable_check(p_reg, mask);
508 nrf_barrier_r();
509 return check;
510 }
511
512 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
513 /** @refhal{nrf_twim_subscribe_set} */
nrfy_twim_subscribe_set(NRF_TWIM_Type * p_reg,nrf_twim_task_t task,uint8_t channel)514 NRFY_STATIC_INLINE void nrfy_twim_subscribe_set(NRF_TWIM_Type * p_reg,
515 nrf_twim_task_t task,
516 uint8_t channel)
517 {
518 nrf_twim_subscribe_set(p_reg, task, channel);
519 nrf_barrier_w();
520 }
521
522 /** @refhal{nrf_twim_subscribe_clear} */
nrfy_twim_subscribe_clear(NRF_TWIM_Type * p_reg,nrf_twim_task_t task)523 NRFY_STATIC_INLINE void nrfy_twim_subscribe_clear(NRF_TWIM_Type * p_reg,
524 nrf_twim_task_t task)
525 {
526 nrf_twim_subscribe_clear(p_reg, task);
527 nrf_barrier_w();
528
529 }
530
531 /** @refhal{nrf_twim_publish_set} */
nrfy_twim_publish_set(NRF_TWIM_Type * p_reg,nrf_twim_event_t event,uint8_t channel)532 NRFY_STATIC_INLINE void nrfy_twim_publish_set(NRF_TWIM_Type * p_reg,
533 nrf_twim_event_t event,
534 uint8_t channel)
535 {
536 nrf_twim_publish_set(p_reg, event, channel);
537 nrf_barrier_w();
538 }
539
540 /** @refhal{nrf_twim_publish_clear} */
nrfy_twim_publish_clear(NRF_TWIM_Type * p_reg,nrf_twim_event_t event)541 NRFY_STATIC_INLINE void nrfy_twim_publish_clear(NRF_TWIM_Type * p_reg,
542 nrf_twim_event_t event)
543 {
544 nrf_twim_publish_clear(p_reg, event);
545 nrf_barrier_w();
546 }
547 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
548
549 /** @refhal{nrf_twim_enable} */
nrfy_twim_enable(NRF_TWIM_Type * p_reg)550 NRFY_STATIC_INLINE void nrfy_twim_enable(NRF_TWIM_Type * p_reg)
551 {
552 nrf_twim_enable(p_reg);
553 nrf_barrier_w();
554 }
555
556 /** @refhal{nrf_twim_disable} */
nrfy_twim_disable(NRF_TWIM_Type * p_reg)557 NRFY_STATIC_INLINE void nrfy_twim_disable(NRF_TWIM_Type * p_reg)
558 {
559 nrf_twim_disable(p_reg);
560 nrf_barrier_w();
561 }
562
563 /** @refhal{nrf_twim_scl_pin_get} */
nrfy_twim_scl_pin_get(NRF_TWIM_Type const * p_reg)564 NRFY_STATIC_INLINE uint32_t nrfy_twim_scl_pin_get(NRF_TWIM_Type const * p_reg)
565 {
566 nrf_barrier_rw();
567 uint32_t scl_pin = nrf_twim_scl_pin_get(p_reg);
568 nrf_barrier_r();
569 return scl_pin;
570 }
571
572 /** @refhal{nrf_twim_sda_pin_get} */
nrfy_twim_sda_pin_get(NRF_TWIM_Type const * p_reg)573 NRFY_STATIC_INLINE uint32_t nrfy_twim_sda_pin_get(NRF_TWIM_Type const * p_reg)
574 {
575 nrf_barrier_rw();
576 uint32_t sda_pin = nrf_twim_sda_pin_get(p_reg);
577 nrf_barrier_r();
578 return sda_pin;
579 }
580
581 /** @refhal{nrf_twim_frequency_set} */
nrfy_twim_frequency_set(NRF_TWIM_Type * p_reg,nrf_twim_frequency_t frequency)582 NRFY_STATIC_INLINE void nrfy_twim_frequency_set(NRF_TWIM_Type * p_reg,
583 nrf_twim_frequency_t frequency)
584 {
585 nrf_twim_frequency_set(p_reg, frequency);
586 nrf_barrier_w();
587 }
588
589 /** @refhal{nrf_twim_errorsrc_get_and_clear} */
nrfy_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg)590 NRFY_STATIC_INLINE uint32_t nrfy_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg)
591 {
592 nrf_barrier_rw();
593 uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_reg);
594 nrf_barrier_rw();
595 return errorsrc;
596 }
597
598 /** @refhal{nrf_twim_address_set} */
nrfy_twim_address_set(NRF_TWIM_Type * p_reg,uint8_t address)599 NRFY_STATIC_INLINE void nrfy_twim_address_set(NRF_TWIM_Type * p_reg,
600 uint8_t address)
601 {
602 nrf_twim_address_set(p_reg, address);
603 nrf_barrier_w();
604 }
605
606 /** @refhal{nrf_twim_shorts_set} */
nrfy_twim_shorts_set(NRF_TWIM_Type * p_reg,uint32_t mask)607 NRFY_STATIC_INLINE void nrfy_twim_shorts_set(NRF_TWIM_Type * p_reg,
608 uint32_t mask)
609 {
610 nrf_twim_shorts_set(p_reg, mask);
611 nrf_barrier_w();
612 }
613
614 /** @refhal{nrf_twim_shorts_get} */
nrfy_twim_shorts_get(NRF_TWIM_Type const * p_reg)615 NRFY_STATIC_INLINE uint32_t nrfy_twim_shorts_get(NRF_TWIM_Type const * p_reg)
616 {
617 nrf_barrier_rw();
618 uint32_t shorts = nrf_twim_shorts_get(p_reg);
619 nrf_barrier_r();
620 return shorts;
621 }
622
623 /** @refhal{nrf_twim_txd_amount_get} */
nrfy_twim_txd_amount_get(NRF_TWIM_Type const * p_reg)624 NRFY_STATIC_INLINE size_t nrfy_twim_txd_amount_get(NRF_TWIM_Type const * p_reg)
625 {
626 nrf_barrier_r();
627 size_t amount = nrf_twim_txd_amount_get(p_reg);
628 nrf_barrier_r();
629 return amount;
630 }
631
632 /** @refhal{nrf_twim_rxd_amount_get} */
nrfy_twim_rxd_amount_get(NRF_TWIM_Type const * p_reg)633 NRFY_STATIC_INLINE size_t nrfy_twim_rxd_amount_get(NRF_TWIM_Type const * p_reg)
634 {
635 nrf_barrier_r();
636 size_t amount = nrf_twim_rxd_amount_get(p_reg);
637 nrf_barrier_r();
638 return amount;
639 }
640
641 #if NRFY_TWIM_HAS_ARRAY_LIST
642 /** @refhal{nrf_twim_tx_list_enable} */
nrfy_twim_tx_list_enable(NRF_TWIM_Type * p_reg)643 NRFY_STATIC_INLINE void nrfy_twim_tx_list_enable(NRF_TWIM_Type * p_reg)
644 {
645 nrf_twim_tx_list_enable(p_reg);
646 nrf_barrier_w();
647 }
648
649 /** @refhal{nrf_twim_tx_list_disable} */
nrfy_twim_tx_list_disable(NRF_TWIM_Type * p_reg)650 NRFY_STATIC_INLINE void nrfy_twim_tx_list_disable(NRF_TWIM_Type * p_reg)
651 {
652 nrf_twim_tx_list_disable(p_reg);
653 nrf_barrier_w();
654 }
655
656 /** @refhal{nrf_twim_rx_list_enable} */
nrfy_twim_rx_list_enable(NRF_TWIM_Type * p_reg)657 NRFY_STATIC_INLINE void nrfy_twim_rx_list_enable(NRF_TWIM_Type * p_reg)
658 {
659 nrf_twim_rx_list_enable(p_reg);
660 nrf_barrier_w();
661 }
662
663 /** @refhal{nrf_twim_rx_list_disable} */
nrfy_twim_rx_list_disable(NRF_TWIM_Type * p_reg)664 NRFY_STATIC_INLINE void nrfy_twim_rx_list_disable(NRF_TWIM_Type * p_reg)
665 {
666 nrf_twim_rx_list_disable(p_reg);
667 nrf_barrier_w();
668 }
669 #endif
670
671 /** @} */
672
__nrfy_internal_twim_event_enabled_clear(NRF_TWIM_Type * p_reg,uint32_t mask,nrf_twim_event_t event)673 NRFY_STATIC_INLINE void __nrfy_internal_twim_event_enabled_clear(NRF_TWIM_Type * p_reg,
674 uint32_t mask,
675 nrf_twim_event_t event)
676 {
677 if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
678 {
679 nrf_twim_event_clear(p_reg, event);
680 }
681 }
682
__nrfy_internal_twim_event_handle(NRF_TWIM_Type * p_reg,uint32_t mask,nrf_twim_event_t event,uint32_t * p_evt_mask)683 NRFY_STATIC_INLINE bool __nrfy_internal_twim_event_handle(NRF_TWIM_Type * p_reg,
684 uint32_t mask,
685 nrf_twim_event_t event,
686 uint32_t * p_evt_mask)
687 {
688 if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_twim_event_check(p_reg, event))
689 {
690 nrf_twim_event_clear(p_reg, event);
691 if (p_evt_mask)
692 {
693 *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
694 }
695 return true;
696 }
697 return false;
698 }
699
700 NRFY_STATIC_INLINE
__nrfy_internal_twim_events_process(NRF_TWIM_Type * p_reg,uint32_t mask,nrfy_twim_xfer_desc_t const * p_xfer)701 uint32_t __nrfy_internal_twim_events_process(NRF_TWIM_Type * p_reg,
702 uint32_t mask,
703 nrfy_twim_xfer_desc_t const * p_xfer)
704 {
705 uint32_t evt_mask = 0;
706
707 nrf_barrier_r();
708 (void)__nrfy_internal_twim_event_handle(p_reg, mask, NRF_TWIM_EVENT_SUSPENDED, &evt_mask);
709 (void)__nrfy_internal_twim_event_handle(p_reg, mask, NRF_TWIM_EVENT_STOPPED, &evt_mask);
710 (void)__nrfy_internal_twim_event_handle(p_reg, mask, NRF_TWIM_EVENT_ERROR, &evt_mask);
711 (void)__nrfy_internal_twim_event_handle(p_reg, mask, NRF_TWIM_EVENT_TXSTARTED, &evt_mask);
712 (void)__nrfy_internal_twim_event_handle(p_reg, mask, NRF_TWIM_EVENT_RXSTARTED, &evt_mask);
713 (void)__nrfy_internal_twim_event_handle(p_reg, mask, NRF_TWIM_EVENT_LASTTX, &evt_mask);
714 (void)__nrfy_internal_twim_event_handle(p_reg, mask, NRF_TWIM_EVENT_LASTRX, &evt_mask);
715
716 if (p_xfer && (mask & NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_STOPPED)))
717 {
718 NRFY_CACHE_INV(p_xfer->p_buffer, p_xfer->length);
719 }
720 else if (p_xfer && (mask & NRFY_EVENT_TO_INT_BITMASK(NRF_TWIM_EVENT_LASTRX)))
721 {
722 NRFY_CACHE_INV(p_xfer->p_buffer, p_xfer->length);
723 }
724 nrf_barrier_w();
725 return evt_mask;
726 }
727
728 #ifdef __cplusplus
729 }
730 #endif
731
732 #endif // NRFY_TWIM_H__
733