| # Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. |
| # SPDX-License-Identifier: Apache-2.0 |
| |
| description: | |
| Espressif's Pin controller Node |
| Based on pincfg-node.yaml binding. |
| Espressif's pin controller is in charge of controlling pin configurations, pin |
| functionalities and pin properties as defined by pin states. In its turn, pin |
| states are composed of pre-defined pin muxing definitions and user-provided |
| pin properties. |
| |
| Each Zephyr-based application has its own set of pin muxing/pin configuration |
| requirements. The next steps use ESP-WROVER-KIT's I2C_0 to illustrate how one |
| could change a node's pin state properties. Though based on a particular board, |
| the same steps can be tweaked to address specifics of any other target board. |
| |
| Suppose an application running on top of the ESP-WROVER-KIT board, for some |
| reason it needs I2C_0's SDA signal to be routed to GPIO_33. When looking at |
| that board's original device tree source file (i.e., 'esp_wrover_kit.dts'), |
| you'll notice that the I2C_0 node is already assigned to a set of states. |
| Below is highlighted the information that most interests us on that file |
| |
| |
| #include "esp_wrover_kit-pinctrl.dtsi" |
| |
| &i2c0 { |
| pinctrl-0 = <&i2c0_sda_gpio21 &i2c0_scl_gpio22>; |
| pinctrl-names = "default"; |
| }; |
| |
| |
| From the above excerpt, the pincrl-0 property is composed of 'i2c0_sda_gpio21' |
| and 'i2c0_scl_gpio22' pin states. The naming convention makes it clear that |
| I2C_0's SDA signal is, by default, routed to GPIO_21 on the target board. Pin |
| states are defined on another file (i.e, 'esp_wrover_kit-pinctrl.dtsi') on |
| the same folder of the DTS file. Check below the excerpt describing SDA's |
| pin state |
| |
| |
| i2c0_sda_gpio21: i2c0_sda_gpio21 { |
| pinmux = <I2C0_SDA_GPIO21>; |
| bias-pull-up; |
| drive-open-drain; |
| output-high; |
| }; |
| |
| |
| Only the 'pinmux' property above is actually required, other properties can |
| be chosen if meaningful for the target application and, of course, supported |
| by your target hardware. For example, some custom board may have an external |
| pull-up resistor soldered to GPIO_21's pin pad, in which case, 'bias-pull-up' |
| could be no longer required. |
| |
| Back to our fictional application, the previous SDA state definition does not |
| meet our expectations, remember, we would like to route I2C_0's SDA signal to |
| GPIO_33 and not to GPIO_21. To achieve our goal, we need to update the 'pinmux' |
| property accordingly. |
| |
| Note that replacing 'I2C0_SDA_GPIO21' by 'I2C0_SDA_GPIO33' is very tempting and |
| may even work, however, unless you have checked the hardware documentation first, |
| it is not recommended. That's because there are no guarantees that a particular |
| IO pin has the capability to route any specific signal. |
| |
| The recommendation is to check the pinmux macros definitions available for the |
| target SoC in the following URL |
| |
| |
| https://github.com/zephyrproject-rtos/hal_espressif/tree/zephyr/include/dt-bindings/pinctrl |
| |
| |
| The ESP-WROVER-KIT board is based on the ESP32 SoC, in that case, we search |
| through the file 'esp32-pinctrl.h' in the above URL. Luckily for us, there is |
| one definition on that file that corresponds to our needs |
| |
| |
| #define I2C0_SDA_GPIO33 \ |
| ESP32_PINMUX(33, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) |
| |
| |
| Now, we go back to edit 'esp_wrover_kit-pinctrl.dtsi' and create a new pin state |
| on that file (or replace/update the one already defined) using the pinmux macro |
| definition above, yielding |
| |
| |
| i2c0_sda_gpio33: i2c0_sda_gpio33 { |
| pinmux = <I2C0_SDA_GPIO33>; |
| bias-pull-up; |
| drive-open-drain; |
| output-high; |
| }; |
| |
| |
| Finally, update the I2C0 node state information in the device tree source using the |
| new (or updated) state |
| |
| |
| &ic20 { |
| pinctrl-0 = <&i2c0_sda_gpio33 &i2c0_scl_gpio22>; |
| pinctrl-names = "default"; |
| }; |
| |
| |
| With proper adaptations, the same steps above apply when using different |
| combinations of boards, SoCs, peripherals and peripheral pins. |
| |
| Note: Not all pins are available for a given peripheral, it depends if that |
| pin supports a set of properties required by the target peripheral. |
| |
| When defining a state, the pin muxing information is constrained to |
| the definitions at 'hal_espressif', however, pin properties (like |
| bias-push-pull, drive-open-drain, etc) can be freely chosen, given the |
| property is meaningful to the peripheral signal and that it is also |
| available in the target GPIO. |
| |
| |
| compatible: "espressif,esp32-pinctrl" |
| |
| include: |
| - name: base.yaml |
| - name: pincfg-node.yaml |
| child-binding: |
| property-allowlist: |
| - bias-disable |
| - bias-pull-down |
| - bias-pull-up |
| - drive-push-pull |
| - drive-open-drain |
| - input-enable |
| - output-enable |
| - output-high |
| - output-low |
| |
| properties: |
| reg: |
| required: false |
| |
| child-binding: |
| description: | |
| This binding gives a base representation of the ESP32 pins configuration |
| |
| properties: |
| pinmux: |
| required: true |
| type: int |
| description: | |
| Integer value, represents pin mux settings. |
| With: |
| - pin: The gpio pin number (0, 1, ..., GPIO_NUM_MAX) |
| - sigi: The input signal assigned to a pin, if not available, it gets |
| assigned to ESP_NOSIG |
| - sigo: The output signal assigned to a pin, if not available, it gets |
| assigned to ESP_NOSIG |
| To simplify the usage, macro is available to generate "pinmux" field. |
| This macro is available here: |
| -include/zephyr/dt-bindings/pinctrl/esp-pinctrl-common.h |
| Some examples of macro usage: |
| GPIO 3 set as UART0's RX pin |
| ... { |
| pinmux = <ESP32_PINMUX(3, ESP_U0RXD_IN, ESP_NOSIG)>; |
| }; |