77#include < Arduino.h>
88#include " zephyrInternal.h"
99
10- static const struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP (
11- DT_PATH (zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))};
1210
1311namespace {
12+ struct gpio_dt_spec local_gpio_dt (int ) {
13+ struct gpio_dt_spec sp = {0 };
14+ return sp;
15+ }
1416
15- /*
16- * Calculate GPIO ports/pins number statically from devicetree configuration
17- */
17+ constexpr pin_size_t local_gpio_pin ( int ) {
18+ return 0 ;
19+ }
1820
19- template <class N , class Head > constexpr const N sum_of_list (const N sum, const Head &head)
20- {
21- return sum + head;
21+ constexpr struct device * local_gpio_port (int ) {
22+ return nullptr ;
2223}
2324
24- template <class N , class Head , class ... Tail>
25- constexpr const N sum_of_list (const N sum, const Head &head, const Tail &...tail)
26- {
27- return sum_of_list (sum + head, tail...);
25+ constexpr pin_size_t global_gpio_pin (struct device * port, int pin) {
26+ return pin;
2827}
2928
29+ static const uint32_t xpins[] = {16u , 32u }; // exclusive-upper
30+ static const int port_num = sizeof (xpins) / sizeof (xpins[0 ]);
31+ static const int pin_num = 32u ;
32+
3033template <class N , class Head > constexpr const N max_in_list (const N max, const Head &head)
3134{
3235 return (max >= head) ? max : head;
@@ -38,32 +41,6 @@ constexpr const N max_in_list(const N max, const Head &head, const Tail &...tail
3841 return max_in_list ((max >= head) ? max : head, tail...);
3942}
4043
41- template <class Query , class Head >
42- constexpr const size_t is_first_appearance (const size_t &idx, const size_t &at, const size_t &found,
43- const Query &query, const Head &head)
44- {
45- return ((found == ((size_t )-1 )) && (query == head) && (idx == at)) ? 1 : 0 ;
46- }
47-
48- template <class Query , class Head , class ... Tail>
49- constexpr const size_t is_first_appearance (const size_t &idx, const size_t &at, const size_t &found,
50- const Query &query, const Head &head,
51- const Tail &...tail)
52- {
53- return ((found == ((size_t )-1 )) && (query == head) && (idx == at))
54- ? 1
55- : is_first_appearance (idx + 1 , at, (query == head ? idx : found), query,
56- tail...);
57- }
58-
59- #define GET_DEVICE_VARGS (n, p, i, _ ) DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i))
60- #define FIRST_APPEARANCE (n, p, i ) \
61- is_first_appearance (0 , i, ((size_t )-1 ), DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i)), \
62- DT_FOREACH_PROP_ELEM_SEP_VARGS (n, p, GET_DEVICE_VARGS, (, ), 0 ))
63- const int port_num =
64- sum_of_list (0 , DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios,
65- FIRST_APPEARANCE, (, )));
66-
6744#define GPIO_NGPIOS (n, p, i ) DT_PROP(DT_GPIO_CTLR_BY_IDX(n, p, i), ngpios)
6845const int max_ngpios = max_in_list(
6946 0 , DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, GPIO_NGPIOS, (, )));
@@ -101,10 +78,10 @@ struct gpio_port_callback *find_gpio_port_callback(const struct device *dev)
10178
10279void setInterruptHandler (pin_size_t pinNumber, voidFuncPtr func)
10380{
104- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
81+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
10582
10683 if (pcb) {
107- pcb->handlers [BIT (arduino_pins[ pinNumber]. pin )].handler = func;
84+ pcb->handlers [BIT (local_gpio_pin ( pinNumber) )].handler = func;
10885 }
10986}
11087
@@ -208,45 +185,56 @@ void yield(void) {
208185 * A high physical level will be interpreted as value 1
209186 */
210187void pinMode (pin_size_t pinNumber, PinMode pinMode) {
188+ const gpio_dt_spec spec = local_gpio_dt (pinNumber);
211189 if (pinMode == INPUT) { // input mode
212- gpio_pin_configure_dt (&arduino_pins[pinNumber],
213- GPIO_INPUT | GPIO_ACTIVE_HIGH);
190+ gpio_pin_configure_dt (&spec, GPIO_INPUT | GPIO_ACTIVE_HIGH);
214191 } else if (pinMode == INPUT_PULLUP) { // input with internal pull-up
215- gpio_pin_configure_dt (&arduino_pins[pinNumber],
216- GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_HIGH);
192+ gpio_pin_configure_dt (&spec, GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_HIGH);
217193 } else if (pinMode == INPUT_PULLDOWN) { // input with internal pull-down
218- gpio_pin_configure_dt (&arduino_pins[pinNumber],
219- GPIO_INPUT | GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH);
194+ gpio_pin_configure_dt (&spec, GPIO_INPUT | GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH);
220195 } else if (pinMode == OUTPUT) { // output mode
221- gpio_pin_configure_dt (&arduino_pins[pinNumber],
222- GPIO_OUTPUT_LOW | GPIO_ACTIVE_HIGH);
196+ gpio_pin_configure_dt (&spec, GPIO_OUTPUT_LOW | GPIO_ACTIVE_HIGH);
223197 }
224198}
225199
226200void digitalWrite (pin_size_t pinNumber, PinStatus status) {
227- gpio_pin_set_dt (&arduino_pins[pinNumber], status);
201+ const gpio_dt_spec spec = local_gpio_dt (pinNumber);
202+ gpio_pin_set_dt (&spec, status);
228203}
229204
230205PinStatus digitalRead (pin_size_t pinNumber) {
231- return (gpio_pin_get_dt (&arduino_pins[pinNumber]) == 1 ) ? HIGH : LOW;
206+ const gpio_dt_spec spec = local_gpio_dt (pinNumber);
207+ return (gpio_pin_get_dt (&spec) == 1 ) ? HIGH : LOW;
208+ }
209+
210+ struct k_timer arduino_pin_timers[pin_num];
211+ struct k_timer arduino_pin_timers_timeout[pin_num];
212+
213+ void tone_expiry_cb (struct k_timer *timer) {
214+ const struct gpio_dt_spec *spec = (gpio_dt_spec*)k_timer_user_data_get (timer);
215+ gpio_pin_toggle_dt (spec);
216+ }
217+
218+ void tone_timeout_cb (struct k_timer *timer) {
219+ pin_size_t pinNumber = (pin_size_t )(uintptr_t )k_timer_user_data_get (timer);
220+ noTone (pinNumber);
232221}
233222
234223void tone (pin_size_t pinNumber, unsigned int frequency, unsigned long duration) {
235224 struct k_timer *timer = &arduino_pin_timers[pinNumber].timer ;
236- const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
225+ const struct gpio_dt_spec *spec = &arduino_pins[pinNumber]. spec ;
237226 k_timeout_t timeout;
238227
239228 pinMode (pinNumber, OUTPUT);
240229
241230 if (frequency == 0 ) {
242- gpio_pin_set_dt (spec, 0 );
231+ gpio_pin_set_dt (& spec, 0 );
243232 return ;
244233 }
245234
246235 timeout = K_NSEC (NSEC_PER_SEC / (2 * frequency));
247236
248237 k_timer_init (timer, tone_expiry_cb, NULL );
249- arduino_pin_timers[pinNumber].spec = *spec;
250238 k_timer_user_data_set (timer, &arduino_pin_timers[pinNumber]);
251239 gpio_pin_set_dt (spec, 1 );
252240 k_timer_start (timer, timeout, timeout);
@@ -381,16 +369,16 @@ void attachInterrupt(pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinSt
381369 return ;
382370 }
383371
384- pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
372+ pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
385373 __ASSERT (pcb != nullptr , " gpio_port_callback not found" );
386374
387- pcb->pins |= BIT (arduino_pins[ pinNumber]. pin );
375+ pcb->pins |= BIT (local_gpio_pin ( pinNumber) );
388376 setInterruptHandler (pinNumber, callback);
389377 enableInterrupt (pinNumber);
390378
391- gpio_pin_interrupt_configure (arduino_pins[ pinNumber]. port , arduino_pins[ pinNumber]. pin , intmode);
379+ gpio_pin_interrupt_configure (local_gpio_port ( pinNumber), local_gpio_pin ( pinNumber) , intmode);
392380 gpio_init_callback (&pcb->callback , handleGpioCallback, pcb->pins );
393- gpio_add_callback (arduino_pins[ pinNumber]. port , &pcb->callback );
381+ gpio_add_callback (local_gpio_port ( pinNumber) , &pcb->callback );
394382}
395383
396384void detachInterrupt (pin_size_t pinNumber)
@@ -422,31 +410,31 @@ long random(long max) {
422410unsigned long pulseIn (pin_size_t pinNumber, uint8_t state, unsigned long timeout) {
423411 struct k_timer timer;
424412 int64_t start, end, delta = 0 ;
425- const struct gpio_dt_spec * spec = &arduino_pins[ pinNumber] ;
413+ const struct gpio_dt_spec spec = local_gpio_dt ( pinNumber) ;
426414
427415 k_timer_init (&timer, NULL , NULL );
428416 k_timer_start (&timer, K_MSEC (timeout), K_NO_WAIT);
429417
430- if (!gpio_is_ready_dt (spec)) {
418+ if (!gpio_is_ready_dt (& spec)) {
431419 goto cleanup;
432420 }
433421
434- if (!gpio_pin_is_input_dt (spec)) {
422+ if (!gpio_pin_is_input_dt (& spec)) {
435423 goto cleanup;
436424 }
437425
438- while (gpio_pin_get_dt (spec) == state && k_timer_status_get (&timer) == 0 );
426+ while (gpio_pin_get_dt (& spec) == state && k_timer_status_get (&timer) == 0 );
439427 if (k_timer_status_get (&timer) > 0 ) {
440428 goto cleanup;
441429 }
442430
443- while (gpio_pin_get_dt (spec) != state && k_timer_status_get (&timer) == 0 );
431+ while (gpio_pin_get_dt (& spec) != state && k_timer_status_get (&timer) == 0 );
444432 if (k_timer_status_get (&timer) > 0 ) {
445433 goto cleanup;
446434 }
447435
448436 start = k_uptime_ticks ();
449- while (gpio_pin_get_dt (spec) == state && k_timer_status_get (&timer) == 0 );
437+ while (gpio_pin_get_dt (& spec) == state && k_timer_status_get (&timer) == 0 );
450438 if (k_timer_status_get (&timer) > 0 ) {
451439 goto cleanup;
452440 }
@@ -462,18 +450,18 @@ unsigned long pulseIn(pin_size_t pinNumber, uint8_t state, unsigned long timeout
462450#endif // CONFIG_GPIO_GET_DIRECTION
463451
464452void enableInterrupt (pin_size_t pinNumber) {
465- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
453+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
466454
467455 if (pcb) {
468- pcb->handlers [BIT (arduino_pins[ pinNumber]. pin )].enabled = true ;
456+ pcb->handlers [BIT (local_gpio_pin ( pinNumber) )].enabled = true ;
469457 }
470458}
471459
472460void disableInterrupt (pin_size_t pinNumber) {
473- struct gpio_port_callback *pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
461+ struct gpio_port_callback *pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
474462
475463 if (pcb) {
476- pcb->handlers [BIT (arduino_pins[ pinNumber]. pin )].enabled = false ;
464+ pcb->handlers [BIT (local_gpio_pin ( pinNumber) )].enabled = false ;
477465 }
478466}
479467
@@ -493,7 +481,7 @@ void noInterrupts(void) {
493481
494482int digitalPinToInterrupt (pin_size_t pin) {
495483 struct gpio_port_callback *pcb =
496- find_gpio_port_callback (arduino_pins[ pin]. port );
484+ find_gpio_port_callback (local_gpio_port ( pin) );
497485
498486 return (pcb) ? pin : -1 ;
499487}
0 commit comments