mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
feat(ana_cmpr): add ETM periodic scan example
This commit is contained in:
@@ -222,7 +222,10 @@ Kconfig Options
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
* :example:`peripherals/analog_comparator` shows the basic usage of the analog comparator, and other potential usages like hysteresis comparator and SPWM generator.
|
||||
.. list::
|
||||
|
||||
:SOC_ANA_CMPR_SUPPORT_AUTO_SCAN: - :example:`peripherals/analog_comparator/auto_scan` shows auto scan based threshold detection with internal or external reference. After enabling the comparator, hardware scans continuously and updates output in real time, while the example demonstrates interrupt-based or ETM-based monitor GPIO control depending on target capabilities.
|
||||
:SOC_ANA_CMPR_SUPPORT_ETM_SCAN: - :example:`peripherals/analog_comparator/etm_periodic_scan` shows how to use GPTimer and ETM to trigger periodic comparator scans and drive a monitor GPIO from comparator crossing events.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
@@ -222,7 +222,10 @@ Kconfig 选项
|
||||
应用示例
|
||||
--------
|
||||
|
||||
* :example:`peripherals/analog_comparator` 展示了模拟比较器的基本用法以及其他用途(如迟滞比较器和 SPWM 发生器)。
|
||||
.. list::
|
||||
|
||||
:SOC_ANA_CMPR_SUPPORT_AUTO_SCAN: - :example:`peripherals/analog_comparator/auto_scan` 展示了基于自动扫描功能的阈值检测(支持内部参考或外部参考)。比较器在使能后会持续扫描并实时更新输出,示例根据目标能力演示了基于中断或 ETM 的监控 GPIO 控制。
|
||||
:SOC_ANA_CMPR_SUPPORT_ETM_SCAN: - :example:`peripherals/analog_comparator/etm_periodic_scan` 展示了如何使用 GPTimer 和 ETM 周期性触发比较器扫描,并通过比较器跨越事件驱动监控 GPIO。
|
||||
|
||||
API 参考
|
||||
--------
|
||||
|
||||
@@ -37,6 +37,16 @@ examples/peripherals/analog_comparator/auto_scan:
|
||||
- esp_hal_ana_cmpr
|
||||
- soc
|
||||
|
||||
examples/peripherals/analog_comparator/etm_periodic_scan:
|
||||
disable:
|
||||
- if: SOC_ANA_CMPR_SUPPORT_ETM_SCAN != 1
|
||||
depends_components:
|
||||
- esp_driver_gpio
|
||||
- esp_driver_ana_cmpr
|
||||
- esp_driver_gptimer
|
||||
- esp_hal_ana_cmpr
|
||||
- soc
|
||||
|
||||
examples/peripherals/bitscrambler:
|
||||
disable:
|
||||
- if: SOC_BITSCRAMBLER_SUPPORTED != 1
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# For more information about build system see
|
||||
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
|
||||
project(ana_cmpr_etm_periodic_scan)
|
||||
@@ -0,0 +1,114 @@
|
||||
| Supported Targets | ESP32-S31 |
|
||||
| ----------------- | --------- |
|
||||
|
||||
# Analog Comparator ETM Periodic Scan Example
|
||||
|
||||
(See the README.md file in the upper level `examples` directory for more information about examples.)
|
||||
|
||||
This example shows how to use a GPTimer periodic ETM event to trigger the analog comparator scan task. The analog comparator uses the internal 50% VDD reference, and the comparator positive and negative crossing events set or clear a monitor GPIO through ETM. With an external sine wave connected to the source channel, the monitor GPIO becomes a square wave representation of the sampled input.
|
||||
|
||||
## Realization
|
||||
|
||||
This example builds the following ETM chain:
|
||||
|
||||
- GPTimer alarm event -> GPTimer enable-alarm task
|
||||
- GPTimer alarm event -> Analog comparator start task
|
||||
- Analog comparator positive cross event -> GPIO set task
|
||||
- Analog comparator negative cross event -> GPIO clear task
|
||||
|
||||
The steady-state signal path runs without CPU intervention. The CPU is only used during one-time initialization.
|
||||
|
||||
## How to Use Example
|
||||
|
||||
### Hardware Requirement
|
||||
|
||||
* A development board with a supported Espressif SOC chip (see `Supported Targets` table above)
|
||||
* A USB cable for power supply and programming
|
||||
* A signal generator for generating the source sine wave
|
||||
* An oscilloscope or logic analyzer to observe the source input and monitor GPIO
|
||||
|
||||
### Example Connection
|
||||
|
||||
The example uses a configurable comparator source input GPIO. The shipped default value matches the comparator pad0 GPIO for each supported target, and the example logs the actual source GPIO number at startup.
|
||||
|
||||
```
|
||||
+--------------+ +--------------+
|
||||
| ESP Board | | Signal Gen |
|
||||
| | source signal | |
|
||||
+----+GPIO Src In|<----+----------+OUT |
|
||||
| | | | | |
|
||||
| | GND+-----+----+-----+GND |
|
||||
| | | | | | |
|
||||
| +--------------+ | | +--------------+
|
||||
| | |
|
||||
| +--------------+ | |
|
||||
| | Oscilloscope | | |
|
||||
| | | | |
|
||||
+--->|Probe1 Probe2|<----+ |
|
||||
| | |
|
||||
| GND+----------+
|
||||
| |
|
||||
+--------------+
|
||||
```
|
||||
|
||||
Probe the source sine wave on the comparator source GPIO and probe the monitor GPIO at the same time.
|
||||
|
||||
### Configure the Project
|
||||
|
||||
Open the project configuration menu:
|
||||
|
||||
```bash
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
Under `Example Configuration`, you can configure:
|
||||
|
||||
- `Source GPIO number`
|
||||
- `Monitor GPIO number`
|
||||
- `Comparator scan period (us)`
|
||||
|
||||
The comparator reference voltage is fixed to the internal 50% VDD reference in this example.
|
||||
The shipped default source GPIO value matches comparator pad0 on each supported target.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run the monitor tool to view serial output:
|
||||
|
||||
```bash
|
||||
idf.py -p PORT build flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type `Ctrl-]`.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
```text
|
||||
I (252) main_task: Started on CPU0
|
||||
I (262) main_task: Calling app_main()
|
||||
I (262) example: Monitor GPIO 4
|
||||
I (262) example: Analog comparator source GPIO 37
|
||||
I (262) example: Analog comparator internal reference 50% VDD
|
||||
I (272) example: GPTimer scan period 50 us
|
||||
I (282) example: Periodic ETM-driven comparator scan started
|
||||
I (282) main_task: Returned from app_main()
|
||||
```
|
||||
|
||||
The exact source GPIO number depends on the target and package.
|
||||
|
||||
## Expected Result On Hardware
|
||||
|
||||
Feed a sine wave into the comparator source channel. Because the comparator reference is fixed at 50% VDD, the monitor GPIO stays high while the sampled source voltage is above the threshold and low while it is below the threshold.
|
||||
|
||||
On an oscilloscope, the monitor GPIO appears as a square wave derived from the sampled sine wave.
|
||||
|
||||

|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- This example only works on targets that support analog comparator channel scan and the ETM scan-task path.
|
||||
- If the monitor GPIO does not change, reduce the input frequency or shorten the scan period.
|
||||
- If the square wave looks unstable, confirm the input sine wave amplitude crosses the 50% VDD threshold.
|
||||
|
||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
||||
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "ana_cmpr_etm_periodic_scan_main.c"
|
||||
PRIV_REQUIRES esp_driver_ana_cmpr esp_driver_gptimer esp_driver_gpio
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,23 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_SRC_GPIO_NUM
|
||||
int "Source GPIO number"
|
||||
default 0
|
||||
help
|
||||
GPIO connected to analog comparator source channel 0.
|
||||
|
||||
config EXAMPLE_MONITOR_GPIO_NUM
|
||||
int "Monitor GPIO number"
|
||||
default 4
|
||||
range 0 SOC_GPIO_OUT_RANGE_MAX
|
||||
help
|
||||
GPIO that outputs the square wave converted from the analog comparator result.
|
||||
|
||||
config EXAMPLE_SCAN_PERIOD_US
|
||||
int "Comparator scan period (us)"
|
||||
default 50
|
||||
range 10 1000000
|
||||
help
|
||||
Period of the GPTimer ETM event that triggers the analog comparator scan task.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_etm.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/gptimer.h"
|
||||
#include "driver/ana_cmpr.h"
|
||||
#include "driver/gpio_etm.h"
|
||||
#include "driver/gptimer_etm.h"
|
||||
#include "driver/ana_cmpr_etm.h"
|
||||
|
||||
#define EXAMPLE_ANA_CMPR_UNIT (0)
|
||||
#define EXAMPLE_MONITOR_GPIO_NUM CONFIG_EXAMPLE_MONITOR_GPIO_NUM
|
||||
#define EXAMPLE_SCAN_PERIOD_US CONFIG_EXAMPLE_SCAN_PERIOD_US
|
||||
#define EXAMPLE_ANA_CMPR_SRC_GPIO_NUM CONFIG_EXAMPLE_SRC_GPIO_NUM
|
||||
|
||||
#define TAG "example"
|
||||
|
||||
typedef struct {
|
||||
/* ETM events are produced by peripherals and can trigger ETM tasks without CPU intervention. */
|
||||
esp_etm_event_handle_t gptimer_alarm_evt;
|
||||
esp_etm_event_handle_t cmpr_pos_evt;
|
||||
esp_etm_event_handle_t cmpr_neg_evt;
|
||||
/* ETM tasks are the hardware actions we want to execute when an event happens. */
|
||||
esp_etm_task_handle_t gptimer_en_alarm_task;
|
||||
esp_etm_task_handle_t cmpr_start_task;
|
||||
esp_etm_task_handle_t gpio_set_task;
|
||||
esp_etm_task_handle_t gpio_clr_task;
|
||||
/* One ETM channel connects exactly one event source to one task target. */
|
||||
esp_etm_channel_handle_t etm_realarm_handle;
|
||||
esp_etm_channel_handle_t etm_scan_handle;
|
||||
esp_etm_channel_handle_t etm_pos_handle;
|
||||
esp_etm_channel_handle_t etm_neg_handle;
|
||||
} example_etm_handles_t;
|
||||
|
||||
static void example_init_monitor_gpio(void)
|
||||
{
|
||||
gpio_config_t io_conf = {
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pin_bit_mask = 1ULL << EXAMPLE_MONITOR_GPIO_NUM,
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||
ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_MONITOR_GPIO_NUM, 0));
|
||||
ESP_LOGI(TAG, "Monitor GPIO %d", EXAMPLE_MONITOR_GPIO_NUM);
|
||||
}
|
||||
|
||||
static ana_cmpr_handle_t example_init_ana_cmpr(void)
|
||||
{
|
||||
gpio_num_t src_gpio = -1;
|
||||
ana_cmpr_handle_t cmpr = NULL;
|
||||
ana_cmpr_config_t config = {
|
||||
.unit = EXAMPLE_ANA_CMPR_UNIT,
|
||||
.clk_src = ANA_CMPR_CLK_SRC_DEFAULT,
|
||||
.ref_src = ANA_CMPR_REF_SRC_INTERNAL,
|
||||
.cross_type = ANA_CMPR_CROSS_ANY,
|
||||
.src_chan0_gpio = EXAMPLE_ANA_CMPR_SRC_GPIO_NUM,
|
||||
/* Require several consistent samples before the scan result is updated.
|
||||
* This makes the output more stable when the input is noisy. */
|
||||
.resample_limit = 3,
|
||||
};
|
||||
ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));
|
||||
ESP_ERROR_CHECK(ana_cmpr_get_channel_gpio(cmpr, ANA_CMPR_SOURCE_CHAN, 0, &src_gpio));
|
||||
|
||||
ana_cmpr_internal_ref_config_t ref_cfg = {
|
||||
.ref_volt = ANA_CMPR_REF_VOLT_50_PCT_VDD,
|
||||
.ref_hys_level = ANA_CMPR_REF_HYS_LEVEL0,
|
||||
};
|
||||
/* Compare the input signal against an internal reference set to 50% of VDD. */
|
||||
ESP_ERROR_CHECK(ana_cmpr_set_internal_reference(cmpr, &ref_cfg));
|
||||
|
||||
ana_cmpr_scan_config_t scan_cfg = {
|
||||
.scan_mode = ANA_CMPR_SCAN_MODE_FULL,
|
||||
/* Stay on each source channel for a short time before moving to the next one. */
|
||||
.poll_period_us = 2,
|
||||
};
|
||||
/* Scan parameters control how the hardware walks through the enabled source channels. */
|
||||
ESP_ERROR_CHECK(ana_cmpr_set_scan_config(cmpr, &scan_cfg));
|
||||
|
||||
ESP_LOGI(TAG, "Analog comparator source GPIO %d", src_gpio);
|
||||
ESP_LOGI(TAG, "Analog comparator internal reference 50%% VDD");
|
||||
|
||||
return cmpr;
|
||||
}
|
||||
|
||||
static gptimer_handle_t example_init_gptimer(void)
|
||||
{
|
||||
gptimer_handle_t gptimer = NULL;
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 1 * 1000 * 1000, // 1 MHz, which means the timer count value will increase by 1 every microsecond
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
|
||||
ESP_ERROR_CHECK(gptimer_set_raw_count(gptimer, 0));
|
||||
ESP_ERROR_CHECK(gptimer_enable(gptimer));
|
||||
|
||||
gptimer_alarm_config_t alarm_config = {
|
||||
.reload_count = 0,
|
||||
/* The alarm period is the high-level scan period of this example.
|
||||
* Every alarm will trigger one comparator scan through ETM. */
|
||||
.alarm_count = EXAMPLE_SCAN_PERIOD_US,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
|
||||
ESP_LOGI(TAG, "GPTimer scan period %d us", EXAMPLE_SCAN_PERIOD_US);
|
||||
|
||||
return gptimer;
|
||||
}
|
||||
|
||||
static void example_init_etm(ana_cmpr_handle_t cmpr, gptimer_handle_t gptimer)
|
||||
{
|
||||
example_etm_handles_t handles = {};
|
||||
|
||||
/* Step 1: create the ETM event generated when the timer alarm fires. */
|
||||
gptimer_etm_event_config_t gptimer_evt_cfg = {
|
||||
.event_type = GPTIMER_ETM_EVENT_ALARM_MATCH,
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_new_etm_event(gptimer, &gptimer_evt_cfg, &handles.gptimer_alarm_evt));
|
||||
|
||||
/* Step 2: create the timer task that rearms the alarm after each trigger. */
|
||||
gptimer_etm_task_config_t gptimer_task_cfg = {
|
||||
.task_type = GPTIMER_ETM_TASK_EN_ALARM,
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_new_etm_task(gptimer, &gptimer_task_cfg, &handles.gptimer_en_alarm_task));
|
||||
|
||||
/* Step 3: create the comparator task that starts one scan sequence. */
|
||||
ana_cmpr_etm_task_config_t cmpr_task_cfg = {
|
||||
.task_type = ANA_CMPR_TASK_START,
|
||||
};
|
||||
ESP_ERROR_CHECK(ana_cmpr_new_etm_task(cmpr, &cmpr_task_cfg, &handles.cmpr_start_task));
|
||||
|
||||
/* Step 4: create comparator events for positive and negative threshold crossings. */
|
||||
ana_cmpr_etm_event_config_t cmpr_evt_cfg = {
|
||||
.event_type = ANA_CMPR_EVENT_POS_CROSS,
|
||||
};
|
||||
ESP_ERROR_CHECK(ana_cmpr_new_etm_event(cmpr, &cmpr_evt_cfg, &handles.cmpr_pos_evt));
|
||||
cmpr_evt_cfg.event_type = ANA_CMPR_EVENT_NEG_CROSS;
|
||||
ESP_ERROR_CHECK(ana_cmpr_new_etm_event(cmpr, &cmpr_evt_cfg, &handles.cmpr_neg_evt));
|
||||
|
||||
/* Step 5: create GPIO ETM tasks so the comparator result is visible on a normal output pin.
|
||||
* Positive crossing drives the monitor GPIO high, negative crossing drives it low. */
|
||||
gpio_etm_task_config_t gpio_task_cfg = {};
|
||||
gpio_task_cfg.actions[0] = GPIO_ETM_TASK_ACTION_SET;
|
||||
gpio_task_cfg.actions[1] = GPIO_ETM_TASK_ACTION_CLR;
|
||||
ESP_ERROR_CHECK(gpio_new_etm_task(&gpio_task_cfg, &handles.gpio_set_task, &handles.gpio_clr_task));
|
||||
ESP_ERROR_CHECK(gpio_etm_task_add_gpio(handles.gpio_set_task, EXAMPLE_MONITOR_GPIO_NUM));
|
||||
ESP_ERROR_CHECK(gpio_etm_task_add_gpio(handles.gpio_clr_task, EXAMPLE_MONITOR_GPIO_NUM));
|
||||
|
||||
/* Step 6: allocate ETM channels. Each channel is an event-to-task connection. */
|
||||
esp_etm_channel_config_t etm_cfg = {};
|
||||
ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &handles.etm_realarm_handle));
|
||||
ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &handles.etm_scan_handle));
|
||||
ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &handles.etm_pos_handle));
|
||||
ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &handles.etm_neg_handle));
|
||||
|
||||
/* Step 7: wire the ETM graph:
|
||||
* - timer alarm event -> timer rearm task
|
||||
* - timer alarm event -> comparator start task
|
||||
* - comparator positive event -> GPIO set task
|
||||
* - comparator negative event -> GPIO clear task */
|
||||
ESP_ERROR_CHECK(esp_etm_channel_connect(handles.etm_realarm_handle, handles.gptimer_alarm_evt, handles.gptimer_en_alarm_task));
|
||||
ESP_ERROR_CHECK(esp_etm_channel_connect(handles.etm_scan_handle, handles.gptimer_alarm_evt, handles.cmpr_start_task));
|
||||
ESP_ERROR_CHECK(esp_etm_channel_connect(handles.etm_pos_handle, handles.cmpr_pos_evt, handles.gpio_set_task));
|
||||
ESP_ERROR_CHECK(esp_etm_channel_connect(handles.etm_neg_handle, handles.cmpr_neg_evt, handles.gpio_clr_task));
|
||||
|
||||
/* Step 8: enable the channels so the hardware pipeline becomes active. */
|
||||
ESP_ERROR_CHECK(esp_etm_channel_enable(handles.etm_realarm_handle));
|
||||
ESP_ERROR_CHECK(esp_etm_channel_enable(handles.etm_scan_handle));
|
||||
ESP_ERROR_CHECK(esp_etm_channel_enable(handles.etm_pos_handle));
|
||||
ESP_ERROR_CHECK(esp_etm_channel_enable(handles.etm_neg_handle));
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
example_init_monitor_gpio();
|
||||
ana_cmpr_handle_t cmpr = example_init_ana_cmpr();
|
||||
gptimer_handle_t gptimer = example_init_gptimer();
|
||||
example_init_etm(cmpr, gptimer);
|
||||
|
||||
ESP_ERROR_CHECK(ana_cmpr_enable(cmpr));
|
||||
/* Run one software-triggered scan before the periodic timer starts.
|
||||
* This gives the comparator an initial result immediately, instead of waiting for the first timer alarm. */
|
||||
ESP_ERROR_CHECK(ana_cmpr_trigger_scan(cmpr));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
/* After the timer starts, future scans are launched by ETM rather than by CPU code. */
|
||||
ESP_ERROR_CHECK(gptimer_start(gptimer));
|
||||
ESP_LOGI(TAG, "Periodic ETM-driven comparator scan started");
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
from pytest_embedded_idf.utils import soc_filtered_targets
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize(
|
||||
'target',
|
||||
soc_filtered_targets('SOC_ANA_CMPR_SUPPORT_ETM_SCAN == 1'),
|
||||
indirect=['target'],
|
||||
)
|
||||
def test_ana_cmpr_etm_periodic_scan(dut: Dut) -> None:
|
||||
dut.expect(r'Monitor GPIO \d+')
|
||||
dut.expect(r'Analog comparator source GPIO \d+')
|
||||
dut.expect_exact('Analog comparator internal reference 50% VDD')
|
||||
dut.expect(r'GPTimer scan period \d+ us')
|
||||
dut.expect_exact('Periodic ETM-driven comparator scan started')
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_EXAMPLE_SRC_GPIO_NUM=0
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_EXAMPLE_SRC_GPIO_NUM=37
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Reference in New Issue
Block a user