1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*
8 * GPIO - General purpose input/output
9 * https://infocenter.nordicsemi.com/topic/ps_nrf52833/gpio.html?cp=5_1_0_5_7
10 *
11 * This model has the following limitations:
12 * * Note a.1:
13 * PIN_CNF.PULL is ignored. If a pin input is disconnected and not driven externally it will
14 * just remain at zero/low.
15 * * Note a.2:
16 * PIN_CNF.DRIVE / drive strength is ignored
17 * It is not possible to connect two outputs together building a logical AND or OR
18 * * Note a.3:
19 * Reading OUTCLR & DIRCLR reads always 0
20 * * Note a.4: There is no modeling of system idle/off, and as such a DETECT raising edge from the
21 * GPIO will not cause the system to exit those states.
22 *
23 * This model has the following approximations:
24 * * Note b.1:
25 * If a DIR bit is cleared for a pin which was being driven as a high output,
26 * that pin will be lowered immediately (like if it was driven low)
27 * * Note b.2:
28 * All drives are instantaneous.
29 * * Note b.3:
30 * During pin reconfigurations, there can be spurious transitions in the pins outputs
31 * which may not correspond to how the real HW would behave
32 * * In real HW, after a write to LATCH, the DETECT event output to the GPIOTE is kept low for
33 * a few clocks, before being raised again (if it needs to), in the model the new pulse/raise
34 * is sent instantaneously to the GPIOTE
35 */
36
37 #include <stdint.h>
38 #include <stdbool.h>
39 #include <string.h>
40 #include "NHW_common_types.h"
41 #include "NHW_config.h"
42 #include "NHW_common_types.h"
43 #include "NHW_config.h"
44 #include "NHW_peri_types.h"
45 #include "NRF_GPIO.h"
46 #include "NRF_GPIOTE.h"
47 #include "bs_tracing.h"
48 #include "nsi_tasks.h"
49
50 NRF_GPIO_Type NRF_GPIO_regs[NRF_GPIOS];
51
52 /* Number of pins per port: */
53 static int GPIO_n_ports_pins[NRF_GPIOS] = NRF_GPIO_PORTS_PINS;
54
55 static uint32_t IO_level[NRF_GPIOS]; /* Actual level in the pin */
56 static uint32_t DETECT[NRF_GPIOS]; /* Sense output / unlatched/non-sticky detect */
57 static uint32_t LDETECT[NRF_GPIOS]; /* Latched sense output */
58 static bool DETECT_signal[NRF_GPIOS]; /* Individual detect signal to the GPIOTE */
59
60 static uint32_t INPUT_mask[NRF_GPIOS]; /* As a 32bit mask, PIN_CNF[*].INPUT (0: enabled; 1: disabled)*/
61 static uint32_t SENSE_mask[NRF_GPIOS]; /* As a 32bit mask, PIN_CNF[*].SENSE.en (1: enabled; 0: disabled)*/
62 static uint32_t SENSE_inv[NRF_GPIOS]; /* As a 32bit mask, PIN_CNF[*].SENSE.inv (1: inverted;0: not inverted) */
63
64 /*
65 * Is the output driven by another peripheral (1) or the GPIO directly (0).
66 * Note that we don't keep track of who "owns" a pin, only that somebody else does
67 */
68 static uint32_t out_override[NRF_GPIOS];
69 /* Out value provided by other peripherals */
70 static uint32_t external_OUT[NRF_GPIOS];
71
72 /* Is the pin input controlled by a peripheral(1) or the GPIO(0) */
73 static uint32_t input_override[NRF_GPIOS];
74 /* If input_override, is the peripheral configuring the input buffer as connected (1) or disconnected (0) */
75 static uint32_t input_override_connected[NRF_GPIOS];
76
77 /* Is "dir" controlled by a peripheral(1) or the GPIO(0) */
78 static uint32_t dir_override[NRF_GPIOS];
79 /* If dir_override is set, is the peripheral configuring the output as connected (1) or disconnected (0) */
80 static uint32_t dir_override_set[NRF_GPIOS];
81
82 /* Callbacks for peripherals to be informed of input changes */
83 static nrf_gpio_input_callback_t per_intoggle_callbacks[NRF_GPIOS][NRF_GPIO_MAX_PINS_PER_PORT];
84 static nrf_gpio_input_callback_t test_intoggle_callback;
85
86 /*
87 * Initialize the GPIOs model
88 */
nrf_gpio_init(void)89 static void nrf_gpio_init(void) {
90 memset(NRF_GPIO_regs, 0, sizeof(NRF_GPIO_regs));
91
92 for (int p = 0; p < NRF_GPIOS; p ++) {
93 for (int n = 0; n < GPIO_n_ports_pins[p]; n++) {
94 NRF_GPIO_regs[p].PIN_CNF[n] = 0x2; /* Disconnected out of reset */
95 }
96 INPUT_mask[p] = UINT32_MAX; /* All disconnected out of reset */
97 }
98
99 nrf_gpio_backend_init();
100 }
101
102 NSI_TASK(nrf_gpio_init, HW_INIT, 100);
103
nrf_gpio_get_number_pins_in_port(int port)104 unsigned int nrf_gpio_get_number_pins_in_port(int port) {
105 return GPIO_n_ports_pins[port];
106 }
107
108 static void nrf_gpio_eval_outputs(unsigned int port);
109 static void nrf_gpio_eval_inputs(unsigned int port);
110 void nrf_gpio_eval_input(unsigned int port, unsigned int n, bool value);
111
112 /*
113 * Register a test callback to be called whenever a pin IN register changes
114 */
nrf_gpio_test_register_in_callback(nrf_gpio_input_callback_t fptr)115 void nrf_gpio_test_register_in_callback(nrf_gpio_input_callback_t fptr) {
116 test_intoggle_callback = fptr;
117 }
118
119 /*
120 * Change a pin input value
121 *
122 * Note: The pin must not be currently driven by the SOC, or you will get an error
123 *
124 * Inputs:
125 * * port: Which GPIO port
126 * * n: which pin in that GPIO port
127 * * value: true: high, false: low
128 */
nrf_gpio_test_change_pin_level(unsigned int port,unsigned int n,bool value)129 void nrf_gpio_test_change_pin_level(unsigned int port, unsigned int n, bool value) {
130 nrf_gpio_eval_input(port, n, value);
131 }
132
133 /*
134 * Get a pin level
135 *
136 * Inputs:
137 * * port: Which GPIO port
138 * * n: which pin in that GPIO port
139 * Return: true (high), false (low)
140 */
nrf_gpio_get_pin_level(unsigned int port,unsigned int n)141 bool nrf_gpio_get_pin_level(unsigned int port, unsigned int n) {
142 return (IO_level[port] >> n) & 0x1;
143 }
144
145 #define CHECK_PIN_EXISTS(port, n, dir) \
146 if (port >= NRF_GPIOS || n >= GPIO_n_ports_pins[port]) { \
147 bs_trace_error_time_line("%s: Error, attempted to toggle "dir" for nonexistent " \
148 "GPIO port %i, pin %i\n", \
149 __func__, port, n); \
150 }
151
get_enabled_inputs(unsigned int port)152 static inline uint32_t get_enabled_inputs(unsigned int port){
153 return (~input_override[port] & ~INPUT_mask[port])
154 | (input_override[port] & input_override_connected[port]);
155 }
156
get_dir(unsigned int port)157 static inline uint32_t get_dir(unsigned int port){
158 return (~dir_override[port] & NRF_GPIO_regs[port].DIR)
159 | (dir_override[port] & dir_override_set[port]);
160 }
161
162 /*
163 * Function with which another peripheral can claim configuration control of a pin.
164 *
165 * Inputs:
166 * * port: Which GPIO port
167 * * n : which pin in that GPIO port
168 * * override_output:
169 * * -1 : Don't change
170 * * 0 : Leave for GPIO control (GPIO OUT register sets the output value)
171 * * 1 : Take external control of pin output value (peripheral sets the output value
172 * with nrf_gpio_peri_change_output() )
173 * * override_input:
174 * * -1 : Don't change
175 * * 0 : Leave input to be controlled by the GPIO module
176 * * 2 : Take external control of input, and disconnect
177 * * 3 : Take external control of input, and connect
178 * * override_dir:
179 * * -1 : Don't change
180 * * 0 : Leave DIR to be controlled by the GPIO module
181 * * 2 : Take external control of DIR, and disconnect
182 * * 3 : Take external control of DIR, and connect
183 * * fptr: Function to be called whenever that input toggles (if enabled).
184 * Set to NULL if not needed.
185 * * new_level:
186 * * -1: Don't change
187 * * 0: low
188 * * 1: high
189 */
nrf_gpio_peri_pin_control(unsigned int port,unsigned int n,int override_output,int override_input,int override_dir,nrf_gpio_input_callback_t fptr,int new_level)190 void nrf_gpio_peri_pin_control(unsigned int port, unsigned int n,
191 int override_output, int override_input, int override_dir,
192 nrf_gpio_input_callback_t fptr, int new_level) {
193
194 if (port >= NRF_GPIOS || n >= GPIO_n_ports_pins[port]) { /* LCOV_EXCL_BR_LINE */
195 bs_trace_error_time_line("Programming error\n"); /* LCOV_EXCL_LINE */
196 }
197
198 uint32_t mask = 1<<n;
199 bool need_output_eval = false;
200 bool need_input_eval = false;
201
202 if (override_output >= 0) {
203 out_override[port] &= ~mask;
204 out_override[port] |= (uint32_t)(override_output?1:0) << n;
205 need_output_eval = true;
206 }
207 if (override_input >= 0) {
208 input_override[port] &= ~mask;
209 input_override[port] |= (uint32_t)(override_input?1:0) << n;
210
211 input_override_connected[port] &= ~mask;
212 input_override_connected[port] |= (uint32_t)(override_input==3?1:0) << n;
213
214 need_input_eval = true;
215 }
216 if (override_dir >= 0) {
217 dir_override[port] &= ~mask;
218 dir_override[port] |= (uint32_t)(override_dir?1:0) << n;
219
220 dir_override_set[port] &= ~mask;
221 dir_override_set[port] |= (uint32_t)(override_dir==3?1:0) << n;
222
223 need_output_eval = true;
224 }
225 per_intoggle_callbacks[port][n] = fptr;
226 if (new_level >= 0) {
227 external_OUT[port] &= ~((uint32_t)1 << n);
228 external_OUT[port] |= (uint32_t)(new_level?1:0) << n;
229 need_output_eval = true;
230 }
231
232 if (need_output_eval) {
233 nrf_gpio_eval_outputs(port);
234 }
235 if (need_input_eval) {
236 nrf_gpio_eval_inputs(port);
237 }
238 }
239
240 /*
241 * A peripheral wants to toggle a GPIO output to a new value <value>.
242 * Note: The value may be the same as it was, in which case nothing will happen.
243 *
244 * Inputs:
245 * * port is the GPIO port
246 * * n is the pin number inside that GPIO port (0..31)
247 * * value is the new output value high (true) or low (false)
248 */
nrf_gpio_peri_change_output(unsigned int port,unsigned int n,bool value)249 void nrf_gpio_peri_change_output(unsigned int port, unsigned int n, bool value)
250 {
251 CHECK_PIN_EXISTS(port, n, "output"); /* LCOV_EXCL_BR_LINE */
252
253 if (((out_override[port] >> n) & 0x1) != 1) { /* LCOV_EXCL_START */
254 bs_trace_error_time_line("%s: Programming error, a peripheral is trying to toggle "
255 "a GPIO output it does not own, GPIO port %i, pin %i\n",
256 __func__, port, n);
257 }
258
259 if (((get_dir(port) >> n) & 0x1) != 1) {
260 bs_trace_warning_time_line("%s: A peripheral is trying to toggle "
261 "a GPIO output but the output is disabled, "
262 "GPIO port %i, pin %i\n",
263 __func__, port, n);
264 } /* LCOV_EXCL_STOP */
265
266 external_OUT[port] &= ~((uint32_t)1 << n);
267 external_OUT[port] |= (uint32_t)value << n;
268 nrf_gpio_eval_outputs(port);
269 }
270
nrf_gpio_update_detect_signal(unsigned int port)271 static void nrf_gpio_update_detect_signal(unsigned int port) {
272 if (NRF_GPIO_regs[port].DETECTMODE == 0){ //gpio.detect signal from not latched detect
273 DETECT_signal[port] = (DETECT[port] != 0);
274 } else {//gpio.detect signal from latched detect
275 DETECT_signal[port] = (LDETECT[port] != 0);
276 }
277 }
278
279 /*
280 * Evaluate sense output (after a change of input or configuration)
281 */
nrf_gpio_eval_sense(unsigned int port)282 static void nrf_gpio_eval_sense(unsigned int port){
283 /* Note SENSE_dir inverts the output */
284 DETECT[port] = (NRF_GPIO_regs[port].IN ^ SENSE_inv[port]) & SENSE_mask[port];
285 LDETECT[port] |= DETECT[port];
286 NRF_GPIO_regs[port].LATCH = LDETECT[port];
287
288 bool old_DETECT_signal = DETECT_signal[port];
289
290 nrf_gpio_update_detect_signal(port);
291
292 if ((DETECT_signal[port] == true) && (old_DETECT_signal==false)) {
293 nrf_gpiote_port_event_raise(port);
294 }
295 }
296
297 /*
298 * Return the level of the DETECT output signal for a GPIO instance
299 *
300 * input: port: The GPIO instance number
301 */
nrf_gpio_get_detect_level(unsigned int port)302 bool nrf_gpio_get_detect_level(unsigned int port){
303 return DETECT_signal[port];
304 }
305
306 /*
307 * The input has changed and the driver is connected,
308 * notify as necessary
309 */
nrf_gpio_input_change_sideeffects(unsigned int port,unsigned int n)310 static void nrf_gpio_input_change_sideeffects(unsigned int port,unsigned int n)
311 {
312 if (per_intoggle_callbacks[port][n] != NULL) {
313 per_intoggle_callbacks[port][n](port, n, (NRF_GPIO_regs[port].IN >> n) & 0x1);
314 }
315 if (test_intoggle_callback != NULL) {
316 test_intoggle_callback(port, n, (NRF_GPIO_regs[port].IN >> n) & 0x1);
317 }
318 }
319
320 /*
321 * Get the level of the IN signal for GPIO <port> pin <n>
322 */
nrf_gpio_get_IN(unsigned int port,unsigned int n)323 bool nrf_gpio_get_IN(unsigned int port, unsigned int n) {
324 return (NRF_GPIO_regs[port].IN >> n) & 0x1;
325 }
326
327 /*
328 * An input pin has toggled or the input configuration has changed,
329 * propagate it
330 */
nrf_gpio_eval_inputs(unsigned int port)331 static void nrf_gpio_eval_inputs(unsigned int port)
332 {
333 uint32_t new_IN = IO_level[port] & get_enabled_inputs(port);
334
335 uint32_t diff = new_IN ^ NRF_GPIO_regs[port].IN;
336
337 NRF_GPIO_regs[port].IN = new_IN;
338
339 for (int n = __builtin_ffs(diff) - 1; n >= 0; n = __builtin_ffs(diff) - 1) {
340 nrf_gpio_input_change_sideeffects(port, n);
341 diff &= ~(1 << n);
342 }
343
344 nrf_gpio_eval_sense(port);
345 }
346
347 /*
348 * An input *may* be changing to a new value <value>.
349 * Note: The value may be the same as it was, in which case nothing will happen.
350 *
351 * This function is meant to be called from something which drives the input
352 * **externally**
353 *
354 * Inputs:
355 * * port is the GPIO port
356 * * n is the pin number inside that GPIO port (0..31)
357 * * value: is the input high (true) or low (false)
358 */
nrf_gpio_eval_input(unsigned int port,unsigned int n,bool value)359 void nrf_gpio_eval_input(unsigned int port, unsigned int n, bool value)
360 {
361 CHECK_PIN_EXISTS(port, n, "input"); /* LCOV_EXCL_BR_LINE */
362
363 uint32_t dir = get_dir(port);
364
365 if ((dir >> n) & 0x1) { /* LCOV_EXCL_START */
366 bs_trace_warning_time_line("%s: Attempted to drive externally a pin which is "
367 "currently being driven by the SOC. It will be ignored."
368 "GPIO port %i, pin %i\n",
369 __func__, port, n);
370 return;
371 } /* LCOV_EXCL_STOP */
372
373 int diff = ((IO_level[port] >> n) & 0x1) ^ (uint32_t)value;
374
375 if (diff == 0) {
376 /* No toggle */
377 return;
378 }
379
380 IO_level[port] ^= (uint32_t)1 << n;
381
382 nrf_gpio_eval_inputs(port);
383 }
384
385 /*
386 * The output is being changed, propagate it as necessary and/or record it.
387 */
nrf_gpio_output_change_sideeffects(unsigned int port,unsigned int n,bool value)388 static void nrf_gpio_output_change_sideeffects(unsigned int port,unsigned int n, bool value)
389 {
390 nrf_gpio_backend_write_output_change(port, n, value);
391 nrf_gpio_backend_short_propagate(port, n, value);
392 }
393
394 /*
395 * Reevaluate outputs after a configuration or OUT/external_OUT change
396 */
nrf_gpio_eval_outputs(unsigned int port)397 static void nrf_gpio_eval_outputs(unsigned int port)
398 {
399 /* Actual level in the pin, but only of the bits driven by output: */
400 static uint32_t O_level[NRF_GPIOS];
401
402 uint32_t dir = get_dir(port); /* Which pins are driven by output */
403
404 uint32_t out = (~out_override[port] & NRF_GPIO_regs[port].OUT)
405 | (out_override[port] & external_OUT[port]);
406
407 uint32_t new_output = dir & out;
408
409 uint32_t diff = new_output ^ O_level[port];
410
411 if (diff == 0) {
412 return;
413 }
414
415 O_level[port] = new_output;
416
417 IO_level[port] &= ~dir;
418 IO_level[port] |= O_level[port];
419
420 for (int n = __builtin_ffs(diff) - 1; n >= 0; n = __builtin_ffs(diff) - 1) {
421 nrf_gpio_output_change_sideeffects(port, n, (new_output >> n) & 0x1);
422 diff &= ~(1 << n);
423 }
424
425 /* Inputs may be connected to pins driven by outputs, let's check */
426 nrf_gpio_eval_inputs(port);
427 }
428
429
430 /*
431 * Register write side-effecting functions:
432 */
433
nrf_gpio_regw_sideeffects_OUT(unsigned int port)434 void nrf_gpio_regw_sideeffects_OUT(unsigned int port) {
435 nrf_gpio_eval_outputs(port);
436 }
437
nrf_gpio_regw_sideeffects_OUTSET(unsigned int port)438 void nrf_gpio_regw_sideeffects_OUTSET(unsigned int port) {
439 if (NRF_GPIO_regs[port].OUTSET) {
440 NRF_GPIO_regs[port].OUT |= NRF_GPIO_regs[port].OUTSET;
441 nrf_gpio_eval_outputs(port);
442 }
443 NRF_GPIO_regs[port].OUTSET = NRF_GPIO_regs[port].OUT;
444 }
445
nrf_gpio_regw_sideeffects_OUTCLR(unsigned int port)446 void nrf_gpio_regw_sideeffects_OUTCLR(unsigned int port) {
447 if (NRF_GPIO_regs[port].OUTCLR) {
448 NRF_GPIO_regs[port].OUT &= ~NRF_GPIO_regs[port].OUTCLR;
449 NRF_GPIO_regs[port].OUTCLR = 0;
450 nrf_gpio_eval_outputs(port);
451 }
452 }
453
nrf_gpio_regw_sideeffects_DIR(unsigned int port)454 void nrf_gpio_regw_sideeffects_DIR(unsigned int port) {
455 /* Mirror change into PIN_CNF[*].DIR */
456 for (int n = 0; n < GPIO_n_ports_pins[port]; n++ ) {
457 NRF_GPIO_regs[port].PIN_CNF[n] &= ~GPIO_PIN_CNF_DIR_Msk;
458 NRF_GPIO_regs[port].PIN_CNF[n] |= (NRF_GPIO_regs[port].DIR >> n) & 0x1;
459 }
460
461 nrf_gpio_eval_outputs(port);
462 }
463
nrf_gpio_regw_sideeffects_DIRSET(unsigned int port)464 void nrf_gpio_regw_sideeffects_DIRSET(unsigned int port) {
465 if (NRF_GPIO_regs[port].DIRSET) {
466 NRF_GPIO_regs[port].DIR |= NRF_GPIO_regs[port].DIRSET;
467 nrf_gpio_regw_sideeffects_DIR(port);
468 }
469 NRF_GPIO_regs[port].DIRSET = NRF_GPIO_regs[port].DIR;
470 }
471
nrf_gpio_regw_sideeffects_DIRCLR(unsigned int port)472 void nrf_gpio_regw_sideeffects_DIRCLR(unsigned int port) {
473 if (NRF_GPIO_regs[port].DIRCLR) {
474 NRF_GPIO_regs[port].DIR &= ~NRF_GPIO_regs[port].DIRCLR;
475 NRF_GPIO_regs[port].DIRCLR = 0;
476 nrf_gpio_regw_sideeffects_DIR(port);
477 }
478 }
479
nrf_gpio_regw_sideeffects_LATCH(unsigned int port)480 void nrf_gpio_regw_sideeffects_LATCH(unsigned int port) {
481
482 /* LATCH contains what SW wrote: */
483 uint32_t sw_input = NRF_GPIO_regs[port].LATCH;
484
485 /* Whatever bits SW set to 1, it is trying to clear: */
486 LDETECT[port] &= ~sw_input;
487
488 /* But where the sense output is high, the bits are kept high: */
489 LDETECT[port] |= DETECT[port];
490
491 NRF_GPIO_regs[port].LATCH = LDETECT[port];
492
493 nrf_gpio_update_detect_signal(port);
494
495 /*
496 * Note the text from the spec:
497 * If one or more bits in the LATCH register are '1' after the CPU has
498 * performed a clear operation on the LATCH registers, a rising edge will be generated
499 * on the LDETECT signal.
500 * "the CPU has performed a clear operation" == after writing LATCH with any bit to 1
501 */
502 if (sw_input != 0 && LDETECT[port] != 0 && NRF_GPIO_regs[port].DETECTMODE == 1) {
503 nrf_gpiote_port_event_raise(port);
504 }
505 }
506
nrf_gpio_regw_sideeffects_DETECTMODE(unsigned int port)507 void nrf_gpio_regw_sideeffects_DETECTMODE(unsigned int port) {
508 nrf_gpio_eval_sense(port);
509 }
510
nrf_gpio_regw_sideeffects_PIN_CNF(unsigned int port,unsigned int n)511 void nrf_gpio_regw_sideeffects_PIN_CNF(unsigned int port,unsigned int n) {
512
513 bool need_output_eval = false;
514 bool need_input_eval = false;
515 bool need_sense_eval = false;
516
517 int dir = NRF_GPIO_regs[port].PIN_CNF[n] & GPIO_PIN_CNF_DIR_Msk;
518
519 if (dir != ((NRF_GPIO_regs[port].DIR >> n) & 0x1)) {
520 NRF_GPIO_regs[port].DIR ^= 1 << n;
521 need_output_eval = true;
522 }
523
524 /* Note: DRIVE and PULL are not yet used in this model
525 int pull = (NRF_GPIO_regs[port].PIN_CNF[n] & GPIO_PIN_CNF_PULL_Msk)
526 >> GPIO_PIN_CNF_PULL_Pos;
527
528 int drive = (NRF_GPIO_regs[port].PIN_CNF[n] & GPIO_PIN_CNF_DRIVE_Msk)
529 >> GPIO_PIN_CNF_DRIVE_Pos;
530 */
531
532 int input = (NRF_GPIO_regs[port].PIN_CNF[n] & GPIO_PIN_CNF_INPUT_Msk)
533 >> GPIO_PIN_CNF_INPUT_Pos;
534 if (input != ((INPUT_mask[port] >> n) & 0x1)) {
535 INPUT_mask[port] ^= 1 << n;
536 need_input_eval = true;
537 }
538
539 int sense = (NRF_GPIO_regs[port].PIN_CNF[n] & GPIO_PIN_CNF_SENSE_Msk)
540 >> GPIO_PIN_CNF_SENSE_Pos;
541 if (((sense >> 1) & 0x1) != ((SENSE_mask[port] >> n) & 0x1)) {
542 SENSE_mask[port] ^= 1 << n;
543 need_sense_eval = true;
544 }
545 if ((sense & 0x1) != ((SENSE_inv[port] >> n) & 0x1)) {
546 SENSE_inv[port] ^= 1 << n;
547 need_sense_eval = true;
548 }
549
550 if (need_output_eval) {
551 nrf_gpio_eval_outputs(port);
552 }
553 if (need_input_eval) {
554 nrf_gpio_eval_inputs(port);
555 }
556 if (need_sense_eval) {
557 nrf_gpio_eval_sense(port);
558 }
559 }
560