1 /*
2 * Copyright (c) 2015 - 2020, 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 Interface Slave with EasyDMA (TWIS) peripheral driver.
48 */
49
50 /** @brief TWIS driver instance data structure. */
51 typedef struct
52 {
53 NRF_TWIS_Type * p_reg; ///< Pointer to a structure with TWIS registers.
54 uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
55 } nrfx_twis_t;
56
57 #ifndef __NRFX_DOXYGEN__
58 enum {
59 #if NRFX_CHECK(NRFX_TWIS0_ENABLED)
60 NRFX_TWIS0_INST_IDX,
61 #endif
62 #if NRFX_CHECK(NRFX_TWIS1_ENABLED)
63 NRFX_TWIS1_INST_IDX,
64 #endif
65 #if NRFX_CHECK(NRFX_TWIS2_ENABLED)
66 NRFX_TWIS2_INST_IDX,
67 #endif
68 #if NRFX_CHECK(NRFX_TWIS3_ENABLED)
69 NRFX_TWIS3_INST_IDX,
70 #endif
71 NRFX_TWIS_ENABLED_COUNT
72 };
73 #endif
74
75 /** @brief Macro for creating a TWIS driver instance. */
76 #define NRFX_TWIS_INSTANCE(id) \
77 { \
78 .p_reg = NRFX_CONCAT_2(NRF_TWIS, id), \
79 .drv_inst_idx = NRFX_CONCAT_3(NRFX_TWIS, id, _INST_IDX), \
80 }
81
82 /** @brief Event callback function event definitions. */
83 typedef enum
84 {
85 NRFX_TWIS_EVT_READ_REQ, ///< Read request detected.
86 /**< If there is no buffer prepared, buf_req flag in the even will be set.
87 Call then @ref nrfx_twis_tx_prepare to give parameters for buffer.
88 */
89 NRFX_TWIS_EVT_READ_DONE, ///< Read request finished - free any data.
90 NRFX_TWIS_EVT_READ_ERROR, ///< Read request finished with error.
91 NRFX_TWIS_EVT_WRITE_REQ, ///< Write request detected.
92 /**< If there is no buffer prepared, buf_req flag in the even will be set.
93 Call then @ref nrfx_twis_rx_prepare to give parameters for buffer.
94 */
95 NRFX_TWIS_EVT_WRITE_DONE, ///< Write request finished - process data.
96 NRFX_TWIS_EVT_WRITE_ERROR, ///< Write request finished with error.
97 NRFX_TWIS_EVT_GENERAL_ERROR ///< Error that happens not inside WRITE or READ transaction.
98 } nrfx_twis_evt_type_t;
99
100 /**
101 * @brief Possible error sources.
102 *
103 * This is flag enum - values from this enum can be connected using logical or operator.
104 * @note
105 * You can use directly @ref nrf_twis_error_t. Error type enum is redefined here because
106 * of possible future extension (eg. supporting timeouts and synchronous mode).
107 */
108 typedef enum
109 {
110 NRFX_TWIS_ERROR_OVERFLOW = NRF_TWIS_ERROR_OVERFLOW, /**< RX buffer overflow detected, and prevented. */
111 NRFX_TWIS_ERROR_DATA_NACK = NRF_TWIS_ERROR_DATA_NACK, /**< NACK sent after receiving a data byte. */
112 NRFX_TWIS_ERROR_OVERREAD = NRF_TWIS_ERROR_OVERREAD, /**< TX buffer over-read detected, and prevented. */
113 NRFX_TWIS_ERROR_UNEXPECTED_EVENT = 1 << 8 /**< Unexpected event detected by state machine. */
114 } nrfx_twis_error_t;
115
116 /** @brief TWIS driver event structure. */
117 typedef struct
118 {
119 nrfx_twis_evt_type_t type; ///< Event type.
120 union
121 {
122 bool buf_req; ///< Flag for @ref NRFX_TWIS_EVT_READ_REQ and @ref NRFX_TWIS_EVT_WRITE_REQ.
123 /**< Information if transmission buffer requires to be prepared. */
124 uint32_t tx_amount; ///< Data for @ref NRFX_TWIS_EVT_READ_DONE.
125 uint32_t rx_amount; ///< Data for @ref NRFX_TWIS_EVT_WRITE_DONE.
126 uint32_t error; ///< Data for @ref NRFX_TWIS_EVT_GENERAL_ERROR.
127 } data; ///< Union to store event data.
128 } nrfx_twis_evt_t;
129
130 /**
131 * @brief TWI slave event callback function type.
132 *
133 * @param[in] p_event Event information structure.
134 */
135 typedef void (*nrfx_twis_event_handler_t)(nrfx_twis_evt_t const * p_event);
136
137 /** @brief Structure for TWIS configuration. */
138 typedef struct
139 {
140 uint32_t addr[2]; //!< Set addresses that this slave should respond. Set 0 to disable.
141 uint32_t scl; //!< SCL pin number.
142 uint32_t sda; //!< SDA pin number.
143 nrf_gpio_pin_pull_t scl_pull; //!< SCL pin pull.
144 nrf_gpio_pin_pull_t sda_pull; //!< SDA pin pull.
145 uint8_t interrupt_priority; //!< The priority of interrupt for the module to be set.
146 } nrfx_twis_config_t;
147
148 /**
149 * @brief TWIS driver default configuration.
150 *
151 * This configuration sets up TWIS with the following options:
152 * - second slave address disabled
153 * - SCL pull-up disabled
154 * - SDA pull-up disabled
155 *
156 * @param[in] _pin_scl SCL pin.
157 * @param[in] _pin_sda SDA pin.
158 * @param[in] _addr Slave address on TWI bus.
159 */
160 #define NRFX_TWIS_DEFAULT_CONFIG(_pin_scl, _pin_sda, _addr) \
161 { \
162 .addr = { _addr, 0x00 }, \
163 .scl = _pin_scl, \
164 .scl_pull = NRF_GPIO_PIN_NOPULL, \
165 .sda = _pin_sda, \
166 .sda_pull = NRF_GPIO_PIN_NOPULL, \
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 the TWIS driver.
174 * @attention After driver initialization enable it with @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 will be used by interrupts so make it sure that object
179 * is not destroyed when function is leaving.
180 * @param[in] p_config Pointer to the structure with the initial configuration.
181 * @param[in] event_handler Event handler provided by the user.
182 *
183 * @retval NRFX_SUCCESS Initialization is successful.
184 * @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
185 * @retval NRFX_ERROR_BUSY 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 uninitializes the peripheral and resets all registers to default values.
198 *
199 * @note
200 * It is safe to call nrfx_twis_uninit even before initialization.
201 * Actually, @ref nrfx_twis_init function calls this function to
202 * make sure that TWIS state is known.
203 * @note
204 * If TWIS driver was in uninitialized state before calling this function,
205 * the selected pins would not be reset to default configuration.
206 *
207 * @param[in] p_instance Pointer to the driver instance structure.
208 */
209 void nrfx_twis_uninit(nrfx_twis_t const * p_instance);
210
211 /**
212 * @brief Function for enabling the TWIS instance.
213 *
214 * This function enables the TWIS instance.
215 * Function defined if there is need for dynamically enabling and disabling the peripheral.
216 * Use @ref nrfx_twis_enable and @ref nrfx_twis_disable functions.
217 * They do not change any configuration registers.
218 *
219 * @param p_instance Pointer to the driver instance structure.
220 */
221 void nrfx_twis_enable(nrfx_twis_t const * p_instance);
222
223 /**
224 * @brief Function for disabling the TWIS instance.
225 *
226 * This function disables the TWIS instance, which gives possibility to turn off the TWIS while
227 * holding configuration done by @ref nrfx_twis_init.
228 *
229 * @param p_instance Pointer to the driver instance structure.
230 */
231 void nrfx_twis_disable(nrfx_twis_t const * p_instance);
232
233 /**
234 * @brief Function for getting and clearing the last error flags.
235 *
236 * This function gets the information about errors.
237 * This is also the only possibility to exit from the error substate of the internal state machine.
238 * @attention
239 * This function clears error state and flags.
240 *
241 * @param[in] p_instance Pointer to the driver instance structure.
242 *
243 * @return Error flags defined in @ref nrfx_twis_error_t.
244 */
245 uint32_t nrfx_twis_error_get_and_clear(nrfx_twis_t const * p_instance);
246
247 /**
248 * @brief Function for preparing the data for sending.
249 *
250 * This function is to be used in response to the @ref NRFX_TWIS_EVT_READ_REQ event.
251 *
252 * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
253 * to be placed in the Data RAM region. If this condition is not met,
254 * this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
255 * @attention Transmission buffer must be placed in RAM.
256 *
257 * @param[in] p_instance Pointer to the driver instance structure.
258 * @param[in] p_buf Transmission buffer.
259 * @param[in] size Maximum number of bytes that master may read from buffer given.
260 *
261 * @retval NRFX_SUCCESS The preparation finished properly.
262 * @retval NRFX_ERROR_INVALID_ADDR The given @em p_buf is not placed inside the RAM.
263 * @retval NRFX_ERROR_INVALID_LENGTH There is a wrong value in the @em size parameter.
264 * @retval NRFX_ERROR_INVALID_STATE The module is not initialized or not enabled.
265 */
266 nrfx_err_t nrfx_twis_tx_prepare(nrfx_twis_t const * p_instance,
267 void const * p_buf,
268 size_t size);
269
270 /**
271 * @brief Function for getting the number of transmitted bytes.
272 *
273 * This function returns the number of bytes sent.
274 * This function can be called after @ref NRFX_TWIS_EVT_READ_DONE or @ref NRFX_TWIS_EVT_READ_ERROR events.
275 *
276 * @param[in] p_instance Pointer to the driver instance structure.
277 *
278 * @return Number of bytes sent.
279 */
280 NRFX_STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance);
281
282 /**
283 * @brief Function for preparing the data for receiving.
284 *
285 * This function must be used in response to the @ref NRFX_TWIS_EVT_WRITE_REQ event.
286 *
287 * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
288 * to be placed in the Data RAM region. If this condition is not met,
289 * this function fails with the error code NRFX_ERROR_INVALID_ADDR.
290 *
291 * @param[in] p_instance Pointer to the driver instance structure.
292 * @param[in] p_buf Buffer that is to be filled with received data.
293 * @param[in] size Size of the buffer (maximum amount of data to receive).
294 *
295 * @retval NRFX_SUCCESS The preparation finished properly.
296 * @retval NRFX_ERROR_INVALID_ADDR The given @em p_buf is not placed inside the RAM.
297 * @retval NRFX_ERROR_INVALID_LENGTH There is a wrong value in the @em size parameter.
298 * @retval NRFX_ERROR_INVALID_STATE The module is 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 Function for getting the number of received bytes.
306 *
307 * This function returns number of bytes received.
308 * It can 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 NRFX_STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance);
315
316 /**
317 * @brief Function for checking if the driver is busy right now.
318 *
319 * This function tests the actual driver substate.
320 * If the 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 The 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 for checking if the driver is waiting for a TX buffer.
331 *
332 * If this function returns true, the 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 The driver is waiting for @ref nrfx_twis_tx_prepare.
338 * @retval false The driver is not in the state where it is waiting for preparing a TX buffer.
339 */
340 bool nrfx_twis_is_waiting_tx_buff(nrfx_twis_t const * p_instance);
341
342 /**
343 * @brief Function for checking if the driver is waiting for an RX buffer.
344 *
345 * If this function returns true, the driver is stalled 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 The driver is waiting for @ref nrfx_twis_rx_prepare.
351 * @retval false The driver is not in the state where it is waiting for preparing an RX buffer.
352 */
353 bool nrfx_twis_is_waiting_rx_buff(nrfx_twis_t const * p_instance);
354
355 /**
356 * @brief Function for checking if the driver is sending data.
357 *
358 * If this function returns true, there is an ongoing output transmission.
359 *
360 * @param[in] p_instance Pointer to the driver instance structure.
361 *
362 * @retval true There is an ongoing output transmission.
363 * @retval false The driver is in other state.
364 */
365 bool nrfx_twis_is_pending_tx(nrfx_twis_t const * p_instance);
366
367 /**
368 * @brief Function for checking if the driver is receiving data.
369 *
370 * If this function returns true, there is an ongoing input transmission.
371 *
372 * @param[in] p_instance Pointer to the driver instance structure.
373 *
374 * @retval true There is an ongoing input transmission.
375 * @retval false The driver is in other state.
376 */
377 bool nrfx_twis_is_pending_rx(nrfx_twis_t const * p_instance);
378
379 #ifndef NRFX_DECLARE_ONLY
nrfx_twis_tx_amount(nrfx_twis_t const * p_instance)380 NRFX_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 NRFX_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 // NRFX_DECLARE_ONLY
390
391 /** @} */
392
393
394 void nrfx_twis_0_irq_handler(void);
395 void nrfx_twis_1_irq_handler(void);
396 void nrfx_twis_2_irq_handler(void);
397 void nrfx_twis_3_irq_handler(void);
398
399
400 #ifdef __cplusplus
401 }
402 #endif
403
404 #endif // NRFX_TWIS_H__
405