Digestly

Apr 3, 2025

Introduction to Zephyr Part 5: Devicetree Bindings | DigiKey

DigiKey - Introduction to Zephyr Part 5: Devicetree Bindings | DigiKey

The discussion delves into Zephyr bindings, which are unique to Zephyr and not used in Linux. These bindings help connect device trees to device driver code. The episode focuses on creating a simple analog-to-digital conversion demo using an ESP32. The hardware setup involves a 10K potentiometer connected to pin one of the ESP32 S3 devkit C and an LED connected to pin 13. The process involves understanding the ESP32's ADC peripherals, configuring the device tree, and writing code to read analog values. The video also covers the importance of understanding YAML syntax for bindings files and how to use them to define properties for device nodes. It highlights the limitations of the ESP32's ADC, such as its inaccuracy and limited range, and suggests using an external chip for more accurate ADC readings. The episode concludes with a challenge to assign a PWM controller to an LED pin and control its brightness using the potentiometer.

Key Points:

  • Zephyr bindings connect device trees to driver code, unique to Zephyr.
  • ESP32 ADC peripherals are hardwired, no pin mixing allowed.
  • YAML syntax is crucial for defining device node properties in bindings files.
  • ESP32's ADC is inaccurate; consider using an external chip for precision.
  • Challenge: Use PWM to control LED brightness with a potentiometer.

Details:

1. 🔧 Introduction to Zephyr Bindings

  • Zephyr bindings create an interface for device tree specifications, connecting them to device driver code.
  • In this episode, the focus is on creating a simple analog to digital demo on the ESP32.
  • Bindings files are unique to Zephyr, unlike Linux, which does not use them.
  • The episode aims to build up to writing device driver code using cmake, K config, device tree, and bindings.

2. 📟 Setting Up Hardware for ADC Demo

  • Use the same hardware setup as previous sessions, focusing on connecting a 10K potentiometer to pin one of the ESP32 S3 DevKit C for analog-to-digital conversion. Include a visual diagram to illustrate these connections clearly.
  • Connect an LED to pin 13 as part of the demonstration challenge, providing a practical example of ADC output application.
  • Identify ADC pins linked to external pins using the ESP32 S3 datasheet or technical reference manual, emphasizing the sections related to ADCs for accurate configuration.
  • Understand that the ESP32 has two ADC peripherals, ADC1 and ADC2, each with specific channels associated with particular pins, as they are hardwired and do not allow pin muxing. Include specific pin numbers and channel configurations for clarity.
  • Refer to configuration registers for ADC1 and ADC2 in the register summary section of the datasheet to understand their offsets and base addresses. A step-by-step guide for adjusting these settings can enhance the configuration process.

3. 📄 Exploring Device Tree Source Files

  • To access ESP32 S3 peripherals, navigate to the Zephyr base directory and locate the device tree source include file under DTS extensa for ESP32 S3.
  • ADC peripherals are referenced as adc0 and adc1 in Zephyr, which corresponds to adc1 and adc2 in the ESP32 data sheet, respectively.
  • The node name uses the 'at' symbol followed by the memory address, aligning with the data sheet, and the 'reg' property indicates the memory location used for driver communication.
  • Each ADC node is disabled by default and must be enabled in an overlay file by setting the status to 'okay'.
  • Zephyr requires the inclusion of 'number address cells' and 'number size cells' for specifying peripherals, with one address cell and one size cell needed for peripherals under the S node.
  • The address cell must be an unsigned 32-bit integer, and the size cell defines the memory size expected by the driver.

4. 📂 Understanding Bindings and Yaml Files

  • Bindings files in Zephyr are named based on the 'compatible' field, though the file name is less important than its content, which is vital for defining device properties.
  • Yaml syntax is akin to Python dictionaries or JSON, featuring key-value pairs, arrays denoted by dashes, and the ability to nest structures.
  • Esp32 ADC controllers have specific properties outlined in bindings files, including multiple resolution options and gain settings, crucial for defining the analog to digital converter's function.
  • The Esp32 ADC is noted for its inaccuracy and limited range, with an internal reference voltage of approximately 1.1 volts. It is especially inaccurate above 0.95 volts, and setting attenuation to 11 dB extends the range to about 3.1 volts.
  • For precise ADC readings, it's advised to opt for an external i2c chip over the Esp32's built-in ADC, unless limited by budget or space constraints.
  • Zephyr employs predefined values for ADC gain, such as ADC gain one qu or 1/4th, equating to 11 dB attenuation, although 11 dB corresponds more closely to 1/3.54.
  • Bindings files specify required and optional node properties, functioning like interfaces, with certain properties expected in the device tree.
  • The 'reg' property is essential for arrays, determining the number of address and size cells per parent properties.
  • Zephyr distinguishes property groups with a 'zephyr,' prefix, which includes gain, reference, and acquisition time as necessary fields.
  • The Esp32 features a fixed reference voltage setting, with resolution set to 12 bits, as detailed in the binding files.
  • Additional binding files, like ADC controller bindings, enhance Zephyr's standard ADC bindings by incorporating unique properties needed for specific drivers, like those for Esp32.
  • The 'zephyr,user' node serves as a space for custom properties, where IO channels are defined as phandle arrays.
  • Sample code in Zephyr's repository is beneficial for grasping device tree configurations and driver implementations.
  • In device trees, phandle arrays can specify ADC channels, with each element corresponding to ADC nodes and channels, aiding in the configuration of multiple channels.

5. 🛠️ Delving into ADC Driver and API

5.1. Device Tree Compatibility and Naming Conventions

5.2. ADC Driver Structure and Implementation

6. 🖥️ Writing and Running ADC Demo Code

6.1. Setup for ADC Demo

6.2. Configuration of ADC Settings

6.3. Execution and Calculation

6.4. Project Configuration and Testing

7. 📑 Learning Resources and Blog Recommendations

  • Explore Zephyr's practical blog post on device tree semantics to understand overlays, matching bindings files, and locating associated device driver source code.
  • Martin's blog provides in-depth insights into device tree structures, explaining their functionalities and practical applications.

8. 🎯 Challenge: Implementing PWM with Potentiometer

  • Create a PWM controller for the LED pin in the device tree to adjust LED brightness using a potentiometer.
  • Utilize the Zephyr OS Source folder, specifically the 'samples/basic/Blinky' and 'pwm' examples, and consult ESP 32 S3 overlays for reference.
  • Specify a pwm LEDs node with the PWM property in your device tree, including a handle array to the LED controller node and parameters such as channel, period, and polarity.
  • Define the LED controller name 'c0' in the s so dtsi file for PWM LED configuration.
  • Use 'espressive esp32 ledc compatible bindings' for configuration, reviewing binding files for proper LED PWM controller setup.
  • Assign pins to functions with the pinmux property in the pin control node, as shown in the 'esp32 devkit M Pro' sample, assigning gpio2 to Channel Zero of the LED controller.
  • Utilize DT bindings to assign pin control settings in your overlay file, mapping GPIO pins to LED controller channels, specifically using ledc Channel Zero and gp13 for the LED.

9. 🔜 Next Episode Teaser: Writing a Device Driver

  • The next episode will focus on writing a bindings file for creating a custom device driver.
View Full Content
Upgrade to Plus to unlock complete episodes, key insights, and in-depth analysis
Starting at $5/month. Cancel anytime.