1 /*
2  * Copyright (c) 2015 - 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 NRF_TWIS_H__
35 #define NRF_TWIS_H__
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 #if defined(NRF54H20_XXAA)
44 #define NRF_TWIS_CLOCKPIN_SDA_NEEDED 1
45 #endif
46 
47 #if defined(HALTIUM_XXAA)
48 #define NRF_TWIS_CLOCKPIN_SCL_NEEDED 1
49 #endif
50 
51 /**
52  * @defgroup nrf_twis_hal TWIS HAL
53  * @{
54  * @ingroup nrf_twis
55  * @brief   Hardware access layer for managing the Two Wire Interface Slave with EasyDMA
56  *          (TWIS) peripheral.
57  */
58 
59 #if defined(TWIS_DMA_RX_PTR_PTR_Msk) || defined(__NRFX_DOXYGEN__)
60 /** @brief Symbol indicating whether dedicated DMA register is present. */
61 #define NRF_TWIS_HAS_DMA_REG 1
62 #else
63 #define NRF_TWIS_HAS_DMA_REG 0
64 #endif
65 
66 #if (defined(TWIS_TASKS_DMA_RX_ENABLEMATCH_ENABLEMATCH_Msk) && \
67      defined(TWIS_EVENTS_DMA_RX_END_END_Msk)) || \
68     defined(__NRFX_DOXYGEN__)
69 /** @brief Symbol indicating whether TWIS DMA tasks and events are present. */
70 #define NRF_TWIS_HAS_DMA_TASKS_EVENTS 1
71 #else
72 #define NRF_TWIS_HAS_DMA_TASKS_EVENTS 0
73 #endif
74 
75 #if defined(TWIS_TXD_LIST_LIST_Msk) || defined(TWIS_RXD_LIST_LIST_Msk) || defined(__NRFX_DOXYGEN__)
76 /** @brief Symbol indicating whether TX or RX LIST is present. */
77 #define NRF_TWIS_HAS_LIST_REG 1
78 #else
79 #define NRF_TWIS_HAS_LIST_REG 0
80 #endif
81 
82 #if NRF_TWIS_HAS_DMA_REG
83 /** @brief Symbol specifying maximum possible size of the TX channel buffer. */
84 #define NRF_TWIS_TX_MAX_COUNT_SIZE TWIS_DMA_TX_MAXCNT_MAXCNT_Max
85 /** @brief Symbol specifying maximum possible size of the RX channel buffer. */
86 #define NRF_TWIS_RX_MAX_COUNT_SIZE TWIS_DMA_RX_MAXCNT_MAXCNT_Max
87 #else
88 #define NRF_TWIS_TX_MAX_COUNT_SIZE TWIS_TXD_MAXCNT_MAXCNT_Msk
89 #define NRF_TWIS_RX_MAX_COUNT_SIZE TWIS_RXD_MAXCNT_MAXCNT_Msk
90 #endif
91 
92 /**
93  * @brief Macro getting pointer to the structure of registers of the TWIS peripheral.
94  *
95  * @param[in] idx TWIS instance index.
96  *
97  * @return Pointer to the structure of registers of the TWIS peripheral.
98  */
99 #define NRF_TWIS_INST_GET(idx) NRFX_CONCAT(NRF_, TWIS, idx)
100 
101 /** @brief TWIS tasks. */
102 typedef enum
103 {
104     NRF_TWIS_TASK_STOP      = offsetof(NRF_TWIS_Type, TASKS_STOP),      ///< Stop TWIS transaction.
105     NRF_TWIS_TASK_SUSPEND   = offsetof(NRF_TWIS_Type, TASKS_SUSPEND),   ///< Suspend TWIS transaction.
106     NRF_TWIS_TASK_RESUME    = offsetof(NRF_TWIS_Type, TASKS_RESUME),    ///< Resume TWIS transaction.
107     NRF_TWIS_TASK_PREPARERX = offsetof(NRF_TWIS_Type, TASKS_PREPARERX), ///< Prepare the TWIS slave to respond to a write command.
108     NRF_TWIS_TASK_PREPARETX = offsetof(NRF_TWIS_Type, TASKS_PREPARETX)  ///< Prepare the TWIS slave to respond to a read command.
109 } nrf_twis_task_t;
110 
111 /** @brief TWIS events. */
112 typedef enum
113 {
114     NRF_TWIS_EVENT_STOPPED   = offsetof(NRF_TWIS_Type, EVENTS_STOPPED),      ///< TWIS stopped.
115     NRF_TWIS_EVENT_ERROR     = offsetof(NRF_TWIS_Type, EVENTS_ERROR),        ///< TWIS error.
116 #if NRF_TWIS_HAS_DMA_TASKS_EVENTS
117     NRF_TWIS_EVENT_RXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_DMA.RX.READY), ///< Receive sequence started.
118     NRF_TWIS_EVENT_TXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_DMA.TX.READY), ///< Transmit sequence started.
119 #else
120     NRF_TWIS_EVENT_RXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_RXSTARTED),    ///< Receive sequence started.
121     NRF_TWIS_EVENT_TXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_TXSTARTED),    ///< Transmit sequence started.
122 #endif
123     NRF_TWIS_EVENT_WRITE     = offsetof(NRF_TWIS_Type, EVENTS_WRITE),        ///< Write command received.
124     NRF_TWIS_EVENT_READ      = offsetof(NRF_TWIS_Type, EVENTS_READ)          ///< Read command received.
125 } nrf_twis_event_t;
126 
127 /** @brief TWIS shortcuts. */
128 typedef enum
129 {
130     NRF_TWIS_SHORT_WRITE_SUSPEND_MASK   = TWIS_SHORTS_WRITE_SUSPEND_Msk, ///< Shortcut between WRITE event and SUSPEND task.
131     NRF_TWIS_SHORT_READ_SUSPEND_MASK    = TWIS_SHORTS_READ_SUSPEND_Msk,  ///< Shortcut between READ event and SUSPEND task.
132 } nrf_twis_short_mask_t;
133 
134 /** @brief TWIS interrupts. */
135 typedef enum
136 {
137     NRF_TWIS_INT_STOPPED_MASK   = TWIS_INTEN_STOPPED_Msk,    ///< Interrupt on STOPPED event.
138     NRF_TWIS_INT_ERROR_MASK     = TWIS_INTEN_ERROR_Msk,      ///< Interrupt on ERROR event.
139 #if NRF_TWIS_HAS_DMA_TASKS_EVENTS
140     NRF_TWIS_INT_RXSTARTED_MASK = TWIS_INTEN_DMARXREADY_Msk, ///< Interrupt on RXSTARTED event.
141     NRF_TWIS_INT_TXSTARTED_MASK = TWIS_INTEN_DMATXREADY_Msk, ///< Interrupt on TXSTARTED event.
142 #else
143     NRF_TWIS_INT_RXSTARTED_MASK = TWIS_INTEN_RXSTARTED_Msk,  ///< Interrupt on RXSTARTED event.
144     NRF_TWIS_INT_TXSTARTED_MASK = TWIS_INTEN_TXSTARTED_Msk,  ///< Interrupt on TXSTARTED event.
145 #endif
146     NRF_TWIS_INT_WRITE_MASK     = TWIS_INTEN_WRITE_Msk,      ///< Interrupt on WRITE event.
147     NRF_TWIS_INT_READ_MASK      = TWIS_INTEN_READ_Msk,       ///< Interrupt on READ event.
148 } nrf_twis_int_mask_t;
149 
150 /** @brief TWIS error source. */
151 typedef enum
152 {
153     NRF_TWIS_ERROR_OVERFLOW  = TWIS_ERRORSRC_OVERFLOW_Msk, ///< RX buffer overflow detected, and prevented.
154     NRF_TWIS_ERROR_DATA_NACK = TWIS_ERRORSRC_DNACK_Msk,    ///< NACK sent after receiving a data byte.
155     NRF_TWIS_ERROR_OVERREAD  = TWIS_ERRORSRC_OVERREAD_Msk  ///< TX buffer over-read detected, and prevented.
156 } nrf_twis_error_t;
157 
158 /** @brief TWIS address matching configuration. */
159 typedef enum
160 {
161     NRF_TWIS_CONFIG_ADDRESS0_MASK  = TWIS_CONFIG_ADDRESS0_Msk, ///< Enable or disable address matching on ADDRESS[0].
162     NRF_TWIS_CONFIG_ADDRESS1_MASK  = TWIS_CONFIG_ADDRESS1_Msk, ///< Enable or disable address matching on ADDRESS[1].
163     NRF_TWIS_CONFIG_ADDRESS01_MASK = TWIS_CONFIG_ADDRESS0_Msk |
164                                      TWIS_CONFIG_ADDRESS1_Msk  ///< Enable both address matching.
165 } nrf_twis_config_addr_mask_t;
166 
167 /**
168  * @brief Smallest variable type to hold the TWI address.
169  *
170  * Variable of the minimum size that can hold a single TWI address.
171  *
172  * @note Defined to make it simple to change if the new TWI supports for example
173  *       10 bit addressing mode.
174  */
175 typedef uint8_t nrf_twis_address_t;
176 
177 /**
178  * @brief Function for activating the specified TWIS task.
179  *
180  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
181  * @param[in] task  Task to be activated.
182  */
183 NRF_STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * p_reg, nrf_twis_task_t task);
184 
185 /**
186  * @brief Function for returning the address of the specified TWIS task register.
187  *
188  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
189  * @param[in] task  The specified task.
190  *
191  * @return Task address.
192  */
193 NRF_STATIC_INLINE uint32_t nrf_twis_task_address_get(NRF_TWIS_Type const * p_reg,
194                                                      nrf_twis_task_t       task);
195 
196 /**
197  * @brief Function for clearing the specified event.
198  *
199  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
200  * @param[in] event The specified event.
201  */
202 NRF_STATIC_INLINE void nrf_twis_event_clear(NRF_TWIS_Type * p_reg, nrf_twis_event_t event);
203 
204 /**
205  * @brief Function for retrieving the state of the TWIS event.
206  *
207  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
208  * @param[in] event Event to be checked.
209  *
210  * @retval true  The event has been generated.
211  * @retval false The event has not been generated.
212  */
213 NRF_STATIC_INLINE bool nrf_twis_event_check(NRF_TWIS_Type const * p_reg, nrf_twis_event_t event);
214 
215 /**
216  * @brief Function for getting and clearing the state of the specified event.
217  *
218  * This function checks the state of the event and clears it.
219  *
220  * @param[in,out] p_reg Pointer to the structure of registers of the peripheral.
221  * @param[in]     event Event.
222  *
223  * @retval true  The event was set.
224  * @retval false The event was not set.
225  */
226 NRF_STATIC_INLINE bool nrf_twis_event_get_and_clear(NRF_TWIS_Type * p_reg, nrf_twis_event_t event);
227 
228 /**
229  * @brief Function for returning the address of the specified TWIS event register.
230  *
231  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
232  * @param[in] event Event.
233  *
234  * @return Address.
235  */
236 NRF_STATIC_INLINE uint32_t nrf_twis_event_address_get(NRF_TWIS_Type const * p_reg,
237                                                       nrf_twis_event_t      event);
238 
239 /**
240  * @brief Function for setting a shortcut.
241  *
242  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
243  * @param[in] mask  Mask of shortcuts to be enabled.
244  */
245 NRF_STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * p_reg, uint32_t mask);
246 
247 /**
248  * @brief Function for clearing shortcuts.
249  *
250  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
251  * @param[in] mask  Mask of shortcuts to be disabled.
252  */
253 NRF_STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * p_reg, uint32_t mask);
254 
255 /**
256  * @brief Function for getting the shorts mask.
257  *
258  * Function returns shorts register.
259  *
260  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
261  *
262  * @return Flags of currently enabled shortcuts
263  */
264 NRF_STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type const * p_reg);
265 
266 /**
267  * @brief Function for enabling the specified interrupts.
268  *
269  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
270  * @param[in] mask  Mask of interrupts to be enabled.
271  *                  Use @ref nrf_twis_int_mask_t values for bit masking.
272  */
273 NRF_STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * p_reg, uint32_t mask);
274 
275 /**
276  * @brief Function for checking if the specified interrupts are enabled.
277  *
278  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
279  * @param[in] mask  Mask of interrupts to be checked.
280  *                  Use @ref nrf_twis_int_mask_t values for bit masking.
281  *
282  * @return Mask of enabled interrupts.
283  */
284 NRF_STATIC_INLINE uint32_t nrf_twis_int_enable_check(NRF_TWIS_Type const * p_reg, uint32_t mask);
285 
286 /**
287  * @brief Function for disabling the specified interrupts.
288  *
289  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
290  * @param[in] mask  Mask of interrupts to be disabled.
291  *                  Use @ref nrf_twis_int_mask_t values for bit masking.
292  */
293 NRF_STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * p_reg, uint32_t mask);
294 
295 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
296 /**
297  * @brief Function for setting the subscribe configuration for a given TWIS task.
298  *
299  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
300  * @param[in] task    Task for which to set the configuration.
301  * @param[in] channel Channel through which to subscribe events.
302  */
303 NRF_STATIC_INLINE void nrf_twis_subscribe_set(NRF_TWIS_Type * p_reg,
304                                               nrf_twis_task_t task,
305                                               uint8_t         channel);
306 
307 /**
308  * @brief Function for clearing the subscribe configuration for a given
309  *        TWIS task.
310  *
311  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
312  * @param[in] task  Task for which to clear the configuration.
313  */
314 NRF_STATIC_INLINE void nrf_twis_subscribe_clear(NRF_TWIS_Type * p_reg, nrf_twis_task_t task);
315 
316 /**
317  * @brief Function for setting the publish configuration for a given TWIS event.
318  *
319  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
320  * @param[in] event   Event for which to set the configuration.
321  * @param[in] channel Channel through which to publish the event.
322  */
323 NRF_STATIC_INLINE void nrf_twis_publish_set(NRF_TWIS_Type *  p_reg,
324                                             nrf_twis_event_t event,
325                                             uint8_t         channel);
326 
327 /**
328  * @brief Function for clearing the publish configuration for a given TWIS event.
329  *
330  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
331  * @param[in] event Event for which to clear the configuration.
332  */
333 NRF_STATIC_INLINE void nrf_twis_publish_clear(NRF_TWIS_Type * p_reg, nrf_twis_event_t event);
334 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
335 
336 /**
337  * @brief Function for retrieving and clearing the TWIS error source.
338  *
339  * @attention Error sources are cleared after read.
340  *
341  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
342  *
343  * @return Error source mask with values from @ref nrf_twis_error_t.
344  */
345 NRF_STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * p_reg);
346 
347 /**
348  * @brief Function for getting information about which of the addresses matched.
349  *
350  * Function returns index in the address table
351  * that points to the address that already matched.
352  *
353  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
354  *
355  * @return Index of matched address.
356  */
357 NRF_STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg);
358 
359 /**
360  * @brief Function for enabling TWIS.
361  *
362  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
363  */
364 NRF_STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * p_reg);
365 
366 /**
367  * @brief Function for disabling TWIS.
368  *
369  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
370  */
371 NRF_STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * p_reg);
372 
373 /**
374  * @brief Function for checking if the TWIS is enabled.
375  *
376  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
377  *
378  * @retval true  The TWIS is enabled.
379  * @retval false The TWIS is not enabled.
380  */
381 NRF_STATIC_INLINE bool nrf_twis_enable_check(NRF_TWIS_Type const * p_reg);
382 
383 /**
384  * @brief Function for configuring TWIS pins.
385  *
386  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
387  * @param[in] scl   SCL pin number.
388  * @param[in] sda   SDA pin number.
389  */
390 NRF_STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * p_reg, uint32_t scl, uint32_t sda);
391 
392 /**
393  * @brief Function for setting the SCL pin.
394  *
395  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
396  * @param[in] pin   SCL pin number.
397  */
398 NRF_STATIC_INLINE void nrf_twis_scl_pin_set(NRF_TWIS_Type * p_reg, uint32_t pin);
399 
400 /**
401  * @brief Function for retrieving the SCL pin selection.
402  *
403  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
404  *
405  * @return SCL pin selection.
406  */
407 NRF_STATIC_INLINE uint32_t nrf_twis_scl_pin_get(NRF_TWIS_Type const * p_reg);
408 
409 /**
410  * @brief Function for setting the SDA pin.
411  *
412  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
413  * @param[in] pin   SDA pin number.
414  */
415 NRF_STATIC_INLINE void nrf_twis_sda_pin_set(NRF_TWIS_Type * p_reg, uint32_t pin);
416 
417 /**
418  * @brief Function for retrieving the SDA pin selection.
419  *
420  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
421  *
422  * @return SDA pin selection.
423  */
424 NRF_STATIC_INLINE uint32_t nrf_twis_sda_pin_get(NRF_TWIS_Type const * p_reg);
425 
426 /**
427  * @brief Function for setting the receive buffer.
428  *
429  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
430  * @param[in] p_buf  Pointer to the buffer for received data.
431  * @param[in] length Maximum number of data bytes to receive.
432  */
433 NRF_STATIC_INLINE void nrf_twis_rx_buffer_set(NRF_TWIS_Type * p_reg,
434                                               uint8_t       * p_buf,
435                                               size_t          length);
436 
437 /**
438  * @brief Function for getting the receive buffer.
439  *
440  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
441  *
442  * @return Pointer to the receive buffer.
443  */
444 NRF_STATIC_INLINE uint8_t * nrf_twis_rx_buffer_get(NRF_TWIS_Type const * p_reg);
445 
446 /**
447  * @brief Function that prepares TWIS for receiving
448  *
449  * This function sets receive buffer and then sets NRF_TWIS_TASK_PREPARERX task.
450  *
451  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
452  * @param[in] p_buf  Pointer to the buffer for received data.
453  * @param[in] length Maximum number of data bytes to receive.
454  */
455 NRF_STATIC_INLINE void nrf_twis_rx_prepare(NRF_TWIS_Type * p_reg, uint8_t * p_buf, size_t length);
456 
457 /**
458  * @brief Function for getting number of bytes received in the last transaction.
459  *
460  * @param[in] p_reg TWIS instance.
461  *
462  * @return Amount of received bytes.
463  * */
464 NRF_STATIC_INLINE size_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * p_reg);
465 
466 /**
467  * @brief Function for setting the transmit buffer.
468  *
469  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
470  * @param[in] p_buf  Pointer to the buffer with data to send.
471  * @param[in] length Maximum number of data bytes to transmit.
472  */
473 NRF_STATIC_INLINE void nrf_twis_tx_buffer_set(NRF_TWIS_Type * p_reg,
474                                               uint8_t const * p_buf,
475                                               size_t          length);
476 
477 /**
478  * @brief Function for getting the transmit buffer.
479  *
480  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
481  *
482  * @return Pointer to the transmit buffer.
483  */
484 NRF_STATIC_INLINE uint8_t * nrf_twis_tx_buffer_get(NRF_TWIS_Type const * p_reg);
485 
486 /**
487  * @brief Function for preparing TWIS for transmitting.
488  *
489  * This function sets transmit buffer and then sets NRF_TWIS_TASK_PREPARETX task.
490  *
491  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
492  * @param[in] p_buf  Pointer to the buffer with data to send.
493  * @param[in] length Maximum number of data bytes to transmit.
494  */
495 NRF_STATIC_INLINE void nrf_twis_tx_prepare(NRF_TWIS_Type * p_reg,
496                                            uint8_t const * p_buf,
497                                            size_t          length);
498 
499 /**
500  * @brief Function for getting the number of bytes transmitted in the last transaction.
501  *
502  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
503  *
504  * @return Amount of bytes transmitted.
505  */
506 NRF_STATIC_INLINE size_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * p_reg);
507 
508 /**
509  * @brief Function for setting the slave address.
510  *
511  * Function sets the selected address for this TWI interface.
512  *
513  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
514  * @param[in] n     Index of address to be set.
515  * @param[in] addr  Addres to be set.
516  *
517  * @sa nrf_twis_config_address_set
518  * @sa nrf_twis_config_address_get
519  */
520 NRF_STATIC_INLINE void nrf_twis_address_set(NRF_TWIS_Type *    p_reg,
521                                             uint_fast8_t       n,
522                                             nrf_twis_address_t addr);
523 
524 /**
525  * @brief Function for retrieving configured slave address.
526  *
527  * Function gets the selected address for this TWI interface.
528  *
529  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
530  * @param[in] n     Index of address to get.
531  *
532  * @return Configured slave address.
533  */
534 NRF_STATIC_INLINE nrf_twis_address_t nrf_twis_address_get(NRF_TWIS_Type const * p_reg,
535                                                           uint_fast8_t          n);
536 
537 /**
538  * @brief Function for setting the device address configuration.
539  *
540  * @param[in] p_reg     Pointer to the structure of registers of the peripheral.
541  * @param[in] addr_mask Mask of address indexes of what device should answer to.
542  *
543  * @sa nrf_twis_address_set
544  */
545 NRF_STATIC_INLINE void nrf_twis_config_address_set(NRF_TWIS_Type *             p_reg,
546                                                    nrf_twis_config_addr_mask_t addr_mask);
547 
548 /**
549  * @brief Function for retrieving the device address configuration.
550  *
551  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
552  *
553  * @return Mask of address indexes of what device should answer to.
554  */
555 NRF_STATIC_INLINE
556 nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * p_reg);
557 
558 /**
559  * @brief Function for setting the over-read character.
560  *
561  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
562  * @param[in] orc   Over-read character. Character clocked out in case of
563  *                  over-read of the TXD buffer.
564  */
565 NRF_STATIC_INLINE void nrf_twis_orc_set(NRF_TWIS_Type * p_reg, uint8_t orc);
566 
567 /**
568  * @brief Function for setting the over-read character.
569  *
570  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
571  *
572  * @return Over-read character configured for selected instance.
573  */
574 NRF_STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * p_reg);
575 
576 #if NRF_TWIS_HAS_LIST_REG
577 /**
578  * @brief Function for enabling the TX list feature.
579  *
580  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
581  */
582 NRF_STATIC_INLINE void nrf_twis_tx_list_enable(NRF_TWIS_Type * p_reg);
583 
584 /**
585  * @brief Function for disabling the TX list feature.
586  *
587  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
588  */
589 NRF_STATIC_INLINE void nrf_twis_tx_list_disable(NRF_TWIS_Type * p_reg);
590 
591 /**
592  * @brief Function for enabling the RX list feature.
593  *
594  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
595  */
596 NRF_STATIC_INLINE void nrf_twis_rx_list_enable(NRF_TWIS_Type * p_reg);
597 
598 /**
599  * @brief Function for disabling the RX list feature.
600  *
601  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
602  */
603 NRF_STATIC_INLINE void nrf_twis_rx_list_disable(NRF_TWIS_Type * p_reg);
604 #endif
605 
606 /** @} */ /*  End of nrf_twis_hal */
607 
608 #ifndef NRF_DECLARE_ONLY
609 
610 /* ------------------------------------------------------------------------------------------------
611  *  Internal functions
612  */
613 
614 /**
615  * @internal
616  * @brief Internal function for getting task or event register address.
617  *
618  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
619  * @param[in] offset Offset of the register from the beginning of the instance.
620  *
621  * @attention Offset must be modulo 4 value. In other case, hardware fault can occur.
622  * @return Pointer to the register.
623  */
nrf_twis_getRegPtr(NRF_TWIS_Type * p_reg,uint32_t offset)624 NRF_STATIC_INLINE volatile uint32_t* nrf_twis_getRegPtr(NRF_TWIS_Type * p_reg, uint32_t offset)
625 {
626     return (volatile uint32_t*)((uint8_t *)p_reg + (uint32_t)offset);
627 }
628 
629 /**
630  * @internal
631  * @brief Internal function for getting task/event register address - constant version.
632  *
633  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
634  * @param[in] offset Offset of the register from the beginning of the instance.
635  *
636  * @attention Offset must be modulo 4 value. In other case, hardware fault can occur.
637  * @return Pointer to the register.
638  */
nrf_twis_getRegPtr_c(NRF_TWIS_Type const * p_reg,uint32_t offset)639 NRF_STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type const * p_reg,
640                                                                 uint32_t              offset)
641 {
642     return (volatile const uint32_t*)((uint8_t const *)p_reg + (uint32_t)offset);
643 }
644 
645 
646 /* ------------------------------------------------------------------------------------------------
647  *  Interface functions definitions
648  */
649 
650 
nrf_twis_task_trigger(NRF_TWIS_Type * p_reg,nrf_twis_task_t task)651 NRF_STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * p_reg, nrf_twis_task_t task)
652 {
653     *(nrf_twis_getRegPtr(p_reg, (uint32_t)task)) = 1UL;
654 }
655 
nrf_twis_task_address_get(NRF_TWIS_Type const * p_reg,nrf_twis_task_t task)656 NRF_STATIC_INLINE uint32_t nrf_twis_task_address_get(NRF_TWIS_Type const * p_reg,
657                                                      nrf_twis_task_t       task)
658 {
659     return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)task);
660 }
661 
nrf_twis_event_clear(NRF_TWIS_Type * p_reg,nrf_twis_event_t event)662 NRF_STATIC_INLINE void nrf_twis_event_clear(NRF_TWIS_Type * p_reg, nrf_twis_event_t event)
663 {
664     *(nrf_twis_getRegPtr(p_reg, (uint32_t)event)) = 0UL;
665     nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
666 }
667 
nrf_twis_event_check(NRF_TWIS_Type const * p_reg,nrf_twis_event_t event)668 NRF_STATIC_INLINE bool nrf_twis_event_check(NRF_TWIS_Type const * p_reg, nrf_twis_event_t event)
669 {
670     return (bool)*nrf_twis_getRegPtr_c(p_reg, (uint32_t)event);
671 }
672 
nrf_twis_event_get_and_clear(NRF_TWIS_Type * p_reg,nrf_twis_event_t event)673 NRF_STATIC_INLINE bool nrf_twis_event_get_and_clear(NRF_TWIS_Type * p_reg, nrf_twis_event_t event)
674 {
675     bool ret = nrf_twis_event_check(p_reg, event);
676     if (ret)
677     {
678         nrf_twis_event_clear(p_reg, event);
679     }
680     return ret;
681 }
682 
nrf_twis_event_address_get(NRF_TWIS_Type const * p_reg,nrf_twis_event_t event)683 NRF_STATIC_INLINE uint32_t nrf_twis_event_address_get(NRF_TWIS_Type const * p_reg,
684                                                       nrf_twis_event_t      event)
685 {
686     return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)event);
687 }
688 
nrf_twis_shorts_enable(NRF_TWIS_Type * p_reg,uint32_t mask)689 NRF_STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * p_reg, uint32_t mask)
690 {
691     p_reg->SHORTS |= mask;
692 }
693 
nrf_twis_shorts_disable(NRF_TWIS_Type * p_reg,uint32_t mask)694 NRF_STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * p_reg, uint32_t mask)
695 {
696     if (~0U == mask)
697     {
698         /* Optimized version for "disable all" */
699         p_reg->SHORTS = 0;
700     }
701     else
702     {
703         p_reg->SHORTS &= ~mask;
704     }
705 }
706 
nrf_twis_shorts_get(NRF_TWIS_Type const * p_reg)707 NRF_STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type const * p_reg)
708 {
709     return p_reg->SHORTS;
710 }
711 
nrf_twis_int_enable(NRF_TWIS_Type * p_reg,uint32_t mask)712 NRF_STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * p_reg, uint32_t mask)
713 {
714     p_reg->INTENSET = mask;
715 }
716 
nrf_twis_int_enable_check(NRF_TWIS_Type const * p_reg,uint32_t mask)717 NRF_STATIC_INLINE uint32_t nrf_twis_int_enable_check(NRF_TWIS_Type const * p_reg, uint32_t mask)
718 {
719     return p_reg->INTENSET & mask;
720 }
721 
nrf_twis_int_disable(NRF_TWIS_Type * p_reg,uint32_t mask)722 NRF_STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * p_reg, uint32_t mask)
723 {
724     p_reg->INTENCLR = mask;
725 }
726 
727 #if defined(DPPI_PRESENT)
nrf_twis_subscribe_set(NRF_TWIS_Type * p_reg,nrf_twis_task_t task,uint8_t channel)728 NRF_STATIC_INLINE void nrf_twis_subscribe_set(NRF_TWIS_Type * p_reg,
729                                               nrf_twis_task_t task,
730                                               uint8_t         channel)
731 {
732     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
733             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
734 }
735 
nrf_twis_subscribe_clear(NRF_TWIS_Type * p_reg,nrf_twis_task_t task)736 NRF_STATIC_INLINE void nrf_twis_subscribe_clear(NRF_TWIS_Type * p_reg, nrf_twis_task_t task)
737 {
738     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
739 }
740 
nrf_twis_publish_set(NRF_TWIS_Type * p_reg,nrf_twis_event_t event,uint8_t channel)741 NRF_STATIC_INLINE void nrf_twis_publish_set(NRF_TWIS_Type *  p_reg,
742                                             nrf_twis_event_t event,
743                                             uint8_t          channel)
744 {
745     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
746             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
747 }
748 
nrf_twis_publish_clear(NRF_TWIS_Type * p_reg,nrf_twis_event_t event)749 NRF_STATIC_INLINE void nrf_twis_publish_clear(NRF_TWIS_Type *  p_reg, nrf_twis_event_t event)
750 {
751     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
752 }
753 #endif // defined(DPPI_PRESENT)
754 
nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * p_reg)755 NRF_STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * p_reg)
756 {
757     uint32_t ret = p_reg->ERRORSRC;
758     p_reg->ERRORSRC = ret;
759     return ret;
760 }
761 
nrf_twis_match_get(NRF_TWIS_Type const * p_reg)762 NRF_STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg)
763 {
764     return (uint_fast8_t)p_reg->MATCH;
765 }
766 
nrf_twis_enable(NRF_TWIS_Type * p_reg)767 NRF_STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * p_reg)
768 {
769     p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos);
770 }
771 
nrf_twis_disable(NRF_TWIS_Type * p_reg)772 NRF_STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * p_reg)
773 {
774     p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Disabled << TWIS_ENABLE_ENABLE_Pos);
775 }
776 
nrf_twis_enable_check(NRF_TWIS_Type const * p_reg)777 NRF_STATIC_INLINE bool nrf_twis_enable_check(NRF_TWIS_Type const * p_reg)
778 {
779     return (p_reg->ENABLE == (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos));
780 }
781 
nrf_twis_pins_set(NRF_TWIS_Type * p_reg,uint32_t scl,uint32_t sda)782 NRF_STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * p_reg, uint32_t scl, uint32_t sda)
783 {
784     p_reg->PSEL.SCL = scl;
785     p_reg->PSEL.SDA = sda;
786 }
787 
nrf_twis_scl_pin_set(NRF_TWIS_Type * p_reg,uint32_t pin)788 NRF_STATIC_INLINE void nrf_twis_scl_pin_set(NRF_TWIS_Type * p_reg, uint32_t pin)
789 {
790     p_reg->PSEL.SCL = pin;
791 }
792 
nrf_twis_scl_pin_get(NRF_TWIS_Type const * p_reg)793 NRF_STATIC_INLINE uint32_t nrf_twis_scl_pin_get(NRF_TWIS_Type const * p_reg)
794 {
795     return p_reg->PSEL.SCL;
796 }
797 
nrf_twis_sda_pin_set(NRF_TWIS_Type * p_reg,uint32_t pin)798 NRF_STATIC_INLINE void nrf_twis_sda_pin_set(NRF_TWIS_Type * p_reg, uint32_t pin)
799 {
800     p_reg->PSEL.SDA = pin;
801 }
802 
nrf_twis_sda_pin_get(NRF_TWIS_Type const * p_reg)803 NRF_STATIC_INLINE uint32_t nrf_twis_sda_pin_get(NRF_TWIS_Type const * p_reg)
804 {
805     return p_reg->PSEL.SDA;
806 }
807 
nrf_twis_rx_buffer_set(NRF_TWIS_Type * p_reg,uint8_t * p_buf,size_t length)808 NRF_STATIC_INLINE void nrf_twis_rx_buffer_set(NRF_TWIS_Type * p_reg, uint8_t * p_buf, size_t length)
809 {
810 #if NRF_TWIS_HAS_DMA_REG
811     p_reg->DMA.RX.PTR    = (uint32_t)p_buf;
812     p_reg->DMA.RX.MAXCNT = (uint32_t)length;
813 #else
814     p_reg->RXD.PTR    = (uint32_t)p_buf;
815     p_reg->RXD.MAXCNT = length;
816 #endif
817 }
818 
nrf_twis_rx_buffer_get(NRF_TWIS_Type const * p_reg)819 NRF_STATIC_INLINE uint8_t * nrf_twis_rx_buffer_get(NRF_TWIS_Type const * p_reg)
820 {
821 #if NRF_TWIS_HAS_DMA_REG
822     return (uint8_t *)p_reg->DMA.RX.PTR;
823 #else
824     return (uint8_t *)p_reg->RXD.PTR;
825 #endif
826 }
827 
nrf_twis_rx_prepare(NRF_TWIS_Type * p_reg,uint8_t * p_buf,size_t length)828 NRF_STATIC_INLINE void nrf_twis_rx_prepare(NRF_TWIS_Type * p_reg, uint8_t * p_buf, size_t length)
829 {
830     nrf_twis_rx_buffer_set(p_reg, p_buf, length);
831     nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARERX);
832 }
833 
nrf_twis_rx_amount_get(NRF_TWIS_Type const * p_reg)834 NRF_STATIC_INLINE size_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * p_reg)
835 {
836 #if NRF_TWIS_HAS_DMA_REG
837     return p_reg->DMA.RX.AMOUNT;
838 #else
839     return p_reg->RXD.AMOUNT;
840 #endif
841 }
842 
nrf_twis_tx_buffer_set(NRF_TWIS_Type * p_reg,uint8_t const * p_buf,size_t length)843 NRF_STATIC_INLINE void nrf_twis_tx_buffer_set(NRF_TWIS_Type * p_reg,
844                                               uint8_t const * p_buf,
845                                               size_t          length)
846 {
847 #if NRF_TWIS_HAS_DMA_REG
848     p_reg->DMA.TX.PTR    = (uint32_t)p_buf;
849     p_reg->DMA.TX.MAXCNT = (uint32_t)length;
850 #else
851     p_reg->TXD.PTR    = (uint32_t)p_buf;
852     p_reg->TXD.MAXCNT = length;
853 #endif
854 }
855 
nrf_twis_tx_buffer_get(NRF_TWIS_Type const * p_reg)856 NRF_STATIC_INLINE uint8_t * nrf_twis_tx_buffer_get(NRF_TWIS_Type const * p_reg)
857 {
858 #if NRF_TWIS_HAS_DMA_REG
859     return (uint8_t *)p_reg->DMA.TX.PTR;
860 #else
861     return (uint8_t *)p_reg->TXD.PTR;
862 #endif
863 }
864 
nrf_twis_tx_prepare(NRF_TWIS_Type * p_reg,uint8_t const * p_buf,size_t length)865 NRF_STATIC_INLINE void nrf_twis_tx_prepare(NRF_TWIS_Type * p_reg,
866                                            uint8_t const * p_buf,
867                                            size_t          length)
868 {
869     nrf_twis_tx_buffer_set(p_reg, p_buf, length);
870     nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARETX);
871 }
872 
nrf_twis_tx_amount_get(NRF_TWIS_Type const * p_reg)873 NRF_STATIC_INLINE size_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * p_reg)
874 {
875 #if NRF_TWIS_HAS_DMA_REG
876     return p_reg->DMA.TX.AMOUNT;
877 #else
878     return p_reg->TXD.AMOUNT;
879 #endif
880 }
881 
nrf_twis_address_set(NRF_TWIS_Type * p_reg,uint_fast8_t n,nrf_twis_address_t addr)882 NRF_STATIC_INLINE void nrf_twis_address_set(NRF_TWIS_Type *    p_reg,
883                                             uint_fast8_t       n,
884                                             nrf_twis_address_t addr)
885 {
886     NRFX_ASSERT((uint32_t)addr <= TWIS_ADDRESS_ADDRESS_Msk);
887     p_reg->ADDRESS[n] = (uint32_t)addr;
888 }
889 
nrf_twis_address_get(NRF_TWIS_Type const * p_reg,uint_fast8_t n)890 NRF_STATIC_INLINE nrf_twis_address_t nrf_twis_address_get(NRF_TWIS_Type const * p_reg,
891                                                           uint_fast8_t          n)
892 {
893     return (nrf_twis_address_t)p_reg->ADDRESS[n];
894 }
895 
nrf_twis_config_address_set(NRF_TWIS_Type * p_reg,nrf_twis_config_addr_mask_t addr_mask)896 NRF_STATIC_INLINE void nrf_twis_config_address_set(NRF_TWIS_Type *             p_reg,
897                                                    nrf_twis_config_addr_mask_t addr_mask)
898 {
899     /* This is the only configuration in TWIS - just write it without masking. */
900     p_reg->CONFIG = (uint32_t)addr_mask;
901 }
902 
903 NRF_STATIC_INLINE
nrf_twis_config_address_get(NRF_TWIS_Type const * p_reg)904 nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * p_reg)
905 {
906     return (nrf_twis_config_addr_mask_t)(p_reg->CONFIG & NRF_TWIS_CONFIG_ADDRESS01_MASK);
907 }
908 
nrf_twis_orc_set(NRF_TWIS_Type * p_reg,uint8_t orc)909 NRF_STATIC_INLINE void nrf_twis_orc_set(NRF_TWIS_Type * p_reg, uint8_t orc)
910 {
911     p_reg->ORC = orc;
912 }
913 
nrf_twis_orc_get(NRF_TWIS_Type const * p_reg)914 NRF_STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * p_reg)
915 {
916     return (uint8_t)p_reg->ORC;
917 }
918 
919 #if NRF_TWIS_HAS_LIST_REG
nrf_twis_tx_list_enable(NRF_TWIS_Type * p_reg)920 NRF_STATIC_INLINE void nrf_twis_tx_list_enable(NRF_TWIS_Type * p_reg)
921 {
922     p_reg->TXD.LIST = TWIS_TXD_LIST_LIST_ArrayList << TWIS_TXD_LIST_LIST_Pos;
923 }
924 
nrf_twis_tx_list_disable(NRF_TWIS_Type * p_reg)925 NRF_STATIC_INLINE void nrf_twis_tx_list_disable(NRF_TWIS_Type * p_reg)
926 {
927     p_reg->TXD.LIST = TWIS_TXD_LIST_LIST_Disabled << TWIS_TXD_LIST_LIST_Pos;
928 }
929 
nrf_twis_rx_list_enable(NRF_TWIS_Type * p_reg)930 NRF_STATIC_INLINE void nrf_twis_rx_list_enable(NRF_TWIS_Type * p_reg)
931 {
932     p_reg->RXD.LIST = TWIS_RXD_LIST_LIST_ArrayList << TWIS_RXD_LIST_LIST_Pos;
933 }
934 
nrf_twis_rx_list_disable(NRF_TWIS_Type * p_reg)935 NRF_STATIC_INLINE void nrf_twis_rx_list_disable(NRF_TWIS_Type * p_reg)
936 {
937     p_reg->RXD.LIST = TWIS_RXD_LIST_LIST_Disabled << TWIS_RXD_LIST_LIST_Pos;
938 }
939 #endif
940 
941 #endif /* NRF_DECLARE_ONLY */
942 
943 
944 #ifdef __cplusplus
945 }
946 #endif
947 
948 #endif /* NRF_TWIS_H__ */
949