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