This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 0c63840b18 arch/risc-v: add support for capture driver on ESP32C6 and
ESP32H2.
0c63840b18 is described below
commit 0c63840b18932f3201fcd7d92c7febd4a4e37181
Author: Filipe Cavalcanti <[email protected]>
AuthorDate: Wed Jul 3 09:38:49 2024 -0300
arch/risc-v: add support for capture driver on ESP32C6 and ESP32H2.
---
.../esp32c6/boards/esp32c6-devkitc/index.rst | 16 +
Documentation/platforms/risc-v/esp32c6/index.rst | 2 +-
arch/risc-v/src/common/espressif/Kconfig | 72 +++
arch/risc-v/src/common/espressif/Make.defs | 4 +
arch/risc-v/src/common/espressif/esp_mcpwm.c | 691 +++++++++++++++++++++
arch/risc-v/src/common/espressif/esp_mcpwm.h | 86 +++
arch/risc-v/src/esp32c6/hal_esp32c6.mk | 2 +
arch/risc-v/src/esp32h2/hal_esp32h2.mk | 2 +
.../esp32c6/common/include/esp_board_mcpwm.h | 70 +++
boards/risc-v/esp32c6/common/src/Make.defs | 4 +
boards/risc-v/esp32c6/common/src/esp_board_mcpwm.c | 114 ++++
.../esp32c6-devkitc/configs/capture/defconfig | 51 ++
.../esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c | 12 +
.../esp32h2/common/include/esp_board_mcpwm.h | 70 +++
boards/risc-v/esp32h2/common/src/Make.defs | 4 +
boards/risc-v/esp32h2/common/src/esp_board_mcpwm.c | 114 ++++
.../esp32h2-devkit/configs/capture/defconfig | 51 ++
.../esp32h2/esp32h2-devkit/src/esp32h2_bringup.c | 12 +
18 files changed, 1376 insertions(+), 1 deletion(-)
diff --git
a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst
b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst
index c886f3e5ed..e9309ce10b 100644
--- a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst
+++ b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/index.rst
@@ -99,6 +99,22 @@ You can check that the sensor is working by using the
``bmp180`` application::
Pressure value = 91526
Pressure value = 91525
+capture
+--------
+
+The capture configuration enables the capture driver and the capture example,
allowing
+the user to measure duty cycle and frequency of a signal. Default pin is GPIO
18 with
+an internal pull-up resistor enabled. When connecting a 50 Hz pulse with 50%
duty cycle,
+the following output is expected:
+
+nsh> cap
+cap_main: Hardware initialized. Opening the capture device: /dev/capture0
+cap_main: Number of samples: 0
+pwm duty cycle: 50 %
+pwm frequence: 50 Hz
+pwm duty cycle: 50 %
+pwm frequence: 50 Hz
+
coremark
--------
diff --git a/Documentation/platforms/risc-v/esp32c6/index.rst
b/Documentation/platforms/risc-v/esp32c6/index.rst
index 958fb885f3..b4dc9b5ca9 100644
--- a/Documentation/platforms/risc-v/esp32c6/index.rst
+++ b/Documentation/platforms/risc-v/esp32c6/index.rst
@@ -152,7 +152,7 @@ I2S No
Int. Temp. No
LED No
LED_PWM Yes
-MCPWM No
+MCPWM Yes (Capture)
Pulse Counter No
RMT No
RNG No
diff --git a/arch/risc-v/src/common/espressif/Kconfig
b/arch/risc-v/src/common/espressif/Kconfig
index 9e13007002..233fb43dce 100644
--- a/arch/risc-v/src/common/espressif/Kconfig
+++ b/arch/risc-v/src/common/espressif/Kconfig
@@ -473,6 +473,14 @@ config ESP_COEX_SW_COEXIST_ENABLE
If only Bluetooth is used, it is recommended to disable this
option to reduce binary file
size.
+config ESP_MCPWM
+ bool "Motor Control PWM (MCPWM)"
+ default n
+ depends on ESPRESSIF_ESP32C6 || ESPRESSIF_ESP32H2
+ ---help---
+ Enable support for timer capture and motor control using
+ the Motor Control PWM peripheral.
+
endmenu # Peripheral Support
menu "Wi-Fi Configuration"
@@ -1273,6 +1281,70 @@ config ESPRESSIF_I2CTIMEOMS
default 500
endmenu # I2C configuration
+menu "MCPWM Configuration"
+ depends on ESP_MCPWM
+
+config ESP_MCPWM_CAPTURE
+ bool "MCPWM Capture Submodule"
+ depends on ESP_MCPWM
+ select CAPTURE
+ default n
+ ---help---
+ Enables the use of the MCPWM capture submodule.
+
+if ESP_MCPWM_CAPTURE
+
+config ESP_MCPWM_CAPTURE_CH0
+ bool "Capture Channel 0"
+ default n
+ ---help---
+ Enables capture on channel 0.
+
+if ESP_MCPWM_CAPTURE_CH0
+
+config ESP_MCPWM_CAPTURE_CH0_GPIO
+ int "GPIO Pin"
+ default 18
+ ---help---
+ GPIO pin assigned to capture channel 0.
+
+endif # ESP_MCPWM_CAPTURE_CH0
+
+config ESP_MCPWM_CAPTURE_CH1
+ bool "Capture Channel 1"
+ default n
+ ---help---
+ Enables capture on channel 1.
+
+if ESP_MCPWM_CAPTURE_CH1
+
+config ESP_MCPWM_CAPTURE_CH1_GPIO
+ int "GPIO Pin"
+ default 19
+ ---help---
+ GPIO pin assigned to capture channel 1.
+
+endif # ESP_MCPWM_CAPTURE_CH1
+
+config ESP_MCPWM_CAPTURE_CH2
+ bool "Capture Channel 2"
+ default n
+ ---help---
+ Enables capture on channel 2.
+
+if ESP_MCPWM_CAPTURE_CH2
+
+config ESP_MCPWM_CAPTURE_CH2_GPIO
+ int "GPIO Pin"
+ default 20
+ ---help---
+ GPIO pin assigned to capture channel 2.
+
+endif # ESP_MCPWM_CAPTURE_CH2
+
+endif # ESP_MCPWM_CAPTURE
+
+endmenu # MCPWM Configuration
menu "High Resolution Timer"
depends on ESPRESSIF_HR_TIMER
diff --git a/arch/risc-v/src/common/espressif/Make.defs
b/arch/risc-v/src/common/espressif/Make.defs
index 287db4d9b2..c51ad327bb 100644
--- a/arch/risc-v/src/common/espressif/Make.defs
+++ b/arch/risc-v/src/common/espressif/Make.defs
@@ -114,6 +114,10 @@ ifeq ($(CONFIG_ESP_WIRELESS),y)
endif
endif
+ifeq ($(CONFIG_ESP_MCPWM),y)
+ CHIP_CSRCS += esp_mcpwm.c
+endif
+
#############################################################################
# Espressif HAL for 3rd Party Platforms
#############################################################################
diff --git a/arch/risc-v/src/common/espressif/esp_mcpwm.c
b/arch/risc-v/src/common/espressif/esp_mcpwm.c
new file mode 100644
index 0000000000..e4562e4a95
--- /dev/null
+++ b/arch/risc-v/src/common/espressif/esp_mcpwm.c
@@ -0,0 +1,691 @@
+/****************************************************************************
+ * arch/risc-v/src/common/espressif/esp_mcpwm.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+#include <inttypes.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/timers/capture.h>
+
+#include "esp_gpio.h"
+#include "esp_irq.h"
+
+#include "esp_attr.h"
+#include "hal/mcpwm_hal.h"
+#include "hal/mcpwm_ll.h"
+#include "soc/mcpwm_periph.h"
+#include "periph_ctrl.h"
+#include "hal/clk_tree_hal.h"
+#include "esp_clk_tree.h"
+
+#ifdef CONFIG_ESP_MCPWM
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_CHIP_ESP32H2
+# define MCPWM_DEV_CLK_SOURCE MCPWM_TIMER_CLK_SRC_PLL96M
+#else
+# define MCPWM_DEV_CLK_SOURCE SOC_MOD_CLK_PLL_F160M
+#endif
+
+#define MCPWM_DEV_CLK_PRESCALE 4
+#define MCPWM_CAPTURE_DEFAULT_GROUP 0
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct mcpwm_dev_common_s
+{
+ mcpwm_hal_init_config_t group;
+ mcpwm_hal_context_t hal;
+ spinlock_t mcpwm_spinlock;
+ bool initialized; /* MCPWM peripheral and HAL has been initialized
*/
+ bool capture_initialized; /* Capture submodule has been initialized */
+ int group_prescale;
+};
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+/* Capture event data. The 'last_' value is used to calculate frequency */
+
+struct mcpwm_capture_event_data_s
+{
+ uint32_t pos_edge_count;
+ uint32_t neg_edge_count;
+ uint32_t last_pos_edge_count;
+};
+
+enum mcpwm_capture_channel_e
+{
+ MCPWM_CAP_CHANNEL_0, /* MCPWM capture channel number 0 */
+ MCPWM_CAP_CHANNEL_1, /* MCPWM capture channel number 1 */
+ MCPWM_CAP_CHANNEL_2, /* MCPWM capture channel number 2 */
+ MCPWM_CAP_CHANNEL_MAX /* Number of MCPWM capture channels */
+};
+
+/* Lowe-half data structure for a capture channel */
+
+struct mcpwm_cap_channel_lowerhalf_s
+{
+ /* The following block is part of the upper-half device struct */
+
+ const struct cap_ops_s *ops;
+
+ /* The following is private to the ESP MCPWM driver */
+
+ struct mcpwm_dev_common_s *common;
+ struct mcpwm_capture_event_data_s *data;
+ int channel_id;
+ int gpio_pin;
+ uint32_t clock;
+ uint32_t freq;
+ uint8_t duty;
+ uint8_t isr_count;
+ bool ready;
+ bool enabled;
+};
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void esp_mcpwm_group_start(void);
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int esp_mcpwm_capture_set_gpio(
+ struct mcpwm_cap_channel_lowerhalf_s *lower);
+static int esp_mcpwm_capture_isr_register(int (*fn)(int, void *, void *),
+ void *arg);
+static int IRAM_ATTR mcpwm_capture_driver_isr_default(int irq, void *context,
+ void *arg);
+
+/* Lower half methods required by capture driver */
+
+static int esp_capture_start(struct cap_lowerhalf_s *lower);
+static int esp_capture_stop(struct cap_lowerhalf_s *lower);
+static int esp_capture_getduty(struct cap_lowerhalf_s *lower,
+ uint8_t *duty);
+static int esp_capture_getfreq(struct cap_lowerhalf_s *lower,
+ uint32_t *freq);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct mcpwm_dev_common_s mcpwm_common =
+{
+ .group.group_id = MCPWM_CAPTURE_DEFAULT_GROUP,
+ .initialized = false,
+ .capture_initialized = false,
+ .group_prescale = MCPWM_DEV_CLK_PRESCALE,
+};
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+/* Lower half methods required by the capture driver */
+
+static const struct cap_ops_s mcpwm_cap_ops =
+{
+ .start = esp_capture_start,
+ .stop = esp_capture_stop,
+ .getduty = esp_capture_getduty,
+ .getfreq = esp_capture_getfreq,
+};
+
+/* Data structures for the available capture channels */
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH0
+static struct mcpwm_capture_event_data_s event_data_ch0;
+static struct mcpwm_cap_channel_lowerhalf_s mcpwm_cap_ch0_lowerhalf =
+{
+ .ops = &mcpwm_cap_ops,
+ .common = &mcpwm_common,
+ .data = &event_data_ch0,
+ .channel_id = MCPWM_CAP_CHANNEL_0,
+ .ready = false,
+};
+#endif
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH1
+static struct mcpwm_capture_event_data_s event_data_ch1;
+static struct mcpwm_cap_channel_lowerhalf_s mcpwm_cap_ch1_lowerhalf =
+{
+ .ops = &mcpwm_cap_ops,
+ .common = &mcpwm_common,
+ .data = &event_data_ch1,
+ .channel_id = MCPWM_CAP_CHANNEL_1,
+ .ready = false,
+};
+#endif
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH2
+static struct mcpwm_capture_event_data_s event_data_ch2;
+static struct mcpwm_cap_channel_lowerhalf_s mcpwm_cap_ch2_lowerhalf =
+{
+ .ops = &mcpwm_cap_ops,
+ .common = &mcpwm_common,
+ .data = &event_data_ch2,
+ .channel_id = MCPWM_CAP_CHANNEL_2,
+ .ready = false,
+};
+#endif
+#endif /* CONFIG_ESP_MCPWM_CAPTURE */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_capture_start
+ *
+ * Description:
+ * This function is a requirement of the upper-half driver. When called,
+ * enables the capture channel, interruption routine, sets the positive
+ * edge to trigger this interrupt and resets the frequency and duty
+ * values. The positive edge is always the first expected.
+ *
+ * Input Parameters:
+ * lower - Pointer to the capture channel lower-half data structure.
+ *
+ * Returned Value:
+ * Returns OK on success.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int esp_capture_start(struct cap_lowerhalf_s *lower)
+{
+ struct mcpwm_cap_channel_lowerhalf_s *priv = (
+ struct mcpwm_cap_channel_lowerhalf_s *)lower;
+
+ DEBUGASSERT(priv != NULL);
+
+ mcpwm_hal_context_t *hal = &priv->common->hal;
+
+ /* Enable channel and interruption for rising edge */
+
+ mcpwm_ll_capture_enable_channel(hal->dev, priv->channel_id, true);
+ mcpwm_ll_intr_enable(hal->dev,
+ MCPWM_LL_EVENT_CAPTURE(priv->channel_id),
+ true);
+ mcpwm_ll_intr_clear_status(hal->dev,
+ MCPWM_LL_EVENT_CAPTURE(priv->channel_id));
+ mcpwm_ll_capture_enable_posedge(hal->dev, priv->channel_id, true);
+ mcpwm_ll_capture_enable_negedge(hal->dev, priv->channel_id, false);
+
+ /* Reset values of interest */
+
+ priv->freq = 0;
+ priv->duty = 0;
+ priv->isr_count = 0;
+ priv->enabled = true;
+ priv->ready = false;
+
+ cpinfo("Channel enabled: %d\n", priv->channel_id);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp_capture_stop
+ *
+ * Description:
+ * This function is a requirement of the upper-half driver. When called,
+ * disables the capture channel and the interrupt routine associated.
+ *
+ * Input Parameters:
+ * lower - Pointer to the capture channel lower-half data structure.
+ *
+ * Returned Value:
+ * Returns OK on success.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int esp_capture_stop(struct cap_lowerhalf_s *lower)
+{
+ struct mcpwm_cap_channel_lowerhalf_s *priv = (
+ struct mcpwm_cap_channel_lowerhalf_s *)lower;
+
+ DEBUGASSERT(priv != NULL);
+
+ mcpwm_hal_context_t *hal = &priv->common->hal;
+
+ /* Disable channel and interrupts */
+
+ mcpwm_ll_capture_enable_channel(hal->dev, priv->channel_id, false);
+ mcpwm_ll_intr_enable(hal->dev,
+ MCPWM_LL_EVENT_CAPTURE(priv->channel_id),
+ false);
+ priv->enabled = false;
+
+ cpinfo("Channel disabled: %d\n", priv->channel_id);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp_capture_getduty
+ *
+ * Description:
+ * This function is a requirement of the upper-half driver. Returns
+ * the last calculated duty cycle value.
+ *
+ * Input Parameters:
+ * lower - Pointer to the capture channel lower-half data structure.
+ * duty - uint8_t pointer where the duty cycle value is written.
+ *
+ * Returned Value:
+ * Returns OK on success.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int esp_capture_getduty(struct cap_lowerhalf_s *lower,
+ uint8_t *duty)
+{
+ struct mcpwm_cap_channel_lowerhalf_s *priv = (
+ struct mcpwm_cap_channel_lowerhalf_s *)lower;
+
+ DEBUGASSERT(priv != NULL);
+
+ *duty = priv->duty;
+ cpinfo("Get duty called from channel %d\n", priv->channel_id);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp_capture_getfreq
+ *
+ * Description:
+ * This function is a requirement of the upper-half driver. Returns
+ * the last calculated frequency value.
+ *
+ * Input Parameters:
+ * lower - Pointer to the capture channel lower-half data structure.
+ * duty - uint8_t pointer where the frequency value is written.
+ *
+ * Returned Value:
+ * Returns OK on success.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int esp_capture_getfreq(struct cap_lowerhalf_s *lower,
+ uint32_t *freq)
+{
+ struct mcpwm_cap_channel_lowerhalf_s *priv = (
+ struct mcpwm_cap_channel_lowerhalf_s *)lower;
+
+ DEBUGASSERT(priv != NULL);
+
+ *freq = priv->freq;
+ cpinfo("Get freq called from channel %d\n", priv->channel_id);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp_mcpwm_group_start
+ *
+ * Description:
+ * Initializes the MCPWM0 module, MCPWM HAL.
+ * Should be called only once.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void esp_mcpwm_group_start(void)
+{
+ mcpwm_hal_context_t *hal = &mcpwm_common.hal;
+
+ /* HAL and MCPWM Initialization */
+
+ periph_module_enable(PERIPH_MCPWM0_MODULE);
+ mcpwm_hal_init(hal, &mcpwm_common.group);
+ mcpwm_hal_timer_reset(hal, 0);
+ mcpwm_ll_group_set_clock_source(hal->dev, MCPWM_DEV_CLK_SOURCE);
+ mcpwm_ll_group_set_clock_prescale(hal->dev, 4);
+ mcpwm_ll_group_enable_clock(hal->dev, true);
+
+ mcpwm_common.initialized = true;
+}
+
+/****************************************************************************
+ * Name: esp_mcpwm_capture_set_gpio
+ *
+ * Description:
+ * Configures the lower-half GPIO pin to be used as a capture input.
+ *
+ * Input Parameters:
+ * lower - Pointer to the capture channel lower-half data structure.
+ *
+ * Returned Value:
+ * OK on success, otherwise a negated errno value is returned on
+ * any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int esp_mcpwm_capture_set_gpio(
+ struct mcpwm_cap_channel_lowerhalf_s *lower)
+{
+ mcpwm_hal_context_t *hal = &lower->common->hal;
+ int ret;
+
+ ret = esp_configgpio(lower->gpio_pin, INPUT | PULLUP);
+ if (ret < 0)
+ {
+ cperr("Failed configuring GPIO pin\n");
+ return ret;
+ }
+
+ esp_gpio_matrix_in(lower->gpio_pin,
+ mcpwm_periph_signals.groups[0].captures[lower->channel_id].cap_sig,
+ false);
+
+ cpinfo("GPIO: %d configured for channel %d\n", lower->gpio_pin,
+ lower->channel_id);
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp_mcpwm_capture_isr_register
+ *
+ * Description:
+ * Registers a callback function for a channel interrupt request.
+ *
+ * Input Parameters:
+ * fn - Pointer to ISR function that is to be called.
+ * arg - Pointer to arguments passed to said function.
+ *
+ * Returned Value:
+ * OK on success, otherwise a negated errno value is returned on
+ * any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int esp_mcpwm_capture_isr_register(int (*fn)(int, void *, void *),
+ void *arg)
+{
+ int cpuint;
+ int ret;
+
+ cpuint = esp_setup_irq(mcpwm_periph_signals.groups[0].irq_id,
+ ESP_IRQ_PRIORITY_DEFAULT,
+ ESP_IRQ_TRIGGER_LEVEL);
+ if (cpuint < 0)
+ {
+ cperr("Failed to allocate a CPU interrupt.\n");
+ return -ENOMEM;
+ }
+
+ ret = irq_attach(ESP_IRQ_MCPWM0,
+ mcpwm_capture_driver_isr_default,
+ &mcpwm_common);
+ if (ret < 0)
+ {
+ cperr("Couldn't attach IRQ to handler.\n");
+ esp_teardown_irq(mcpwm_periph_signals.groups[0].irq_id, cpuint);
+ return ret;
+ }
+
+ up_enable_irq(ESP_IRQ_MCPWM0);
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: mcpwm_capture_driver_isr_default
+ *
+ * Description:
+ * Default function called when a capture interrupt occurs.
+ * It reads the capture timer value and the interrupt edge. When positive
+ * edge triggered the interrupt, the current capture value is stored and
+ * the interrupt edge is modified to falling edge.
+ * When the negative edge triggers the interrupt, the timer count
+ * difference is calculated and the high time period is obtained.
+ *
+ * Two pulses are required to properly calculate the frequency.
+ *
+ * Input Parameters:
+ * irq - The interrupt request number.
+ * context - Pointer to the interrupt context.
+ * arg - Pointer to the argument to be passed to the ISR.
+ *
+ * Returned Value:
+ * OK on success, otherwise a negated errno value is returned on
+ * any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+static int IRAM_ATTR mcpwm_capture_driver_isr_default(int irq, void *context,
+ void *arg)
+{
+ struct mcpwm_dev_common_s *common = (struct mcpwm_dev_common_s *)arg;
+ struct mcpwm_cap_channel_lowerhalf_s *lower = NULL;
+ struct mcpwm_capture_event_data_s *data = NULL;
+ irqstate_t flags;
+ uint32_t cap_value;
+ uint32_t status;
+ mcpwm_capture_edge_t cap_edge;
+
+ flags = spin_lock_irqsave(common->mcpwm_spinlock);
+ status = mcpwm_ll_intr_get_status(common->hal.dev);
+
+ if (status & MCPWM_LL_EVENT_CAPTURE(MCPWM_CAP_CHANNEL_0))
+ {
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH0
+ lower = &mcpwm_cap_ch0_lowerhalf;
+#endif
+ }
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH1
+ else if (status & MCPWM_LL_EVENT_CAPTURE(MCPWM_CAP_CHANNEL_1))
+ {
+ lower = &mcpwm_cap_ch1_lowerhalf;
+ }
+#endif
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH2
+ else if (status & MCPWM_LL_EVENT_CAPTURE(MCPWM_CAP_CHANNEL_2))
+ {
+ lower = &mcpwm_cap_ch2_lowerhalf;
+ }
+#endif
+ else
+ {
+ return -ERANGE;
+ }
+
+ mcpwm_ll_intr_clear_status(common->hal.dev,
+ status &
+ MCPWM_LL_EVENT_CAPTURE(lower->channel_id));
+
+ /* At least 4 interrupts are required on a channel before a
+ * frequency measurement can be executed, otherwise you can
+ * obtain negative values.
+ */
+
+ if (lower->isr_count < 4)
+ {
+ lower->isr_count++;
+ }
+
+ if (!lower->ready && (lower->isr_count >= 4))
+ {
+ cpinfo("Channel %d ready\n", lower->channel_id);
+ lower->ready = true;
+ }
+
+ data = lower->data;
+ cap_value = mcpwm_ll_capture_get_value(common->hal.dev,
+ lower->channel_id);
+ cap_edge = mcpwm_ll_capture_get_edge(common->hal.dev,
+ lower->channel_id);
+
+ if (cap_edge == MCPWM_CAP_EDGE_POS)
+ {
+ data->last_pos_edge_count = data->pos_edge_count;
+ data->pos_edge_count = cap_value;
+ data->neg_edge_count = data->pos_edge_count;
+ mcpwm_ll_capture_enable_negedge(common->hal.dev,
+ lower->channel_id,
+ true);
+ mcpwm_ll_capture_enable_posedge(common->hal.dev,
+ lower->channel_id,
+ false);
+ }
+ else
+ {
+ data->neg_edge_count = cap_value;
+
+ if (lower->ready)
+ {
+ uint32_t high_time = data->neg_edge_count - data->pos_edge_count;
+ uint32_t period = data->pos_edge_count - data->last_pos_edge_count;
+
+ if (period != 0)
+ {
+ lower->freq = lower->clock / period;
+ lower->duty = 100 * high_time / period;
+ }
+ }
+
+ mcpwm_ll_capture_enable_negedge(common->hal.dev,
+ lower->channel_id,
+ false);
+ mcpwm_ll_capture_enable_posedge(common->hal.dev,
+ lower->channel_id,
+ true);
+ }
+
+ spin_unlock_irqrestore(common->mcpwm_spinlock, flags);
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_mcpwm_capture_initialize
+ *
+ * Description:
+ * This function initializes the specified MCPWM peripheral and the capture
+ * submodule with the provided configuration.
+ *
+ * Input Parameters:
+ * channel - Channel to be initialized [0-3].
+ * pin - GPIO pin assigned to this channel.
+ *
+ * Returned Value:
+ * On success, this function returns a valid pointer to the Capture device
+ * structure. If the initialization fails, it returns NULL.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+struct cap_lowerhalf_s *esp_mcpwm_capture_initialize(int channel, int pin)
+{
+ struct mcpwm_cap_channel_lowerhalf_s *lower = NULL;
+ uint32_t group_clock;
+
+ /* Single time initialization for the entire MCPWM Peripheral
+ * and MCPWM Capture group.
+ */
+
+ if (!mcpwm_common.initialized)
+ {
+ esp_mcpwm_group_start();
+ }
+
+ if (!mcpwm_common.capture_initialized)
+ {
+ mcpwm_ll_capture_enable_timer(mcpwm_common.hal.dev, true);
+ esp_mcpwm_capture_isr_register(mcpwm_capture_driver_isr_default,
+ &mcpwm_common);
+ mcpwm_common.capture_initialized = true;
+ }
+
+ switch (channel)
+ {
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH0
+ case MCPWM_CAP_CHANNEL_0:
+ lower = &mcpwm_cap_ch0_lowerhalf;
+ break;
+#endif
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH1
+ case MCPWM_CAP_CHANNEL_1:
+ lower = &mcpwm_cap_ch1_lowerhalf;
+ break;
+#endif
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH2
+ case MCPWM_CAP_CHANNEL_2:
+ lower = &mcpwm_cap_ch2_lowerhalf;
+ break;
+#endif
+ default:
+ cperr("Invalid channel selection: %d\n", channel);
+ return NULL;
+ }
+
+ esp_clk_tree_src_get_freq_hz(MCPWM_DEV_CLK_SOURCE,
+ ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,
+ &group_clock);
+
+ /* Set the clock to be used when calculating frequency */
+
+ lower->gpio_pin = pin;
+ lower->clock = group_clock / MCPWM_DEV_CLK_PRESCALE;
+
+ /* Configure GPIO pin */
+
+ esp_mcpwm_capture_set_gpio(lower);
+
+ return (struct cap_lowerhalf_s *)lower;
+}
+#endif
+
+#endif /* CONFIG_ESP_MCPWM */
diff --git a/arch/risc-v/src/common/espressif/esp_mcpwm.h
b/arch/risc-v/src/common/espressif/esp_mcpwm.h
new file mode 100644
index 0000000000..946f7310d7
--- /dev/null
+++ b/arch/risc-v/src/common/espressif/esp_mcpwm.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * arch/risc-v/src/common/espressif/esp_mcpwm.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_MCPWM_H
+#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_MCPWM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#ifdef CONFIG_ESP_MCPWM
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_mcpwm_capture_initialize
+ *
+ * Description:
+ * This function initializes the MCPWM peripheral and the capture
+ * submodule with the provided configuration.
+ *
+ * Input Parameters:
+ * channel - Channel to be initialized [0-3].
+ * pin - GPIO pin assigned to this channel.
+ *
+ * Returned Value:
+ * On success, this function returns a valid pointer to the Capture device
+ * structure. If the initialization fails, it returns NULL.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+struct cap_lowerhalf_s *esp_mcpwm_capture_initialize(int channel, int pin);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_ESP_MCPWM */
+#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_MCPWM_CAPTURE_H */
diff --git a/arch/risc-v/src/esp32c6/hal_esp32c6.mk
b/arch/risc-v/src/esp32c6/hal_esp32c6.mk
index f871db775b..7837d29b42 100644
--- a/arch/risc-v/src/esp32c6/hal_esp32c6.mk
+++ b/arch/risc-v/src/esp32c6/hal_esp32c6.mk
@@ -136,6 +136,7 @@ CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)cache_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mpu_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mmu_hal.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mcpwm_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)uart_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)uart_hal_iram.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)wdt_hal_iram.c
@@ -152,6 +153,7 @@ CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)ledc_periph.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)rmt_periph.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)i2c_periph.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)mcpwm_periph.c
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)bootloader_banner_wrap.c
diff --git a/arch/risc-v/src/esp32h2/hal_esp32h2.mk
b/arch/risc-v/src/esp32h2/hal_esp32h2.mk
index e94c983bcf..df170588cf 100644
--- a/arch/risc-v/src/esp32h2/hal_esp32h2.mk
+++ b/arch/risc-v/src/esp32h2/hal_esp32h2.mk
@@ -118,6 +118,7 @@ CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)timer_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)timer_hal_iram.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mpu_hal.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mcpwm_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mmu_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)uart_hal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)uart_hal_iram.c
@@ -135,6 +136,7 @@ CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)ledc_periph.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)rmt_periph.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)i2c_periph.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)mcpwm_periph.c
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)bootloader_banner_wrap.c
diff --git a/boards/risc-v/esp32c6/common/include/esp_board_mcpwm.h
b/boards/risc-v/esp32c6/common/include/esp_board_mcpwm.h
new file mode 100644
index 0000000000..421fbffd3a
--- /dev/null
+++ b/boards/risc-v/esp32c6/common/include/esp_board_mcpwm.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * boards/risc-v/esp32c6/common/include/esp_board_mcpwm.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_RISCV_ESP32C6_COMMON_INCLUDE_ESP_BOARD_MCPWM_H
+#define __BOARDS_RISCV_ESP32C6_COMMON_INCLUDE_ESP_BOARD_MCPWM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+
+/****************************************************************************
+ * Name: board_capture_initialize
+ *
+ * Description:
+ * Initialize and register the capture driver using the MCPWM peripheral.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_capture_initialize(void);
+
+#endif /* CONFIG_ESP_MCPWM_CAPTURE */
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOARDS_RISCV_ESP32C6_COMMON_INCLUDE_ESP_BOARD_MCPWM_H */
diff --git a/boards/risc-v/esp32c6/common/src/Make.defs
b/boards/risc-v/esp32c6/common/src/Make.defs
index 0a56520102..764c8920ba 100644
--- a/boards/risc-v/esp32c6/common/src/Make.defs
+++ b/boards/risc-v/esp32c6/common/src/Make.defs
@@ -60,6 +60,10 @@ ifeq ($(CONFIG_SENSORS_BMP180),y)
CSRCS += esp_board_bmp180.c
endif
+ifeq ($(CONFIG_ESP_MCPWM),y)
+ CSRCS += esp_board_mcpwm.c
+endif
+
DEPPATH += --dep-path src
VPATH += :src
CFLAGS +=
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
diff --git a/boards/risc-v/esp32c6/common/src/esp_board_mcpwm.c
b/boards/risc-v/esp32c6/common/src/esp_board_mcpwm.c
new file mode 100644
index 0000000000..5229de617c
--- /dev/null
+++ b/boards/risc-v/esp32c6/common/src/esp_board_mcpwm.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * boards/risc-v/esp32c6/common/src/esp_board_mcpwm.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/board.h>
+#include <nuttx/timers/capture.h>
+
+#include <arch/board/board.h>
+
+#include "espressif/esp_mcpwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_capture_initialize
+ *
+ * Description:
+ * Initialize MCPWM Capture submodule and register the capture device.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_capture_initialize(void)
+{
+ int ret;
+ struct cap_lowerhalf_s *cap;
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH0
+ cap = esp_mcpwm_capture_initialize(0, CONFIG_ESP_MCPWM_CAPTURE_CH0_GPIO);
+ if (cap == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to start MCPWM Capture: CH0\n");
+ return -ENODEV;
+ }
+
+ ret = cap_register("/dev/capture0", cap);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: cap_register failed: %d\n", ret);
+ return ret;
+ }
+#endif
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH1
+ cap = esp_mcpwm_capture_initialize(1, CONFIG_ESP_MCPWM_CAPTURE_CH1_GPIO);
+ if (cap == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to start MCPWM Capture: CH1\n");
+ return -ENODEV;
+ }
+
+ ret = cap_register("/dev/capture1", cap);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: cap_register failed: %d\n", ret);
+ return ret;
+ }
+#endif
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH2
+ cap = esp_mcpwm_capture_initialize(2, CONFIG_ESP_MCPWM_CAPTURE_CH2_GPIO);
+ if (cap == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to start MCPWM Capture: CH2\n");
+ return -ENODEV;
+ }
+
+ ret = cap_register("/dev/capture2", cap);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: cap_register failed: %d\n", ret);
+ return ret;
+ }
+#endif
+
+ return OK;
+}
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/capture/defconfig
b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/capture/defconfig
new file mode 100644
index 0000000000..b005c879c0
--- /dev/null
+++ b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/capture/defconfig
@@ -0,0 +1,51 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that
includes your
+# modifications.
+#
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="esp32c6-devkitc"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32C6_DEVKITC=y
+CONFIG_ARCH_CHIP="esp32c6"
+CONFIG_ARCH_CHIP_ESP32C6=y
+CONFIG_ARCH_CHIP_ESP32C6WROOM1=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_LOOPSPERMSEC=15000
+CONFIG_BUILTIN=y
+CONFIG_DEV_ZERO=y
+CONFIG_ESPRESSIF_ESP32C6=y
+CONFIG_ESP_MCPWM=y
+CONFIG_ESP_MCPWM_CAPTURE=y
+CONFIG_ESP_MCPWM_CAPTURE_CH0=y
+CONFIG_FS_PROCFS=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LIBC_PERROR_STDOUT=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_READLINE=y
+CONFIG_NSH_STRERROR=y
+CONFIG_PREALLOC_TIMERS=0
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_BACKTRACE=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=29
+CONFIG_START_MONTH=11
+CONFIG_START_YEAR=2019
+CONFIG_SYSTEM_DUMPSTACK=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TESTING_GETPRIME=y
+CONFIG_TESTING_OSTEST=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c
b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c
index 86f8816702..5a1b11ef34 100644
--- a/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c
+++ b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c
@@ -85,6 +85,10 @@
# include "esp_board_spislavedev.h"
#endif
+#ifdef CONFIG_ESP_MCPWM
+# include "esp_board_mcpwm.h"
+#endif
+
#include "esp32c6-devkitc.h"
/****************************************************************************
@@ -322,6 +326,14 @@ int esp_bringup(void)
}
#endif /* CONFIG_ESPRESSIF_LEDC */
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+ ret = board_capture_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: board_capture_initialize failed: %d\n", ret);
+ }
+#endif
+
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.
diff --git a/boards/risc-v/esp32h2/common/include/esp_board_mcpwm.h
b/boards/risc-v/esp32h2/common/include/esp_board_mcpwm.h
new file mode 100644
index 0000000000..3572dfe2ce
--- /dev/null
+++ b/boards/risc-v/esp32h2/common/include/esp_board_mcpwm.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * boards/risc-v/esp32h2/common/include/esp_board_mcpwm.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_RISCV_ESP32H2_COMMON_INCLUDE_ESP_BOARD_MCPWM_H
+#define __BOARDS_RISCV_ESP32H2_COMMON_INCLUDE_ESP_BOARD_MCPWM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+
+/****************************************************************************
+ * Name: board_capture_initialize
+ *
+ * Description:
+ * Initialize and register the capture driver using the MCPWM peripheral.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_capture_initialize(void);
+
+#endif /* CONFIG_ESP_MCPWM_CAPTURE */
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOARDS_RISCV_ESP32H2_COMMON_INCLUDE_ESP_BOARD_MCPWM_H */
diff --git a/boards/risc-v/esp32h2/common/src/Make.defs
b/boards/risc-v/esp32h2/common/src/Make.defs
index 4ac1b9b459..7d8708f4dd 100644
--- a/boards/risc-v/esp32h2/common/src/Make.defs
+++ b/boards/risc-v/esp32h2/common/src/Make.defs
@@ -56,6 +56,10 @@ ifeq ($(CONFIG_SENSORS_BMP180),y)
CSRCS += esp_board_bmp180.c
endif
+ifeq ($(CONFIG_ESP_MCPWM),y)
+ CSRCS += esp_board_mcpwm.c
+endif
+
DEPPATH += --dep-path src
VPATH += :src
CFLAGS +=
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
diff --git a/boards/risc-v/esp32h2/common/src/esp_board_mcpwm.c
b/boards/risc-v/esp32h2/common/src/esp_board_mcpwm.c
new file mode 100644
index 0000000000..e5a080af07
--- /dev/null
+++ b/boards/risc-v/esp32h2/common/src/esp_board_mcpwm.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * boards/risc-v/esp32h2/common/src/esp_board_mcpwm.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/board.h>
+#include <nuttx/timers/capture.h>
+
+#include <arch/board/board.h>
+
+#include "espressif/esp_mcpwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_capture_initialize
+ *
+ * Description:
+ * Initialize MCPWM Capture submodule and register the capture device.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_capture_initialize(void)
+{
+ int ret;
+ struct cap_lowerhalf_s *cap;
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH0
+ cap = esp_mcpwm_capture_initialize(0, CONFIG_ESP_MCPWM_CAPTURE_CH0_GPIO);
+ if (cap == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to start MCPWM Capture: CH0\n");
+ return -ENODEV;
+ }
+
+ ret = cap_register("/dev/capture0", cap);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: cap_register failed: %d\n", ret);
+ return ret;
+ }
+#endif
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH1
+ cap = esp_mcpwm_capture_initialize(1, CONFIG_ESP_MCPWM_CAPTURE_CH1_GPIO);
+ if (cap == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to start MCPWM Capture: CH1\n");
+ return -ENODEV;
+ }
+
+ ret = cap_register("/dev/capture1", cap);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: cap_register failed: %d\n", ret);
+ return ret;
+ }
+#endif
+
+#ifdef CONFIG_ESP_MCPWM_CAPTURE_CH2
+ cap = esp_mcpwm_capture_initialize(2, CONFIG_ESP_MCPWM_CAPTURE_CH2_GPIO);
+ if (cap == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to start MCPWM Capture: CH2\n");
+ return -ENODEV;
+ }
+
+ ret = cap_register("/dev/capture2", cap);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: cap_register failed: %d\n", ret);
+ return ret;
+ }
+#endif
+
+ return OK;
+}
diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/configs/capture/defconfig
b/boards/risc-v/esp32h2/esp32h2-devkit/configs/capture/defconfig
new file mode 100644
index 0000000000..ff3be99da5
--- /dev/null
+++ b/boards/risc-v/esp32h2/esp32h2-devkit/configs/capture/defconfig
@@ -0,0 +1,51 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that
includes your
+# modifications.
+#
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="esp32h2-devkit"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32H2_DEVKIT=y
+CONFIG_ARCH_CHIP="esp32h2"
+CONFIG_ARCH_CHIP_ESP32H2=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_LOOPSPERMSEC=15000
+CONFIG_BUILTIN=y
+CONFIG_DEV_ZERO=y
+CONFIG_ESPRESSIF_ESP32H2=y
+CONFIG_ESP_MCPWM=y
+CONFIG_ESP_MCPWM_CAPTURE=y
+CONFIG_ESP_MCPWM_CAPTURE_CH0=y
+CONFIG_ESP_MCPWM_CAPTURE_CH0_GPIO=12
+CONFIG_FS_PROCFS=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LIBC_PERROR_STDOUT=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_READLINE=y
+CONFIG_NSH_STRERROR=y
+CONFIG_PREALLOC_TIMERS=0
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_BACKTRACE=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=29
+CONFIG_START_MONTH=11
+CONFIG_START_YEAR=2019
+CONFIG_SYSTEM_DUMPSTACK=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TESTING_GETPRIME=y
+CONFIG_TESTING_OSTEST=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c
b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c
index 265ceccc86..c97f0d02f8 100644
--- a/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c
+++ b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c
@@ -77,6 +77,10 @@
# include "esp_board_spislavedev.h"
#endif
+#ifdef CONFIG_ESP_MCPWM
+# include "esp_board_mcpwm.h"
+#endif
+
#include "esp32h2-devkit.h"
/****************************************************************************
@@ -289,6 +293,14 @@ int esp_bringup(void)
}
#endif /* CONFIG_ESPRESSIF_LEDC */
+#ifdef CONFIG_ESP_MCPWM_CAPTURE
+ ret = board_capture_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: board_capture_initialize failed: %d\n", ret);
+ }
+#endif
+
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.