1*150812a8SEvalZero /*
2*150812a8SEvalZero * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3*150812a8SEvalZero * All rights reserved.
4*150812a8SEvalZero *
5*150812a8SEvalZero * Redistribution and use in source and binary forms, with or without
6*150812a8SEvalZero * modification, are permitted provided that the following conditions are met:
7*150812a8SEvalZero *
8*150812a8SEvalZero * 1. Redistributions of source code must retain the above copyright notice, this
9*150812a8SEvalZero * list of conditions and the following disclaimer.
10*150812a8SEvalZero *
11*150812a8SEvalZero * 2. Redistributions in binary form must reproduce the above copyright
12*150812a8SEvalZero * notice, this list of conditions and the following disclaimer in the
13*150812a8SEvalZero * documentation and/or other materials provided with the distribution.
14*150812a8SEvalZero *
15*150812a8SEvalZero * 3. Neither the name of the copyright holder nor the names of its
16*150812a8SEvalZero * contributors may be used to endorse or promote products derived from this
17*150812a8SEvalZero * software without specific prior written permission.
18*150812a8SEvalZero *
19*150812a8SEvalZero * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*150812a8SEvalZero * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*150812a8SEvalZero * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*150812a8SEvalZero * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*150812a8SEvalZero * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*150812a8SEvalZero * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*150812a8SEvalZero * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*150812a8SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*150812a8SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*150812a8SEvalZero * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*150812a8SEvalZero * POSSIBILITY OF SUCH DAMAGE.
30*150812a8SEvalZero */
31*150812a8SEvalZero
32*150812a8SEvalZero #include <nrfx.h>
33*150812a8SEvalZero
34*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM_ENABLED)
35*150812a8SEvalZero
36*150812a8SEvalZero #if !(NRFX_CHECK(NRFX_TWIM0_ENABLED) || \
37*150812a8SEvalZero NRFX_CHECK(NRFX_TWIM1_ENABLED) || \
38*150812a8SEvalZero NRFX_CHECK(NRFX_TWIM2_ENABLED) || \
39*150812a8SEvalZero NRFX_CHECK(NRFX_TWIM3_ENABLED))
40*150812a8SEvalZero #error "No enabled TWIM instances. Check <nrfx_config.h>."
41*150812a8SEvalZero #endif
42*150812a8SEvalZero
43*150812a8SEvalZero #include <nrfx_twim.h>
44*150812a8SEvalZero #include <hal/nrf_gpio.h>
45*150812a8SEvalZero #include "prs/nrfx_prs.h"
46*150812a8SEvalZero
47*150812a8SEvalZero #define NRFX_LOG_MODULE TWIM
48*150812a8SEvalZero #include <nrfx_log.h>
49*150812a8SEvalZero
50*150812a8SEvalZero #define EVT_TO_STR(event) \
51*150812a8SEvalZero (event == NRFX_TWIM_EVT_DONE ? "EVT_DONE" : \
52*150812a8SEvalZero (event == NRFX_TWIM_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \
53*150812a8SEvalZero (event == NRFX_TWIM_EVT_DATA_NACK ? "EVT_DATA_NACK" : \
54*150812a8SEvalZero "UNKNOWN ERROR")))
55*150812a8SEvalZero
56*150812a8SEvalZero #define EVT_TO_STR_TWIM(event) \
57*150812a8SEvalZero (event == NRF_TWIM_EVENT_STOPPED ? "NRF_TWIM_EVENT_STOPPED" : \
58*150812a8SEvalZero (event == NRF_TWIM_EVENT_ERROR ? "NRF_TWIM_EVENT_ERROR" : \
59*150812a8SEvalZero (event == NRF_TWIM_EVENT_SUSPENDED ? "NRF_TWIM_EVENT_SUSPENDED" : \
60*150812a8SEvalZero (event == NRF_TWIM_EVENT_RXSTARTED ? "NRF_TWIM_EVENT_RXSTARTED" : \
61*150812a8SEvalZero (event == NRF_TWIM_EVENT_TXSTARTED ? "NRF_TWIM_EVENT_TXSTARTED" : \
62*150812a8SEvalZero (event == NRF_TWIM_EVENT_LASTRX ? "NRF_TWIM_EVENT_LASTRX" : \
63*150812a8SEvalZero (event == NRF_TWIM_EVENT_LASTTX ? "NRF_TWIM_EVENT_LASTTX" : \
64*150812a8SEvalZero "UNKNOWN ERROR")))))))
65*150812a8SEvalZero
66*150812a8SEvalZero #define TRANSFER_TO_STR(type) \
67*150812a8SEvalZero (type == NRFX_TWIM_XFER_TX ? "XFER_TX" : \
68*150812a8SEvalZero (type == NRFX_TWIM_XFER_RX ? "XFER_RX" : \
69*150812a8SEvalZero (type == NRFX_TWIM_XFER_TXRX ? "XFER_TXRX" : \
70*150812a8SEvalZero (type == NRFX_TWIM_XFER_TXTX ? "XFER_TXTX" : \
71*150812a8SEvalZero "UNKNOWN TRANSFER TYPE"))))
72*150812a8SEvalZero
73*150812a8SEvalZero #define TWIM_PIN_INIT(_pin) nrf_gpio_cfg((_pin), \
74*150812a8SEvalZero NRF_GPIO_PIN_DIR_INPUT, \
75*150812a8SEvalZero NRF_GPIO_PIN_INPUT_CONNECT, \
76*150812a8SEvalZero NRF_GPIO_PIN_PULLUP, \
77*150812a8SEvalZero NRF_GPIO_PIN_S0D1, \
78*150812a8SEvalZero NRF_GPIO_PIN_NOSENSE)
79*150812a8SEvalZero
80*150812a8SEvalZero #define TWIMX_LENGTH_VALIDATE(peripheral, drv_inst_idx, len1, len2) \
81*150812a8SEvalZero (((drv_inst_idx) == NRFX_CONCAT_3(NRFX_, peripheral, _INST_IDX)) && \
82*150812a8SEvalZero NRFX_EASYDMA_LENGTH_VALIDATE(peripheral, len1, len2))
83*150812a8SEvalZero
84*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM0_ENABLED)
85*150812a8SEvalZero #define TWIM0_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM0, __VA_ARGS__)
86*150812a8SEvalZero #else
87*150812a8SEvalZero #define TWIM0_LENGTH_VALIDATE(...) 0
88*150812a8SEvalZero #endif
89*150812a8SEvalZero
90*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM1_ENABLED)
91*150812a8SEvalZero #define TWIM1_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM1, __VA_ARGS__)
92*150812a8SEvalZero #else
93*150812a8SEvalZero #define TWIM1_LENGTH_VALIDATE(...) 0
94*150812a8SEvalZero #endif
95*150812a8SEvalZero
96*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM2_ENABLED)
97*150812a8SEvalZero #define TWIM2_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM2, __VA_ARGS__)
98*150812a8SEvalZero #else
99*150812a8SEvalZero #define TWIM2_LENGTH_VALIDATE(...) 0
100*150812a8SEvalZero #endif
101*150812a8SEvalZero
102*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM3_ENABLED)
103*150812a8SEvalZero #define TWIM3_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM3, __VA_ARGS__)
104*150812a8SEvalZero #else
105*150812a8SEvalZero #define TWIM3_LENGTH_VALIDATE(...) 0
106*150812a8SEvalZero #endif
107*150812a8SEvalZero
108*150812a8SEvalZero #define TWIM_LENGTH_VALIDATE(drv_inst_idx, len1, len2) \
109*150812a8SEvalZero (TWIM0_LENGTH_VALIDATE(drv_inst_idx, len1, len2) || \
110*150812a8SEvalZero TWIM1_LENGTH_VALIDATE(drv_inst_idx, len1, len2) || \
111*150812a8SEvalZero TWIM2_LENGTH_VALIDATE(drv_inst_idx, len1, len2) || \
112*150812a8SEvalZero TWIM3_LENGTH_VALIDATE(drv_inst_idx, len1, len2))
113*150812a8SEvalZero
114*150812a8SEvalZero // Control block - driver instance local data.
115*150812a8SEvalZero typedef struct
116*150812a8SEvalZero {
117*150812a8SEvalZero nrfx_twim_evt_handler_t handler;
118*150812a8SEvalZero void * p_context;
119*150812a8SEvalZero volatile uint32_t int_mask;
120*150812a8SEvalZero nrfx_twim_xfer_desc_t xfer_desc;
121*150812a8SEvalZero uint32_t flags;
122*150812a8SEvalZero uint8_t * p_curr_buf;
123*150812a8SEvalZero size_t curr_length;
124*150812a8SEvalZero bool curr_no_stop;
125*150812a8SEvalZero nrfx_drv_state_t state;
126*150812a8SEvalZero bool error;
127*150812a8SEvalZero volatile bool busy;
128*150812a8SEvalZero bool repeated;
129*150812a8SEvalZero uint8_t bytes_transferred;
130*150812a8SEvalZero bool hold_bus_uninit;
131*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
132*150812a8SEvalZero nrf_twim_frequency_t bus_frequency;
133*150812a8SEvalZero #endif
134*150812a8SEvalZero } twim_control_block_t;
135*150812a8SEvalZero
136*150812a8SEvalZero static twim_control_block_t m_cb[NRFX_TWIM_ENABLED_COUNT];
137*150812a8SEvalZero
twi_process_error(uint32_t errorsrc)138*150812a8SEvalZero static nrfx_err_t twi_process_error(uint32_t errorsrc)
139*150812a8SEvalZero {
140*150812a8SEvalZero nrfx_err_t ret = NRFX_ERROR_INTERNAL;
141*150812a8SEvalZero
142*150812a8SEvalZero if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK)
143*150812a8SEvalZero {
144*150812a8SEvalZero ret = NRFX_ERROR_DRV_TWI_ERR_ANACK;
145*150812a8SEvalZero }
146*150812a8SEvalZero
147*150812a8SEvalZero if (errorsrc & NRF_TWIM_ERROR_DATA_NACK)
148*150812a8SEvalZero {
149*150812a8SEvalZero ret = NRFX_ERROR_DRV_TWI_ERR_DNACK;
150*150812a8SEvalZero }
151*150812a8SEvalZero
152*150812a8SEvalZero return ret;
153*150812a8SEvalZero }
154*150812a8SEvalZero
nrfx_twim_init(nrfx_twim_t const * p_instance,nrfx_twim_config_t const * p_config,nrfx_twim_evt_handler_t event_handler,void * p_context)155*150812a8SEvalZero nrfx_err_t nrfx_twim_init(nrfx_twim_t const * p_instance,
156*150812a8SEvalZero nrfx_twim_config_t const * p_config,
157*150812a8SEvalZero nrfx_twim_evt_handler_t event_handler,
158*150812a8SEvalZero void * p_context)
159*150812a8SEvalZero {
160*150812a8SEvalZero NRFX_ASSERT(p_config);
161*150812a8SEvalZero NRFX_ASSERT(p_config->scl != p_config->sda);
162*150812a8SEvalZero twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
163*150812a8SEvalZero nrfx_err_t err_code;
164*150812a8SEvalZero
165*150812a8SEvalZero if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
166*150812a8SEvalZero {
167*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
168*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
169*150812a8SEvalZero __func__,
170*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
171*150812a8SEvalZero return err_code;
172*150812a8SEvalZero }
173*150812a8SEvalZero
174*150812a8SEvalZero #if NRFX_CHECK(NRFX_PRS_ENABLED)
175*150812a8SEvalZero static nrfx_irq_handler_t const irq_handlers[NRFX_TWIM_ENABLED_COUNT] = {
176*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM0_ENABLED)
177*150812a8SEvalZero nrfx_twim_0_irq_handler,
178*150812a8SEvalZero #endif
179*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM1_ENABLED)
180*150812a8SEvalZero nrfx_twim_1_irq_handler,
181*150812a8SEvalZero #endif
182*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM2_ENABLED)
183*150812a8SEvalZero nrfx_twim_2_irq_handler,
184*150812a8SEvalZero #endif
185*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM3_ENABLED)
186*150812a8SEvalZero nrfx_twim_3_irq_handler,
187*150812a8SEvalZero #endif
188*150812a8SEvalZero };
189*150812a8SEvalZero if (nrfx_prs_acquire(p_instance->p_twim,
190*150812a8SEvalZero irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
191*150812a8SEvalZero {
192*150812a8SEvalZero err_code = NRFX_ERROR_BUSY;
193*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
194*150812a8SEvalZero __func__,
195*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
196*150812a8SEvalZero return err_code;
197*150812a8SEvalZero }
198*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
199*150812a8SEvalZero
200*150812a8SEvalZero p_cb->handler = event_handler;
201*150812a8SEvalZero p_cb->p_context = p_context;
202*150812a8SEvalZero p_cb->int_mask = 0;
203*150812a8SEvalZero p_cb->repeated = false;
204*150812a8SEvalZero p_cb->busy = false;
205*150812a8SEvalZero p_cb->hold_bus_uninit = p_config->hold_bus_uninit;
206*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
207*150812a8SEvalZero p_cb->bus_frequency = (nrf_twim_frequency_t)p_config->frequency;
208*150812a8SEvalZero #endif
209*150812a8SEvalZero
210*150812a8SEvalZero /* To secure correct signal levels on the pins used by the TWI
211*150812a8SEvalZero master when the system is in OFF mode, and when the TWI master is
212*150812a8SEvalZero disabled, these pins must be configured in the GPIO peripheral.
213*150812a8SEvalZero */
214*150812a8SEvalZero TWIM_PIN_INIT(p_config->scl);
215*150812a8SEvalZero TWIM_PIN_INIT(p_config->sda);
216*150812a8SEvalZero
217*150812a8SEvalZero NRF_TWIM_Type * p_twim = p_instance->p_twim;
218*150812a8SEvalZero nrf_twim_pins_set(p_twim, p_config->scl, p_config->sda);
219*150812a8SEvalZero nrf_twim_frequency_set(p_twim,
220*150812a8SEvalZero (nrf_twim_frequency_t)p_config->frequency);
221*150812a8SEvalZero
222*150812a8SEvalZero if (p_cb->handler)
223*150812a8SEvalZero {
224*150812a8SEvalZero NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_instance->p_twim),
225*150812a8SEvalZero p_config->interrupt_priority);
226*150812a8SEvalZero NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_instance->p_twim));
227*150812a8SEvalZero }
228*150812a8SEvalZero
229*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_INITIALIZED;
230*150812a8SEvalZero
231*150812a8SEvalZero err_code = NRFX_SUCCESS;
232*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
233*150812a8SEvalZero return err_code;
234*150812a8SEvalZero }
235*150812a8SEvalZero
nrfx_twim_uninit(nrfx_twim_t const * p_instance)236*150812a8SEvalZero void nrfx_twim_uninit(nrfx_twim_t const * p_instance)
237*150812a8SEvalZero {
238*150812a8SEvalZero twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
239*150812a8SEvalZero NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
240*150812a8SEvalZero
241*150812a8SEvalZero if (p_cb->handler)
242*150812a8SEvalZero {
243*150812a8SEvalZero NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_instance->p_twim));
244*150812a8SEvalZero }
245*150812a8SEvalZero nrfx_twim_disable(p_instance);
246*150812a8SEvalZero
247*150812a8SEvalZero #if NRFX_CHECK(NRFX_PRS_ENABLED)
248*150812a8SEvalZero nrfx_prs_release(p_instance->p_twim);
249*150812a8SEvalZero #endif
250*150812a8SEvalZero
251*150812a8SEvalZero if (!p_cb->hold_bus_uninit)
252*150812a8SEvalZero {
253*150812a8SEvalZero nrf_gpio_cfg_default(p_instance->p_twim->PSEL.SCL);
254*150812a8SEvalZero nrf_gpio_cfg_default(p_instance->p_twim->PSEL.SDA);
255*150812a8SEvalZero }
256*150812a8SEvalZero
257*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
258*150812a8SEvalZero NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
259*150812a8SEvalZero }
260*150812a8SEvalZero
nrfx_twim_enable(nrfx_twim_t const * p_instance)261*150812a8SEvalZero void nrfx_twim_enable(nrfx_twim_t const * p_instance)
262*150812a8SEvalZero {
263*150812a8SEvalZero twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
264*150812a8SEvalZero NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
265*150812a8SEvalZero
266*150812a8SEvalZero nrf_twim_enable(p_instance->p_twim);
267*150812a8SEvalZero
268*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_POWERED_ON;
269*150812a8SEvalZero NRFX_LOG_INFO("Instance enabled: %d.", p_instance->drv_inst_idx);
270*150812a8SEvalZero }
271*150812a8SEvalZero
nrfx_twim_disable(nrfx_twim_t const * p_instance)272*150812a8SEvalZero void nrfx_twim_disable(nrfx_twim_t const * p_instance)
273*150812a8SEvalZero {
274*150812a8SEvalZero twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
275*150812a8SEvalZero NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
276*150812a8SEvalZero
277*150812a8SEvalZero NRF_TWIM_Type * p_twim = p_instance->p_twim;
278*150812a8SEvalZero p_cb->int_mask = 0;
279*150812a8SEvalZero nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
280*150812a8SEvalZero nrf_twim_shorts_disable(p_twim, NRF_TWIM_ALL_SHORTS_MASK);
281*150812a8SEvalZero nrf_twim_disable(p_twim);
282*150812a8SEvalZero
283*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_INITIALIZED;
284*150812a8SEvalZero NRFX_LOG_INFO("Instance disabled: %d.", p_instance->drv_inst_idx);
285*150812a8SEvalZero }
286*150812a8SEvalZero
287*150812a8SEvalZero
nrfx_twim_is_busy(nrfx_twim_t const * p_instance)288*150812a8SEvalZero bool nrfx_twim_is_busy(nrfx_twim_t const * p_instance)
289*150812a8SEvalZero {
290*150812a8SEvalZero twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
291*150812a8SEvalZero return p_cb->busy;
292*150812a8SEvalZero }
293*150812a8SEvalZero
294*150812a8SEvalZero
twim_list_enable_handle(NRF_TWIM_Type * p_twim,uint32_t flags)295*150812a8SEvalZero __STATIC_INLINE void twim_list_enable_handle(NRF_TWIM_Type * p_twim, uint32_t flags)
296*150812a8SEvalZero {
297*150812a8SEvalZero if (NRFX_TWIM_FLAG_TX_POSTINC & flags)
298*150812a8SEvalZero {
299*150812a8SEvalZero nrf_twim_tx_list_enable(p_twim);
300*150812a8SEvalZero }
301*150812a8SEvalZero else
302*150812a8SEvalZero {
303*150812a8SEvalZero nrf_twim_tx_list_disable(p_twim);
304*150812a8SEvalZero }
305*150812a8SEvalZero
306*150812a8SEvalZero if (NRFX_TWIM_FLAG_RX_POSTINC & flags)
307*150812a8SEvalZero {
308*150812a8SEvalZero nrf_twim_rx_list_enable(p_twim);
309*150812a8SEvalZero }
310*150812a8SEvalZero else
311*150812a8SEvalZero {
312*150812a8SEvalZero nrf_twim_rx_list_disable(p_twim);
313*150812a8SEvalZero }
314*150812a8SEvalZero }
twim_xfer(twim_control_block_t * p_cb,NRF_TWIM_Type * p_twim,nrfx_twim_xfer_desc_t const * p_xfer_desc,uint32_t flags)315*150812a8SEvalZero __STATIC_INLINE nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
316*150812a8SEvalZero NRF_TWIM_Type * p_twim,
317*150812a8SEvalZero nrfx_twim_xfer_desc_t const * p_xfer_desc,
318*150812a8SEvalZero uint32_t flags)
319*150812a8SEvalZero {
320*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
321*150812a8SEvalZero nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX;
322*150812a8SEvalZero nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED;
323*150812a8SEvalZero
324*150812a8SEvalZero if (!nrfx_is_in_ram(p_xfer_desc->p_primary_buf))
325*150812a8SEvalZero {
326*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_ADDR;
327*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
328*150812a8SEvalZero __func__,
329*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
330*150812a8SEvalZero return err_code;
331*150812a8SEvalZero }
332*150812a8SEvalZero /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */
333*150812a8SEvalZero nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
334*150812a8SEvalZero if (p_cb->busy)
335*150812a8SEvalZero {
336*150812a8SEvalZero nrf_twim_int_enable(p_twim, p_cb->int_mask);
337*150812a8SEvalZero err_code = NRFX_ERROR_BUSY;
338*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
339*150812a8SEvalZero __func__,
340*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
341*150812a8SEvalZero return err_code;
342*150812a8SEvalZero }
343*150812a8SEvalZero else
344*150812a8SEvalZero {
345*150812a8SEvalZero p_cb->busy = ((NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER & flags) ||
346*150812a8SEvalZero (NRFX_TWIM_FLAG_REPEATED_XFER & flags)) ? false: true;
347*150812a8SEvalZero }
348*150812a8SEvalZero
349*150812a8SEvalZero p_cb->xfer_desc = *p_xfer_desc;
350*150812a8SEvalZero p_cb->repeated = (flags & NRFX_TWIM_FLAG_REPEATED_XFER) ? true : false;
351*150812a8SEvalZero nrf_twim_address_set(p_twim, p_xfer_desc->address);
352*150812a8SEvalZero
353*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
354*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
355*150812a8SEvalZero
356*150812a8SEvalZero twim_list_enable_handle(p_twim, flags);
357*150812a8SEvalZero switch (p_xfer_desc->type)
358*150812a8SEvalZero {
359*150812a8SEvalZero case NRFX_TWIM_XFER_TXTX:
360*150812a8SEvalZero NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_REPEATED_XFER));
361*150812a8SEvalZero NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_HOLD_XFER));
362*150812a8SEvalZero NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER));
363*150812a8SEvalZero if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf))
364*150812a8SEvalZero {
365*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_ADDR;
366*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
367*150812a8SEvalZero __func__,
368*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
369*150812a8SEvalZero return err_code;
370*150812a8SEvalZero }
371*150812a8SEvalZero nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
372*150812a8SEvalZero nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
373*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
374*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
375*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
376*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
377*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
378*150812a8SEvalZero while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
379*150812a8SEvalZero {}
380*150812a8SEvalZero NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED));
381*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
382*150812a8SEvalZero nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
383*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
384*150812a8SEvalZero break;
385*150812a8SEvalZero case NRFX_TWIM_XFER_TXRX:
386*150812a8SEvalZero nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
387*150812a8SEvalZero if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf))
388*150812a8SEvalZero {
389*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_ADDR;
390*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
391*150812a8SEvalZero __func__,
392*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
393*150812a8SEvalZero return err_code;
394*150812a8SEvalZero }
395*150812a8SEvalZero nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
396*150812a8SEvalZero nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK |
397*150812a8SEvalZero NRF_TWIM_SHORT_LASTRX_STOP_MASK);
398*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
399*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
400*150812a8SEvalZero break;
401*150812a8SEvalZero case NRFX_TWIM_XFER_TX:
402*150812a8SEvalZero nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
403*150812a8SEvalZero if (NRFX_TWIM_FLAG_TX_NO_STOP & flags)
404*150812a8SEvalZero {
405*150812a8SEvalZero nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
406*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
407*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
408*150812a8SEvalZero evt_to_wait = NRF_TWIM_EVENT_SUSPENDED;
409*150812a8SEvalZero }
410*150812a8SEvalZero else
411*150812a8SEvalZero {
412*150812a8SEvalZero nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
413*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
414*150812a8SEvalZero }
415*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
416*150812a8SEvalZero break;
417*150812a8SEvalZero case NRFX_TWIM_XFER_RX:
418*150812a8SEvalZero nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
419*150812a8SEvalZero nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK);
420*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
421*150812a8SEvalZero start_task = NRF_TWIM_TASK_STARTRX;
422*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
423*150812a8SEvalZero break;
424*150812a8SEvalZero default:
425*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
426*150812a8SEvalZero break;
427*150812a8SEvalZero }
428*150812a8SEvalZero
429*150812a8SEvalZero if (!(flags & NRFX_TWIM_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRFX_TWIM_XFER_TXTX))
430*150812a8SEvalZero {
431*150812a8SEvalZero nrf_twim_task_trigger(p_twim, start_task);
432*150812a8SEvalZero }
433*150812a8SEvalZero
434*150812a8SEvalZero if (p_cb->handler)
435*150812a8SEvalZero {
436*150812a8SEvalZero if (flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER)
437*150812a8SEvalZero {
438*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK;
439*150812a8SEvalZero }
440*150812a8SEvalZero nrf_twim_int_enable(p_twim, p_cb->int_mask);
441*150812a8SEvalZero
442*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
443*150812a8SEvalZero if ((flags & NRFX_TWIM_FLAG_HOLD_XFER) && ((p_xfer_desc->type == NRFX_TWIM_XFER_TX) ||
444*150812a8SEvalZero (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)))
445*150812a8SEvalZero {
446*150812a8SEvalZero p_cb->flags = flags;
447*150812a8SEvalZero twim_list_enable_handle(p_twim, 0);
448*150812a8SEvalZero p_twim->FREQUENCY = 0;
449*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
450*150812a8SEvalZero nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
451*150812a8SEvalZero }
452*150812a8SEvalZero #endif
453*150812a8SEvalZero }
454*150812a8SEvalZero else
455*150812a8SEvalZero {
456*150812a8SEvalZero while (!nrf_twim_event_check(p_twim, evt_to_wait))
457*150812a8SEvalZero {
458*150812a8SEvalZero if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
459*150812a8SEvalZero {
460*150812a8SEvalZero NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
461*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
462*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
463*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
464*150812a8SEvalZero evt_to_wait = NRF_TWIM_EVENT_STOPPED;
465*150812a8SEvalZero }
466*150812a8SEvalZero }
467*150812a8SEvalZero
468*150812a8SEvalZero uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
469*150812a8SEvalZero
470*150812a8SEvalZero p_cb->busy = false;
471*150812a8SEvalZero
472*150812a8SEvalZero if (errorsrc)
473*150812a8SEvalZero {
474*150812a8SEvalZero err_code = twi_process_error(errorsrc);
475*150812a8SEvalZero }
476*150812a8SEvalZero }
477*150812a8SEvalZero return err_code;
478*150812a8SEvalZero }
479*150812a8SEvalZero
480*150812a8SEvalZero
nrfx_twim_xfer(nrfx_twim_t const * p_instance,nrfx_twim_xfer_desc_t const * p_xfer_desc,uint32_t flags)481*150812a8SEvalZero nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance,
482*150812a8SEvalZero nrfx_twim_xfer_desc_t const * p_xfer_desc,
483*150812a8SEvalZero uint32_t flags)
484*150812a8SEvalZero {
485*150812a8SEvalZero NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx,
486*150812a8SEvalZero p_xfer_desc->primary_length,
487*150812a8SEvalZero p_xfer_desc->secondary_length));
488*150812a8SEvalZero
489*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
490*150812a8SEvalZero twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
491*150812a8SEvalZero
492*150812a8SEvalZero // TXRX and TXTX transfers are supported only in non-blocking mode.
493*150812a8SEvalZero NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)));
494*150812a8SEvalZero NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXTX)));
495*150812a8SEvalZero
496*150812a8SEvalZero NRFX_LOG_INFO("Transfer type: %s.", TRANSFER_TO_STR(p_xfer_desc->type));
497*150812a8SEvalZero NRFX_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.",
498*150812a8SEvalZero p_xfer_desc->primary_length,
499*150812a8SEvalZero p_xfer_desc->secondary_length);
500*150812a8SEvalZero NRFX_LOG_DEBUG("Primary buffer data:");
501*150812a8SEvalZero NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_primary_buf,
502*150812a8SEvalZero p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf[0]));
503*150812a8SEvalZero NRFX_LOG_DEBUG("Secondary buffer data:");
504*150812a8SEvalZero NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_secondary_buf,
505*150812a8SEvalZero p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf[0]));
506*150812a8SEvalZero
507*150812a8SEvalZero err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->p_twim, p_xfer_desc, flags);
508*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
509*150812a8SEvalZero __func__,
510*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
511*150812a8SEvalZero return err_code;
512*150812a8SEvalZero }
513*150812a8SEvalZero
nrfx_twim_tx(nrfx_twim_t const * p_instance,uint8_t address,uint8_t const * p_data,size_t length,bool no_stop)514*150812a8SEvalZero nrfx_err_t nrfx_twim_tx(nrfx_twim_t const * p_instance,
515*150812a8SEvalZero uint8_t address,
516*150812a8SEvalZero uint8_t const * p_data,
517*150812a8SEvalZero size_t length,
518*150812a8SEvalZero bool no_stop)
519*150812a8SEvalZero {
520*150812a8SEvalZero nrfx_twim_xfer_desc_t xfer = NRFX_TWIM_XFER_DESC_TX(address, (uint8_t*)p_data, length);
521*150812a8SEvalZero
522*150812a8SEvalZero return nrfx_twim_xfer(p_instance, &xfer, no_stop ? NRFX_TWIM_FLAG_TX_NO_STOP : 0);
523*150812a8SEvalZero }
524*150812a8SEvalZero
nrfx_twim_rx(nrfx_twim_t const * p_instance,uint8_t address,uint8_t * p_data,size_t length)525*150812a8SEvalZero nrfx_err_t nrfx_twim_rx(nrfx_twim_t const * p_instance,
526*150812a8SEvalZero uint8_t address,
527*150812a8SEvalZero uint8_t * p_data,
528*150812a8SEvalZero size_t length)
529*150812a8SEvalZero {
530*150812a8SEvalZero nrfx_twim_xfer_desc_t xfer = NRFX_TWIM_XFER_DESC_RX(address, p_data, length);
531*150812a8SEvalZero return nrfx_twim_xfer(p_instance, &xfer, 0);
532*150812a8SEvalZero }
533*150812a8SEvalZero
nrfx_twim_start_task_get(nrfx_twim_t const * p_instance,nrfx_twim_xfer_type_t xfer_type)534*150812a8SEvalZero uint32_t nrfx_twim_start_task_get(nrfx_twim_t const * p_instance,
535*150812a8SEvalZero nrfx_twim_xfer_type_t xfer_type)
536*150812a8SEvalZero {
537*150812a8SEvalZero return (uint32_t)nrf_twim_task_address_get(p_instance->p_twim,
538*150812a8SEvalZero (xfer_type != NRFX_TWIM_XFER_RX) ? NRF_TWIM_TASK_STARTTX : NRF_TWIM_TASK_STARTRX);
539*150812a8SEvalZero }
540*150812a8SEvalZero
nrfx_twim_stopped_event_get(nrfx_twim_t const * p_instance)541*150812a8SEvalZero uint32_t nrfx_twim_stopped_event_get(nrfx_twim_t const * p_instance)
542*150812a8SEvalZero {
543*150812a8SEvalZero return (uint32_t)nrf_twim_event_address_get(p_instance->p_twim, NRF_TWIM_EVENT_STOPPED);
544*150812a8SEvalZero }
545*150812a8SEvalZero
twim_irq_handler(NRF_TWIM_Type * p_twim,twim_control_block_t * p_cb)546*150812a8SEvalZero static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb)
547*150812a8SEvalZero {
548*150812a8SEvalZero
549*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
550*150812a8SEvalZero /* Handle only workaround case. Can be used without TWIM handler in IRQs. */
551*150812a8SEvalZero if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
552*150812a8SEvalZero {
553*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
554*150812a8SEvalZero nrf_twim_int_disable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
555*150812a8SEvalZero if (p_twim->FREQUENCY == 0)
556*150812a8SEvalZero {
557*150812a8SEvalZero // Set enable to zero to reset TWIM internal state.
558*150812a8SEvalZero nrf_twim_disable(p_twim);
559*150812a8SEvalZero nrf_twim_enable(p_twim);
560*150812a8SEvalZero
561*150812a8SEvalZero // Set proper frequency.
562*150812a8SEvalZero nrf_twim_frequency_set(p_twim, p_cb->bus_frequency);
563*150812a8SEvalZero twim_list_enable_handle(p_twim, p_cb->flags);
564*150812a8SEvalZero
565*150812a8SEvalZero // Start proper transmission.
566*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
567*150812a8SEvalZero return;
568*150812a8SEvalZero }
569*150812a8SEvalZero }
570*150812a8SEvalZero #endif
571*150812a8SEvalZero
572*150812a8SEvalZero NRFX_ASSERT(p_cb->handler);
573*150812a8SEvalZero
574*150812a8SEvalZero if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
575*150812a8SEvalZero {
576*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
577*150812a8SEvalZero NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
578*150812a8SEvalZero if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
579*150812a8SEvalZero {
580*150812a8SEvalZero nrf_twim_int_disable(p_twim, p_cb->int_mask);
581*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
582*150812a8SEvalZero nrf_twim_int_enable(p_twim, p_cb->int_mask);
583*150812a8SEvalZero
584*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
585*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
586*150812a8SEvalZero return;
587*150812a8SEvalZero }
588*150812a8SEvalZero }
589*150812a8SEvalZero
590*150812a8SEvalZero nrfx_twim_evt_t event;
591*150812a8SEvalZero
592*150812a8SEvalZero if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
593*150812a8SEvalZero {
594*150812a8SEvalZero NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
595*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
596*150812a8SEvalZero event.xfer_desc = p_cb->xfer_desc;
597*150812a8SEvalZero if (p_cb->error)
598*150812a8SEvalZero {
599*150812a8SEvalZero
600*150812a8SEvalZero event.xfer_desc.primary_length = (p_cb->xfer_desc.type == NRFX_TWIM_XFER_RX) ?
601*150812a8SEvalZero nrf_twim_rxd_amount_get(p_twim) : nrf_twim_txd_amount_get(p_twim);
602*150812a8SEvalZero event.xfer_desc.secondary_length = (p_cb->xfer_desc.type == NRFX_TWIM_XFER_TXRX) ?
603*150812a8SEvalZero nrf_twim_rxd_amount_get(p_twim) : nrf_twim_txd_amount_get(p_twim);
604*150812a8SEvalZero
605*150812a8SEvalZero }
606*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
607*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX);
608*150812a8SEvalZero if (!p_cb->repeated || p_cb->error)
609*150812a8SEvalZero {
610*150812a8SEvalZero nrf_twim_shorts_set(p_twim, 0);
611*150812a8SEvalZero p_cb->int_mask = 0;
612*150812a8SEvalZero nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
613*150812a8SEvalZero }
614*150812a8SEvalZero }
615*150812a8SEvalZero else
616*150812a8SEvalZero {
617*150812a8SEvalZero nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
618*150812a8SEvalZero NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED));
619*150812a8SEvalZero if (p_cb->xfer_desc.type == NRFX_TWIM_XFER_TX)
620*150812a8SEvalZero {
621*150812a8SEvalZero event.xfer_desc = p_cb->xfer_desc;
622*150812a8SEvalZero if (!p_cb->repeated)
623*150812a8SEvalZero {
624*150812a8SEvalZero nrf_twim_shorts_set(p_twim, 0);
625*150812a8SEvalZero p_cb->int_mask = 0;
626*150812a8SEvalZero nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
627*150812a8SEvalZero }
628*150812a8SEvalZero }
629*150812a8SEvalZero else
630*150812a8SEvalZero {
631*150812a8SEvalZero nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
632*150812a8SEvalZero p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
633*150812a8SEvalZero nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
634*150812a8SEvalZero nrf_twim_int_enable(p_twim, p_cb->int_mask);
635*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
636*150812a8SEvalZero nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
637*150812a8SEvalZero return;
638*150812a8SEvalZero }
639*150812a8SEvalZero }
640*150812a8SEvalZero
641*150812a8SEvalZero uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
642*150812a8SEvalZero if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK)
643*150812a8SEvalZero {
644*150812a8SEvalZero event.type = NRFX_TWIM_EVT_ADDRESS_NACK;
645*150812a8SEvalZero NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_ADDRESS_NACK));
646*150812a8SEvalZero }
647*150812a8SEvalZero else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK)
648*150812a8SEvalZero {
649*150812a8SEvalZero event.type = NRFX_TWIM_EVT_DATA_NACK;
650*150812a8SEvalZero NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DATA_NACK));
651*150812a8SEvalZero }
652*150812a8SEvalZero else
653*150812a8SEvalZero {
654*150812a8SEvalZero event.type = NRFX_TWIM_EVT_DONE;
655*150812a8SEvalZero NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DONE));
656*150812a8SEvalZero }
657*150812a8SEvalZero
658*150812a8SEvalZero if (!p_cb->repeated)
659*150812a8SEvalZero {
660*150812a8SEvalZero p_cb->busy = false;
661*150812a8SEvalZero }
662*150812a8SEvalZero p_cb->handler(&event, p_cb->p_context);
663*150812a8SEvalZero }
664*150812a8SEvalZero
665*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM0_ENABLED)
nrfx_twim_0_irq_handler(void)666*150812a8SEvalZero void nrfx_twim_0_irq_handler(void)
667*150812a8SEvalZero {
668*150812a8SEvalZero twim_irq_handler(NRF_TWIM0, &m_cb[NRFX_TWIM0_INST_IDX]);
669*150812a8SEvalZero }
670*150812a8SEvalZero #endif
671*150812a8SEvalZero
672*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM1_ENABLED)
nrfx_twim_1_irq_handler(void)673*150812a8SEvalZero void nrfx_twim_1_irq_handler(void)
674*150812a8SEvalZero {
675*150812a8SEvalZero twim_irq_handler(NRF_TWIM1, &m_cb[NRFX_TWIM1_INST_IDX]);
676*150812a8SEvalZero }
677*150812a8SEvalZero #endif
678*150812a8SEvalZero
679*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM2_ENABLED)
nrfx_twim_2_irq_handler(void)680*150812a8SEvalZero void nrfx_twim_2_irq_handler(void)
681*150812a8SEvalZero {
682*150812a8SEvalZero twim_irq_handler(NRF_TWIM2, &m_cb[NRFX_TWIM2_INST_IDX]);
683*150812a8SEvalZero }
684*150812a8SEvalZero #endif
685*150812a8SEvalZero
686*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIM3_ENABLED)
nrfx_twim_3_irq_handler(void)687*150812a8SEvalZero void nrfx_twim_3_irq_handler(void)
688*150812a8SEvalZero {
689*150812a8SEvalZero twim_irq_handler(NRF_TWIM3, &m_cb[NRFX_TWIM3_INST_IDX]);
690*150812a8SEvalZero }
691*150812a8SEvalZero #endif
692*150812a8SEvalZero
693*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_TWIM_ENABLED)
694