11/*
22 * Copyright (c) 2022 Dhruva Gole
3+ * Copyright (c) 2026 TOKITA Hiroshi
34 *
45 * SPDX-License-Identifier: Apache-2.0
56 */
910
1011#include < zephyr/spinlock.h>
1112
13+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
1214static constexpr struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP (
1315 DT_PATH (zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))};
16+ #else
17+ #define GET_GPIO_DEVICES (node_id ) \
18+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(node_id), \
19+ (COND_CODE_1(DT_NODE_HAS_PROP(node_id, gpio_controller), \
20+ (DEVICE_DT_GET(node_id),), ())), ())
21+
22+ #define GET_GPIO_NGPIOS (node_id ) \
23+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(node_id), \
24+ (COND_CODE_1(DT_NODE_HAS_PROP(node_id, gpio_controller), \
25+ (DT_PROP(node_id, ngpios),), ())), ())
26+
27+ static constexpr const struct device *gpio_ports[] = {DT_FOREACH_NODE (GET_GPIO_DEVICES)};
28+ static constexpr uint32_t gpio_ngpios[] = {DT_FOREACH_NODE (GET_GPIO_NGPIOS)};
29+ #endif
1430
1531namespace {
1632
@@ -58,18 +74,77 @@ constexpr const size_t is_first_appearance(const size_t &idx, const size_t &at,
5874 tail...);
5975}
6076
77+ #if !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
78+ constexpr inline const struct device *local_gpio_port (pin_size_t gpin);
79+
80+ constexpr inline const struct device *local_gpio_port_r (pin_size_t pin,
81+ const struct device *const *ctrl,
82+ const uint32_t accum, const uint32_t *end,
83+ size_t n) {
84+ return (n == 0 ) ? nullptr :
85+ (pin < accum + end[0 ]) ? ctrl[0 ] :
86+ local_gpio_port_r (pin, ctrl + 1 , accum + end[0 ], end + 1 , n - 1 );
87+ }
88+
89+ constexpr inline size_t port_index_r (const struct device *target, const struct device *const *table,
90+ pin_size_t idx, size_t n) {
91+ return (n == 0 ) ? size_t (-1 ) :
92+ (target == table[0 ]) ? idx : port_index_r (target, table + 1 , idx + 1 , n - 1 );
93+ }
94+
95+ constexpr inline pin_size_t port_idx (pin_size_t gpin) {
96+ return port_index_r (local_gpio_port (gpin), gpio_ports, 0 , ARRAY_SIZE (gpio_ports));
97+ }
98+
99+ constexpr inline pin_size_t end_accum_r (const uint32_t accum, const uint32_t *end, size_t n) {
100+ return (n == 0 ) ? accum : end_accum_r (accum + end[0 ], end + 1 , n - 1 );
101+ }
102+
103+ constexpr inline pin_size_t end_accum (size_t n) {
104+ return end_accum_r (0 , gpio_ngpios, n);
105+ }
106+
107+ constexpr inline pin_size_t global_gpio_pin_ (size_t port_idx, pin_size_t lpin) {
108+ return port_idx == size_t (-1 ) ? size_t (-1 ) : end_accum (port_idx) + lpin;
109+ }
110+
111+ constexpr inline pin_size_t global_gpio_pin (const struct device *lport, pin_size_t lpin) {
112+ return global_gpio_pin_ (port_index_r (lport, gpio_ports, 0 , ARRAY_SIZE (gpio_ports)), lpin);
113+ }
114+ #endif
115+
61116constexpr inline const struct device *local_gpio_port (pin_size_t gpin) {
117+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
62118 return arduino_pins[gpin].port ;
119+ #else
120+ return local_gpio_port_r (gpin, gpio_ports, 0 , gpio_ngpios, ARRAY_SIZE (gpio_ports));
121+ #endif
63122}
64123
65124constexpr inline pin_size_t local_gpio_pin (pin_size_t gpin) {
125+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
66126 return arduino_pins[gpin].pin ;
127+ #else
128+ return port_idx (gpin) == pin_size_t (-1 ) ? pin_size_t (-1 ) : gpin - end_accum (port_idx (gpin));
129+ #endif
67130}
68131
69132inline int global_gpio_pin_configure (pin_size_t pinNumber, int flags) {
133+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
70134 return gpio_pin_configure_dt (&arduino_pins[pinNumber], flags);
135+ #else
136+ const struct device *port = local_gpio_port (pinNumber);
137+
138+ if (port) {
139+ return gpio_pin_configure (port, local_gpio_pin (pinNumber), flags);
140+ } else {
141+ return -1 ;
142+ }
143+ #endif
71144}
72145
146+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
147+ #if DT_PROP_LEN_OR(DT_PATH(zephyr_user), digital_pin_gpios, 0) > 0
73148#define GET_DEVICE_VARGS (n, p, i, _ ) DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i))
74149#define FIRST_APPEARANCE (n, p, i ) \
75150 is_first_appearance (0 , i, ((size_t )-1), DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i)), \
@@ -81,6 +156,14 @@ const int port_num =
81156#define GPIO_NGPIOS (n, p, i ) DT_PROP(DT_GPIO_CTLR_BY_IDX(n, p, i), ngpios)
82157const int max_ngpios = max_in_list(
83158 0 , DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, GPIO_NGPIOS, (, )));
159+ #else
160+ const int port_num = 1 ;
161+ const int max_ngpios = 0 ;
162+ #endif
163+ #else
164+ const int port_num = ARRAY_SIZE(gpio_ports);
165+ const int max_ngpios = max_in_list(DT_FOREACH_NODE(GET_GPIO_NGPIOS) 0 );
166+ #endif
84167
85168/*
86169 * GPIO callback implementation
@@ -100,6 +183,10 @@ struct gpio_port_callback {
100183
101184struct gpio_port_callback *find_gpio_port_callback (const struct device *dev)
102185{
186+ if (dev == nullptr ) {
187+ return nullptr ;
188+ }
189+
103190 for (size_t i = 0 ; i < ARRAY_SIZE (port_callback); i++) {
104191 if (port_callback[i].dev == dev) {
105192 return &port_callback[i];
@@ -140,13 +227,32 @@ void handleGpioCallback(const struct device *port, struct gpio_callback *cb, uin
140227 DIGITAL_PIN_GPIOS_FIND_PIN ( \
141228 DT_REG_ADDR (DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \
142229 DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)),
143-
144- const struct pwm_dt_spec arduino_pwm[] =
145- { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), pwms, PWM_DT_SPEC) };
230+ #define PWM_CONN_CHANNEL_DT (n, p, i ) \
231+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(DT_MAP_ENTRY_PARENT_BY_IDX(n, p, i)), \
232+ ({ .dev = DEVICE_DT_GET (DT_MAP_ENTRY_PARENT_BY_IDX (n, p, i)), \
233+ .channel = DT_MAP_ENTRY_PARENT_SPECIFIER_BY_IDX (n, p, i, 0 ), },), \
234+ ())
235+ #define PWM_CONN_PINNUM (n, p, i ) \
236+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(DT_MAP_ENTRY_PARENT_BY_IDX(n, p, i)), \
237+ (DT_MAP_ENTRY_CHILD_SPECIFIER_BY_IDX(n, p, i, 0 ),), \
238+ ())
239+
240+ const struct pwm_dt_spec arduino_pwm[] = {
241+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), adc_pin_gpios)
242+ DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), pwms, PWM_DT_SPEC)
243+ #elif defined(ZARD_PWM_CONNECTOR)
244+ DT_FOREACH_MAP_ENTRY (DT_NODELABEL (ZARD_PWM_CONNECTOR), pwm_map, PWM_CONN_CHANNEL_DT)
245+ #endif
246+ };
146247
147248/* pwm-pins node provides a mapping digital pin numbers to pwm channels */
148- const pin_size_t arduino_pwm_pins[] =
149- { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), pwm_pin_gpios, PWM_PINS) };
249+ const pin_size_t arduino_pwm_pins[] = {
250+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), pwm_pin_gpios)
251+ DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), pwm_pin_gpios, PWM_PINS)
252+ #elif defined(ZARD_PWM_CONNECTOR)
253+ DT_FOREACH_MAP_ENTRY (DT_NODELABEL (ZARD_PWM_CONNECTOR), pwm_map, PWM_CONN_PINNUM)
254+ #endif
255+ };
150256
151257size_t pwm_pin_index (pin_size_t pinNumber) {
152258 for (size_t i=0 ; i<ARRAY_SIZE (arduino_pwm_pins); i++) {
@@ -167,16 +273,45 @@ size_t pwm_pin_index(pin_size_t pinNumber) {
167273 DT_REG_ADDR (DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \
168274 DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)),
169275#define ADC_CH_CFG (n,p,i ) arduino_adc[i].channel_cfg,
170-
171- const struct adc_dt_spec arduino_adc[] =
172- { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), io_channels, ADC_DT_SPEC) };
276+ #define ADC_CONN_CHANNEL_CFG (n, p, i ) \
277+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(DT_MAP_ENTRY_PARENT_BY_IDX(n, p, i)), \
278+ (ADC_CHANNEL_CFG_DT(ADC_CHANNEL_DT_NODE(DT_MAP_ENTRY_PARENT_BY_IDX(n, p, i), \
279+ DT_MAP_ENTRY_PARENT_SPECIFIER_BY_IDX(n, p, i, 0 ))),), \
280+ ())
281+ #define ADC_CONN_CHANNEL_DT (n, p, i ) \
282+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(DT_MAP_ENTRY_PARENT_BY_IDX(n, p, i)), \
283+ (ADC_DT_SPEC_STRUCT(DT_MAP_ENTRY_PARENT_BY_IDX(n, p, i), \
284+ DT_MAP_ENTRY_PARENT_SPECIFIER_BY_IDX(n, p, i, 0 )),), \
285+ ())
286+ #define ADC_CONN_PINNUM (n, p, i ) \
287+ COND_CODE_1 (DT_NODE_HAS_STATUS_OKAY(DT_MAP_ENTRY_PARENT_BY_IDX(n, p, i)), \
288+ (DT_MAP_ENTRY_CHILD_SPECIFIER_BY_IDX(n, p, i, 0 ),), \
289+ ())
290+
291+ const struct adc_dt_spec arduino_adc[] = {
292+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), adc_pin_gpios)
293+ DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), io_channels, ADC_DT_SPEC)
294+ #elif defined(ZARD_ADC_CONNECTOR)
295+ DT_FOREACH_MAP_ENTRY (DT_NODELABEL (ZARD_ADC_CONNECTOR), io_channel_map, ADC_CONN_CHANNEL_DT)
296+ #endif
297+ };
173298
174299/* io-channel-pins node provides a mapping digital pin numbers to adc channels */
175- const pin_size_t arduino_analog_pins[] =
176- { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), adc_pin_gpios, ADC_PINS) };
300+ const pin_size_t arduino_analog_pins[] = {
301+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), adc_pin_gpios)
302+ DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), adc_pin_gpios, ADC_PINS)
303+ #elif defined(ZARD_ADC_CONNECTOR)
304+ DT_FOREACH_MAP_ENTRY (DT_NODELABEL (ZARD_ADC_CONNECTOR), io_channel_map, ADC_CONN_PINNUM)
305+ #endif
306+ };
177307
178- struct adc_channel_cfg channel_cfg[ARRAY_SIZE(arduino_analog_pins)] =
179- { DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), io_channels, ADC_CH_CFG) };
308+ struct adc_channel_cfg channel_cfg[ARRAY_SIZE(arduino_analog_pins)] = {
309+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), adc_pin_gpios)
310+ DT_FOREACH_PROP_ELEM (DT_PATH (zephyr_user), io_channels, ADC_CH_CFG)
311+ #elif defined(ZARD_ADC_CONNECTOR)
312+ DT_FOREACH_MAP_ENTRY (DT_NODELABEL (ZARD_ADC_CONNECTOR), io_channel_map, ADC_CONN_CHANNEL_CFG)
313+ #endif
314+ };
180315
181316size_t analog_pin_index (pin_size_t pinNumber) {
182317 for (size_t i=0 ; i<ARRAY_SIZE (arduino_analog_pins); i++) {
@@ -237,7 +372,11 @@ PinStatus digitalRead(pin_size_t pinNumber) {
237372}
238373
239374#if CONFIG_ARDUINO_MAX_TONES < 0
375+ #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), digital_pin_gpios)
240376#define MAX_TONE_PINS DT_PROP_LEN (DT_PATH(zephyr_user), digital_pin_gpios)
377+ #elif defined(ZARD_CONNECTOR)
378+ #define MAX_TONE_PINS DT_PROP_LEN (DT_NODELABEL(ZARD_CONNECTOR), gpio_map)
379+ #endif
241380#else
242381#define MAX_TONE_PINS CONFIG_ARDUINO_MAX_TONES
243382#endif
0 commit comments