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_TWIS_ENABLED)
35*150812a8SEvalZero
36*150812a8SEvalZero #if !(NRFX_CHECK(NRFX_TWIS0_ENABLED) || \
37*150812a8SEvalZero NRFX_CHECK(NRFX_TWIS1_ENABLED) || \
38*150812a8SEvalZero NRFX_CHECK(NRFX_TWIS2_ENABLED) || \
39*150812a8SEvalZero NRFX_CHECK(NRFX_TWIS3_ENABLED))
40*150812a8SEvalZero #error "No enabled TWIS instances. Check <nrfx_config.h>."
41*150812a8SEvalZero #endif
42*150812a8SEvalZero
43*150812a8SEvalZero #include <nrfx_twis.h>
44*150812a8SEvalZero #include "prs/nrfx_prs.h"
45*150812a8SEvalZero
46*150812a8SEvalZero #define NRFX_LOG_MODULE TWIS
47*150812a8SEvalZero #include <nrfx_log.h>
48*150812a8SEvalZero
49*150812a8SEvalZero #define EVT_TO_STR(event) \
50*150812a8SEvalZero (event == NRF_TWIS_EVENT_STOPPED ? "NRF_TWIS_EVENT_STOPPED" : \
51*150812a8SEvalZero (event == NRF_TWIS_EVENT_ERROR ? "NRF_TWIS_EVENT_ERROR" : \
52*150812a8SEvalZero (event == NRF_TWIS_EVENT_RXSTARTED ? "NRF_TWIS_EVENT_RXSTARTED" : \
53*150812a8SEvalZero (event == NRF_TWIS_EVENT_TXSTARTED ? "NRF_TWIS_EVENT_TXSTARTED" : \
54*150812a8SEvalZero (event == NRF_TWIS_EVENT_WRITE ? "NRF_TWIS_EVENT_WRITE" : \
55*150812a8SEvalZero (event == NRF_TWIS_EVENT_READ ? "NRF_TWIS_EVENT_READ" : \
56*150812a8SEvalZero "UNKNOWN EVENT"))))))
57*150812a8SEvalZero
58*150812a8SEvalZero
59*150812a8SEvalZero /**
60*150812a8SEvalZero * @brief Actual state of internal state machine
61*150812a8SEvalZero *
62*150812a8SEvalZero * Current substate of powered on state.
63*150812a8SEvalZero */
64*150812a8SEvalZero typedef enum
65*150812a8SEvalZero {
66*150812a8SEvalZero NRFX_TWIS_SUBSTATE_IDLE, ///< No ongoing transmission
67*150812a8SEvalZero NRFX_TWIS_SUBSTATE_READ_WAITING, ///< Read request received, waiting for data
68*150812a8SEvalZero NRFX_TWIS_SUBSTATE_READ_PENDING, ///< Reading is actually pending (data sending)
69*150812a8SEvalZero NRFX_TWIS_SUBSTATE_WRITE_WAITING, ///< Write request received, waiting for data buffer
70*150812a8SEvalZero NRFX_TWIS_SUBSTATE_WRITE_PENDING, ///< Writing is actually pending (data receiving)
71*150812a8SEvalZero } nrfx_twis_substate_t;
72*150812a8SEvalZero
73*150812a8SEvalZero // Control block - driver instance local data.
74*150812a8SEvalZero typedef struct
75*150812a8SEvalZero {
76*150812a8SEvalZero nrfx_twis_event_handler_t ev_handler;
77*150812a8SEvalZero // Internal copy of hardware errors flags merged with specific internal
78*150812a8SEvalZero // driver errors flags.
79*150812a8SEvalZero // This value can be changed in the interrupt and cleared in the main program.
80*150812a8SEvalZero // Always use Atomic load-store when updating this value in main loop.
81*150812a8SEvalZero volatile uint32_t error;
82*150812a8SEvalZero nrfx_drv_state_t state;
83*150812a8SEvalZero volatile nrfx_twis_substate_t substate;
84*150812a8SEvalZero
85*150812a8SEvalZero volatile bool semaphore;
86*150812a8SEvalZero } twis_control_block_t;
87*150812a8SEvalZero static twis_control_block_t m_cb[NRFX_TWIS_ENABLED_COUNT];
88*150812a8SEvalZero
89*150812a8SEvalZero /**
90*150812a8SEvalZero * @brief Used interrupts mask
91*150812a8SEvalZero *
92*150812a8SEvalZero * Mask for all interrupts used by this library
93*150812a8SEvalZero */
94*150812a8SEvalZero static const uint32_t m_used_ints_mask = NRF_TWIS_INT_STOPPED_MASK |
95*150812a8SEvalZero NRF_TWIS_INT_ERROR_MASK |
96*150812a8SEvalZero NRF_TWIS_INT_RXSTARTED_MASK |
97*150812a8SEvalZero NRF_TWIS_INT_TXSTARTED_MASK |
98*150812a8SEvalZero NRF_TWIS_INT_WRITE_MASK |
99*150812a8SEvalZero NRF_TWIS_INT_READ_MASK;
100*150812a8SEvalZero
101*150812a8SEvalZero /**
102*150812a8SEvalZero * @brief Clear all events
103*150812a8SEvalZero *
104*150812a8SEvalZero * Function clears all actually pending events
105*150812a8SEvalZero */
nrfx_twis_clear_all_events(NRF_TWIS_Type * const p_reg)106*150812a8SEvalZero static void nrfx_twis_clear_all_events(NRF_TWIS_Type * const p_reg)
107*150812a8SEvalZero {
108*150812a8SEvalZero /* Clear all events */
109*150812a8SEvalZero nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_STOPPED);
110*150812a8SEvalZero nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_ERROR);
111*150812a8SEvalZero nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_RXSTARTED);
112*150812a8SEvalZero nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_TXSTARTED);
113*150812a8SEvalZero nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_WRITE);
114*150812a8SEvalZero nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_READ);
115*150812a8SEvalZero }
116*150812a8SEvalZero
117*150812a8SEvalZero /**
118*150812a8SEvalZero * @brief Reset all the registers to known state
119*150812a8SEvalZero *
120*150812a8SEvalZero * This function clears all registers that requires it to known state.
121*150812a8SEvalZero * TWIS is left disabled after this function.
122*150812a8SEvalZero * All events are cleared.
123*150812a8SEvalZero * @param[out] p_reg TWIS to reset register address
124*150812a8SEvalZero */
nrfx_twis_swreset(NRF_TWIS_Type * p_reg)125*150812a8SEvalZero static inline void nrfx_twis_swreset(NRF_TWIS_Type * p_reg)
126*150812a8SEvalZero {
127*150812a8SEvalZero /* Disable TWIS */
128*150812a8SEvalZero nrf_twis_disable(p_reg);
129*150812a8SEvalZero
130*150812a8SEvalZero /* Disconnect pins */
131*150812a8SEvalZero nrf_twis_pins_set(p_reg, ~0U, ~0U);
132*150812a8SEvalZero
133*150812a8SEvalZero /* Disable interrupt global for the instance */
134*150812a8SEvalZero NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
135*150812a8SEvalZero
136*150812a8SEvalZero /* Disable interrupts */
137*150812a8SEvalZero nrf_twis_int_disable(p_reg, ~0U);
138*150812a8SEvalZero }
139*150812a8SEvalZero
140*150812a8SEvalZero /**
141*150812a8SEvalZero * @brief Configure pin
142*150812a8SEvalZero *
143*150812a8SEvalZero * Function configures selected for work as SDA or SCL.
144*150812a8SEvalZero * @param pin Pin number to configure
145*150812a8SEvalZero */
nrfx_twis_config_pin(uint32_t pin,nrf_gpio_pin_pull_t pull)146*150812a8SEvalZero static inline void nrfx_twis_config_pin(uint32_t pin, nrf_gpio_pin_pull_t pull)
147*150812a8SEvalZero {
148*150812a8SEvalZero nrf_gpio_cfg(pin,
149*150812a8SEvalZero NRF_GPIO_PIN_DIR_INPUT,
150*150812a8SEvalZero NRF_GPIO_PIN_INPUT_DISCONNECT,
151*150812a8SEvalZero pull,
152*150812a8SEvalZero NRF_GPIO_PIN_S0D1,
153*150812a8SEvalZero NRF_GPIO_PIN_NOSENSE);
154*150812a8SEvalZero }
155*150812a8SEvalZero
156*150812a8SEvalZero /**
157*150812a8SEvalZero * @brief Auxiliary function for getting event state on right bit possition
158*150812a8SEvalZero *
159*150812a8SEvalZero * This function calls @ref nrf_twis_event_get function but the the result
160*150812a8SEvalZero * is shifted to match INTEN register scheme.
161*150812a8SEvalZero *
162*150812a8SEvalZero * @param[in,out] p_reg TWIS to read event from
163*150812a8SEvalZero * @param ev Event code
164*150812a8SEvalZero *
165*150812a8SEvalZero * @return Selected event state shifted by @ref nrfx_event_to_bitpos
166*150812a8SEvalZero *
167*150812a8SEvalZero * @sa nrf_twis_event_get
168*150812a8SEvalZero * @sa nrfx_event_to_bitpos
169*150812a8SEvalZero */
nrfx_twis_event_bit_get(NRF_TWIS_Type * p_reg,nrf_twis_event_t ev)170*150812a8SEvalZero static inline uint32_t nrfx_twis_event_bit_get(NRF_TWIS_Type * p_reg,
171*150812a8SEvalZero nrf_twis_event_t ev)
172*150812a8SEvalZero {
173*150812a8SEvalZero return (uint32_t)nrf_twis_event_get_and_clear(p_reg, ev) << nrfx_event_to_bitpos(ev);
174*150812a8SEvalZero }
175*150812a8SEvalZero
176*150812a8SEvalZero /**
177*150812a8SEvalZero * @brief Auxiliary function for checking event bit inside given flags value
178*150812a8SEvalZero *
179*150812a8SEvalZero * Function used here to check presence of the event inside given flags value.
180*150812a8SEvalZero * It transforms given event to bit possition and then checks if in given variable it is cleared.
181*150812a8SEvalZero *
182*150812a8SEvalZero * @param flags Flags to test
183*150812a8SEvalZero * @param ev Event code
184*150812a8SEvalZero *
185*150812a8SEvalZero * @retval true Flag for selected event is set
186*150812a8SEvalZero * @retval false Flag for selected event is cleared
187*150812a8SEvalZero */
nrfx_twis_check_bit(uint32_t flags,nrf_twis_event_t ev)188*150812a8SEvalZero static inline bool nrfx_twis_check_bit(uint32_t flags,
189*150812a8SEvalZero nrf_twis_event_t ev)
190*150812a8SEvalZero {
191*150812a8SEvalZero return 0 != (flags & (1U << nrfx_event_to_bitpos(ev)));
192*150812a8SEvalZero }
193*150812a8SEvalZero
194*150812a8SEvalZero /**
195*150812a8SEvalZero * @brief Auxiliary function for clearing event bit in given flags value
196*150812a8SEvalZero *
197*150812a8SEvalZero * Function used to clear selected event bit.
198*150812a8SEvalZero *
199*150812a8SEvalZero * @param flags Flags to process
200*150812a8SEvalZero * @param ev Event code to clear
201*150812a8SEvalZero *
202*150812a8SEvalZero * @return Value @em flags with cleared event bit that matches given @em ev
203*150812a8SEvalZero */
nrfx_twis_clear_bit(uint32_t flags,nrf_twis_event_t ev)204*150812a8SEvalZero static inline uint32_t nrfx_twis_clear_bit(uint32_t flags,
205*150812a8SEvalZero nrf_twis_event_t ev)
206*150812a8SEvalZero {
207*150812a8SEvalZero return flags & ~(1U << nrfx_event_to_bitpos(ev));
208*150812a8SEvalZero }
209*150812a8SEvalZero
call_event_handler(twis_control_block_t const * p_cb,nrfx_twis_evt_t const * p_evt)210*150812a8SEvalZero static void call_event_handler(twis_control_block_t const * p_cb,
211*150812a8SEvalZero nrfx_twis_evt_t const * p_evt)
212*150812a8SEvalZero {
213*150812a8SEvalZero nrfx_twis_event_handler_t handler = p_cb->ev_handler;
214*150812a8SEvalZero if (handler != NULL)
215*150812a8SEvalZero {
216*150812a8SEvalZero handler(p_evt);
217*150812a8SEvalZero }
218*150812a8SEvalZero }
219*150812a8SEvalZero
220*150812a8SEvalZero /**
221*150812a8SEvalZero * @brief Auxiliary function for error processing
222*150812a8SEvalZero *
223*150812a8SEvalZero * Function called when in current substate the event apears and it cannot be processed.
224*150812a8SEvalZero * It should be called also on ERROR event.
225*150812a8SEvalZero * If given @em error parameter has zero value the @ref NRFX_TWIS_ERROR_UNEXPECTED_EVENT
226*150812a8SEvalZero * would be set.
227*150812a8SEvalZero *
228*150812a8SEvalZero * @param p_cb Pointer to the driver instance control block.
229*150812a8SEvalZero * @param evt What error event raport to event handler
230*150812a8SEvalZero * @param error Error flags
231*150812a8SEvalZero */
nrfx_twis_process_error(twis_control_block_t * p_cb,nrfx_twis_evt_type_t evt,uint32_t error)232*150812a8SEvalZero static inline void nrfx_twis_process_error(twis_control_block_t * p_cb,
233*150812a8SEvalZero nrfx_twis_evt_type_t evt,
234*150812a8SEvalZero uint32_t error)
235*150812a8SEvalZero {
236*150812a8SEvalZero if (0 == error)
237*150812a8SEvalZero {
238*150812a8SEvalZero error = NRFX_TWIS_ERROR_UNEXPECTED_EVENT;
239*150812a8SEvalZero }
240*150812a8SEvalZero nrfx_twis_evt_t evdata;
241*150812a8SEvalZero evdata.type = evt;
242*150812a8SEvalZero evdata.data.error = error;
243*150812a8SEvalZero
244*150812a8SEvalZero p_cb->error |= error;
245*150812a8SEvalZero
246*150812a8SEvalZero call_event_handler(p_cb, &evdata);
247*150812a8SEvalZero }
248*150812a8SEvalZero
nrfx_twis_state_machine(NRF_TWIS_Type * p_reg,twis_control_block_t * p_cb)249*150812a8SEvalZero static void nrfx_twis_state_machine(NRF_TWIS_Type * p_reg,
250*150812a8SEvalZero twis_control_block_t * p_cb)
251*150812a8SEvalZero {
252*150812a8SEvalZero if (!NRFX_TWIS_NO_SYNC_MODE)
253*150812a8SEvalZero {
254*150812a8SEvalZero /* Exclude parallel processing of this function */
255*150812a8SEvalZero if (p_cb->semaphore)
256*150812a8SEvalZero {
257*150812a8SEvalZero return;
258*150812a8SEvalZero }
259*150812a8SEvalZero p_cb->semaphore = 1;
260*150812a8SEvalZero }
261*150812a8SEvalZero
262*150812a8SEvalZero /* Event data structure to be passed into event handler */
263*150812a8SEvalZero nrfx_twis_evt_t evdata;
264*150812a8SEvalZero /* Current substate copy */
265*150812a8SEvalZero nrfx_twis_substate_t substate = p_cb->substate;
266*150812a8SEvalZero /* Event flags */
267*150812a8SEvalZero uint32_t ev = 0;
268*150812a8SEvalZero
269*150812a8SEvalZero /* Get all events */
270*150812a8SEvalZero ev |= nrfx_twis_event_bit_get(p_reg, NRF_TWIS_EVENT_STOPPED);
271*150812a8SEvalZero ev |= nrfx_twis_event_bit_get(p_reg, NRF_TWIS_EVENT_ERROR);
272*150812a8SEvalZero ev |= nrfx_twis_event_bit_get(p_reg, NRF_TWIS_EVENT_RXSTARTED);
273*150812a8SEvalZero ev |= nrfx_twis_event_bit_get(p_reg, NRF_TWIS_EVENT_TXSTARTED);
274*150812a8SEvalZero ev |= nrfx_twis_event_bit_get(p_reg, NRF_TWIS_EVENT_WRITE);
275*150812a8SEvalZero ev |= nrfx_twis_event_bit_get(p_reg, NRF_TWIS_EVENT_READ);
276*150812a8SEvalZero
277*150812a8SEvalZero /* State machine */
278*150812a8SEvalZero while (0 != ev)
279*150812a8SEvalZero {
280*150812a8SEvalZero switch (substate)
281*150812a8SEvalZero {
282*150812a8SEvalZero case NRFX_TWIS_SUBSTATE_IDLE:
283*150812a8SEvalZero if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED))
284*150812a8SEvalZero {
285*150812a8SEvalZero /* Stopped event is always allowed in IDLE state - just ignore */
286*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_STOPPED);
287*150812a8SEvalZero }
288*150812a8SEvalZero else if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_READ))
289*150812a8SEvalZero {
290*150812a8SEvalZero evdata.type = NRFX_TWIS_EVT_READ_REQ;
291*150812a8SEvalZero if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_TXSTARTED))
292*150812a8SEvalZero {
293*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_READ_PENDING;
294*150812a8SEvalZero evdata.data.buf_req = false;
295*150812a8SEvalZero }
296*150812a8SEvalZero else
297*150812a8SEvalZero {
298*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_READ_WAITING;
299*150812a8SEvalZero evdata.data.buf_req = true;
300*150812a8SEvalZero }
301*150812a8SEvalZero call_event_handler(p_cb, &evdata);
302*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_READ);
303*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_TXSTARTED);
304*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_WRITE);
305*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_RXSTARTED);
306*150812a8SEvalZero }
307*150812a8SEvalZero else if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE))
308*150812a8SEvalZero {
309*150812a8SEvalZero evdata.type = NRFX_TWIS_EVT_WRITE_REQ;
310*150812a8SEvalZero if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_RXSTARTED))
311*150812a8SEvalZero {
312*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_WRITE_PENDING;
313*150812a8SEvalZero evdata.data.buf_req = false;
314*150812a8SEvalZero }
315*150812a8SEvalZero else
316*150812a8SEvalZero {
317*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_WRITE_WAITING;
318*150812a8SEvalZero evdata.data.buf_req = true;
319*150812a8SEvalZero }
320*150812a8SEvalZero call_event_handler(p_cb, &evdata);
321*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_READ);
322*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_TXSTARTED);
323*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_WRITE);
324*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_RXSTARTED);
325*150812a8SEvalZero }
326*150812a8SEvalZero else
327*150812a8SEvalZero {
328*150812a8SEvalZero nrfx_twis_process_error(p_cb,
329*150812a8SEvalZero NRFX_TWIS_EVT_GENERAL_ERROR,
330*150812a8SEvalZero nrf_twis_error_source_get_and_clear(p_reg));
331*150812a8SEvalZero ev = 0;
332*150812a8SEvalZero }
333*150812a8SEvalZero break;
334*150812a8SEvalZero case NRFX_TWIS_SUBSTATE_READ_WAITING:
335*150812a8SEvalZero if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_TXSTARTED) ||
336*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE) ||
337*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_READ) ||
338*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED))
339*150812a8SEvalZero {
340*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_READ_PENDING;
341*150812a8SEvalZero /* Any other bits requires further processing in PENDING substate */
342*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_TXSTARTED);
343*150812a8SEvalZero }
344*150812a8SEvalZero else
345*150812a8SEvalZero {
346*150812a8SEvalZero nrfx_twis_process_error(p_cb,
347*150812a8SEvalZero NRFX_TWIS_EVT_READ_ERROR,
348*150812a8SEvalZero nrf_twis_error_source_get_and_clear(p_reg));
349*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_IDLE;
350*150812a8SEvalZero ev = 0;
351*150812a8SEvalZero }
352*150812a8SEvalZero break;
353*150812a8SEvalZero case NRFX_TWIS_SUBSTATE_READ_PENDING:
354*150812a8SEvalZero if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE) ||
355*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_READ) ||
356*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED))
357*150812a8SEvalZero {
358*150812a8SEvalZero evdata.type = NRFX_TWIS_EVT_READ_DONE;
359*150812a8SEvalZero evdata.data.tx_amount = nrf_twis_tx_amount_get(p_reg);
360*150812a8SEvalZero NRFX_LOG_INFO("Transfer tx_len:%d", evdata.data.tx_amount);
361*150812a8SEvalZero NRFX_LOG_DEBUG("Tx data:");
362*150812a8SEvalZero NRFX_LOG_HEXDUMP_DEBUG((uint8_t const *)p_reg->TXD.PTR,
363*150812a8SEvalZero evdata.data.tx_amount * sizeof(uint8_t));
364*150812a8SEvalZero call_event_handler(p_cb, &evdata);
365*150812a8SEvalZero /* Go to idle and repeat the state machine if READ or WRITE events detected.
366*150812a8SEvalZero * This time READ or WRITE would be started */
367*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_IDLE;
368*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_STOPPED);
369*150812a8SEvalZero }
370*150812a8SEvalZero else
371*150812a8SEvalZero {
372*150812a8SEvalZero nrfx_twis_process_error(p_cb,
373*150812a8SEvalZero NRFX_TWIS_EVT_READ_ERROR,
374*150812a8SEvalZero nrf_twis_error_source_get_and_clear(p_reg));
375*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_IDLE;
376*150812a8SEvalZero ev = 0;
377*150812a8SEvalZero }
378*150812a8SEvalZero break;
379*150812a8SEvalZero case NRFX_TWIS_SUBSTATE_WRITE_WAITING:
380*150812a8SEvalZero if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_RXSTARTED) ||
381*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE) ||
382*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_READ) ||
383*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED))
384*150812a8SEvalZero {
385*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_WRITE_PENDING;
386*150812a8SEvalZero /* Any other bits requires further processing in PENDING substate */
387*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_RXSTARTED);
388*150812a8SEvalZero }
389*150812a8SEvalZero else
390*150812a8SEvalZero {
391*150812a8SEvalZero nrfx_twis_process_error(p_cb,
392*150812a8SEvalZero NRFX_TWIS_EVT_WRITE_ERROR,
393*150812a8SEvalZero nrf_twis_error_source_get_and_clear(p_reg));
394*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_IDLE;
395*150812a8SEvalZero ev = 0;
396*150812a8SEvalZero }
397*150812a8SEvalZero break;
398*150812a8SEvalZero case NRFX_TWIS_SUBSTATE_WRITE_PENDING:
399*150812a8SEvalZero if (nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE) ||
400*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_READ) ||
401*150812a8SEvalZero nrfx_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED))
402*150812a8SEvalZero {
403*150812a8SEvalZero evdata.type = NRFX_TWIS_EVT_WRITE_DONE;
404*150812a8SEvalZero evdata.data.rx_amount = nrf_twis_rx_amount_get(p_reg);
405*150812a8SEvalZero call_event_handler(p_cb, &evdata);
406*150812a8SEvalZero /* Go to idle and repeat the state machine if READ or WRITE events detected.
407*150812a8SEvalZero * This time READ or WRITE would be started */
408*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_IDLE;
409*150812a8SEvalZero ev = nrfx_twis_clear_bit(ev, NRF_TWIS_EVENT_STOPPED);
410*150812a8SEvalZero }
411*150812a8SEvalZero else
412*150812a8SEvalZero {
413*150812a8SEvalZero nrfx_twis_process_error(p_cb,
414*150812a8SEvalZero NRFX_TWIS_EVT_WRITE_ERROR,
415*150812a8SEvalZero nrf_twis_error_source_get_and_clear(p_reg));
416*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_IDLE;
417*150812a8SEvalZero ev = 0;
418*150812a8SEvalZero }
419*150812a8SEvalZero break;
420*150812a8SEvalZero default:
421*150812a8SEvalZero substate = NRFX_TWIS_SUBSTATE_IDLE;
422*150812a8SEvalZero /* Do not clear any events and repeat the machine */
423*150812a8SEvalZero break;
424*150812a8SEvalZero }
425*150812a8SEvalZero }
426*150812a8SEvalZero
427*150812a8SEvalZero p_cb->substate = substate;
428*150812a8SEvalZero if (!NRFX_TWIS_NO_SYNC_MODE)
429*150812a8SEvalZero {
430*150812a8SEvalZero p_cb->semaphore = 0;
431*150812a8SEvalZero }
432*150812a8SEvalZero }
433*150812a8SEvalZero
434*150812a8SEvalZero
nrfx_twis_preprocess_status(nrfx_twis_t const * p_instance)435*150812a8SEvalZero static inline void nrfx_twis_preprocess_status(nrfx_twis_t const * p_instance)
436*150812a8SEvalZero {
437*150812a8SEvalZero if (!NRFX_TWIS_NO_SYNC_MODE)
438*150812a8SEvalZero {
439*150812a8SEvalZero NRF_TWIS_Type * p_reg = p_instance->p_reg;
440*150812a8SEvalZero twis_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
441*150812a8SEvalZero if (NULL == p_cb->ev_handler)
442*150812a8SEvalZero {
443*150812a8SEvalZero nrfx_twis_state_machine(p_reg, p_cb);
444*150812a8SEvalZero }
445*150812a8SEvalZero }
446*150812a8SEvalZero }
447*150812a8SEvalZero
448*150812a8SEvalZero
449*150812a8SEvalZero /* -------------------------------------------------------------------------
450*150812a8SEvalZero * Implementation of interface functions
451*150812a8SEvalZero *
452*150812a8SEvalZero */
453*150812a8SEvalZero
454*150812a8SEvalZero
nrfx_twis_init(nrfx_twis_t const * p_instance,nrfx_twis_config_t const * p_config,nrfx_twis_event_handler_t event_handler)455*150812a8SEvalZero nrfx_err_t nrfx_twis_init(nrfx_twis_t const * p_instance,
456*150812a8SEvalZero nrfx_twis_config_t const * p_config,
457*150812a8SEvalZero nrfx_twis_event_handler_t event_handler)
458*150812a8SEvalZero {
459*150812a8SEvalZero NRFX_ASSERT(p_config);
460*150812a8SEvalZero NRFX_ASSERT(p_config->scl != p_config->sda);
461*150812a8SEvalZero nrfx_err_t err_code;
462*150812a8SEvalZero
463*150812a8SEvalZero NRF_TWIS_Type * p_reg = p_instance->p_reg;
464*150812a8SEvalZero twis_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
465*150812a8SEvalZero
466*150812a8SEvalZero if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
467*150812a8SEvalZero {
468*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
469*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
470*150812a8SEvalZero __func__,
471*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
472*150812a8SEvalZero return err_code;
473*150812a8SEvalZero }
474*150812a8SEvalZero
475*150812a8SEvalZero #if NRFX_CHECK(NRFX_PRS_ENABLED)
476*150812a8SEvalZero static nrfx_irq_handler_t const irq_handlers[NRFX_TWIS_ENABLED_COUNT] = {
477*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS0_ENABLED)
478*150812a8SEvalZero nrfx_twis_0_irq_handler,
479*150812a8SEvalZero #endif
480*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS1_ENABLED)
481*150812a8SEvalZero nrfx_twis_1_irq_handler,
482*150812a8SEvalZero #endif
483*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS2_ENABLED)
484*150812a8SEvalZero nrfx_twis_2_irq_handler,
485*150812a8SEvalZero #endif
486*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS3_ENABLED)
487*150812a8SEvalZero nrfx_twis_3_irq_handler,
488*150812a8SEvalZero #endif
489*150812a8SEvalZero };
490*150812a8SEvalZero if (nrfx_prs_acquire(p_reg,
491*150812a8SEvalZero irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
492*150812a8SEvalZero {
493*150812a8SEvalZero err_code = NRFX_ERROR_BUSY;
494*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
495*150812a8SEvalZero __func__,
496*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
497*150812a8SEvalZero return err_code;
498*150812a8SEvalZero }
499*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
500*150812a8SEvalZero
501*150812a8SEvalZero if (!NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY)
502*150812a8SEvalZero {
503*150812a8SEvalZero nrfx_twis_swreset(p_reg);
504*150812a8SEvalZero }
505*150812a8SEvalZero
506*150812a8SEvalZero nrfx_twis_config_pin(p_config->scl, p_config->scl_pull);
507*150812a8SEvalZero nrfx_twis_config_pin(p_config->sda, p_config->sda_pull);
508*150812a8SEvalZero
509*150812a8SEvalZero nrf_twis_config_addr_mask_t addr_mask = (nrf_twis_config_addr_mask_t)0;
510*150812a8SEvalZero if (0 == (p_config->addr[0] | p_config->addr[1]))
511*150812a8SEvalZero {
512*150812a8SEvalZero addr_mask = NRF_TWIS_CONFIG_ADDRESS0_MASK;
513*150812a8SEvalZero }
514*150812a8SEvalZero else
515*150812a8SEvalZero {
516*150812a8SEvalZero if (0 != p_config->addr[0])
517*150812a8SEvalZero {
518*150812a8SEvalZero addr_mask |= NRF_TWIS_CONFIG_ADDRESS0_MASK;
519*150812a8SEvalZero }
520*150812a8SEvalZero if (0 != p_config->addr[1])
521*150812a8SEvalZero {
522*150812a8SEvalZero addr_mask |= NRF_TWIS_CONFIG_ADDRESS1_MASK;
523*150812a8SEvalZero }
524*150812a8SEvalZero }
525*150812a8SEvalZero
526*150812a8SEvalZero /* Peripheral interrupt configure
527*150812a8SEvalZero * (note - interrupts still needs to be configured in INTEN register.
528*150812a8SEvalZero * This is done in enable function) */
529*150812a8SEvalZero NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg),
530*150812a8SEvalZero p_config->interrupt_priority);
531*150812a8SEvalZero NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
532*150812a8SEvalZero
533*150812a8SEvalZero /* Configure */
534*150812a8SEvalZero nrf_twis_pins_set (p_reg, p_config->scl, p_config->sda);
535*150812a8SEvalZero nrf_twis_address_set (p_reg, 0, p_config->addr[0]);
536*150812a8SEvalZero nrf_twis_address_set (p_reg, 1, p_config->addr[1]);
537*150812a8SEvalZero nrf_twis_config_address_set(p_reg, addr_mask);
538*150812a8SEvalZero
539*150812a8SEvalZero /* Clear semaphore */
540*150812a8SEvalZero if (!NRFX_TWIS_NO_SYNC_MODE)
541*150812a8SEvalZero {
542*150812a8SEvalZero p_cb->semaphore = 0;
543*150812a8SEvalZero }
544*150812a8SEvalZero /* Set internal instance variables */
545*150812a8SEvalZero p_cb->substate = NRFX_TWIS_SUBSTATE_IDLE;
546*150812a8SEvalZero p_cb->ev_handler = event_handler;
547*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_INITIALIZED;
548*150812a8SEvalZero err_code = NRFX_SUCCESS;
549*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
550*150812a8SEvalZero return err_code;
551*150812a8SEvalZero }
552*150812a8SEvalZero
553*150812a8SEvalZero
nrfx_twis_uninit(nrfx_twis_t const * p_instance)554*150812a8SEvalZero void nrfx_twis_uninit(nrfx_twis_t const * p_instance)
555*150812a8SEvalZero {
556*150812a8SEvalZero NRF_TWIS_Type * p_reg = p_instance->p_reg;
557*150812a8SEvalZero twis_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
558*150812a8SEvalZero NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
559*150812a8SEvalZero
560*150812a8SEvalZero TWIS_PSEL_Type psel = p_reg->PSEL;
561*150812a8SEvalZero
562*150812a8SEvalZero nrfx_twis_swreset(p_reg);
563*150812a8SEvalZero
564*150812a8SEvalZero /* Clear pins state if */
565*150812a8SEvalZero if (!(TWIS_PSEL_SCL_CONNECT_Msk & psel.SCL))
566*150812a8SEvalZero {
567*150812a8SEvalZero nrf_gpio_cfg_default(psel.SCL);
568*150812a8SEvalZero }
569*150812a8SEvalZero if (!(TWIS_PSEL_SDA_CONNECT_Msk & psel.SDA))
570*150812a8SEvalZero {
571*150812a8SEvalZero nrf_gpio_cfg_default(psel.SDA);
572*150812a8SEvalZero }
573*150812a8SEvalZero
574*150812a8SEvalZero #if NRFX_CHECK(NRFX_PRS_ENABLED)
575*150812a8SEvalZero nrfx_prs_release(p_reg);
576*150812a8SEvalZero #endif
577*150812a8SEvalZero
578*150812a8SEvalZero /* Clear variables */
579*150812a8SEvalZero p_cb->ev_handler = NULL;
580*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
581*150812a8SEvalZero }
582*150812a8SEvalZero
583*150812a8SEvalZero
nrfx_twis_enable(nrfx_twis_t const * p_instance)584*150812a8SEvalZero void nrfx_twis_enable(nrfx_twis_t const * p_instance)
585*150812a8SEvalZero {
586*150812a8SEvalZero NRF_TWIS_Type * p_reg = p_instance->p_reg;
587*150812a8SEvalZero twis_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
588*150812a8SEvalZero NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
589*150812a8SEvalZero
590*150812a8SEvalZero nrfx_twis_clear_all_events(p_reg);
591*150812a8SEvalZero
592*150812a8SEvalZero /* Enable interrupts */
593*150812a8SEvalZero if (NULL != p_cb->ev_handler)
594*150812a8SEvalZero {
595*150812a8SEvalZero nrf_twis_int_enable(p_reg, m_used_ints_mask);
596*150812a8SEvalZero }
597*150812a8SEvalZero
598*150812a8SEvalZero nrf_twis_enable(p_reg);
599*150812a8SEvalZero p_cb->error = 0;
600*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_POWERED_ON;
601*150812a8SEvalZero p_cb->substate = NRFX_TWIS_SUBSTATE_IDLE;
602*150812a8SEvalZero }
603*150812a8SEvalZero
604*150812a8SEvalZero
nrfx_twis_disable(nrfx_twis_t const * p_instance)605*150812a8SEvalZero void nrfx_twis_disable(nrfx_twis_t const * p_instance)
606*150812a8SEvalZero {
607*150812a8SEvalZero NRF_TWIS_Type * p_reg = p_instance->p_reg;
608*150812a8SEvalZero twis_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
609*150812a8SEvalZero NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
610*150812a8SEvalZero
611*150812a8SEvalZero nrf_twis_int_disable(p_reg, m_used_ints_mask);
612*150812a8SEvalZero
613*150812a8SEvalZero nrf_twis_disable(p_reg);
614*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_INITIALIZED;
615*150812a8SEvalZero }
616*150812a8SEvalZero
617*150812a8SEvalZero /* ARM recommends not using the LDREX and STREX instructions in C code.
618*150812a8SEvalZero * This is because the compiler might generate loads and stores between
619*150812a8SEvalZero * LDREX and STREX, potentially clearing the exclusive monitor set by LDREX.
620*150812a8SEvalZero * This recommendation also applies to the byte, halfword, and doubleword
621*150812a8SEvalZero * variants LDREXB, STREXB, LDREXH, STREXH, LDREXD, and STREXD.
622*150812a8SEvalZero *
623*150812a8SEvalZero * This is the reason for the function below to be implemented in assembly.
624*150812a8SEvalZero */
625*150812a8SEvalZero //lint -save -e578
626*150812a8SEvalZero #if defined (__CC_ARM )
nrfx_twis_error_get_and_clear_internal(uint32_t volatile * perror)627*150812a8SEvalZero static __ASM uint32_t nrfx_twis_error_get_and_clear_internal(uint32_t volatile * perror)
628*150812a8SEvalZero {
629*150812a8SEvalZero mov r3, r0
630*150812a8SEvalZero mov r1, #0
631*150812a8SEvalZero nrfx_twis_error_get_and_clear_internal_try
632*150812a8SEvalZero ldrex r0, [r3]
633*150812a8SEvalZero strex r2, r1, [r3]
634*150812a8SEvalZero cmp r2, r1 /* did this succeed? */
635*150812a8SEvalZero bne nrfx_twis_error_get_and_clear_internal_try /* no - try again */
636*150812a8SEvalZero bx lr
637*150812a8SEvalZero }
638*150812a8SEvalZero #elif defined ( __GNUC__ )
nrfx_twis_error_get_and_clear_internal(uint32_t volatile * perror)639*150812a8SEvalZero static uint32_t nrfx_twis_error_get_and_clear_internal(uint32_t volatile * perror)
640*150812a8SEvalZero {
641*150812a8SEvalZero uint32_t ret;
642*150812a8SEvalZero uint32_t temp;
643*150812a8SEvalZero __ASM volatile(
644*150812a8SEvalZero " .syntax unified \n"
645*150812a8SEvalZero "nrfx_twis_error_get_and_clear_internal_try: \n"
646*150812a8SEvalZero " ldrex %[ret], [%[perror]] \n"
647*150812a8SEvalZero " strex %[temp], %[zero], [%[perror]] \n"
648*150812a8SEvalZero " cmp %[temp], %[zero] \n"
649*150812a8SEvalZero " bne nrfx_twis_error_get_and_clear_internal_try \n"
650*150812a8SEvalZero : /* Output */
651*150812a8SEvalZero [ret]"=&l"(ret),
652*150812a8SEvalZero [temp]"=&l"(temp)
653*150812a8SEvalZero : /* Input */
654*150812a8SEvalZero [zero]"l"(0),
655*150812a8SEvalZero [perror]"l"(perror)
656*150812a8SEvalZero );
657*150812a8SEvalZero (void)temp;
658*150812a8SEvalZero return ret;
659*150812a8SEvalZero }
660*150812a8SEvalZero #elif defined ( __ICCARM__ )
nrfx_twis_error_get_and_clear_internal(uint32_t volatile * perror)661*150812a8SEvalZero static uint32_t nrfx_twis_error_get_and_clear_internal(uint32_t volatile * perror)
662*150812a8SEvalZero {
663*150812a8SEvalZero uint32_t ret;
664*150812a8SEvalZero uint32_t temp;
665*150812a8SEvalZero __ASM volatile(
666*150812a8SEvalZero "1: \n"
667*150812a8SEvalZero " ldrex %[ret], [%[perror]] \n"
668*150812a8SEvalZero " strex %[temp], %[zero], [%[perror]] \n"
669*150812a8SEvalZero " cmp %[temp], %[zero] \n"
670*150812a8SEvalZero " bne.n 1b \n"
671*150812a8SEvalZero : /* Output */
672*150812a8SEvalZero [ret]"=&l"(ret),
673*150812a8SEvalZero [temp]"=&l"(temp)
674*150812a8SEvalZero : /* Input */
675*150812a8SEvalZero [zero]"l"(0),
676*150812a8SEvalZero [perror]"l"(perror)
677*150812a8SEvalZero );
678*150812a8SEvalZero (void)temp;
679*150812a8SEvalZero return ret;
680*150812a8SEvalZero }
681*150812a8SEvalZero #else
682*150812a8SEvalZero #error Unknown compiler
683*150812a8SEvalZero #endif
684*150812a8SEvalZero //lint -restore
685*150812a8SEvalZero
nrfx_twis_error_get_and_clear(nrfx_twis_t const * p_instance)686*150812a8SEvalZero uint32_t nrfx_twis_error_get_and_clear(nrfx_twis_t const * p_instance)
687*150812a8SEvalZero {
688*150812a8SEvalZero nrfx_twis_preprocess_status(p_instance);
689*150812a8SEvalZero /* Make sure that access to error member is atomic
690*150812a8SEvalZero * so there is no bit that is cleared if it is not copied to local variable already. */
691*150812a8SEvalZero twis_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
692*150812a8SEvalZero return nrfx_twis_error_get_and_clear_internal(&p_cb->error);
693*150812a8SEvalZero }
694*150812a8SEvalZero
695*150812a8SEvalZero
nrfx_twis_tx_prepare(nrfx_twis_t const * p_instance,void const * p_buf,size_t size)696*150812a8SEvalZero nrfx_err_t nrfx_twis_tx_prepare(nrfx_twis_t const * p_instance,
697*150812a8SEvalZero void const * p_buf,
698*150812a8SEvalZero size_t size)
699*150812a8SEvalZero {
700*150812a8SEvalZero nrfx_err_t err_code;
701*150812a8SEvalZero twis_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
702*150812a8SEvalZero
703*150812a8SEvalZero /* Check power state*/
704*150812a8SEvalZero if (p_cb->state != NRFX_DRV_STATE_POWERED_ON)
705*150812a8SEvalZero {
706*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
707*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
708*150812a8SEvalZero __func__,
709*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
710*150812a8SEvalZero return err_code;
711*150812a8SEvalZero }
712*150812a8SEvalZero /* Check data address */
713*150812a8SEvalZero if (!nrfx_is_in_ram(p_buf))
714*150812a8SEvalZero {
715*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_ADDR;
716*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
717*150812a8SEvalZero __func__,
718*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
719*150812a8SEvalZero return err_code;
720*150812a8SEvalZero }
721*150812a8SEvalZero /* Check data size */
722*150812a8SEvalZero if ((size & TWIS_TXD_MAXCNT_MAXCNT_Msk) != size)
723*150812a8SEvalZero {
724*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_LENGTH;
725*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
726*150812a8SEvalZero __func__,
727*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
728*150812a8SEvalZero return err_code;
729*150812a8SEvalZero }
730*150812a8SEvalZero
731*150812a8SEvalZero nrf_twis_tx_prepare(p_instance->p_reg,
732*150812a8SEvalZero (uint8_t const *)p_buf,
733*150812a8SEvalZero (nrf_twis_amount_t)size);
734*150812a8SEvalZero err_code = NRFX_SUCCESS;
735*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
736*150812a8SEvalZero return err_code;
737*150812a8SEvalZero }
738*150812a8SEvalZero
739*150812a8SEvalZero
nrfx_twis_rx_prepare(nrfx_twis_t const * p_instance,void * p_buf,size_t size)740*150812a8SEvalZero nrfx_err_t nrfx_twis_rx_prepare(nrfx_twis_t const * p_instance,
741*150812a8SEvalZero void * p_buf,
742*150812a8SEvalZero size_t size)
743*150812a8SEvalZero {
744*150812a8SEvalZero nrfx_err_t err_code;
745*150812a8SEvalZero twis_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
746*150812a8SEvalZero
747*150812a8SEvalZero /* Check power state*/
748*150812a8SEvalZero if (p_cb->state != NRFX_DRV_STATE_POWERED_ON)
749*150812a8SEvalZero {
750*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
751*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
752*150812a8SEvalZero __func__,
753*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
754*150812a8SEvalZero return err_code;
755*150812a8SEvalZero }
756*150812a8SEvalZero /* Check data address */
757*150812a8SEvalZero if (!nrfx_is_in_ram(p_buf))
758*150812a8SEvalZero {
759*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_ADDR;
760*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
761*150812a8SEvalZero __func__,
762*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
763*150812a8SEvalZero return err_code;
764*150812a8SEvalZero }
765*150812a8SEvalZero /* Check data size */
766*150812a8SEvalZero if ((size & TWIS_RXD_MAXCNT_MAXCNT_Msk) != size)
767*150812a8SEvalZero {
768*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_LENGTH;
769*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
770*150812a8SEvalZero __func__,
771*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
772*150812a8SEvalZero return err_code;
773*150812a8SEvalZero }
774*150812a8SEvalZero
775*150812a8SEvalZero nrf_twis_rx_prepare(p_instance->p_reg,
776*150812a8SEvalZero (uint8_t *)p_buf,
777*150812a8SEvalZero (nrf_twis_amount_t)size);
778*150812a8SEvalZero err_code = NRFX_SUCCESS;
779*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
780*150812a8SEvalZero return err_code;
781*150812a8SEvalZero }
782*150812a8SEvalZero
783*150812a8SEvalZero
nrfx_twis_is_busy(nrfx_twis_t const * p_instance)784*150812a8SEvalZero bool nrfx_twis_is_busy(nrfx_twis_t const * p_instance)
785*150812a8SEvalZero {
786*150812a8SEvalZero nrfx_twis_preprocess_status(p_instance);
787*150812a8SEvalZero twis_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
788*150812a8SEvalZero return NRFX_TWIS_SUBSTATE_IDLE != p_cb->substate;
789*150812a8SEvalZero }
790*150812a8SEvalZero
nrfx_twis_is_waiting_tx_buff(nrfx_twis_t const * p_instance)791*150812a8SEvalZero bool nrfx_twis_is_waiting_tx_buff(nrfx_twis_t const * p_instance)
792*150812a8SEvalZero {
793*150812a8SEvalZero nrfx_twis_preprocess_status(p_instance);
794*150812a8SEvalZero twis_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
795*150812a8SEvalZero return NRFX_TWIS_SUBSTATE_READ_WAITING == p_cb->substate;
796*150812a8SEvalZero }
797*150812a8SEvalZero
nrfx_twis_is_waiting_rx_buff(nrfx_twis_t const * p_instance)798*150812a8SEvalZero bool nrfx_twis_is_waiting_rx_buff(nrfx_twis_t const * p_instance)
799*150812a8SEvalZero {
800*150812a8SEvalZero nrfx_twis_preprocess_status(p_instance);
801*150812a8SEvalZero twis_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
802*150812a8SEvalZero return NRFX_TWIS_SUBSTATE_WRITE_WAITING == p_cb->substate;
803*150812a8SEvalZero }
804*150812a8SEvalZero
nrfx_twis_is_pending_tx(nrfx_twis_t const * p_instance)805*150812a8SEvalZero bool nrfx_twis_is_pending_tx(nrfx_twis_t const * p_instance)
806*150812a8SEvalZero {
807*150812a8SEvalZero nrfx_twis_preprocess_status(p_instance);
808*150812a8SEvalZero twis_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
809*150812a8SEvalZero return NRFX_TWIS_SUBSTATE_READ_PENDING == p_cb->substate;
810*150812a8SEvalZero }
811*150812a8SEvalZero
nrfx_twis_is_pending_rx(nrfx_twis_t const * p_instance)812*150812a8SEvalZero bool nrfx_twis_is_pending_rx(nrfx_twis_t const * p_instance)
813*150812a8SEvalZero {
814*150812a8SEvalZero nrfx_twis_preprocess_status(p_instance);
815*150812a8SEvalZero twis_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
816*150812a8SEvalZero return NRFX_TWIS_SUBSTATE_WRITE_PENDING == p_cb->substate;
817*150812a8SEvalZero }
818*150812a8SEvalZero
819*150812a8SEvalZero
820*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS0_ENABLED)
nrfx_twis_0_irq_handler(void)821*150812a8SEvalZero void nrfx_twis_0_irq_handler(void)
822*150812a8SEvalZero {
823*150812a8SEvalZero nrfx_twis_state_machine(NRF_TWIS0, &m_cb[NRFX_TWIS0_INST_IDX]);
824*150812a8SEvalZero }
825*150812a8SEvalZero #endif
826*150812a8SEvalZero
827*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS1_ENABLED)
nrfx_twis_1_irq_handler(void)828*150812a8SEvalZero void nrfx_twis_1_irq_handler(void)
829*150812a8SEvalZero {
830*150812a8SEvalZero nrfx_twis_state_machine(NRF_TWIS1, &m_cb[NRFX_TWIS1_INST_IDX]);
831*150812a8SEvalZero }
832*150812a8SEvalZero #endif
833*150812a8SEvalZero
834*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS2_ENABLED)
nrfx_twis_2_irq_handler(void)835*150812a8SEvalZero void nrfx_twis_2_irq_handler(void)
836*150812a8SEvalZero {
837*150812a8SEvalZero nrfx_twis_state_machine(NRF_TWIS2, &m_cb[NRFX_TWIS2_INST_IDX]);
838*150812a8SEvalZero }
839*150812a8SEvalZero #endif
840*150812a8SEvalZero
841*150812a8SEvalZero #if NRFX_CHECK(NRFX_TWIS3_ENABLED)
nrfx_twis_3_irq_handler(void)842*150812a8SEvalZero void nrfx_twis_3_irq_handler(void)
843*150812a8SEvalZero {
844*150812a8SEvalZero nrfx_twis_state_machine(NRF_TWIS3, &m_cb[NRFX_TWIS3_INST_IDX]);
845*150812a8SEvalZero }
846*150812a8SEvalZero #endif
847*150812a8SEvalZero
848*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_TWIS_ENABLED)
849