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 arduino_pins[gpin].port ;
63+ }
64+
65+ constexpr inline pin_size_t local_gpio_pin (pin_size_t gpin) {
66+ return arduino_pins[gpin].pin ;
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
@@ -259,18 +281,19 @@ static struct pin_timer* find_pin_timer(pin_size_t pinNumber, bool active_only)
259281void tone_expiry_cb (struct k_timer *timer) {
260282 struct pin_timer *pt = CONTAINER_OF (timer, struct pin_timer , timer);
261283 k_spinlock_key_t key = k_spin_lock (&pt->lock );
284+ const struct device *port = local_gpio_port (pt->pin );
262285 pin_size_t pin = pt->pin ;
263286
264287 if (pt->count == 0 && !pt->infinity ) {
265- if (pin != pin_size_t (- 1 ) ) {
266- gpio_pin_set_dt (&arduino_pins[ pin] , 0 );
288+ if (port ) {
289+ gpio_pin_set (port, local_gpio_pin (pt-> pin ) , 0 );
267290 }
268291
269292 k_timer_stop (timer);
270293 pt->pin = pin_size_t (-1 );
271294 } else {
272- if (pin != pin_size_t (- 1 ) ) {
273- gpio_pin_toggle_dt (&arduino_pins[ pin] );
295+ if (port ) {
296+ gpio_pin_toggle (port, local_gpio_pin (pt-> pin ) );
274297 }
275298
276299 pt->count --;
@@ -284,8 +307,10 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
284307 k_spinlock_key_t key;
285308 struct pin_timer *pt;
286309 k_timeout_t timeout;
310+ const struct device *port;
287311
288312 pt = find_pin_timer (pinNumber, false );
313+ port = local_gpio_port (pt->pin );
289314
290315 if (pt == nullptr ) {
291316 return ;
@@ -295,7 +320,9 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
295320 k_timer_stop (&pt->timer );
296321
297322 if (frequency == 0 ) {
298- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
323+ if (port) {
324+ gpio_pin_set (port, local_gpio_pin (pinNumber), 0 );
325+ }
299326 return ;
300327 }
301328
@@ -312,15 +339,19 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
312339
313340 k_timer_init (&pt->timer , tone_expiry_cb, NULL );
314341
315- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
342+ if (port) {
343+ gpio_pin_set (port, local_gpio_pin (pinNumber), 0 );
344+ }
316345 k_timer_start (&pt->timer , timeout, timeout);
317346}
318347
319348void noTone (pin_size_t pinNumber) {
320349 struct pin_timer *pt;
321350 k_spinlock_key_t key;
351+ const struct device *port;
322352
323353 pt = find_pin_timer (pinNumber, true );
354+ port = local_gpio_port (pt->pin );
324355
325356 if (pt == nullptr ) {
326357 return ;
@@ -331,7 +362,9 @@ void noTone(pin_size_t pinNumber) {
331362 pt->pin = pin_size_t (-1 );
332363 k_spin_unlock (&pt->lock , key);
333364
334- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
365+ if (port) {
366+ gpio_pin_set (port, local_gpio_pin (pinNumber), 0 );
367+ }
335368}
336369
337370void delay (unsigned long ms) {
@@ -433,6 +466,7 @@ int analogRead(pin_size_t pinNumber)
433466
434467void attachInterrupt (pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinStatus)
435468{
469+ const struct device *port = local_gpio_port (pinNumber);
436470 struct gpio_port_callback *pcb;
437471 gpio_flags_t intmode = 0 ;
438472
@@ -454,16 +488,18 @@ void attachInterrupt(pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinSt
454488 return ;
455489 }
456490
457- pcb = find_gpio_port_callback (arduino_pins[pinNumber]. port );
491+ pcb = find_gpio_port_callback (port);
458492 __ASSERT (pcb != nullptr , " gpio_port_callback not found" );
459493
460- pcb->pins |= BIT (arduino_pins[ pinNumber]. pin );
494+ pcb->pins |= BIT (local_gpio_pin ( pinNumber) );
461495 setInterruptHandler (pinNumber, callback);
462496 enableInterrupt (pinNumber);
463497
464- gpio_pin_interrupt_configure (arduino_pins[pinNumber].port , arduino_pins[pinNumber].pin , intmode);
465- gpio_init_callback (&pcb->callback , handleGpioCallback, pcb->pins );
466- gpio_add_callback (arduino_pins[pinNumber].port , &pcb->callback );
498+ if (port) {
499+ gpio_pin_interrupt_configure (port, local_gpio_pin (pinNumber), intmode);
500+ gpio_init_callback (&pcb->callback , handleGpioCallback, pcb->pins );
501+ gpio_add_callback (port, &pcb->callback );
502+ }
467503}
468504
469505void detachInterrupt (pin_size_t pinNumber)
@@ -491,29 +527,30 @@ long random(long max) {
491527#endif
492528
493529unsigned long pulseIn (pin_size_t pinNumber, uint8_t state, unsigned long timeout) {
530+ const struct device *port = local_gpio_port (pinNumber);
531+ const size_t pin = local_gpio_pin (pinNumber);
494532 struct k_timer timer;
495533 int64_t start, end, delta = 0 ;
496- const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
497534
498- if (!gpio_is_ready_dt (spec )) {
535+ if (!device_is_ready (port )) {
499536 return 0 ;
500537 }
501538
502539 k_timer_init (&timer, NULL , NULL );
503540 k_timer_start (&timer, K_MSEC (timeout), K_NO_WAIT);
504541
505- while (gpio_pin_get_dt (spec ) == state && k_timer_status_get (&timer) == 0 );
542+ while (gpio_pin_get (port, pin ) == state && k_timer_status_get (&timer) == 0 );
506543 if (k_timer_status_get (&timer) > 0 ) {
507544 goto cleanup;
508545 }
509546
510- while (gpio_pin_get_dt (spec ) != state && k_timer_status_get (&timer) == 0 );
547+ while (gpio_pin_get (port, pin ) != state && k_timer_status_get (&timer) == 0 );
511548 if (k_timer_status_get (&timer) > 0 ) {
512549 goto cleanup;
513550 }
514551
515552 start = k_uptime_ticks ();
516- 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 );
517554 if (k_timer_status_get (&timer) > 0 ) {
518555 goto cleanup;
519556 }
@@ -527,18 +564,18 @@ unsigned long pulseIn(pin_size_t pinNumber, uint8_t state, unsigned long timeout
527564}
528565
529566void enableInterrupt (pin_size_t pinNumber) {
530- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
567+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
531568
532569 if (pcb) {
533- pcb->handlers [arduino_pins[ pinNumber]. pin ].enabled = true ;
570+ pcb->handlers [local_gpio_pin ( pinNumber) ].enabled = true ;
534571 }
535572}
536573
537574void disableInterrupt (pin_size_t pinNumber) {
538- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
575+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
539576
540577 if (pcb) {
541- pcb->handlers [arduino_pins[ pinNumber]. pin ].enabled = false ;
578+ pcb->handlers [local_gpio_pin ( pinNumber) ].enabled = false ;
542579 }
543580}
544581
@@ -558,7 +595,7 @@ void noInterrupts(void) {
558595
559596int digitalPinToInterrupt (pin_size_t pin) {
560597 struct gpio_port_callback *pcb =
561- find_gpio_port_callback (arduino_pins[ pin]. port );
598+ find_gpio_port_callback (local_gpio_port ( pin) );
562599
563600 return (pcb) ? pin : -1 ;
564601}
0 commit comments