99
1010#include < zephyr/spinlock.h>
1111
12- static const struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP (
12+ static constexpr struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP (
1313 DT_PATH (zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))};
1414
1515namespace {
@@ -58,6 +58,18 @@ constexpr const size_t is_first_appearance(const size_t &idx, const size_t &at,
5858 tail...);
5959}
6060
61+ constexpr inline const struct device *local_gpio_port (pin_size_t gpin) {
62+ return (gpin < ARRAY_SIZE (arduino_pins)) ? arduino_pins[gpin].port : nullptr ;
63+ }
64+
65+ constexpr inline pin_size_t local_gpio_pin (pin_size_t gpin) {
66+ return (gpin < ARRAY_SIZE (arduino_pins)) ? arduino_pins[gpin].pin : pin_size_t (-1 );
67+ }
68+
69+ inline int global_gpio_pin_configure (pin_size_t pinNumber, int flags) {
70+ return gpio_pin_configure_dt (&arduino_pins[pinNumber], flags);
71+ }
72+
6173#define GET_DEVICE_VARGS (n, p, i, _ ) DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i))
6274#define FIRST_APPEARANCE (n, p, i ) \
6375 is_first_appearance (0 , i, ((size_t )-1 ), DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i)), \
@@ -103,10 +115,10 @@ struct gpio_port_callback *find_gpio_port_callback(const struct device *dev)
103115
104116void setInterruptHandler (pin_size_t pinNumber, voidFuncPtr func)
105117{
106- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
118+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
107119
108120 if (pcb) {
109- pcb->handlers [arduino_pins[ pinNumber]. pin ].handler = func;
121+ pcb->handlers [local_gpio_pin ( pinNumber) ].handler = func;
110122 }
111123}
112124
@@ -192,26 +204,36 @@ void yield(void) {
192204 */
193205void pinMode (pin_size_t pinNumber, PinMode pinMode) {
194206 if (pinMode == INPUT) { // input mode
195- gpio_pin_configure_dt (&arduino_pins[ pinNumber] ,
207+ global_gpio_pin_configure ( pinNumber,
196208 GPIO_INPUT | GPIO_ACTIVE_HIGH);
197209 } else if (pinMode == INPUT_PULLUP) { // input with internal pull-up
198- gpio_pin_configure_dt (&arduino_pins[ pinNumber] ,
210+ global_gpio_pin_configure ( pinNumber,
199211 GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_HIGH);
200212 } else if (pinMode == INPUT_PULLDOWN) { // input with internal pull-down
201- gpio_pin_configure_dt (&arduino_pins[ pinNumber] ,
213+ global_gpio_pin_configure ( pinNumber,
202214 GPIO_INPUT | GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH);
203215 } else if (pinMode == OUTPUT) { // output mode
204- gpio_pin_configure_dt (&arduino_pins[ pinNumber] ,
216+ global_gpio_pin_configure ( pinNumber,
205217 GPIO_OUTPUT_LOW | GPIO_ACTIVE_HIGH);
206218 }
207219}
208220
209221void digitalWrite (pin_size_t pinNumber, PinStatus status) {
210- gpio_pin_set_dt (&arduino_pins[pinNumber], status);
222+ const struct device *port = local_gpio_port (pinNumber);
223+
224+ if (port) {
225+ gpio_pin_set (port, local_gpio_pin (pinNumber), status);
226+ }
211227}
212228
213229PinStatus digitalRead (pin_size_t pinNumber) {
214- return (gpio_pin_get_dt (&arduino_pins[pinNumber]) == 1 ) ? HIGH : LOW;
230+ const struct device *port = local_gpio_port (pinNumber);
231+
232+ if (port) {
233+ return (gpio_pin_get (port, local_gpio_pin (pinNumber)) == 1 ) ? HIGH : LOW;
234+ } else {
235+ return LOW;
236+ }
215237}
216238
217239#if CONFIG_ARDUINO_MAX_TONES < 0
@@ -264,18 +286,19 @@ static struct pin_timer* find_pin_timer(pin_size_t pinNumber, bool active_only)
264286void tone_expiry_cb (struct k_timer *timer) {
265287 struct pin_timer *pt = CONTAINER_OF (timer, struct pin_timer , timer);
266288 k_spinlock_key_t key = k_spin_lock (&pt->lock );
289+ const struct device *port = local_gpio_port (pt->pin );
267290 pin_size_t pin = pt->pin ;
268291
269292 if (pt->count == 0 && !pt->infinity ) {
270- if (pin != pin_size_t (- 1 ) ) {
271- gpio_pin_set_dt (&arduino_pins[ pin] , 0 );
293+ if (port ) {
294+ gpio_pin_set (port, local_gpio_pin (pt-> pin ) , 0 );
272295 }
273296
274297 k_timer_stop (timer);
275298 pt->pin = pin_size_t (-1 );
276299 } else {
277- if (pin != pin_size_t (- 1 ) ) {
278- gpio_pin_toggle_dt (&arduino_pins[ pin] );
300+ if (port ) {
301+ gpio_pin_toggle (port, local_gpio_pin (pt-> pin ) );
279302 }
280303
281304 pt->count --;
@@ -289,13 +312,16 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
289312 k_spinlock_key_t key;
290313 struct pin_timer *pt;
291314 k_timeout_t timeout;
315+ const struct device *port;
292316
293317 pt = find_pin_timer (pinNumber, false );
294318
295319 if (pt == nullptr ) {
296320 return ;
297321 }
298322
323+ port = local_gpio_port (pt->pin );
324+
299325 pinMode (pinNumber, OUTPUT);
300326 k_timer_stop (&pt->timer );
301327
@@ -304,7 +330,9 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
304330 pt->pin = pin_size_t (-1 );
305331 k_spin_unlock (&pt->lock , key);
306332
307- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
333+ if (port) {
334+ gpio_pin_set (port, local_gpio_pin (pinNumber), 0 );
335+ }
308336 return ;
309337 }
310338
@@ -321,26 +349,33 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
321349
322350 k_timer_init (&pt->timer , tone_expiry_cb, NULL );
323351
324- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
352+ if (port) {
353+ gpio_pin_set (port, local_gpio_pin (pinNumber), 0 );
354+ }
325355 k_timer_start (&pt->timer , timeout, timeout);
326356}
327357
328358void noTone (pin_size_t pinNumber) {
329359 struct pin_timer *pt;
330360 k_spinlock_key_t key;
361+ const struct device *port;
331362
332363 pt = find_pin_timer (pinNumber, true );
333364
334365 if (pt == nullptr ) {
335366 return ;
336367 }
337368
369+ port = local_gpio_port (pt->pin );
370+
338371 key = k_spin_lock (&pt->lock );
339372 k_timer_stop (&pt->timer );
340373 pt->pin = pin_size_t (-1 );
341374 k_spin_unlock (&pt->lock , key);
342375
343- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
376+ if (port) {
377+ gpio_pin_set (port, local_gpio_pin (pinNumber), 0 );
378+ }
344379}
345380
346381void delay (unsigned long ms) {
@@ -442,6 +477,7 @@ int analogRead(pin_size_t pinNumber)
442477
443478void attachInterrupt (pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinStatus)
444479{
480+ const struct device *port = local_gpio_port (pinNumber);
445481 struct gpio_port_callback *pcb;
446482 gpio_flags_t intmode = 0 ;
447483
@@ -463,16 +499,18 @@ void attachInterrupt(pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinSt
463499 return ;
464500 }
465501
466- pcb = find_gpio_port_callback (arduino_pins[pinNumber]. port );
502+ pcb = find_gpio_port_callback (port);
467503 __ASSERT (pcb != nullptr , " gpio_port_callback not found" );
468504
469- pcb->pins |= BIT (arduino_pins[ pinNumber]. pin );
505+ pcb->pins |= BIT (local_gpio_pin ( pinNumber) );
470506 setInterruptHandler (pinNumber, callback);
471507 enableInterrupt (pinNumber);
472508
473- gpio_pin_interrupt_configure (arduino_pins[pinNumber].port , arduino_pins[pinNumber].pin , intmode);
474- gpio_init_callback (&pcb->callback , handleGpioCallback, pcb->pins );
475- gpio_add_callback (arduino_pins[pinNumber].port , &pcb->callback );
509+ if (port) {
510+ gpio_pin_interrupt_configure (port, local_gpio_pin (pinNumber), intmode);
511+ gpio_init_callback (&pcb->callback , handleGpioCallback, pcb->pins );
512+ gpio_add_callback (port, &pcb->callback );
513+ }
476514}
477515
478516void detachInterrupt (pin_size_t pinNumber)
@@ -500,29 +538,30 @@ long random(long max) {
500538#endif
501539
502540unsigned long pulseIn (pin_size_t pinNumber, uint8_t state, unsigned long timeout) {
541+ const struct device *port = local_gpio_port (pinNumber);
542+ const size_t pin = local_gpio_pin (pinNumber);
503543 struct k_timer timer;
504544 int64_t start, end, delta = 0 ;
505- const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
506545
507- if (!gpio_is_ready_dt (spec )) {
546+ if (!device_is_ready (port )) {
508547 return 0 ;
509548 }
510549
511550 k_timer_init (&timer, NULL , NULL );
512551 k_timer_start (&timer, K_MSEC (timeout), K_NO_WAIT);
513552
514- while (gpio_pin_get_dt (spec ) == state && k_timer_status_get (&timer) == 0 );
553+ while (gpio_pin_get (port, pin ) == state && k_timer_status_get (&timer) == 0 );
515554 if (k_timer_status_get (&timer) > 0 ) {
516555 goto cleanup;
517556 }
518557
519- while (gpio_pin_get_dt (spec ) != state && k_timer_status_get (&timer) == 0 );
558+ while (gpio_pin_get (port, pin ) != state && k_timer_status_get (&timer) == 0 );
520559 if (k_timer_status_get (&timer) > 0 ) {
521560 goto cleanup;
522561 }
523562
524563 start = k_uptime_ticks ();
525- while (gpio_pin_get_dt (spec ) == state && k_timer_status_get (&timer) == 0 );
564+ while (gpio_pin_get (port, pin ) == state && k_timer_status_get (&timer) == 0 );
526565 if (k_timer_status_get (&timer) > 0 ) {
527566 goto cleanup;
528567 }
@@ -536,18 +575,18 @@ unsigned long pulseIn(pin_size_t pinNumber, uint8_t state, unsigned long timeout
536575}
537576
538577void enableInterrupt (pin_size_t pinNumber) {
539- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
578+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
540579
541580 if (pcb) {
542- pcb->handlers [arduino_pins[ pinNumber]. pin ].enabled = true ;
581+ pcb->handlers [local_gpio_pin ( pinNumber) ].enabled = true ;
543582 }
544583}
545584
546585void disableInterrupt (pin_size_t pinNumber) {
547- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
586+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
548587
549588 if (pcb) {
550- pcb->handlers [arduino_pins[ pinNumber]. pin ].enabled = false ;
589+ pcb->handlers [local_gpio_pin ( pinNumber) ].enabled = false ;
551590 }
552591}
553592
@@ -567,7 +606,7 @@ void noInterrupts(void) {
567606
568607int digitalPinToInterrupt (pin_size_t pin) {
569608 struct gpio_port_callback *pcb =
570- find_gpio_port_callback (arduino_pins[ pin]. port );
609+ find_gpio_port_callback (local_gpio_port ( pin) );
571610
572611 return (pcb) ? pin : -1 ;
573612}
0 commit comments