1 /*
2 * Copyright (c) 2013 - 2020, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <nrfx.h>
33
34 #if NRFX_CHECK(NRFX_SPIS_ENABLED)
35
36 #if !(NRFX_CHECK(NRFX_SPIS0_ENABLED) || \
37 NRFX_CHECK(NRFX_SPIS1_ENABLED) || \
38 NRFX_CHECK(NRFX_SPIS2_ENABLED) || \
39 NRFX_CHECK(NRFX_SPIS3_ENABLED))
40 #error "No enabled SPIS instances. Check <nrfx_config.h>."
41 #endif
42
43 #include <nrfx_spis.h>
44 #include "prs/nrfx_prs.h"
45
46 #define NRFX_LOG_MODULE SPIS
47 #include <nrfx_log.h>
48
49 #define EVT_TO_STR(event) \
50 (event == NRF_SPIS_EVENT_ACQUIRED ? "NRF_SPIS_EVENT_ACQUIRED" : \
51 (event == NRF_SPIS_EVENT_END ? "NRF_SPIS_EVENT_END" : \
52 "UNKNOWN ERROR"))
53
54 #define SPISX_LENGTH_VALIDATE(peripheral, drv_inst_idx, rx_len, tx_len) \
55 (((drv_inst_idx) == NRFX_CONCAT_3(NRFX_, peripheral, _INST_IDX)) && \
56 NRFX_EASYDMA_LENGTH_VALIDATE(peripheral, rx_len, tx_len))
57
58 #if NRFX_CHECK(NRFX_SPIS0_ENABLED)
59 #define SPIS0_LENGTH_VALIDATE(...) SPISX_LENGTH_VALIDATE(SPIS0, __VA_ARGS__)
60 #else
61 #define SPIS0_LENGTH_VALIDATE(...) 0
62 #endif
63
64 #if NRFX_CHECK(NRFX_SPIS1_ENABLED)
65 #define SPIS1_LENGTH_VALIDATE(...) SPISX_LENGTH_VALIDATE(SPIS1, __VA_ARGS__)
66 #else
67 #define SPIS1_LENGTH_VALIDATE(...) 0
68 #endif
69
70 #if NRFX_CHECK(NRFX_SPIS2_ENABLED)
71 #define SPIS2_LENGTH_VALIDATE(...) SPISX_LENGTH_VALIDATE(SPIS2, __VA_ARGS__)
72 #else
73 #define SPIS2_LENGTH_VALIDATE(...) 0
74 #endif
75
76 #if NRFX_CHECK(NRFX_SPIS3_ENABLED)
77 #define SPIS3_LENGTH_VALIDATE(...) SPISX_LENGTH_VALIDATE(SPIS3, __VA_ARGS__)
78 #else
79 #define SPIS3_LENGTH_VALIDATE(...) 0
80 #endif
81
82 #define SPIS_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) \
83 (SPIS0_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
84 SPIS1_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
85 SPIS2_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len) || \
86 SPIS3_LENGTH_VALIDATE(drv_inst_idx, rx_len, tx_len))
87
88
89 #if NRFX_CHECK(NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
90 #include <nrfx_gpiote.h>
91 #define USE_DMA_ISSUE_WORKAROUND
92 // This handler is called by the GPIOTE driver when a falling edge is detected
93 // on the CSN line. There is no need to do anything here. The handling of the
94 // interrupt itself provides a protection for DMA transfers.
csn_event_handler(nrfx_gpiote_pin_t pin,nrf_gpiote_polarity_t action)95 static void csn_event_handler(nrfx_gpiote_pin_t pin,
96 nrf_gpiote_polarity_t action)
97 {
98 }
99 #endif
100
101
102 /**@brief States of the SPI transaction state machine. */
103 typedef enum
104 {
105 SPIS_STATE_INIT, /**< Initialization state. In this state the module waits for a call to @ref spi_slave_buffers_set. */
106 SPIS_BUFFER_RESOURCE_REQUESTED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has started. */
107 SPIS_BUFFER_RESOURCE_CONFIGURED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has completed. */
108 SPIS_XFER_COMPLETED /**< State where SPI transaction has been completed. */
109 } nrfx_spis_state_t;
110
111 /**@brief SPIS control block - driver instance local data. */
112 typedef struct
113 {
114 volatile uint32_t tx_buffer_size; //!< SPI slave TX buffer size in bytes.
115 volatile uint32_t rx_buffer_size; //!< SPI slave RX buffer size in bytes.
116 nrfx_spis_event_handler_t handler; //!< SPI event handler.
117 volatile const uint8_t * tx_buffer; //!< SPI slave TX buffer.
118 volatile uint8_t * rx_buffer; //!< SPI slave RX buffer.
119 nrfx_drv_state_t state; //!< driver initialization state.
120 volatile nrfx_spis_state_t spi_state; //!< SPI slave state.
121 void * p_context; //!< Context set on initialization.
122 } spis_cb_t;
123
124 static spis_cb_t m_cb[NRFX_SPIS_ENABLED_COUNT];
125
nrfx_spis_init(nrfx_spis_t const * p_instance,nrfx_spis_config_t const * p_config,nrfx_spis_event_handler_t event_handler,void * p_context)126 nrfx_err_t nrfx_spis_init(nrfx_spis_t const * p_instance,
127 nrfx_spis_config_t const * p_config,
128 nrfx_spis_event_handler_t event_handler,
129 void * p_context)
130 {
131 NRFX_ASSERT(p_config);
132 NRFX_ASSERT(event_handler);
133 spis_cb_t * p_cb = &m_cb[p_instance->drv_inst_idx];
134 nrfx_err_t err_code;
135
136 NRF_SPIS_Type * p_spis = p_instance->p_reg;
137
138 if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
139 {
140 err_code = NRFX_ERROR_INVALID_STATE;
141 NRFX_LOG_WARNING("Function: %s, error code: %s.",
142 __func__,
143 NRFX_LOG_ERROR_STRING_GET(err_code));
144 return err_code;
145 }
146
147 if ((uint32_t)p_config->mode > (uint32_t)NRF_SPIS_MODE_3)
148 {
149 err_code = NRFX_ERROR_INVALID_PARAM;
150 NRFX_LOG_WARNING("Function: %s, error code: %s.",
151 __func__,
152 NRFX_LOG_ERROR_STRING_GET(err_code));
153 return err_code;
154 }
155 #if NRFX_CHECK(NRFX_PRS_ENABLED)
156 static nrfx_irq_handler_t const irq_handlers[NRFX_SPIS_ENABLED_COUNT] = {
157 #if NRFX_CHECK(NRFX_SPIS0_ENABLED)
158 nrfx_spis_0_irq_handler,
159 #endif
160 #if NRFX_CHECK(NRFX_SPIS1_ENABLED)
161 nrfx_spis_1_irq_handler,
162 #endif
163 #if NRFX_CHECK(NRFX_SPIS2_ENABLED)
164 nrfx_spis_2_irq_handler,
165 #endif
166 #if NRFX_CHECK(NRFX_SPIS3_ENABLED)
167 nrfx_spis_3_irq_handler,
168 #endif
169 };
170 if (nrfx_prs_acquire(p_spis,
171 irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
172 {
173 err_code = NRFX_ERROR_BUSY;
174 NRFX_LOG_WARNING("Function: %s, error code: %s.",
175 __func__,
176 NRFX_LOG_ERROR_STRING_GET(err_code));
177 return err_code;
178 }
179 #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
180
181 // Configure the SPI pins for input.
182 uint32_t mosi_pin;
183 uint32_t miso_pin;
184
185 if (p_config->miso_pin != NRFX_SPIS_PIN_NOT_USED)
186 {
187 nrf_gpio_cfg(p_config->miso_pin,
188 NRF_GPIO_PIN_DIR_INPUT,
189 NRF_GPIO_PIN_INPUT_CONNECT,
190 NRF_GPIO_PIN_NOPULL,
191 p_config->miso_drive,
192 NRF_GPIO_PIN_NOSENSE);
193 miso_pin = p_config->miso_pin;
194 }
195 else
196 {
197 miso_pin = NRF_SPIS_PIN_NOT_CONNECTED;
198 }
199
200 if (p_config->mosi_pin != NRFX_SPIS_PIN_NOT_USED)
201 {
202 nrf_gpio_cfg(p_config->mosi_pin,
203 NRF_GPIO_PIN_DIR_INPUT,
204 NRF_GPIO_PIN_INPUT_CONNECT,
205 NRF_GPIO_PIN_NOPULL,
206 NRF_GPIO_PIN_S0S1,
207 NRF_GPIO_PIN_NOSENSE);
208 mosi_pin = p_config->mosi_pin;
209 }
210 else
211 {
212 mosi_pin = NRF_SPIS_PIN_NOT_CONNECTED;
213 }
214
215 nrf_gpio_cfg(p_config->csn_pin,
216 NRF_GPIO_PIN_DIR_INPUT,
217 NRF_GPIO_PIN_INPUT_CONNECT,
218 p_config->csn_pullup,
219 NRF_GPIO_PIN_S0S1,
220 NRF_GPIO_PIN_NOSENSE);
221
222 nrf_gpio_cfg(p_config->sck_pin,
223 NRF_GPIO_PIN_DIR_INPUT,
224 NRF_GPIO_PIN_INPUT_CONNECT,
225 NRF_GPIO_PIN_NOPULL,
226 NRF_GPIO_PIN_S0S1,
227 NRF_GPIO_PIN_NOSENSE);
228
229 nrf_spis_pins_set(p_spis, p_config->sck_pin, mosi_pin, miso_pin, p_config->csn_pin);
230
231 nrf_spis_rx_buffer_set(p_spis, NULL, 0);
232 nrf_spis_tx_buffer_set(p_spis, NULL, 0);
233
234 // Configure SPI mode.
235 nrf_spis_configure(p_spis, p_config->mode, p_config->bit_order);
236
237 // Configure DEF and ORC characters.
238 nrf_spis_def_set(p_spis, p_config->def);
239 nrf_spis_orc_set(p_spis, p_config->orc);
240
241 // Clear possible pending events.
242 nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END);
243 nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED);
244
245 // Enable END_ACQUIRE shortcut.
246 nrf_spis_shorts_enable(p_spis, NRF_SPIS_SHORT_END_ACQUIRE);
247
248 p_cb->spi_state = SPIS_STATE_INIT;
249 p_cb->handler = event_handler;
250 p_cb->p_context = p_context;
251
252 #if defined(USE_DMA_ISSUE_WORKAROUND)
253 // Configure a GPIOTE channel to generate interrupts on each falling edge
254 // on the CSN line. Handling of these interrupts will make the CPU active,
255 // and thus will protect the DMA transfers started by SPIS right after it
256 // is selected for communication.
257 // [the GPIOTE driver may be already initialized at this point (by this
258 // driver when another SPIS instance is used, or by an application code),
259 // so just ignore the returned value]
260 (void)nrfx_gpiote_init(NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
261 static nrfx_gpiote_in_config_t const csn_gpiote_config =
262 NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
263 nrfx_err_t gpiote_err_code = nrfx_gpiote_in_init(p_config->csn_pin,
264 &csn_gpiote_config, csn_event_handler);
265 if (gpiote_err_code != NRFX_SUCCESS)
266 {
267 err_code = NRFX_ERROR_INTERNAL;
268 NRFX_LOG_INFO("Function: %s, error code: %s.",
269 __func__,
270 NRFX_LOG_ERROR_STRING_GET(err_code));
271 return err_code;
272 }
273 nrfx_gpiote_in_event_enable(p_config->csn_pin, true);
274 #endif
275
276 // Enable IRQ.
277 nrf_spis_int_enable(p_spis, NRF_SPIS_INT_ACQUIRED_MASK |
278 NRF_SPIS_INT_END_MASK);
279 NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_instance->p_reg),
280 p_config->irq_priority);
281 NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_instance->p_reg));
282
283 p_cb->state = NRFX_DRV_STATE_INITIALIZED;
284
285 // Enable SPI slave device.
286 nrf_spis_enable(p_spis);
287
288 NRFX_LOG_INFO("Initialized.");
289 return NRFX_SUCCESS;
290 }
291
292
nrfx_spis_uninit(nrfx_spis_t const * p_instance)293 void nrfx_spis_uninit(nrfx_spis_t const * p_instance)
294 {
295 spis_cb_t * p_cb = &m_cb[p_instance->drv_inst_idx];
296 NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
297
298 NRF_SPIS_Type * p_spis = p_instance->p_reg;
299
300 #define DISABLE_ALL 0xFFFFFFFF
301 nrf_spis_disable(p_spis);
302 NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_instance->p_reg));
303 nrf_spis_int_disable(p_spis, DISABLE_ALL);
304 #undef DISABLE_ALL
305
306 nrf_gpio_cfg_default(nrf_spis_sck_pin_get(p_spis));
307 nrf_gpio_cfg_default(nrf_spis_csn_pin_get(p_spis));
308
309 uint32_t miso_pin = nrf_spis_miso_pin_get(p_spis);
310 if (miso_pin != NRF_SPIS_PIN_NOT_CONNECTED)
311 {
312 nrf_gpio_cfg_default(miso_pin);
313 }
314
315 uint32_t mosi_pin = nrf_spis_mosi_pin_get(p_spis);
316 if (mosi_pin != NRF_SPIS_PIN_NOT_CONNECTED)
317 {
318 nrf_gpio_cfg_default(mosi_pin);
319 }
320
321 #if NRFX_CHECK(NRFX_PRS_ENABLED)
322 nrfx_prs_release(p_spis);
323 #endif
324
325 p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
326 NRFX_LOG_INFO("Uninitialized.");
327 }
328
329
330 /**@brief Function for executing the state entry action. */
spis_state_entry_action_execute(NRF_SPIS_Type * p_spis,spis_cb_t * p_cb)331 static void spis_state_entry_action_execute(NRF_SPIS_Type * p_spis,
332 spis_cb_t * p_cb)
333 {
334 nrfx_spis_evt_t event;
335
336 switch (p_cb->spi_state)
337 {
338 case SPIS_BUFFER_RESOURCE_REQUESTED:
339 nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_ACQUIRE);
340 break;
341
342 case SPIS_BUFFER_RESOURCE_CONFIGURED:
343 event.evt_type = NRFX_SPIS_BUFFERS_SET_DONE;
344 event.rx_amount = 0;
345 event.tx_amount = 0;
346
347 NRFX_ASSERT(p_cb->handler != NULL);
348 p_cb->handler(&event, p_cb->p_context);
349 break;
350
351 case SPIS_XFER_COMPLETED:
352 event.evt_type = NRFX_SPIS_XFER_DONE;
353 event.rx_amount = nrf_spis_rx_amount_get(p_spis);
354 event.tx_amount = nrf_spis_tx_amount_get(p_spis);
355 NRFX_LOG_INFO("Transfer rx_len:%d.", event.rx_amount);
356 NRFX_LOG_DEBUG("Rx data:");
357 NRFX_LOG_HEXDUMP_DEBUG((uint8_t const *)p_cb->rx_buffer,
358 event.rx_amount * sizeof(p_cb->rx_buffer[0]));
359 NRFX_ASSERT(p_cb->handler != NULL);
360 p_cb->handler(&event, p_cb->p_context);
361 break;
362
363 default:
364 // No implementation required.
365 break;
366 }
367 }
368
369 /**@brief Function for changing the state of the SPI state machine.
370 *
371 * @param[in] p_spis SPIS instance register.
372 * @param[in] p_cb SPIS instance control block.
373 * @param[in] new_state State where the state machine transits to.
374 */
spis_state_change(NRF_SPIS_Type * p_spis,spis_cb_t * p_cb,nrfx_spis_state_t new_state)375 static void spis_state_change(NRF_SPIS_Type * p_spis,
376 spis_cb_t * p_cb,
377 nrfx_spis_state_t new_state)
378 {
379 p_cb->spi_state = new_state;
380 spis_state_entry_action_execute(p_spis, p_cb);
381 }
382
nrfx_spis_buffers_set(nrfx_spis_t const * p_instance,uint8_t const * p_tx_buffer,size_t tx_buffer_length,uint8_t * p_rx_buffer,size_t rx_buffer_length)383 nrfx_err_t nrfx_spis_buffers_set(nrfx_spis_t const * p_instance,
384 uint8_t const * p_tx_buffer,
385 size_t tx_buffer_length,
386 uint8_t * p_rx_buffer,
387 size_t rx_buffer_length)
388 {
389 NRFX_ASSERT(p_tx_buffer != NULL || tx_buffer_length == 0);
390 NRFX_ASSERT(p_rx_buffer != NULL || rx_buffer_length == 0);
391
392 spis_cb_t * p_cb = &m_cb[p_instance->drv_inst_idx];
393 nrfx_err_t err_code;
394
395 if (!SPIS_LENGTH_VALIDATE(p_instance->drv_inst_idx,
396 rx_buffer_length,
397 tx_buffer_length))
398 {
399 return NRFX_ERROR_INVALID_LENGTH;
400 }
401
402 // EasyDMA requires that transfer buffers are placed in Data RAM region;
403 // signal error if they are not.
404 if ((p_tx_buffer != NULL && !nrfx_is_in_ram(p_tx_buffer)) ||
405 (p_rx_buffer != NULL && !nrfx_is_in_ram(p_rx_buffer)))
406 {
407 err_code = NRFX_ERROR_INVALID_ADDR;
408 NRFX_LOG_WARNING("Function: %s, error code: %s.",
409 __func__,
410 NRFX_LOG_ERROR_STRING_GET(err_code));
411 return err_code;
412 }
413
414 switch (p_cb->spi_state)
415 {
416 case SPIS_STATE_INIT:
417 case SPIS_XFER_COMPLETED:
418 case SPIS_BUFFER_RESOURCE_CONFIGURED:
419 p_cb->tx_buffer = p_tx_buffer;
420 p_cb->rx_buffer = p_rx_buffer;
421 p_cb->tx_buffer_size = tx_buffer_length;
422 p_cb->rx_buffer_size = rx_buffer_length;
423 err_code = NRFX_SUCCESS;
424
425 spis_state_change(p_instance->p_reg, p_cb, SPIS_BUFFER_RESOURCE_REQUESTED);
426 break;
427
428 case SPIS_BUFFER_RESOURCE_REQUESTED:
429 err_code = NRFX_ERROR_INVALID_STATE;
430 break;
431
432 default:
433 // @note: execution of this code path would imply internal error in the design.
434 err_code = NRFX_ERROR_INTERNAL;
435 break;
436 }
437
438 NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
439 return err_code;
440 }
441
spis_irq_handler(NRF_SPIS_Type * p_spis,spis_cb_t * p_cb)442 static void spis_irq_handler(NRF_SPIS_Type * p_spis, spis_cb_t * p_cb)
443 {
444 // @note: as multiple events can be pending for processing, the correct event processing order
445 // is as follows:
446 // - SPI semaphore acquired event.
447 // - SPI transaction complete event.
448
449 // Check for SPI semaphore acquired event.
450 if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_ACQUIRED))
451 {
452 nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED);
453 NRFX_LOG_DEBUG("SPIS: Event: %s.", EVT_TO_STR(NRF_SPIS_EVENT_ACQUIRED));
454
455 switch (p_cb->spi_state)
456 {
457 case SPIS_BUFFER_RESOURCE_REQUESTED:
458 nrf_spis_tx_buffer_set(p_spis, (uint8_t *)p_cb->tx_buffer, p_cb->tx_buffer_size);
459 nrf_spis_rx_buffer_set(p_spis, (uint8_t *)p_cb->rx_buffer, p_cb->rx_buffer_size);
460
461 nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_RELEASE);
462
463 spis_state_change(p_spis, p_cb, SPIS_BUFFER_RESOURCE_CONFIGURED);
464 break;
465
466 default:
467 // No implementation required.
468 break;
469 }
470 }
471
472 // Check for SPI transaction complete event.
473 if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_END))
474 {
475 nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END);
476 NRFX_LOG_DEBUG("SPIS: Event: %s.", EVT_TO_STR(NRF_SPIS_EVENT_END));
477
478 switch (p_cb->spi_state)
479 {
480 case SPIS_BUFFER_RESOURCE_CONFIGURED:
481 spis_state_change(p_spis, p_cb, SPIS_XFER_COMPLETED);
482 break;
483
484 default:
485 // No implementation required.
486 break;
487 }
488 }
489 }
490
491 #if NRFX_CHECK(NRFX_SPIS0_ENABLED)
nrfx_spis_0_irq_handler(void)492 void nrfx_spis_0_irq_handler(void)
493 {
494 spis_irq_handler(NRF_SPIS0, &m_cb[NRFX_SPIS0_INST_IDX]);
495 }
496 #endif
497
498 #if NRFX_CHECK(NRFX_SPIS1_ENABLED)
nrfx_spis_1_irq_handler(void)499 void nrfx_spis_1_irq_handler(void)
500 {
501 spis_irq_handler(NRF_SPIS1, &m_cb[NRFX_SPIS1_INST_IDX]);
502 }
503 #endif
504
505 #if NRFX_CHECK(NRFX_SPIS2_ENABLED)
nrfx_spis_2_irq_handler(void)506 void nrfx_spis_2_irq_handler(void)
507 {
508 spis_irq_handler(NRF_SPIS2, &m_cb[NRFX_SPIS2_INST_IDX]);
509 }
510 #endif
511
512 #if NRFX_CHECK(NRFX_SPIS3_ENABLED)
nrfx_spis_3_irq_handler(void)513 void nrfx_spis_3_irq_handler(void)
514 {
515 spis_irq_handler(NRF_SPIS3, &m_cb[NRFX_SPIS3_INST_IDX]);
516 }
517 #endif
518
519 #endif // NRFX_CHECK(NRFX_SPIS_ENABLED)
520