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