Skip to content

Support "file-less" configuration#151

Draft
soburi wants to merge 10 commits into
zephyrproject-rtos:nextfrom
soburi:configure_by_connector_def
Draft

Support "file-less" configuration#151
soburi wants to merge 10 commits into
zephyrproject-rtos:nextfrom
soburi:configure_by_connector_def

Conversation

@soburi

@soburi soburi commented Feb 1, 2026

Copy link
Copy Markdown
Member

This PR introduce new configuration system without variants/[board].overlay.

Boards that has arduino like connector mostly has define arduino-header.
We can use this information to configure automatically for each boards.
We can support all zephyr supported that has arduino-header.
That means, we make it works for more 200 boards, including Nucleo series.

However, only Blinky works out of the box, and ADC and PWM channels are required.
These should be made into snippets in the future.

Fix #11
Fix #90

@soburi soburi force-pushed the configure_by_connector_def branch from 30e80c9 to 2157ae2 Compare February 1, 2026 15:38
@soburi soburi changed the title Configure by connector def Support **file-less** configuration Feb 1, 2026
@soburi soburi changed the title Support **file-less** configuration Support "file-less" configuration Feb 1, 2026
@soburi soburi force-pushed the configure_by_connector_def branch 2 times, most recently from d14bab2 to 769f878 Compare February 5, 2026 15:17
@soburi soburi marked this pull request as ready for review February 5, 2026 15:17
Copilot AI review requested due to automatic review settings February 5, 2026 15:17
@soburi soburi marked this pull request as draft February 5, 2026 15:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a "file-less" configuration system that automatically configures boards using Arduino-compatible header definitions from the device tree, eliminating the need for board-specific overlay files. The system detects supported connector types (arduino_header, arduino_mkr_header, etc.) and automatically maps GPIO pins, enabling support for 200+ Zephyr-supported boards including the Nucleo series.

Changes:

  • Added automatic board detection using device tree connector labels (arduino_header, pico_header, etc.)
  • Introduced GPIO port/pin abstraction layer with constexpr helper functions for compile-time pin mapping
  • Modified tone/noTone implementation to support dynamic timer allocation by tracking pin assignments
  • Updated PWM and ADC pin mappings to support both legacy and new connector-based configurations

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 21 comments.

File Description
cores/arduino/Arduino.h Adds macro definitions for automatic connector detection (ZARD_CONNECTOR, ZARD_ADC_CONNECTOR, ZARD_PWM_CONNECTOR) and updates digital/analog pin enums to support both legacy and connector-based configurations
cores/arduino/zephyrCommon.cpp Implements GPIO abstraction layer with constexpr functions for pin mapping, updates all GPIO operations to use new abstraction, and modifies tone/noTone for improved timer management

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/Arduino.h Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread samples/tone_doremi/src/app.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/Arduino.h
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment thread cores/arduino/zephyrCommon.cpp Outdated
@soburi soburi force-pushed the configure_by_connector_def branch 3 times, most recently from 9d23221 to 293076c Compare February 9, 2026 10:57
@DhruvaG2000

Copy link
Copy Markdown
Member

This PR looks quite interesting, will be on my next list of things to review!

@soburi soburi force-pushed the configure_by_connector_def branch from 293076c to 7e1fd4c Compare February 9, 2026 14:23
Comment thread variants/arduino_uno_r4_r7fa4m1ab3cfm/variant.h Outdated
@soburi soburi force-pushed the configure_by_connector_def branch 8 times, most recently from dd32c52 to dc41a17 Compare February 11, 2026 03:46
@soburi soburi requested a review from Copilot February 11, 2026 04:41
@soburi soburi force-pushed the configure_by_connector_def branch from 55ac529 to 33935c2 Compare March 2, 2026 13:26
@soburi soburi added DNM This PR should not be merged (Do Not Merge) and removed DNM This PR should not be merged (Do Not Merge) labels Mar 2, 2026
@DhruvaG2000

Copy link
Copy Markdown
Member

@soburi any reaosn to keep this DNM? What's the wait for?

@soburi

soburi commented Mar 31, 2026

Copy link
Copy Markdown
Member Author

@soburi any reaosn to keep this DNM? What's the wait for?

There are several patches I want to synchronize with the Arduino.
This commit involves extensive modifications, so I want to do it in a way that minimizes the effort required.

arduino#340

@soburi soburi force-pushed the configure_by_connector_def branch from 33935c2 to 34d02a8 Compare April 25, 2026 05:31
@soburi soburi requested a review from Copilot April 25, 2026 05:31
@soburi soburi marked this pull request as draft April 25, 2026 05:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 21 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment on lines +13 to +15
// create an array of arduino_pins with functions to reinitialize pins if needed
static const struct device *pinmux_array[DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios)] = {
nullptr};

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pinmux_array uses DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios) unconditionally. If /zephyr,user does not define digital-pin-gpios (the connector-derived / “file-less” mode described in this PR), DT_PROP_LEN will not compile. Use DT_PROP_LEN_OR(..., 0) and/or guard the whole pinmux_array/reinit machinery behind DT_NODE_HAS_PROP(..., digital_pin_gpios) (or size it from the connector map length / max pin number).

Copilot uses AI. Check for mistakes.
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment on lines 651 to 671
static int _analog_write_resolution = 8;

void analogWriteResolution(int bits) {
_analog_write_resolution = bits;
}

int analogWriteResolution() {
return _analog_write_resolution;
}
#endif

#ifdef CONFIG_PWM

static uint32_t map64(uint32_t x, uint32_t in_min, uint32_t in_max, uint32_t out_min,
uint32_t out_max) {
return ((uint64_t)(x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);
}

void analogWrite(pin_size_t pinNumber, int value) {
const int maxInput = BIT(_analog_write_resolution) - 1U;
size_t idx = pwm_pin_index(pinNumber);

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analogWriteResolution(int bits) stores bits without validation, but analogWrite() later does BIT(_analog_write_resolution); values <= 0 or >= word size can cause undefined behavior (shift overflow) and incorrect clamping/mapping. Clamp bits to a safe range (e.g., 1..16 or 1..32 depending on desired support) and ensure maxInput is computed safely for edge cases.

Copilot uses AI. Check for mistakes.
Comment thread cores/arduino/zephyrInternal.h Outdated

void enableInterrupt(pin_size_t);
void disableInterrupt(pin_size_t);
void _reinit_peripheral_if_needed(pin_size_t pin, const struct device *dev);

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_reinit_peripheral_if_needed is a global C symbol that begins with a leading underscore. Identifiers with a leading underscore at global scope are reserved for the implementation in C/C++, so this name risks conflicts/undefined behavior. Please rename it to a non-reserved identifier (e.g., zarduino_reinit_peripheral_if_needed or similar).

Suggested change
void _reinit_peripheral_if_needed(pin_size_t pin, const struct device *dev);
void zarduino_reinit_peripheral_if_needed(pin_size_t pin, const struct device *dev);

Copilot uses AI. Check for mistakes.
Comment thread libraries/SPI/SPI.cpp
Comment on lines 120 to 122
void arduino::ZephyrSPI::begin() {
spi_dev->ops.init(spi_dev);
}

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling spi_dev->ops.init() directly reaches into Zephyr internal device ops and may double-initialize the device (or break across Zephyr updates). Prefer relying on standard device init (boot) and/or Zephyr PM/runtime-PM APIs; at minimum, check device_is_ready(spi_dev) before use.

Copilot uses AI. Check for mistakes.
Comment on lines +61 to 63
uart->ops.init(uart);

uart_configure(uart, &config);

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling uart->ops.init(uart) directly uses Zephyr internal device ops and may cause double initialization or incompatibilities across Zephyr versions. If the goal is to re-enable a UART after end(), consider using Zephyr’s supported device PM/runtime-PM APIs (or avoid manual init entirely) and guard with device_is_ready(uart)/null checks as needed.

Copilot uses AI. Check for mistakes.
Comment thread cores/arduino/zephyrCommon.cpp Outdated
Comment on lines +750 to +760
// Note: We can not update the arduino_adc structure as it is read only...
static int read_resolution = 10;

void analogReadResolution(int bits) {
read_resolution = bits;
}

int analogReadResolution() {
return read_resolution;
}

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analogReadResolution(int bits) stores bits without validation, but analogRead() later shifts by (read_resolution - seq.resolution). Large values (or <= 0) can lead to undefined behavior due to oversized shifts and nonsensical scaling. Clamp bits to a sensible range (and consider matching Arduino’s typical 1..16 behavior).

Copilot uses AI. Check for mistakes.
Comment thread cores/arduino/Arduino.h
Comment on lines +197 to +199
// Allow namespace-less operations if Arduino.h is included
using namespace arduino;

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using namespace arduino; in a widely-included public header can unexpectedly pollute the global namespace for all consumers and create name collisions/ambiguity in user sketches and libraries. Prefer exposing only the needed symbols (or provide wrapper typedefs/functions) instead of a global using namespace in the header.

Suggested change
// Allow namespace-less operations if Arduino.h is included
using namespace arduino;

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +14
#if DT_NODE_EXISTS(DT_NODELABEL(arduino_header)) && \
DT_NODE_HAS_COMPAT(DT_NODELABEL(arduino_header), arduino_header_r3)
#include "arduino_header_r3.h"
#else
#error "Only arduino-header-r3 connector is supported"
#endif

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

connector.h hard-fails the build with #error when arduino_header is absent or not arduino-header-r3. This prevents the intended “works on any board” / numeric-pin (Level 0) behavior and will break boards that don’t have an Arduino header. Consider making connector support optional (e.g., only enable connector-derived pin mapping when the connector exists; otherwise compile with only numeric/global GPIO APIs and without D/A enums).

Copilot uses AI. Check for mistakes.
Comment thread cores/arduino/inlines.h
Comment on lines +11 to +13
#ifndef __INLINES_H__
#define __INLINES_H__

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The include guard macro __INLINES_H__ uses a double-underscore identifier, which is reserved in C/C++. Please rename the guard to a non-reserved macro (e.g., ARDUINO_INLINES_H), or use #pragma once for consistency with other headers in this PR.

Copilot uses AI. Check for mistakes.
Comment thread libraries/SPI/SPI.cpp
Comment on lines 124 to +129
void arduino::ZephyrSPI::end() {
#ifdef CONFIG_DEVICE_DEINIT_SUPPORT
if (spi_dev->ops.deinit) {
spi_dev->ops.deinit(spi_dev);
}
#endif

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with Wire, calling spi_dev->ops.deinit() directly relies on internal Zephyr device details. Please consider switching to a supported deinit/PM API or isolating this behind a core helper so it’s easier to keep compatible with Zephyr device lifecycle changes.

Copilot uses AI. Check for mistakes.
@soburi soburi force-pushed the configure_by_connector_def branch from 34d02a8 to 949f58a Compare April 25, 2026 05:47
@soburi soburi force-pushed the configure_by_connector_def branch 4 times, most recently from d754f16 to d13186a Compare May 7, 2026 23:31
@soburi soburi force-pushed the configure_by_connector_def branch 2 times, most recently from edaf5de to 900de85 Compare May 31, 2026 10:43
Allow Arduino APIs to switch a pin between GPIO and peripheral
functions by re-running the selected device init path when
the requested owner changes.

This is an interim pinmux handoff mechanism for boards where
sketches may move a pin back and forth between
serial/GPIO/PWM-style use.

Co-Authored-by: Martino Facchin <m.facchin@arduino.cc>
Co-Authored-by: pennam <m.pennasilico@arduino.cc>
Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
@soburi soburi force-pushed the configure_by_connector_def branch from 900de85 to 5e4800f Compare June 1, 2026 05:19
soburi added 5 commits June 1, 2026 14:20
Define `invalid_pin_number` and replace `pin_size_t(-1)`.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
In preparation for improvements to allow the use of GPIOs without
device tree definitions,
the interface will be changed to specify port and pin instead of
`gpio_dt_spec`.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Like digital pins, ADCs and PWMs are also defined from connectors.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Add guide for adding new board configuration and configuration
reference.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
A new configuration method has been adopted, allowing support to be added
with less configuration than before.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
@soburi soburi force-pushed the configure_by_connector_def branch from 5e4800f to d7b3c5b Compare June 1, 2026 05:20
soburi added 4 commits June 1, 2026 14:20
Replace {0} with {} for port_callback, set dac_channel_cfg::internal
explicitly, and expand the adc_sequence initialization to make default
values explicit and avoid C++ initializer warnings.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Move constexpr-specified constants and functions used for compile-time
calculations from zephyrCommon.cpp to wiring_private.h.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Split zephyrCommon.cpp into smaller source files.

wiring_digital.cpp:
  - pinMode
  - digitalWrite
  - digitalRead

wiring_analog.cpp:
  - analogRead
  - analogWrite
  - analogReference
  - analogReadResolution
  - analogWriteResolution

wiring_pulse.cpp:
  - pulseIn

WInterrupts.cpp:
  - attachInterrupt
  - detachInterrupt
  - interrupts
  - noInterrupts
  - digitalPinToInterrupt

WMath.cpp:
  - randomSeed
  - random

Tone.cpp:
  - tone
  - noTone

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Move the constant array derived from devicetree to wiring_private.h
and convert it to constexpr.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DNM This PR should not be merged (Do Not Merge)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Builds fail if variant does not have any GPIOs Autogenerate board support

4 participants