|
| 1 | +Board Configuration Guide |
| 2 | +========================= |
| 3 | + |
| 4 | +This document defines practical support levels for ArduinoCore-Zephyr and explains how to reach each level. |
| 5 | + |
| 6 | +The support level definitions |
| 7 | +----------------------------- |
| 8 | + |
| 9 | +### Level 0 - Basic GPIO runtime |
| 10 | + |
| 11 | +Arduino GPIO APIs are usable with **numeric pins**. |
| 12 | +All boards are expected to satisfy this level **once ArduinoCore-Zephyr is enabled**. |
| 13 | + |
| 14 | +### Level 1 — Blinky-ready |
| 15 | + |
| 16 | +The Blinky sample works if the board provides a built-in LED. |
| 17 | + |
| 18 | +### Level 2 — Digital pin definitions are available |
| 19 | + |
| 20 | +Arduino-style digital pin definitions `D0`, `D1`, … are available. |
| 21 | + |
| 22 | +### Level 3 — Common bus definitions are available |
| 23 | + |
| 24 | +Common buses (`Serial`, `Wire`, and `SPI`) are available for use. |
| 25 | + |
| 26 | +### Level 4 — PWM and ADC are available for use |
| 27 | + |
| 28 | +Channel provisioning and pin association are provided to make PWM and ADC available. |
| 29 | + |
| 30 | +### Level 5 — Supports board-specific features |
| 31 | + |
| 32 | +Board-specific peripherals and features are supported. |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | +Making a configuration for your board |
| 37 | +------------------------------------- |
| 38 | + |
| 39 | +A well-configured board equipped with an Arduino connector provides **Level 3** support without additional configurations. |
| 40 | + |
| 41 | +**Level 4** support is required to cover most standard Arduino use cases. |
| 42 | +Reaching **Level 4 and above** typically requires a board-/variant-specific overlay, typically delivered as snippets. |
| 43 | + |
| 44 | +This guide targets Level 4, which supports standard Arduino functions. |
| 45 | + |
| 46 | + |
| 47 | +### Configuration sources |
| 48 | + |
| 49 | +#### Board-provided devicetree (Zephyr source tree) |
| 50 | + |
| 51 | +A well-configured board DTS typically includes: |
| 52 | + |
| 53 | +- An Arduino-compatible connector definition, |
| 54 | + labeled as `arduino_header` (or other supported connectors) |
| 55 | +- Optionally, connector mapping nodes for PWM/ADC pin association and channel derivation (commonly `arduino_pwm` and `arduino_adc`) |
| 56 | +- Bus defaults via node labels such as `arduino_serial`, `arduino_i2c`, `arduino_spi` |
| 57 | +- A built-in LED via the `led0` alias (recommended) |
| 58 | + |
| 59 | +These are the “works out of the box” ingredients. |
| 60 | + |
| 61 | +#### Overlays |
| 62 | + |
| 63 | +Define nodes/properties under `/zephyr,user` to configure GPIO, ADC, PWM, I2C, and SPI. |
| 64 | +Use this when there is no connector definition or when you want to overwrite it. |
| 65 | + |
| 66 | + |
| 67 | +Configuration point by level |
| 68 | +---------------------------- |
| 69 | + |
| 70 | +### Level 1 |
| 71 | + |
| 72 | +If your board has an onboard LED, you can support it in one of the following ways (**lowest precedence rule first**): |
| 73 | + |
| 74 | +1. Define the `led0` alias for the LED node. |
| 75 | + |
| 76 | + You can usually find a definition like this in the board devicetree. |
| 77 | + If a `led0` alias exists, no additional configuration is needed. |
| 78 | + |
| 79 | + ```dts |
| 80 | + / { |
| 81 | + leds { |
| 82 | + compatible = "gpio-leds"; |
| 83 | +
|
| 84 | + led: led { |
| 85 | + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; |
| 86 | + }; |
| 87 | + }; |
| 88 | +
|
| 89 | + aliases { |
| 90 | + led0 = &led; |
| 91 | + }; |
| 92 | + }; |
| 93 | + ``` |
| 94 | +
|
| 95 | +2. Define `/zephyr,user/builtin-led-gpios` |
| 96 | +
|
| 97 | + Define the `builtin-led-gpios` property to explicitly select the built-in LED GPIO. |
| 98 | +
|
| 99 | + ```dts |
| 100 | + / { |
| 101 | + zephyr,user { |
| 102 | + builtin-led-gpios = <&gpio0 25 0>; |
| 103 | + }; |
| 104 | + }; |
| 105 | + ``` |
| 106 | +
|
| 107 | +3. Manually define `LED_BUILTIN` in the board-specific `variant.h` |
| 108 | +
|
| 109 | + As a last resort, you can define `LED_BUILTIN` directly in variant.h. |
| 110 | +
|
| 111 | + ```c |
| 112 | + #define LED_BUILTIN 13 |
| 113 | + ``` |
| 114 | +
|
| 115 | +
|
| 116 | +### Level 2 |
| 117 | +
|
| 118 | +Two ways to reach it (**lowest precedence rule first**): |
| 119 | +
|
| 120 | +1. **Define an Arduino connector** |
| 121 | +
|
| 122 | + If you have an Arduino header definition like the one below, |
| 123 | + `gpio-map` can be used to generate Arduino-style digital pin names (`D0`, `D1`, …). |
| 124 | + The leftmost value in each map entry is the connector pin identifier (connector-dependent). |
| 125 | +
|
| 126 | + ```dts |
| 127 | + / { |
| 128 | + arduino_header: connector { |
| 129 | + compatible = "arduino-header-r3"; |
| 130 | + #gpio-cells = <2>; |
| 131 | + gpio-map-mask = <0xffffffff 0xffffffc0>; |
| 132 | + gpio-map-pass-thru = <0 0x3f>; |
| 133 | + gpio-map = <ARDUINO_HEADER_R3_A0 0 &ioport0 14 0>, |
| 134 | + /* -- snip -- */ |
| 135 | + <ARDUINO_HEADER_R3_D15 0 &ioport1 0 0>; |
| 136 | + }; |
| 137 | + }; |
| 138 | + ``` |
| 139 | +
|
| 140 | +2. **Define `/zephyr,user/digital-pin-gpios`** |
| 141 | +
|
| 142 | + Set the list of GPIOs to use in `/zephyr,user/digital-pin-gpios`. |
| 143 | + They will be assigned in the order you set them: `D0`, `D1`, `D2`, ... |
| 144 | +
|
| 145 | + ```dts |
| 146 | + / { |
| 147 | + zephyr,user { |
| 148 | + digital-pin-gpios = <&gpio0 0 0>, |
| 149 | + <&gpio0 1 0>, |
| 150 | + /* -- snip -- */ |
| 151 | + <&gpio1 5 0>; |
| 152 | + }; |
| 153 | + }; |
| 154 | + ``` |
| 155 | +
|
| 156 | +Pin number behavior differs between `/zephyr,user/digital-pin-gpios` and connector-derived (`gpio-map`) configuration. |
| 157 | +For detailed rules, examples, and precedence between the two methods, see `documentation/configuration-reference.md`, Section D (`Pin mapping`). |
| 158 | +
|
| 159 | +
|
| 160 | +### Level 3 |
| 161 | +
|
| 162 | +Two ways to reach it (**lowest precedence rule first**): |
| 163 | +
|
| 164 | +1. **Use board default buses via connector** |
| 165 | +
|
| 166 | + If the board provides node labels such as `arduino_serial`, `arduino_i2c`, and `arduino_spi`, |
| 167 | + they will be used as defaults for `Serial`, `Wire`, and `SPI`. |
| 168 | + Use the conventional labels `arduino_serial`, `arduino_i2c`, and `arduino_spi`. |
| 169 | +
|
| 170 | + ```dts |
| 171 | + arduino_i2c: &iic1 {}; |
| 172 | + arduino_spi: &spi1 {}; |
| 173 | + arduino_serial: &uart2 {}; |
| 174 | + ``` |
| 175 | +
|
| 176 | +
|
| 177 | +2. **Define `/zephyr,user/serials`, `/zephyr,user/i2cs`, `/zephyr,user/spis`** |
| 178 | +
|
| 179 | + Set the list of UART devices to use in `/zephyr,user/serials`. |
| 180 | + This will create Arduino `Serial`, `Serial1`, ... objects. |
| 181 | + The same applies to `i2cs` and `spis` for `Wire/Wire1...` and `SPI/SPI1...`. |
| 182 | +
|
| 183 | + ```dts |
| 184 | + / { |
| 185 | + zephyr,user { |
| 186 | + serials = <&uart2>; |
| 187 | + i2cs = <&iic1>; |
| 188 | + spis = <&spi1>; |
| 189 | + }; |
| 190 | + }; |
| 191 | + ``` |
| 192 | +
|
| 193 | +You can also add settings under `/zephyr,user` to fill in missing items in the devicetree. |
| 194 | +
|
| 195 | +
|
| 196 | +### Level 4 |
| 197 | +
|
| 198 | +To correctly configure PWM and ADC, two independent items must be addressed: |
| 199 | +
|
| 200 | +1. **Pin association**: mapping PWM/ADC input/output pins to GPIO numbers |
| 201 | +2. **Channel provisioning**: PWM and ADC channel configuration |
| 202 | +
|
| 203 | +#### 1) Pin association |
| 204 | +
|
| 205 | +This is similar to configuring GPIO: |
| 206 | +
|
| 207 | +1) **Derive from connector maps** |
| 208 | +
|
| 209 | + Provide connector mappings via the board’s connector definitions (e.g., `pwm-map` and `io-channel-map`) |
| 210 | +
|
| 211 | + ```dts |
| 212 | + / { |
| 213 | + arduino_pwm: connector-pwm { |
| 214 | + compatible = "arduino-header-pwm"; |
| 215 | + #pwm-cells = <3>; |
| 216 | + pwm-map = <ARDUINO_HEADER_R3_D2 0 0 &pwm1 0 0 0>, |
| 217 | + /* -- snip -- */ |
| 218 | + <ARDUINO_HEADER_R3_D13 0 0 &pwm3 0 0 0>; |
| 219 | + pwm-map-mask = <0xffffffff 0x0 0x0>; |
| 220 | + pwm-map-pass-thru = <0x0 0xffffffff 0xffffffff>; |
| 221 | + }; |
| 222 | +
|
| 223 | + arduino_adc: analog-connector { |
| 224 | + compatible = "arduino,uno-adc"; |
| 225 | + #io-channel-cells = <1>; |
| 226 | + io-channel-map = <ARDUINO_HEADER_R3_A0 &adc0 9>, |
| 227 | + /* -- snip -- */ |
| 228 | + <ARDUINO_HEADER_R3_A5 &adc0 22>; |
| 229 | + }; |
| 230 | + }; |
| 231 | + ``` |
| 232 | +
|
| 233 | +2) **Explicit lists under `/zephyr,user`** |
| 234 | +
|
| 235 | + Set GPIO pin lists in `/zephyr,user/pwm-pin-gpios` and `/zephyr,user/adc-pin-gpios`. |
| 236 | +
|
| 237 | + ```dts |
| 238 | + / { |
| 239 | + zephyr,user { |
| 240 | + pwm-pin-gpios = <&gpio0 3 0>, |
| 241 | + /* -- snip -- */ |
| 242 | + <&gpio0 11 0>; |
| 243 | +
|
| 244 | + adc-pin-gpios = <&gpio0 14 0>, |
| 245 | + /* -- snip -- */ |
| 246 | + <&gpio0 21 0>; |
| 247 | + }; |
| 248 | + }; |
| 249 | + ``` |
| 250 | +
|
| 251 | +
|
| 252 | +#### 2) Channel provisioning |
| 253 | +
|
| 254 | +ArduinoCore-Zephyr needs a list of available PWM/ADC channels. |
| 255 | +You can provide it in either of the following ways (**lowest precedence rule first**): |
| 256 | +
|
| 257 | +1) **Derive from connector maps** |
| 258 | +
|
| 259 | + If the board defines `arduino_pwm` with `pwm-map` and/or `arduino_adc` with `io-channel-map`, |
| 260 | + ArduinoCore-Zephyr can derive the channel lists from those maps. |
| 261 | + In that case, the additional `/zephyr,user` properties are not required. |
| 262 | + In other words, all you need to do is set the ADC channel settings described below. |
| 263 | +
|
| 264 | +2) **Explicit lists under `/zephyr,user`** |
| 265 | +
|
| 266 | + Set the PWM/ADC channels corresponding to the pins specified by `pwm-pin-gpios` and `adc-pin-gpios`. |
| 267 | + - PWM channels: `/zephyr,user/pwms` |
| 268 | + - ADC channels: `/zephyr,user/io-channels` |
| 269 | +
|
| 270 | + ```dts |
| 271 | + / { |
| 272 | + zephyr,user { |
| 273 | + pwms = <&pwm1 1 255 PWM_POLARITY_NORMAL>, |
| 274 | + /* -- snip -- */ |
| 275 | + <&pwm2 3 255 PWM_POLARITY_NORMAL>; |
| 276 | +
|
| 277 | + io-channels = <&adc 2>, |
| 278 | + /* -- snip -- */ |
| 279 | + <&adc 1>; |
| 280 | + }; |
| 281 | + }; |
| 282 | + ``` |
| 283 | +
|
| 284 | +For ADC, you still need to define per-channel settings under each ADC device node. |
| 285 | +See also the examples in `samples/drivers/adc/adc_dt`. |
| 286 | +
|
| 287 | + ```dts |
| 288 | + &adc { |
| 289 | + #address-cells = <1>; |
| 290 | + #size-cells = <0>; |
| 291 | +
|
| 292 | + channel@0 { |
| 293 | + reg = <0>; |
| 294 | + zephyr,gain = "ADC_GAIN_1_6"; |
| 295 | + zephyr,reference = "ADC_REF_INTERNAL"; |
| 296 | + zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>; |
| 297 | + zephyr,input-positive = <NRF_SAADC_AIN0>; /* P0.02 */ |
| 298 | + zephyr,resolution = <10>; |
| 299 | + }; |
| 300 | + /* -- snip -- */ |
| 301 | + }; |
| 302 | + ``` |
| 303 | +
|
| 304 | +
|
| 305 | +### Level 5 |
| 306 | +
|
| 307 | +Level 5 supports special features of each board, and the way to achieve this varies by board. |
| 308 | +
|
| 309 | +It may require: |
| 310 | +- adding definitions to `variant.h` or overlays, |
| 311 | +- adding libraries to support the features, or |
| 312 | +- adding features to Zephyr itself when necessary. |
0 commit comments