xref: /nrf52832-nimble/nordic/nrfx/drivers/include/nrfx_twis.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 NRFX_TWIS_H__
33 #define NRFX_TWIS_H__
34 
35 #include <nrfx.h>
36 #include <hal/nrf_twis.h>
37 #include <hal/nrf_gpio.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * @defgroup nrfx_twis TWIS driver
45  * @{
46  * @ingroup nrf_twis
47  * @brief   Two Wire Slave interface (TWIS) peripheral driver.
48  */
49 
50 /**
51  * @brief TWIS driver instance data structure.
52  */
53 typedef struct
54 {
55     NRF_TWIS_Type * p_reg;        ///< Pointer to a structure with TWIS registers.
56     uint8_t         drv_inst_idx; ///< Driver instance index.
57 } nrfx_twis_t;
58 
59 enum {
60 #if NRFX_CHECK(NRFX_TWIS0_ENABLED)
61     NRFX_TWIS0_INST_IDX,
62 #endif
63 #if NRFX_CHECK(NRFX_TWIS1_ENABLED)
64     NRFX_TWIS1_INST_IDX,
65 #endif
66 #if NRFX_CHECK(NRFX_TWIS2_ENABLED)
67     NRFX_TWIS2_INST_IDX,
68 #endif
69 #if NRFX_CHECK(NRFX_TWIS3_ENABLED)
70     NRFX_TWIS3_INST_IDX,
71 #endif
72     NRFX_TWIS_ENABLED_COUNT
73 };
74 
75 /**
76  * @brief Macro for creating a TWIS driver instance.
77  */
78 #define NRFX_TWIS_INSTANCE(id)                               \
79 {                                                            \
80     .p_reg        = NRFX_CONCAT_2(NRF_TWIS, id),             \
81     .drv_inst_idx = NRFX_CONCAT_3(NRFX_TWIS, id, _INST_IDX), \
82 }
83 
84 /**
85  * @brief Event callback function event definitions.
86  */
87 typedef enum
88 {
89     NRFX_TWIS_EVT_READ_REQ,     ///< Read request detected.
90                                 /**< If there is no buffer prepared, buf_req flag in the even will be set.
91                                      Call then @ref nrfx_twis_tx_prepare to give parameters for buffer.
92                                      */
93     NRFX_TWIS_EVT_READ_DONE,    ///< Read request has finished - free any data.
94     NRFX_TWIS_EVT_READ_ERROR,   ///< Read request finished with error.
95     NRFX_TWIS_EVT_WRITE_REQ,    ///< Write request detected.
96                                 /**< If there is no buffer prepared, buf_req flag in the even will be set.
97                                      Call then @ref nrfx_twis_rx_prepare to give parameters for buffer.
98                                      */
99     NRFX_TWIS_EVT_WRITE_DONE,   ///< Write request has finished - process data.
100     NRFX_TWIS_EVT_WRITE_ERROR,  ///< Write request finished with error.
101     NRFX_TWIS_EVT_GENERAL_ERROR ///< Error that happens not inside WRITE or READ transaction.
102 } nrfx_twis_evt_type_t;
103 
104 /**
105  * @brief Possible error sources.
106  *
107  * This is flag enum - values from this enum can be connected using logical or operator.
108  * @note
109  * We could use directly @ref nrf_twis_error_t. Error type enum is redefined here because
110  * of possible future extension (eg. supporting timeouts and synchronous mode).
111  */
112 typedef enum
113 {
114     NRFX_TWIS_ERROR_OVERFLOW         = NRF_TWIS_ERROR_OVERFLOW,  /**< RX buffer overflow detected, and prevented. */
115     NRFX_TWIS_ERROR_DATA_NACK        = NRF_TWIS_ERROR_DATA_NACK, /**< NACK sent after receiving a data byte. */
116     NRFX_TWIS_ERROR_OVERREAD         = NRF_TWIS_ERROR_OVERREAD,  /**< TX buffer over-read detected, and prevented. */
117     NRFX_TWIS_ERROR_UNEXPECTED_EVENT = 1 << 8                    /**< Unexpected event detected by state machine. */
118 } nrfx_twis_error_t;
119 
120 /**
121  * @brief TWIS driver event structure.
122  */
123 typedef struct
124 {
125     nrfx_twis_evt_type_t type; ///< Event type.
126     union
127     {
128         bool buf_req;       ///< Flag for @ref NRFX_TWIS_EVT_READ_REQ and @ref NRFX_TWIS_EVT_WRITE_REQ.
129                             /**< Information if transmission buffer requires to be prepared. */
130         uint32_t tx_amount; ///< Data for @ref NRFX_TWIS_EVT_READ_DONE.
131         uint32_t rx_amount; ///< Data for @ref NRFX_TWIS_EVT_WRITE_DONE.
132         uint32_t error;     ///< Data for @ref NRFX_TWIS_EVT_GENERAL_ERROR.
133     } data;
134 } nrfx_twis_evt_t;
135 
136 /**
137  * @brief TWI slave event callback function type.
138  *
139  * @param[in] p_event Event information structure.
140  */
141 typedef void (*nrfx_twis_event_handler_t)(nrfx_twis_evt_t const * p_event);
142 
143 /**
144  * @brief Structure for TWIS configuration.
145  */
146 typedef struct
147 {
148     uint32_t            addr[2];            //!< Set addresses that this slave should respond. Set 0 to disable.
149     uint32_t            scl;                //!< SCL pin number.
150     uint32_t            sda;                //!< SDA pin number.
151     nrf_gpio_pin_pull_t scl_pull;           //!< SCL pin pull.
152     nrf_gpio_pin_pull_t sda_pull;           //!< SDA pin pull.
153     uint8_t             interrupt_priority; //!< The priority of interrupt for the module to set.
154 } nrfx_twis_config_t;
155 
156 /**
157  * @brief Generate default configuration for TWIS driver instance.
158  */
159 #define NRFX_TWIS_DEFAULT_CONFIG \
160 { \
161     .addr               = { NRFX_TWIS_DEFAULT_CONFIG_ADDR0,                       \
162                             NRFX_TWIS_DEFAULT_CONFIG_ADDR1 },                     \
163     .scl                = 31,                                                     \
164     .scl_pull           = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL, \
165     .sda                = 31,                                                     \
166     .sda_pull           = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL, \
167     .interrupt_priority = NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY                   \
168 }
169 
170 /**
171  * @brief Function for initializing the TWIS driver instance.
172  *
173  * Function initializes and enables TWIS driver.
174  * @attention After driver initialization enable it by @ref nrfx_twis_enable.
175  *
176  * @param[in] p_instance      Pointer to the driver instance structure.
177  * @attention                 @em p_instance has to be global object.
178  *                            It would be used by interrupts so make it sure that object
179  *                            would not be destroyed when function is leaving.
180  * @param[in] p_config        Pointer to the structure with initial configuration.
181  * @param[in] event_handler   Event handler provided by the user.
182  *
183  * @retval NRFX_SUCCESS             If initialization was successful.
184  * @retval NRFX_ERROR_INVALID_STATE If the driver is already initialized.
185  * @retval NRFX_ERROR_BUSY          If some other peripheral with the same
186  *                                  instance ID is already in use. This is
187  *                                  possible only if NRFX_PRS_ENABLED
188  *                                  is set to a value other than zero.
189  */
190 nrfx_err_t nrfx_twis_init(nrfx_twis_t const *        p_instance,
191                           nrfx_twis_config_t const * p_config,
192                           nrfx_twis_event_handler_t  event_handler);
193 
194 /**
195  * @brief Function for uninitializing the TWIS driver instance.
196  *
197  * Function initializes the peripheral and resets all registers to default values.
198  *
199  * @param[in] p_instance Pointer to the driver instance structure.
200  * @note
201  * It is safe to call nrfx_twis_uninit even before initialization.
202  * Actually @ref nrfx_twis_init function calls this function to
203  * make sure that TWIS state is known.
204  * @note
205  * If TWIS driver was in uninitialized state before calling this function,
206  * selected pins would not be reset to default configuration.
207  */
208 void nrfx_twis_uninit(nrfx_twis_t const * p_instance);
209 
210 /**
211  * @brief Enable TWIS instance.
212  *
213  * This function enables TWIS instance.
214  * Function defined if there is needs for dynamically enabling and disabling the peripheral.
215  * Use @ref nrfx_twis_enable and @ref nrfx_twis_disable functions.
216  * They do not change any configuration registers.
217  *
218  * @param p_instance Pointer to the driver instance structure.
219  */
220 void nrfx_twis_enable(nrfx_twis_t const * p_instance);
221 
222 /**
223  * @brief Disable TWIS instance.
224  *
225  * Disabling TWIS instance gives possibility to turn off the TWIS while
226  * holding configuration done by @ref nrfx_twis_init.
227  *
228  * @param p_instance Pointer to the driver instance structure.
229  */
230 void nrfx_twis_disable(nrfx_twis_t const * p_instance);
231 
232 /**
233  * @brief Get and clear last error flags.
234  *
235  * Function gets information about errors.
236  * This is also the only possibility to exit from error substate of the internal state machine.
237  *
238  * @param[in] p_instance Pointer to the driver instance structure.
239  * @return Error flags defined in @ref nrfx_twis_error_t.
240  * @attention
241  * This function clears error state and flags.
242  */
243 uint32_t nrfx_twis_error_get_and_clear(nrfx_twis_t const * p_instance);
244 
245 
246 /**
247  * @brief Prepare data for sending.
248  *
249  * This function should be used in response for @ref NRFX_TWIS_EVT_READ_REQ event.
250  *
251  * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
252  *       to be placed in the Data RAM region. If this condition is not met,
253  *       this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
254  *
255  * @param[in] p_instance Pointer to the driver instance structure.
256  * @param[in] p_buf      Transmission buffer.
257  * @attention            Transmission buffer has to be placed in RAM.
258  * @param     size       Maximum number of bytes that master may read from buffer given.
259  *
260  * @retval NRFX_SUCCESS              Preparation finished properly.
261  * @retval NRFX_ERROR_INVALID_ADDR   Given @em p_buf is not placed inside the RAM.
262  * @retval NRFX_ERROR_INVALID_LENGTH Wrong value in @em size parameter.
263  * @retval NRFX_ERROR_INVALID_STATE  Module not initialized or not enabled.
264  */
265 nrfx_err_t nrfx_twis_tx_prepare(nrfx_twis_t const * p_instance,
266                                 void const *        p_buf,
267                                 size_t              size);
268 
269 /**
270  * @brief Get number of transmitted bytes.
271  *
272  * Function returns number of bytes sent.
273  * This function may be called after @ref NRFX_TWIS_EVT_READ_DONE or @ref NRFX_TWIS_EVT_READ_ERROR events.
274  *
275  * @param[in] p_instance Pointer to the driver instance structure.
276  *
277  * @return Number of bytes sent.
278  */
279 __STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance);
280 
281 /**
282  * @brief Prepare data for receiving
283  *
284  * This function should be used in response for @ref NRFX_TWIS_EVT_WRITE_REQ event.
285  *
286  * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
287  *       to be placed in the Data RAM region. If this condition is not met,
288  *       this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
289  *
290  * @param[in] p_instance Pointer to the driver instance structure.
291  * @param[in] p_buf      Buffer that would be filled with received data.
292  * @attention            Receiving buffer has to be placed in RAM.
293  * @param     size       Size of the buffer (maximum amount of data to receive).
294  *
295  * @retval NRFX_SUCCESS              Preparation finished properly.
296  * @retval NRFX_ERROR_INVALID_ADDR   Given @em p_buf is not placed inside the RAM.
297  * @retval NRFX_ERROR_INVALID_LENGTH Wrong value in @em size parameter.
298  * @retval NRFX_ERROR_INVALID_STATE  Module not initialized or not enabled.
299  */
300 nrfx_err_t nrfx_twis_rx_prepare(nrfx_twis_t const * p_instance,
301                                 void *              p_buf,
302                                 size_t              size);
303 
304 /**
305  * @brief Get number of received bytes.
306  *
307  * Function returns number of bytes received.
308  * This function may be called after @ref NRFX_TWIS_EVT_WRITE_DONE or @ref NRFX_TWIS_EVT_WRITE_ERROR events.
309  *
310  * @param[in] p_instance Pointer to the driver instance structure.
311  *
312  * @return Number of bytes received.
313  */
314 __STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance);
315 
316 /**
317  * @brief Function checks if driver is busy right now.
318  *
319  * Actual driver substate is tested.
320  * If driver is in any other state than IDLE or ERROR this function returns true.
321  *
322  * @param[in] p_instance Pointer to the driver instance structure.
323  *
324  * @retval true  Driver is in state other than ERROR or IDLE.
325  * @retval false There is no transmission pending.
326  */
327 bool nrfx_twis_is_busy(nrfx_twis_t const * p_instance);
328 
329 /**
330  * @brief Function checks if driver is waiting for tx buffer.
331  *
332  * If this function returns true, it means that driver is stalled expecting
333  * of the @ref nrfx_twis_tx_prepare function call.
334  *
335  * @param[in] p_instance Pointer to the driver instance structure.
336  *
337  * @retval true  Driver waits for @ref nrfx_twis_tx_prepare.
338  * @retval false Driver is not in the state where it waits for preparing tx buffer.
339  */
340 bool nrfx_twis_is_waiting_tx_buff(nrfx_twis_t const * p_instance);
341 
342 /**
343  * @brief Function checks if driver is waiting for rx buffer.
344  *
345  * If this function returns true, it means that driver is staled expecting
346  * of the @ref nrfx_twis_rx_prepare function call.
347  *
348  * @param[in] p_instance Pointer to the driver instance structure.
349  *
350  * @retval true  Driver waits for @ref nrfx_twis_rx_prepare.
351  * @retval false Driver is not in the state where it waits for preparing rx buffer.
352  */
353 bool nrfx_twis_is_waiting_rx_buff(nrfx_twis_t const * p_instance);
354 
355 /**
356  * @brief Check if driver is sending data.
357  *
358  * If this function returns true, it means that there is ongoing output transmission.
359  *
360  * @param[in] p_instance Pointer to the driver instance structure.
361  *
362  * @retval true  There is ongoing output transmission.
363  * @retval false Driver is in other state.
364  */
365 bool nrfx_twis_is_pending_tx(nrfx_twis_t const * p_instance);
366 
367 /**
368  * @brief Check if driver is receiving data.
369  *
370  * If this function returns true, it means that there is ongoing input transmission.
371  *
372  * @param[in] p_instance Pointer to the driver instance structure.
373  *
374  * @retval true  There is ongoing input transmission.
375  * @retval false Driver is in other state.
376  */
377 bool nrfx_twis_is_pending_rx(nrfx_twis_t const * p_instance);
378 
379 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
nrfx_twis_tx_amount(nrfx_twis_t const * p_instance)380 __STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance)
381 {
382     return nrf_twis_tx_amount_get(p_instance->p_reg);
383 }
384 
nrfx_twis_rx_amount(nrfx_twis_t const * p_instance)385 __STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance)
386 {
387     return nrf_twis_rx_amount_get(p_instance->p_reg);
388 }
389 #endif // SUPPRESS_INLINE_IMPLEMENTATION
390 
391 
392 void nrfx_twis_0_irq_handler(void);
393 void nrfx_twis_1_irq_handler(void);
394 void nrfx_twis_2_irq_handler(void);
395 void nrfx_twis_3_irq_handler(void);
396 
397 
398 /** @} */
399 
400 #ifdef __cplusplus
401 }
402 #endif
403 
404 #endif // NRFX_TWIS_H__
405