Skip to content

Commit 1df12d9

Browse files
committed
x
1 parent e1b7227 commit 1df12d9

File tree

4 files changed

+190
-125
lines changed

4 files changed

+190
-125
lines changed

cores/arduino/Arduino.h

Lines changed: 24 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,92 +8,59 @@
88

99
#include "api/ArduinoAPI.h"
1010

11-
#include <zephyr/kernel.h>
12-
#include <zephyr/drivers/gpio.h>
13-
#include <zephyr/drivers/pwm.h>
1411
#include <zephyr/drivers/adc.h>
12+
#include <zephyr/drivers/gpio.h>
1513
#include <zephyr/drivers/i2c.h>
14+
#include <zephyr/drivers/pwm.h>
15+
#include <zephyr/kernel.h>
1616

17-
#define DIGITAL_PIN_EXISTS(n, p, i, dev, num) \
18-
(((dev == DT_REG_ADDR(DT_PHANDLE_BY_IDX(n, p, i))) && \
19-
(num == DT_PHA_BY_IDX(n, p, i, pin))) \
20-
? 1 \
21-
: 0)
22-
23-
/* Check all pins are defined only once */
24-
#define DIGITAL_PIN_CHECK_UNIQUE(i, _) \
25-
((DT_FOREACH_PROP_ELEM_SEP_VARGS( \
26-
DT_PATH(zephyr_user), digital_pin_gpios, DIGITAL_PIN_EXISTS, (+), \
27-
DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), digital_pin_gpios, i)), \
28-
DT_PHA_BY_IDX(DT_PATH(zephyr_user), digital_pin_gpios, i, pin))) == 1)
29-
30-
#if !LISTIFY(DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios), DIGITAL_PIN_CHECK_UNIQUE, (&&))
31-
#error "digital_pin_gpios has duplicate definition"
32-
#endif
33-
34-
#undef DIGITAL_PIN_CHECK_UNIQUE
17+
#define SUM_NGPIOS(i, n, p) DT_PROP(DT_PROP_BY_IDX(n, p, i), ngpios) +
18+
#define ACCUM_NGPIOS(n, p, i) LISTIFY(i, SUM_NGPIOS, (), n, p)
19+
#define ACCUM_NGPIOS_CHECK(n, p, i, node) \
20+
COND_CODE_1(DT_SAME_NODE(DT_PROP_BY_IDX(n, p, i), node), \
21+
(ACCUM_NGPIOS(n, p, i)), ())
22+
#define FIND_GPIO_IDX(node) \
23+
DT_FOREACH_PROP_ELEM_VARGS(DT_PATH(zephyr_user), gpios, ACCUM_NGPIOS_CHECK, node)
3524

3625
#ifndef LED_BUILTIN
3726

38-
/* Return the index of it if matched, oterwise return 0 */
39-
#define LED_BUILTIN_INDEX_BY_REG_AND_PINNUM(n, p, i, dev, num) \
40-
(DIGITAL_PIN_EXISTS(n, p, i, dev, num) ? i : 0)
41-
42-
/* Only matched pin returns non-zero value, so the sum is matched pin's index */
43-
#define DIGITAL_PIN_GPIOS_FIND_PIN(dev, pin) \
44-
DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_PATH(zephyr_user), digital_pin_gpios, \
45-
LED_BUILTIN_INDEX_BY_REG_AND_PINNUM, (+), dev, pin)
46-
4727
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), builtin_led_gpios) && \
4828
(DT_PROP_LEN(DT_PATH(zephyr_user), builtin_led_gpios) > 0)
4929

50-
#if !(DT_FOREACH_PROP_ELEM_SEP_VARGS( \
51-
DT_PATH(zephyr_user), digital_pin_gpios, DIGITAL_PIN_EXISTS, (+), \
52-
DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0)), \
53-
DT_PHA_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0, pin)) > 0)
54-
#warning "pin not found in digital_pin_gpios"
55-
#else
5630
#define LED_BUILTIN \
57-
DIGITAL_PIN_GPIOS_FIND_PIN( \
58-
DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0)), \
59-
DT_PHA_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0, pin))
60-
#endif
61-
31+
(FIND_GPIO_IDX(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0)) \
32+
DT_PHA_BY_IDX(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0), \
33+
pin))
6234
/* If digital-pin-gpios is not defined, tries to use the led0 alias */
6335
#elif DT_NODE_EXISTS(DT_ALIAS(led0))
64-
65-
#if !(DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_PATH(zephyr_user), digital_pin_gpios, DIGITAL_PIN_EXISTS, \
66-
(+), DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_ALIAS(led0), gpios, 0)), \
67-
DT_PHA_BY_IDX(DT_ALIAS(led0), gpios, 0, pin)) > 0)
68-
#warning "pin not found in digital_pin_gpios"
69-
#else
7036
#define LED_BUILTIN \
71-
DIGITAL_PIN_GPIOS_FIND_PIN(DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_ALIAS(led0), gpios, 0)), \
72-
DT_PHA_BY_IDX(DT_ALIAS(led0), gpios, 0, pin))
73-
#endif
74-
37+
(FIND_GPIO_IDX(DT_PHANDLE(DT_ALIAS(led0), gpios)) DT_PHA(DT_ALIAS(led0), gpios, pin))
7538
#endif // builtin_led_gpios
7639

7740
#endif // LED_BUILTIN
7841

79-
#define DN_ENUMS(n, p, i) D##i = i
42+
#define DN_ENUMS(n, p, i) \
43+
D##i = FIND_GPIO_IDX(DT_PHANDLE_BY_IDX(n, p, i)) DT_PHA_BY_IDX(n, p, i, pin)
8044

8145
/*
8246
* expand as
8347
* enum digitalPins { D0, D1, ... LED... NUM_OF_DIGITAL_PINS };
8448
*/
8549
enum digitalPins {
86-
DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, DN_ENUMS, (, )),
50+
DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, DN_ENUMS,
51+
(, )),
8752
NUM_OF_DIGITAL_PINS
8853
};
8954

9055
#ifdef CONFIG_ADC
9156

92-
#define AN_ENUMS(n, p, i) A ## i = DIGITAL_PIN_GPIOS_FIND_PIN( \
93-
DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \
57+
#define AN_ENUMS(n, p, i) \
58+
A##i = DIGITAL_PIN_GPIOS_FIND_PIN( \
59+
DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \
9460
DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)),
95-
enum analogPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user),
96-
adc_pin_gpios, AN_ENUMS) };
61+
enum analogPins {
62+
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), adc_pin_gpios, AN_ENUMS)
63+
};
9764

9865
#endif
9966

cores/arduino/zephyrCommon.cpp

Lines changed: 56 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,29 @@
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

1311
namespace {
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+
3033
template <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)
6845
const 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

10279
void 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
*/
210187
void 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

226200
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);
228203
}
229204

230205
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);
232221
}
233222

234223
void 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

396384
void detachInterrupt(pin_size_t pinNumber)
@@ -422,31 +410,31 @@ long random(long max) {
422410
unsigned 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

464452
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));
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

472460
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));
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

494482
int 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

Comments
 (0)