xref: /nrf52832-nimble/nordic/nrfx/hal/nrf_twi.h (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1 /*
2  * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this
9  *    list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  *    contributors may be used to endorse or promote products derived from this
17  *    software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef NRF_TWI_H__
33 #define NRF_TWI_H__
34 
35 #include <nrfx.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /**
42  * @defgroup nrf_twi_hal TWI HAL
43  * @{
44  * @ingroup nrf_twi
45  * @brief   Hardware access layer for managing the TWI peripheral.
46  */
47 
48 /**
49  * @brief TWI tasks.
50  */
51 typedef enum
52 {
53     /*lint -save -e30*/
54     NRF_TWI_TASK_STARTRX = offsetof(NRF_TWI_Type, TASKS_STARTRX), ///< Start TWI receive sequence.
55     NRF_TWI_TASK_STARTTX = offsetof(NRF_TWI_Type, TASKS_STARTTX), ///< Start TWI transmit sequence.
56     NRF_TWI_TASK_STOP    = offsetof(NRF_TWI_Type, TASKS_STOP),    ///< Stop TWI transaction.
57     NRF_TWI_TASK_SUSPEND = offsetof(NRF_TWI_Type, TASKS_SUSPEND), ///< Suspend TWI transaction.
58     NRF_TWI_TASK_RESUME  = offsetof(NRF_TWI_Type, TASKS_RESUME)   ///< Resume TWI transaction.
59     /*lint -restore*/
60 } nrf_twi_task_t;
61 
62 /**
63  * @brief TWI events.
64  */
65 typedef enum
66 {
67     /*lint -save -e30*/
68     NRF_TWI_EVENT_STOPPED   = offsetof(NRF_TWI_Type, EVENTS_STOPPED),  ///< TWI stopped.
69     NRF_TWI_EVENT_RXDREADY  = offsetof(NRF_TWI_Type, EVENTS_RXDREADY), ///< TWI RXD byte received.
70     NRF_TWI_EVENT_TXDSENT   = offsetof(NRF_TWI_Type, EVENTS_TXDSENT),  ///< TWI TXD byte sent.
71     NRF_TWI_EVENT_ERROR     = offsetof(NRF_TWI_Type, EVENTS_ERROR),    ///< TWI error.
72     NRF_TWI_EVENT_BB        = offsetof(NRF_TWI_Type, EVENTS_BB),       ///< TWI byte boundary, generated before each byte that is sent or received.
73     NRF_TWI_EVENT_SUSPENDED = offsetof(NRF_TWI_Type, EVENTS_SUSPENDED) ///< TWI entered the suspended state.
74     /*lint -restore*/
75 } nrf_twi_event_t;
76 
77 /**
78  * @brief TWI shortcuts.
79  */
80 typedef enum
81 {
82     NRF_TWI_SHORT_BB_SUSPEND_MASK = TWI_SHORTS_BB_SUSPEND_Msk,  ///< Shortcut between BB event and SUSPEND task.
83     NRF_TWI_SHORT_BB_STOP_MASK    = TWI_SHORTS_BB_STOP_Msk,     ///< Shortcut between BB event and STOP task.
84     NRF_TWI_ALL_SHORTS_MASK       = TWI_SHORTS_BB_SUSPEND_Msk |
85                                     TWI_SHORTS_BB_STOP_Msk      ///< All TWI shortcuts.
86 } nrf_twi_short_mask_t;
87 
88 /**
89  * @brief TWI interrupts.
90  */
91 typedef enum
92 {
93     NRF_TWI_INT_STOPPED_MASK    = TWI_INTENSET_STOPPED_Msk,    ///< Interrupt on STOPPED event.
94     NRF_TWI_INT_RXDREADY_MASK   = TWI_INTENSET_RXDREADY_Msk,   ///< Interrupt on RXDREADY event.
95     NRF_TWI_INT_TXDSENT_MASK    = TWI_INTENSET_TXDSENT_Msk,    ///< Interrupt on TXDSENT event.
96     NRF_TWI_INT_ERROR_MASK      = TWI_INTENSET_ERROR_Msk,      ///< Interrupt on ERROR event.
97     NRF_TWI_INT_BB_MASK         = TWI_INTENSET_BB_Msk,         ///< Interrupt on BB event.
98     NRF_TWI_INT_SUSPENDED_MASK  = TWI_INTENSET_SUSPENDED_Msk,  ///< Interrupt on SUSPENDED event.
99     NRF_TWI_ALL_INTS_MASK       = TWI_INTENSET_STOPPED_Msk   |
100                                   TWI_INTENSET_RXDREADY_Msk  |
101                                   TWI_INTENSET_TXDSENT_Msk   |
102                                   TWI_INTENSET_ERROR_Msk     |
103                                   TWI_INTENSET_BB_Msk        |
104                                   TWI_INTENSET_SUSPENDED_Msk   ///< All TWI interrupts.
105 } nrf_twi_int_mask_t;
106 
107 /**
108  * @brief TWI error source.
109  */
110 typedef enum
111 {
112     NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk,  ///< NACK received after sending the address.
113     NRF_TWI_ERROR_DATA_NACK    = TWI_ERRORSRC_DNACK_Msk,  ///< NACK received after sending a data byte.
114     NRF_TWI_ERROR_OVERRUN      = TWI_ERRORSRC_OVERRUN_Msk ///< Overrun error.
115                                                           /**< A new byte was received before the previous byte was read
116                                                            *   from the RXD register (previous data is lost). */
117 } nrf_twi_error_t;
118 
119 /**
120  * @brief TWI master clock frequency.
121  */
122 typedef enum
123 {
124     NRF_TWI_FREQ_100K = TWI_FREQUENCY_FREQUENCY_K100, ///< 100 kbps.
125     NRF_TWI_FREQ_250K = TWI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
126     NRF_TWI_FREQ_400K = TWI_FREQUENCY_FREQUENCY_K400  ///< 400 kbps.
127 } nrf_twi_frequency_t;
128 
129 
130 /**
131  * @brief Function for activating a specific TWI task.
132  *
133  * @param[in] p_reg Pointer to the peripheral registers structure.
134  * @param[in] task  Task to activate.
135  */
136 __STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg,
137                                           nrf_twi_task_t task);
138 
139 /**
140  * @brief Function for getting the address of a specific TWI task register.
141  *
142  * @param[in] p_reg Pointer to the peripheral registers structure.
143  * @param[in] task  Requested task.
144  *
145  * @return Address of the specified task register.
146  */
147 __STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg,
148                                                     nrf_twi_task_t task);
149 
150 /**
151  * @brief Function for clearing a specific TWI event.
152  *
153  * @param[in] p_reg Pointer to the peripheral registers structure.
154  * @param[in] event Event to clear.
155  */
156 __STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg,
157                                          nrf_twi_event_t event);
158 
159 /**
160  * @brief Function for checking the state of a specific event.
161  *
162  * @param[in] p_reg Pointer to the peripheral registers structure.
163  * @param[in] event Event to check.
164  *
165  * @retval true If the event is set.
166  * @retval false If the event is not set.
167  */
168 __STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type  * p_reg,
169                                          nrf_twi_event_t event);
170 
171 /**
172  * @brief Function for getting the address of a specific TWI event register.
173  *
174  * @param[in] p_reg Pointer to the peripheral registers structure.
175  * @param[in] event Requested event.
176  *
177  * @return Address of the specified event register.
178  */
179 __STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type  * p_reg,
180                                                      nrf_twi_event_t event);
181 
182 /**
183  * @brief Function for enabling specified shortcuts.
184  *
185  * @param[in] p_reg       Pointer to the peripheral registers structure.
186  * @param[in] shorts_mask Shortcuts to enable.
187  */
188 __STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg,
189                                            uint32_t shorts_mask);
190 
191 /**
192  * @brief Function for disabling specified shortcuts.
193  *
194  * @param[in] p_reg       Pointer to the peripheral registers structure.
195  * @param[in] shorts_mask Shortcuts to disable.
196  */
197 __STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg,
198                                             uint32_t shorts_mask);
199 
200 /**
201  * @brief Function for enabling specified interrupts.
202  *
203  * @param[in] p_reg    Pointer to the peripheral registers structure.
204  * @param[in] int_mask Interrupts to enable.
205  */
206 __STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg,
207                                         uint32_t int_mask);
208 
209 /**
210  * @brief Function for disabling specified interrupts.
211  *
212  * @param[in] p_reg    Pointer to the peripheral registers structure.
213  * @param[in] int_mask Interrupts to disable.
214  */
215 __STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg,
216                                          uint32_t int_mask);
217 
218 /**
219  * @brief Function for retrieving the state of a given interrupt.
220  *
221  * @param[in] p_reg    Pointer to the peripheral registers structure.
222  * @param[in] int_mask Interrupt to check.
223  *
224  * @retval true  If the interrupt is enabled.
225  * @retval false If the interrupt is not enabled.
226  */
227 __STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg,
228                                               nrf_twi_int_mask_t int_mask);
229 
230 /**
231  * @brief Function for enabling the TWI peripheral.
232  *
233  * @param[in] p_reg Pointer to the peripheral registers structure.
234  */
235 __STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg);
236 
237 /**
238  * @brief Function for disabling the TWI peripheral.
239  *
240  * @param[in] p_reg Pointer to the peripheral registers structure.
241  */
242 __STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg);
243 
244 /**
245  * @brief Function for configuring TWI pins.
246  *
247  *
248  * @param[in] p_reg   Pointer to the peripheral registers structure.
249  * @param[in] scl_pin SCL pin number.
250  * @param[in] sda_pin SDA pin number.
251  */
252 __STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg,
253                                       uint32_t scl_pin,
254                                       uint32_t sda_pin);
255 
256 /**
257  * @brief Function for setting the TWI master clock frequency.
258  *
259  * @param[in] p_reg     Pointer to the peripheral registers structure.
260  * @param[in] frequency TWI frequency.
261  */
262 __STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg,
263                                            nrf_twi_frequency_t frequency);
264 
265 /**
266  * @brief Function for checking the TWI error source.
267  *
268  * The error flags are cleared after reading.
269  *
270  * @param[in] p_reg Pointer to the peripheral registers structure.
271  *
272  * @return Mask with error source flags.
273  */
274 __STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg);
275 
276 /**
277  * @brief Function for setting the address to be used in TWI transfers.
278  *
279  * @param[in] p_reg   Pointer to the peripheral registers structure.
280  * @param[in] address Address to be used in transfers.
281  */
282 __STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address);
283 
284 /**
285  * @brief Function for reading data received by TWI.
286  *
287  * @param[in] p_reg Pointer to the peripheral registers structure.
288  *
289  * @return Received data.
290  */
291 __STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg);
292 
293 /**
294  * @brief Function for writing data to be transmitted by TWI.
295  *
296  * @param[in] p_reg Pointer to the peripheral registers structure.
297  * @param[in] data  Data to be transmitted.
298  */
299 __STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data);
300 
301 __STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg,
302                                         uint32_t shorts_mask);
303 
304 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
305 
nrf_twi_task_trigger(NRF_TWI_Type * p_reg,nrf_twi_task_t task)306 __STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg,
307                                           nrf_twi_task_t task)
308 {
309     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
310 }
311 
nrf_twi_task_address_get(NRF_TWI_Type * p_reg,nrf_twi_task_t task)312 __STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg,
313                                                     nrf_twi_task_t task)
314 {
315     return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
316 }
317 
nrf_twi_event_clear(NRF_TWI_Type * p_reg,nrf_twi_event_t event)318 __STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type  * p_reg,
319                                          nrf_twi_event_t event)
320 {
321     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
322 #if __CORTEX_M == 0x04
323     volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
324     (void)dummy;
325 #endif
326 }
327 
nrf_twi_event_check(NRF_TWI_Type * p_reg,nrf_twi_event_t event)328 __STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type  * p_reg,
329                                          nrf_twi_event_t event)
330 {
331     return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
332 }
333 
nrf_twi_event_address_get(NRF_TWI_Type * p_reg,nrf_twi_event_t event)334 __STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type  * p_reg,
335                                                      nrf_twi_event_t event)
336 {
337     return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
338 }
339 
nrf_twi_shorts_enable(NRF_TWI_Type * p_reg,uint32_t shorts_mask)340 __STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg,
341                                            uint32_t shorts_mask)
342 {
343     p_reg->SHORTS |= shorts_mask;
344 }
345 
nrf_twi_shorts_disable(NRF_TWI_Type * p_reg,uint32_t shorts_mask)346 __STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg,
347                                             uint32_t shorts_mask)
348 {
349     p_reg->SHORTS &= ~(shorts_mask);
350 }
351 
nrf_twi_int_enable(NRF_TWI_Type * p_reg,uint32_t int_mask)352 __STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg,
353                                         uint32_t int_mask)
354 {
355     p_reg->INTENSET = int_mask;
356 }
357 
nrf_twi_int_disable(NRF_TWI_Type * p_reg,uint32_t int_mask)358 __STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg,
359                                          uint32_t int_mask)
360 {
361     p_reg->INTENCLR = int_mask;
362 }
363 
nrf_twi_int_enable_check(NRF_TWI_Type * p_reg,nrf_twi_int_mask_t int_mask)364 __STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg,
365                                               nrf_twi_int_mask_t int_mask)
366 {
367     return (bool)(p_reg->INTENSET & int_mask);
368 }
369 
nrf_twi_enable(NRF_TWI_Type * p_reg)370 __STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg)
371 {
372     p_reg->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
373 }
374 
nrf_twi_disable(NRF_TWI_Type * p_reg)375 __STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg)
376 {
377     p_reg->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos);
378 }
379 
nrf_twi_pins_set(NRF_TWI_Type * p_reg,uint32_t scl_pin,uint32_t sda_pin)380 __STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg,
381                                       uint32_t scl_pin,
382                                       uint32_t sda_pin)
383 {
384 #if defined(TWI_PSEL_SCL_CONNECT_Pos)
385     p_reg->PSEL.SCL = scl_pin;
386 #else
387     p_reg->PSELSCL = scl_pin;
388 #endif
389 
390 #if defined(TWI_PSEL_SDA_CONNECT_Pos)
391     p_reg->PSEL.SDA = sda_pin;
392 #else
393     p_reg->PSELSDA = sda_pin;
394 #endif
395 }
396 
nrf_twi_frequency_set(NRF_TWI_Type * p_reg,nrf_twi_frequency_t frequency)397 __STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg,
398                                            nrf_twi_frequency_t frequency)
399 {
400     p_reg->FREQUENCY = frequency;
401 }
402 
nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg)403 __STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg)
404 {
405     uint32_t error_source = p_reg->ERRORSRC;
406 
407     // [error flags are cleared by writing '1' on their position]
408     p_reg->ERRORSRC = error_source;
409 
410     return error_source;
411 }
412 
nrf_twi_address_set(NRF_TWI_Type * p_reg,uint8_t address)413 __STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address)
414 {
415     p_reg->ADDRESS = address;
416 }
417 
nrf_twi_rxd_get(NRF_TWI_Type * p_reg)418 __STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg)
419 {
420     return (uint8_t)p_reg->RXD;
421 }
422 
nrf_twi_txd_set(NRF_TWI_Type * p_reg,uint8_t data)423 __STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data)
424 {
425     p_reg->TXD = data;
426 }
427 
nrf_twi_shorts_set(NRF_TWI_Type * p_reg,uint32_t shorts_mask)428 __STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg,
429                                         uint32_t shorts_mask)
430 {
431     p_reg->SHORTS = shorts_mask;
432 }
433 
434 #endif // SUPPRESS_INLINE_IMPLEMENTATION
435 
436 /** @} */
437 
438 #ifdef __cplusplus
439 }
440 #endif
441 
442 #endif // NRF_TWI_H__
443