xref: /nrf52832-nimble/nordic/nrfx/drivers/src/nrfx_twim.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
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