7
7
#include < Arduino.h>
8
8
#include " zephyrInternal.h"
9
9
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, (, ))};
12
10
13
11
namespace {
12
+ struct gpio_dt_spec local_gpio_dt (int ) {
13
+ struct gpio_dt_spec sp = {0 };
14
+ return sp;
15
+ }
14
16
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
+ }
18
20
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 ;
22
23
}
23
24
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;
28
27
}
29
28
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
+
30
33
template <class N , class Head > constexpr const N max_in_list (const N max, const Head &head)
31
34
{
32
35
return (max >= head) ? max : head;
@@ -38,32 +41,6 @@ constexpr const N max_in_list(const N max, const Head &head, const Tail &...tail
38
41
return max_in_list ((max >= head) ? max : head, tail...);
39
42
}
40
43
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
-
67
44
#define GPIO_NGPIOS (n, p, i ) DT_PROP(DT_GPIO_CTLR_BY_IDX(n, p, i), ngpios)
68
45
const int max_ngpios = max_in_list(
69
46
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)
101
78
102
79
void setInterruptHandler (pin_size_t pinNumber, voidFuncPtr func)
103
80
{
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) );
105
82
106
83
if (pcb) {
107
- pcb->handlers [BIT (arduino_pins[ pinNumber]. pin )].handler = func;
84
+ pcb->handlers [BIT (local_gpio_pin ( pinNumber) )].handler = func;
108
85
}
109
86
}
110
87
@@ -208,45 +185,56 @@ void yield(void) {
208
185
* A high physical level will be interpreted as value 1
209
186
*/
210
187
void pinMode (pin_size_t pinNumber, PinMode pinMode) {
188
+ const gpio_dt_spec spec = local_gpio_dt (pinNumber);
211
189
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);
214
191
} 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);
217
193
} 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);
220
195
} 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);
223
197
}
224
198
}
225
199
226
200
void 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);
228
203
}
229
204
230
205
PinStatus 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);
232
221
}
233
222
234
223
void tone (pin_size_t pinNumber, unsigned int frequency, unsigned long duration) {
235
224
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 ;
237
226
k_timeout_t timeout;
238
227
239
228
pinMode (pinNumber, OUTPUT);
240
229
241
230
if (frequency == 0 ) {
242
- gpio_pin_set_dt (spec, 0 );
231
+ gpio_pin_set_dt (& spec, 0 );
243
232
return ;
244
233
}
245
234
246
235
timeout = K_NSEC (NSEC_PER_SEC / (2 * frequency));
247
236
248
237
k_timer_init (timer, tone_expiry_cb, NULL );
249
- arduino_pin_timers[pinNumber].spec = *spec;
250
238
k_timer_user_data_set (timer, &arduino_pin_timers[pinNumber]);
251
239
gpio_pin_set_dt (spec, 1 );
252
240
k_timer_start (timer, timeout, timeout);
@@ -381,16 +369,16 @@ void attachInterrupt(pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinSt
381
369
return ;
382
370
}
383
371
384
- pcb = find_gpio_port_callback (arduino_pins[ pinNumber]. port );
372
+ pcb = find_gpio_port_callback (local_gpio_port ( pinNumber) );
385
373
__ASSERT (pcb != nullptr , " gpio_port_callback not found" );
386
374
387
- pcb->pins |= BIT (arduino_pins[ pinNumber]. pin );
375
+ pcb->pins |= BIT (local_gpio_pin ( pinNumber) );
388
376
setInterruptHandler (pinNumber, callback);
389
377
enableInterrupt (pinNumber);
390
378
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);
392
380
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 );
394
382
}
395
383
396
384
void detachInterrupt (pin_size_t pinNumber)
@@ -422,31 +410,31 @@ long random(long max) {
422
410
unsigned long pulseIn (pin_size_t pinNumber, uint8_t state, unsigned long timeout) {
423
411
struct k_timer timer;
424
412
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) ;
426
414
427
415
k_timer_init (&timer, NULL , NULL );
428
416
k_timer_start (&timer, K_MSEC (timeout), K_NO_WAIT);
429
417
430
- if (!gpio_is_ready_dt (spec)) {
418
+ if (!gpio_is_ready_dt (& spec)) {
431
419
goto cleanup;
432
420
}
433
421
434
- if (!gpio_pin_is_input_dt (spec)) {
422
+ if (!gpio_pin_is_input_dt (& spec)) {
435
423
goto cleanup;
436
424
}
437
425
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 );
439
427
if (k_timer_status_get (&timer) > 0 ) {
440
428
goto cleanup;
441
429
}
442
430
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 );
444
432
if (k_timer_status_get (&timer) > 0 ) {
445
433
goto cleanup;
446
434
}
447
435
448
436
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 );
450
438
if (k_timer_status_get (&timer) > 0 ) {
451
439
goto cleanup;
452
440
}
@@ -462,18 +450,18 @@ unsigned long pulseIn(pin_size_t pinNumber, uint8_t state, unsigned long timeout
462
450
#endif // CONFIG_GPIO_GET_DIRECTION
463
451
464
452
void 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) );
466
454
467
455
if (pcb) {
468
- pcb->handlers [BIT (arduino_pins[ pinNumber]. pin )].enabled = true ;
456
+ pcb->handlers [BIT (local_gpio_pin ( pinNumber) )].enabled = true ;
469
457
}
470
458
}
471
459
472
460
void 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) );
474
462
475
463
if (pcb) {
476
- pcb->handlers [BIT (arduino_pins[ pinNumber]. pin )].enabled = false ;
464
+ pcb->handlers [BIT (local_gpio_pin ( pinNumber) )].enabled = false ;
477
465
}
478
466
}
479
467
@@ -493,7 +481,7 @@ void noInterrupts(void) {
493
481
494
482
int digitalPinToInterrupt (pin_size_t pin) {
495
483
struct gpio_port_callback *pcb =
496
- find_gpio_port_callback (arduino_pins[ pin]. port );
484
+ find_gpio_port_callback (local_gpio_port ( pin) );
497
485
498
486
return (pcb) ? pin : -1 ;
499
487
}
0 commit comments