11/*
22 * Copyright (c) 2022 Dhruva Gole
3+ * Copyright (c) 2026 TOKITA Hiroshi
34 *
45 * SPDX-License-Identifier: Apache-2.0
56 */
67
78#include < Arduino.h>
89#include " zephyrInternal.h"
910
11+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
1012static constexpr struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP (
1113 DT_PATH (zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))};
14+ #else
15+ #define GET_GPIO_DEVICES (node_id ) \
16+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(node_id), \
17+ (COND_CODE_1(DT_NODE_HAS_PROP(node_id, gpio_controller), \
18+ (DEVICE_DT_GET(node_id),), ())), ())
19+
20+ #define GET_GPIO_NGPIOS (node_id ) \
21+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(node_id), \
22+ (COND_CODE_1(DT_NODE_HAS_PROP(node_id, gpio_controller), \
23+ (DT_PROP(node_id, ngpios),), ())), ())
24+
25+ static constexpr const struct device *gpio_ports[] = {
26+ DT_FOREACH_NODE (GET_GPIO_DEVICES)
27+ };
28+ static constexpr uint32_t gpio_ngpios[] = {
29+ DT_FOREACH_NODE (GET_GPIO_NGPIOS)
30+ };
31+ #endif
1232
1333namespace {
1434
@@ -56,18 +76,77 @@ constexpr const size_t is_first_appearance(const size_t &idx, const size_t &at,
5676 tail...);
5777}
5878
79+ #if !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
80+ constexpr inline const struct device *local_gpio_port (pin_size_t gpin);
81+
82+ constexpr inline const struct device *local_gpio_port_r (pin_size_t pin,
83+ const struct device *const *ctrl,
84+ const uint32_t accum,
85+ const uint32_t *end, size_t n) {
86+ return (n == 0 )
87+ ? nullptr
88+ : (pin < accum + end[0 ])
89+ ? ctrl[0 ]
90+ : local_gpio_port_r (pin, ctrl + 1 , accum + end[0 ], end + 1 , n - 1 );
91+ }
92+
93+ constexpr inline size_t port_index_r (const struct device *target,
94+ const struct device *const *table, pin_size_t idx, size_t n) {
95+ return (n == 0 )
96+ ? size_t (-1 )
97+ : (target == table[0 ])
98+ ? idx
99+ : port_index_r (target, table + 1 , idx + 1 , n - 1 );
100+ }
101+
102+
103+ constexpr inline pin_size_t port_idx (pin_size_t gpin) {
104+ return port_index_r (local_gpio_port (gpin), gpio_ports, 0 , ARRAY_SIZE (gpio_ports));
105+ }
106+
107+ constexpr inline pin_size_t end_accum_r (const uint32_t accum, const uint32_t *end, size_t n) {
108+ return (n == 0 ) ? accum : end_accum_r (accum + end[0 ], end + 1 , n - 1 );
109+ }
110+
111+ constexpr inline pin_size_t end_accum (size_t n) {
112+ return end_accum_r (0 , gpio_ngpios, n);
113+ }
114+
115+ constexpr inline pin_size_t global_gpio_pin_ (size_t port_idx, pin_size_t lpin) {
116+ return port_idx == size_t (-1 ) ? size_t (-1 ) : end_accum (port_idx) + lpin;
117+ }
118+
119+ constexpr inline pin_size_t global_gpio_pin (const struct device *lport, pin_size_t lpin) {
120+ return global_gpio_pin_ (port_index_r (lport, gpio_ports, 0 , ARRAY_SIZE (gpio_ports)), lpin);
121+ }
122+ #endif
123+
59124constexpr inline const struct device *local_gpio_port (pin_size_t gpin) {
125+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
60126 return arduino_pins[gpin].port ;
127+ #else
128+ return local_gpio_port_r (gpin, gpio_ports, 0 , gpio_ngpios, ARRAY_SIZE (gpio_ports));
129+ #endif
61130}
62131
63132constexpr inline pin_size_t local_gpio_pin (pin_size_t gpin) {
133+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
64134 return arduino_pins[gpin].pin ;
135+ #else
136+ return port_idx (gpin) == pin_size_t (-1 ) ? pin_size_t (-1 ) : gpin - end_accum (port_idx (gpin));
137+ #endif
65138}
66139
67140inline int global_gpio_pin_configure (pin_size_t pinNumber, int flags) {
141+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
68142 return gpio_pin_configure_dt (&arduino_pins[pinNumber], flags);
143+ #else
144+ return gpio_pin_configure (local_gpio_port (pinNumber), local_gpio_pin (pinNumber), flags);
145+ #endif
69146}
70147
148+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
149+ #if DT_PROP_LEN_OR(DT_PATH(zephyr_user), digital_pin_gpios, 0) > 0
71150#define GET_DEVICE_VARGS (n, p, i, _ ) DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i))
72151#define FIRST_APPEARANCE (n, p, i ) \
73152 is_first_appearance (0 , i, ((size_t )-1), DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i)), \
@@ -79,6 +158,14 @@ const int port_num =
79158#define GPIO_NGPIOS (n, p, i ) DT_PROP(DT_GPIO_CTLR_BY_IDX(n, p, i), ngpios)
80159const int max_ngpios = max_in_list(
81160 0 , DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, GPIO_NGPIOS, (, )));
161+ #else
162+ const int port_num = 1 ;
163+ const int max_ngpios = 0 ;
164+ #endif
165+ #else
166+ const int port_num = ARRAY_SIZE(gpio_ports);
167+ const int max_ngpios = max_in_list( DT_FOREACH_NODE(GET_GPIO_NGPIOS) 0 );
168+ #endif
82169
83170/*
84171 * GPIO callback implementation
@@ -138,13 +225,19 @@ void handleGpioCallback(const struct device *port, struct gpio_callback *cb, uin
138225 DIGITAL_PIN_GPIOS_FIND_PIN ( \
139226 DT_REG_ADDR (DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \
140227 DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)),
228+ #define PWM_CONN_PINNUM (n, p, i ) DT_MAP_ENTRY_CHILD_SPECIFIER_BY_IDX(n, p, i, 0 )
141229
142230const struct pwm_dt_spec arduino_pwm[] =
143231 { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), pwms, PWM_DT_SPEC) };
144232
145233/* pwm-pins node provides a mapping digital pin numbers to pwm channels */
146- const pin_size_t arduino_pwm_pins[] =
147- { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), pwm_pin_gpios, PWM_PINS) };
234+ const pin_size_t arduino_pwm_pins[] = {
235+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), pwm_pin_gpios)
236+ DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), pwm_pin_gpios, PWM_PINS)
237+ #else
238+ DT_FOREACH_MAP_ENTRY_SEP (DT_NODELABEL (ZARD_PWM_CONNECTOR), pwm_map, PWM_CONN_PINNUM, (, ))
239+ #endif
240+ };
148241
149242size_t pwm_pin_index (pin_size_t pinNumber) {
150243 for (size_t i=0 ; i<ARRAY_SIZE (arduino_pwm_pins); i++) {
@@ -165,13 +258,19 @@ size_t pwm_pin_index(pin_size_t pinNumber) {
165258 DT_REG_ADDR (DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \
166259 DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)),
167260#define ADC_CH_CFG (n,p,i ) arduino_adc[i].channel_cfg,
261+ #define ADC_CONN_PINNUM (n, p, i ) DT_MAP_ENTRY_CHILD_SPECIFIER_BY_IDX(n, p, i, 0 )
168262
169263const struct adc_dt_spec arduino_adc[] =
170264 { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), io_channels, ADC_DT_SPEC) };
171265
172266/* io-channel-pins node provides a mapping digital pin numbers to adc channels */
173- const pin_size_t arduino_analog_pins[] =
174- { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), adc_pin_gpios, ADC_PINS) };
267+ const pin_size_t arduino_analog_pins[] = {
268+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), adc_pin_gpios)
269+ DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), adc_pin_gpios, ADC_PINS)
270+ #else
271+ DT_FOREACH_MAP_ENTRY_SEP (DT_NODELABEL (ZARD_ADC_CONNECTOR), io_channel_map, ADC_CONN_PINNUM, (,))
272+ #endif
273+ };
175274
176275struct adc_channel_cfg channel_cfg[ARRAY_SIZE(arduino_analog_pins)] =
177276 { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), io_channels, ADC_CH_CFG) };
@@ -225,7 +324,13 @@ PinStatus digitalRead(pin_size_t pinNumber) {
225324}
226325
227326#ifndef MAX_TONE_PINS
327+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
228328#define MAX_TONE_PINS DT_PROP_LEN (DT_PATH(zephyr_user), digital_pin_gpios)
329+ #elif defined(ZARD_CONNECTOR)
330+ #define MAX_TONE_PINS DT_PROP_LEN (DT_NODELABEL(ZARD_CONNECTOR), gpio_map)
331+ #else
332+ #define MAX_TONE_PINS 1
333+ #endif
229334#endif
230335
231336#define TOGGLES_PER_CYCLE 2ULL
0 commit comments