diff --git a/boards/espressif/esp32_devkitc/esp32_devkitc-pinctrl.dtsi b/boards/espressif/esp32_devkitc/esp32_devkitc-pinctrl.dtsi index 5d05e3bb610b9..ef7428c29c22e 100644 --- a/boards/espressif/esp32_devkitc/esp32_devkitc-pinctrl.dtsi +++ b/boards/espressif/esp32_devkitc/esp32_devkitc-pinctrl.dtsi @@ -120,4 +120,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32_devkitc/esp32_devkitc_procpu.yaml b/boards/espressif/esp32_devkitc/esp32_devkitc_procpu.yaml index 08c3b8e57dd7f..9567793c86c9d 100644 --- a/boards/espressif/esp32_devkitc/esp32_devkitc_procpu.yaml +++ b/boards/espressif/esp32_devkitc/esp32_devkitc_procpu.yaml @@ -20,4 +20,5 @@ supported: - input - crypto - retained_mem + - rmt vendor: espressif diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit-pinctrl.dtsi b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit-pinctrl.dtsi index 13086749c2398..186b06c94e9d0 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit-pinctrl.dtsi +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit-pinctrl.dtsi @@ -58,4 +58,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml index 746a092288401..c64845baa926c 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml @@ -13,4 +13,5 @@ supported: - i2s - crypto - retained_mem + - rmt vendor: espressif diff --git a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc-pinctrl.dtsi b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc-pinctrl.dtsi index 35d54dc58b190..acc105a9da43f 100644 --- a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc-pinctrl.dtsi +++ b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc-pinctrl.dtsi @@ -68,4 +68,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml index 11781db20686a..4b3a05bbf5fb7 100644 --- a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml +++ b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml @@ -18,4 +18,5 @@ supported: - entropy - crypto - retained_mem + - rmt vendor: espressif diff --git a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm-pinctrl.dtsi b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm-pinctrl.dtsi index 79cfcc0cdd09a..1433ebbc9f836 100644 --- a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm-pinctrl.dtsi +++ b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm-pinctrl.dtsi @@ -68,4 +68,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml index b0f9c1619fc6f..8296da2e1e209 100644 --- a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml +++ b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml @@ -18,4 +18,5 @@ supported: - entropy - crypto - retained_mem + - rmt vendor: espressif diff --git a/boards/espressif/esp32c3_rust/esp32c3_rust-pinctrl.dtsi b/boards/espressif/esp32c3_rust/esp32c3_rust-pinctrl.dtsi index e3572b2b688ec..3af63df44fb08 100644 --- a/boards/espressif/esp32c3_rust/esp32c3_rust-pinctrl.dtsi +++ b/boards/espressif/esp32c3_rust/esp32c3_rust-pinctrl.dtsi @@ -43,4 +43,14 @@ output-high; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32c3_rust/esp32c3_rust.yaml b/boards/espressif/esp32c3_rust/esp32c3_rust.yaml index f9b308ed16155..889cb9488fc4b 100644 --- a/boards/espressif/esp32c3_rust/esp32c3_rust.yaml +++ b/boards/espressif/esp32c3_rust/esp32c3_rust.yaml @@ -20,4 +20,5 @@ supported: - entropy - crypto - retained_mem + - rmt vendor: espressif diff --git a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore-pinctrl.dtsi b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore-pinctrl.dtsi index 54c7037fd41ac..62ce0033012af 100644 --- a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore-pinctrl.dtsi +++ b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore-pinctrl.dtsi @@ -61,4 +61,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore.yaml b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore.yaml index d055abdb34f8a..134af705e83ea 100644 --- a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore.yaml +++ b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_hpcore.yaml @@ -20,7 +20,7 @@ supported: - netif:openthread - crypto - retained_mem - + - rmt testing: ignore_tags: - bluetooth diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi index bfb2d3dc13103..c68652f730f1c 100644 --- a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm-pinctrl.dtsi @@ -78,4 +78,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml index 62569973650ca..fb5e6067b73a3 100644 --- a/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml +++ b/boards/espressif/esp32h2_devkitm/esp32h2_devkitm.yaml @@ -20,3 +20,4 @@ supported: - netif:openthread - crypto - retained_mem + - rmt diff --git a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc-pinctrl.dtsi b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc-pinctrl.dtsi index 23e25533f7748..2edae21981dff 100644 --- a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc-pinctrl.dtsi +++ b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc-pinctrl.dtsi @@ -84,4 +84,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml index 81357dbdbfb74..551a978cc5194 100644 --- a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml +++ b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml @@ -22,6 +22,7 @@ supported: - dma - crypto - retained_mem + - rmt testing: ignore_tags: - bluetooth diff --git a/boards/espressif/esp32s2_saola/esp32s2_saola-pinctrl.dtsi b/boards/espressif/esp32s2_saola/esp32s2_saola-pinctrl.dtsi index 0b4e50d88da20..02fef6f11a9bd 100644 --- a/boards/espressif/esp32s2_saola/esp32s2_saola-pinctrl.dtsi +++ b/boards/espressif/esp32s2_saola/esp32s2_saola-pinctrl.dtsi @@ -84,4 +84,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32s2_saola/esp32s2_saola.yaml b/boards/espressif/esp32s2_saola/esp32s2_saola.yaml index a303bed5d4b18..790b07a2e127f 100644 --- a/boards/espressif/esp32s2_saola/esp32s2_saola.yaml +++ b/boards/espressif/esp32s2_saola/esp32s2_saola.yaml @@ -20,6 +20,7 @@ supported: - input - crypto - retained_mem + - rmt testing: ignore_tags: - bluetooth diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc-pinctrl.dtsi b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc-pinctrl.dtsi index 05649cfe3c09e..a3f6cb3928cdc 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc-pinctrl.dtsi +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc-pinctrl.dtsi @@ -113,4 +113,14 @@ ; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml index 68853ee5caf05..5de1f81677858 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml @@ -20,4 +20,5 @@ supported: - video - crypto - retained_mem + - rmt vendor: espressif diff --git a/boards/espressif/esp32s3_eye/esp32s3_eye-pinctrl.dtsi b/boards/espressif/esp32s3_eye/esp32s3_eye-pinctrl.dtsi index 2e6f52af2126d..6295e6a1f4404 100644 --- a/boards/espressif/esp32s3_eye/esp32s3_eye-pinctrl.dtsi +++ b/boards/espressif/esp32s3_eye/esp32s3_eye-pinctrl.dtsi @@ -63,4 +63,14 @@ output-high; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml index 28e4ac58dfeae..e3445c1a64381 100644 --- a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml +++ b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml @@ -20,4 +20,5 @@ supported: - video - crypto - retained_mem + - rmt vendor: espressif diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit-pinctrl.dtsi b/boards/espressif/esp_wrover_kit/esp_wrover_kit-pinctrl.dtsi index 6b2872c3281bb..19ff65fc83ff1 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit-pinctrl.dtsi +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit-pinctrl.dtsi @@ -85,4 +85,14 @@ output-high; }; }; + + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; }; diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml index 7d67e4164198e..0be8ba5b8fe89 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml @@ -19,4 +19,5 @@ supported: - entropy - crypto - retained_mem + - rmt vendor: espressif diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index e36043f45973b..eee260396ae87 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -2,6 +2,7 @@ # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_DEVMUX devmux) +add_subdirectory_ifdef(CONFIG_ESPRESSIF_RMT espressif_rmt) add_subdirectory_ifdef(CONFIG_ETHOS_U ethos_u) add_subdirectory_ifdef(CONFIG_FT800 ft8xx) add_subdirectory_ifdef(CONFIG_GROVE_LCD_RGB grove_lcd_rgb) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 610a2c6a15bf3..84f9941927715 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -7,6 +7,7 @@ menu "Miscellaneous drivers" # zephyr-keep-sorted-start source "drivers/misc/devmux/Kconfig" +source "drivers/misc/espressif_rmt/Kconfig" source "drivers/misc/ethos_u/Kconfig" source "drivers/misc/ft8xx/Kconfig" source "drivers/misc/grove_lcd_rgb/Kconfig" diff --git a/drivers/misc/espressif_rmt/CMakeLists.txt b/drivers/misc/espressif_rmt/CMakeLists.txt new file mode 100644 index 0000000000000..877827a386c65 --- /dev/null +++ b/drivers/misc/espressif_rmt/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(rmt.c rmt_common.c rmt_encoder_bytes.c rmt_encoder_copy.c rmt_encoder_simple.c rmt_encoder.c rmt_rx.c rmt_tx.c) diff --git a/drivers/misc/espressif_rmt/Kconfig b/drivers/misc/espressif_rmt/Kconfig new file mode 100644 index 0000000000000..c9ba7ff969c1b --- /dev/null +++ b/drivers/misc/espressif_rmt/Kconfig @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +menuconfig ESPRESSIF_RMT + bool "ESP32 RMT driver" + default y + depends on DT_HAS_ESPRESSIF_ESP32_RMT_ENABLED + select DMA if DT_HAS_ESPRESSIF_ESP32_GDMA_ENABLED && SOC_SERIES_ESP32S3 + help + Enables the ESP32 Remote Control Transceiver driver. + +if ESPRESSIF_RMT + +config ESPRESSIF_RMT_INIT_PRIORITY + int "ESP32 RMT driver init priority" + default KERNEL_INIT_PRIORITY_DEVICE + help + ESP32 RMT driver initialization priority in POST_KERNEL. + +config ESPRESSIF_RMT_TX_ISR_CACHE_SAFE + bool "RMT TX ISR Cache Safe" + help + Ensure the RMT interrupt is Cache-Safe by allowing the interrupt handler to be + executable when the cache is disabled (e.g. SPI Flash write). + +config ESPRESSIF_RMT_RX_ISR_CACHE_SAFE + bool "RMT RX ISR Cache Safe" + help + Ensure the RMT interrupt is Cache-Safe by allowing the interrupt handler to be + executable when the cache is disabled (e.g. SPI Flash write). + +config ESPRESSIF_RMT_PM + bool "Support for power management" + help + If enabled, RMT driver is compiled with support for power management. + +module = ESPRESSIF_RMT +module-str = espressif_rmt +source "subsys/logging/Kconfig.template.log_config" + +endif diff --git a/drivers/misc/espressif_rmt/rmt.c b/drivers/misc/espressif_rmt/rmt.c new file mode 100644 index 0000000000000..dbe96ed421f1d --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt.c @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT espressif_esp32_rmt + +#include "hal/rmt_hal.h" +#include "rmt_private.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#if SOC_RMT_SUPPORT_DMA && !DT_HAS_COMPAT_STATUS_OKAY(espressif_esp32_gdma) +#error "DMA peripheral is not enabled!" +#endif + +LOG_MODULE_REGISTER(espressif_rmt, CONFIG_ESPRESSIF_RMT_LOG_LEVEL); + +static int rmt_init(const struct device *dev) +{ + const struct espressif_rmt_config *config = dev->config; + int rc; + + /* Check clock device is ready */ + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("DMA device not ready"); + return -ENODEV; + } + +#if SOC_RMT_SUPPORT_DMA + /* Check DMA device is ready (if used) */ + if (config->dma_dev) { + if (!device_is_ready(config->dma_dev)) { + LOG_ERR("Clock device not ready"); + return -ENODEV; + } + } +#endif + + /* Configure pins */ + rc = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (rc) { + LOG_ERR("Failed to configure RMT pins"); + return rc; + } + + return 0; +} + +/* Retrieve DMA device if defined, else default to NULL */ +#define ESPRESSIF_RMT_DT_INST_DMA_CTLR(idx) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(idx, dmas), \ + (DEVICE_DT_GET(DT_INST_DMAS_CTLR(idx))), \ + (NULL)) + +/* Retrieve DMA channel if defined, else default to ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED */ +#define ESPRESSIF_RMT_DT_INST_DMA_CELL(idx, name, cell) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(idx, dmas), \ + (COND_CODE_1(DT_INST_DMAS_HAS_NAME(idx, name), \ + (DT_INST_DMAS_CELL_BY_NAME(idx, name, cell)), \ + (ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED))), \ + (ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED)) + +#define ESPRESSIF_RMT_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ + static const DRAM_ATTR struct espressif_rmt_config espressif_rmt_cfg_##idx = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + .dma_dev = ESPRESSIF_RMT_DT_INST_DMA_CTLR(idx), \ + .tx_dma_channel = ESPRESSIF_RMT_DT_INST_DMA_CELL(idx, tx, channel), \ + .rx_dma_channel = ESPRESSIF_RMT_DT_INST_DMA_CELL(idx, rx, channel), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(idx, offset), \ + .irq_source = DT_INST_IRQ_BY_IDX(idx, 0, irq), \ + .irq_priority = DT_INST_IRQ_BY_IDX(idx, 0, priority), \ + .irq_flags = DT_INST_IRQ_BY_IDX(idx, 0, flags), \ + }; \ + static struct espressif_rmt_data espressif_rmt_data_##idx = { \ + .hal = { \ + .regs = (rmt_soc_handle_t)DT_INST_REG_ADDR(idx), \ + }, \ + }; \ + DEVICE_DT_INST_DEFINE(idx, rmt_init, NULL, &espressif_rmt_data_##idx, \ + &espressif_rmt_cfg_##idx, POST_KERNEL, CONFIG_ESPRESSIF_RMT_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(ESPRESSIF_RMT_INIT); diff --git a/drivers/misc/espressif_rmt/rmt_common.c b/drivers/misc/espressif_rmt/rmt_common.c new file mode 100644 index 0000000000000..a3b3d90c03ef0 --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_common.c @@ -0,0 +1,473 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "rmt_private.h" +#include "clk_ctrl_os.h" +#include "esp_private/esp_clk_tree_common.h" +#include "esp_private/periph_ctrl.h" +#if SOC_RMT_SUPPORT_SLEEP_RETENTION +#include "esp_private/sleep_retention.h" +#endif + +#include + +LOG_MODULE_DECLARE(espressif_rmt); + +typedef struct rmt_platform_t { + /**< Platform level mutex lock */ + unsigned int key; + /**< Array of RMT group instances */ + rmt_group_t *groups[RMT_LL_GET(INST_NUM)]; + /**< Reference count used to protect group install/uninstall */ + int group_ref_counts[RMT_LL_GET(INST_NUM)]; +} rmt_platform_t; + +static rmt_platform_t s_platform; /* singleton platform */ + +#if SOC_RMT_SUPPORT_SLEEP_RETENTION +static int rmt_create_sleep_retention_link_cb(void *arg); +#endif + +rmt_group_t *rmt_acquire_group_handle(int group_id) +{ + bool new_group = false; + rmt_group_t *group = NULL; + + /* prevent install rmt group concurrently */ + s_platform.key = irq_lock(); + if (!s_platform.groups[group_id]) { + group = k_calloc(1, sizeof(rmt_group_t)); + if (group) { + new_group = true; + s_platform.groups[group_id] = group; + group->group_id = group_id; + /* Initial occupy_mask: 1111...100...0 */ + group->occupy_mask = UINT32_MAX & ~((1 << RMT_LL_GET(CHANS_PER_INST)) - 1); + /* + * Group clock won't be configured at this stage, + * it will be set when allocate the first channel. + */ + group->clk_src = 0; + /** + * Group interrupt priority is shared between all channels, + * it will be set when allocate the first channel. + */ + group->intr_priority = RMT_GROUP_INTR_PRIORITY_UNINITIALIZED; + /* enable the bus clock for the RMT peripheral */ + PERIPH_RCC_ATOMIC() { + rmt_ll_enable_bus_clock(group_id, true); + rmt_ll_reset_register(group_id); + } +#if SOC_RMT_SUPPORT_SLEEP_RETENTION + sleep_retention_module_t module = rmt_reg_retention_info[group_id].module; + sleep_retention_module_init_param_t init_param = { + .cbs = { + .create = { + .handle = rmt_create_sleep_retention_link_cb, + .arg = group, + }, + }, + .depends = RETENTION_MODULE_BITMAP_INIT(CLOCK_SYSTEM) + }; + if (sleep_retention_module_init(module, &init_param) != ESP_OK) { + /** + * Even though the sleep retention module init failed, + * RMT driver should still work, so just warning here + */ + LOG_WRN("Init sleep retention failed %d, power domain may be " + "turned off during sleep", group_id); + } +#endif + /* hal layer initialize */ + rmt_hal_init(&group->hal); + } + } else { + /* group already install */ + group = s_platform.groups[group_id]; + } + if (group) { + /* + * someone acquired the group handle means we have a new object that refer to + * this group + */ + s_platform.group_ref_counts[group_id]++; + } + irq_unlock(s_platform.key); + + if (new_group) { + LOG_DBG("new group(%d) at %p, occupy=%"PRIx32, group_id, group, group->occupy_mask); + } + return group; +} + +void rmt_release_group_handle(rmt_group_t *group) +{ + rmt_clock_source_t clk_src = group->clk_src; + bool do_deinitialize = false; + rmt_hal_context_t *hal = &group->hal; + + s_platform.key = irq_lock(); + s_platform.group_ref_counts[group->group_id]--; + if (s_platform.group_ref_counts[group->group_id] == 0) { + do_deinitialize = true; + s_platform.groups[group->group_id] = NULL; + /* disable core clock */ + PERIPH_RCC_ATOMIC() { + rmt_ll_enable_group_clock(hal->regs, false); + } + /* hal layer deinitialize */ + rmt_hal_deinit(hal); + /* disable bus clock */ + PERIPH_RCC_ATOMIC() { + rmt_ll_enable_bus_clock(group->group_id, false); + } + } + irq_unlock(s_platform.key); + + switch (clk_src) { +#if RMT_LL_SUPPORT(RC_FAST) + case RMT_CLK_SRC_RC_FAST: + periph_rtc_dig_clk8m_disable(); + break; +#endif + default: + break; + } + + if (do_deinitialize) { +#if SOC_RMT_SUPPORT_SLEEP_RETENTION + sleep_retention_module_t module = rmt_reg_retention_info[group->group_id].module; + + if (sleep_retention_is_module_created(module)) { + sleep_retention_module_free(module); + } + if (sleep_retention_is_module_inited(module)) { + sleep_retention_module_deinit(module); + } +#endif + LOG_DBG("del group(%d)", group->group_id); + k_free(group); + } +} + +#if !RMT_LL_GET(CHANNEL_CLK_INDEPENDENT) +static int rmt_set_group_prescale(rmt_channel_t *chan, uint32_t expect_resolution_hz, + uint32_t *ret_channel_prescale) +{ + esp_err_t ret; + uint32_t periph_src_clk_hz = 0; + rmt_group_t *group = chan->group; + uint32_t group_resolution_hz = 0; + uint32_t group_prescale = 0; + uint32_t channel_prescale = 0; + bool prescale_conflict = false; + k_spinlock_key_t key; + + ret = esp_clk_tree_src_get_freq_hz(group->clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, + &periph_src_clk_hz); + if (ret) { + LOG_ERR("get clock source freq failed"); + return -EINVAL; + } + + if (group->resolution_hz == 0) { + while (++group_prescale <= RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE) { + group_resolution_hz = periph_src_clk_hz / group_prescale; + channel_prescale = (group_resolution_hz + expect_resolution_hz / 2) + / expect_resolution_hz; + /** + * Use the first value found during the search that satisfies the division + * requirement (highest frequency) + */ + if (channel_prescale > 0 && + channel_prescale <= RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE) { + break; + } + } + } else { + group_prescale = periph_src_clk_hz / group->resolution_hz; + channel_prescale = (group->resolution_hz + expect_resolution_hz / 2) + / expect_resolution_hz; + } + + if (!(group_prescale > 0 && group_prescale <= RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE)) { + LOG_ERR("group prescale out of the range"); + return -EINVAL; + } + if (!(channel_prescale > 0 && channel_prescale <= RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE)) { + LOG_ERR("channel prescale out of the range"); + return -EINVAL; + } + + /** + * Group prescale is shared by all rmt_channel, only set once. + * Use critical section to avoid race condition. + */ + group_resolution_hz = periph_src_clk_hz / group_prescale; + key = k_spin_lock(&group->spinlock); + if (group->resolution_hz == 0) { + group->resolution_hz = group_resolution_hz; + PERIPH_RCC_ATOMIC() { + rmt_ll_set_group_clock_src(group->hal.regs, chan->channel_id, + group->clk_src, group_prescale, 1, 0); + rmt_ll_enable_group_clock(group->hal.regs, true); + } + } else { + prescale_conflict = (group->resolution_hz != group_resolution_hz); + } + k_spin_unlock(&group->spinlock, key); + if (prescale_conflict) { + LOG_ERR("group resolution conflict, already is %"PRIu32" but attempt to %"PRIu32"", + group->resolution_hz, group_resolution_hz); + return -EINVAL; + } + LOG_DBG("group (%d) clock resolution:%"PRIu32"Hz", group->group_id, group->resolution_hz); + *ret_channel_prescale = channel_prescale; + return 0; +} +#endif + +int rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t clk_src, + uint32_t expect_channel_resolution) +{ + esp_err_t ret; + rmt_group_t *group = chan->group; + bool clock_selection_conflict = false; + k_spinlock_key_t key; + uint32_t real_div = 0; + + /* + * check if we need to update the group clock source, + * group clock source is shared by all channels + */ + key = k_spin_lock(&group->spinlock); + if (group->clk_src == 0) { + group->clk_src = clk_src; + } else { + clock_selection_conflict = (group->clk_src != clk_src); + } + k_spin_unlock(&group->spinlock, key); + if (clock_selection_conflict) { + LOG_ERR("Group clock conflict, already is %d but attempt to %d", group->clk_src, + clk_src); + return -EINVAL; + } + /* + * TODO: [clk_tree] to use a generic clock enable/disable + * or acquire/release function for all clock source + */ +#if RMT_LL_SUPPORT(RC_FAST) + if (clk_src == RMT_CLK_SRC_RC_FAST) { + /* + * RC_FAST clock is not enabled automatically on start up, + * we enable it here manually. + * Note there's a ref count in the enable/disable function, + * we must call them in pair in the driver. + */ + periph_rtc_dig_clk8m_enable(); + } +#endif + +#if CONFIG_ESPRESSIF_RMT_PM + /* if DMA is not used, we're using CPU to push the data to the RMT FIFO. + * if the CPU frequency goes down, the transfer+encoding scheme could be unstable because + * CPU can't fill the data in time so, choose ESP_PM_CPU_FREQ_MAX lock for non-dma mode + * otherwise, chose lock type based on the clock source + */ +#if SOC_RMT_SUPPORT_DMA + esp_pm_lock_type_t pm_lock_type = + channel->dma_dev ? ESP_PM_NO_LIGHT_SLEEP : ESP_PM_CPU_FREQ_MAX; +#else + esp_pm_lock_type_t pm_lock_type = ESP_PM_CPU_FREQ_MAX; +#endif + snprintf(channel->pm_lock_name, RMT_PM_LOCK_NAME_LEN_MAX, "rmt_%d_%d", group->group_id, + channel->channel_id); + ret = esp_pm_lock_create(pm_lock_type, 0, channel->pm_lock_name, &channel->pm_lock); + if (ret) { + LOG_ERR("Create PM lock failed"); + return -ENODEV; + } +#endif + + ret = esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + if (ret) { + LOG_ERR("clock source enable failed"); + return -EINVAL; + } +#if RMT_LL_GET(CHANNEL_CLK_INDEPENDENT) + uint32_t periph_src_clk_hz = 0; + /* get clock source frequency */ + if (esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, + ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz) != ESP_OK) { + LOG_ERR("get clock source frequency failed"); + return -EINVAL; + } + PERIPH_RCC_ATOMIC() { + rmt_ll_set_group_clock_src(group->hal.regs, chan->channel_id, clk_src, 1, 1, 0); + rmt_ll_enable_group_clock(group->hal.regs, true); + } + group->resolution_hz = periph_src_clk_hz; + LOG_DBG("group clock resolution:%"PRIu32, group->resolution_hz); + real_div = (group->resolution_hz + expect_channel_resolution / 2) + / expect_channel_resolution; +#else + /** + * Set division for group clock source, + * to achieve highest resolution while guaranteeing the channel resolution. + */ + if (rmt_set_group_prescale(chan, expect_channel_resolution, &real_div)) { + LOG_ERR("set rmt group prescale failed"); + return -EINVAL; + } +#endif + + if (chan->direction == RMT_CHANNEL_DIRECTION_TX) { + rmt_ll_tx_set_channel_clock_div(group->hal.regs, chan->channel_id, real_div); + } else { + rmt_ll_rx_set_channel_clock_div(group->hal.regs, chan->channel_id, real_div); + } + /* resolution lost due to division, calculate the real resolution */ + chan->resolution_hz = group->resolution_hz / real_div; + if (chan->resolution_hz != expect_channel_resolution) { + LOG_WRN("channel resolution loss, real=%"PRIu32, chan->resolution_hz); + } + + return 0; +} + +int rmt_apply_carrier(rmt_channel_handle_t channel, const rmt_carrier_config_t *config) +{ + /* specially, we allow config to be NULL, means to disable the carrier submodule */ + if (!channel) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + return channel->set_carrier_action(channel, config); +} + +int rmt_del_channel(rmt_channel_handle_t channel) +{ + if (!channel) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + return channel->del(channel); +} + +int rmt_enable(rmt_channel_handle_t channel) +{ + if (!channel) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + return channel->enable(channel); +} + +int rmt_disable(rmt_channel_handle_t channel) +{ + if (!channel) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + return channel->disable(channel); +} + +bool rmt_set_intr_priority_to_group(rmt_group_t *group, int intr_priority) +{ + bool priority_conflict = false; + k_spinlock_key_t key; + + key = k_spin_lock(&group->spinlock); + if (group->intr_priority == RMT_GROUP_INTR_PRIORITY_UNINITIALIZED) { + /* intr_priority never allocated, accept user's value unconditionally */ + /* intr_priority could only be set once here */ + group->intr_priority = intr_priority; + } else { + /* + * group intr_priority already specified + * If interrupt priority specified before, + * it CANNOT BE CHANGED until `rmt_release_group_handle()` called + * So we have to check if the new priority specified conflicts with the old one + */ + if (intr_priority) { + /* + * User specified intr_priority, check if conflict or not + * Even though the `group->intr_priority` is 0, an intr_priority must have + * been specified automatically too, although we do not know it exactly now, + * so specifying the intr_priority again might also cause conflict. + * So no matter if `group->intr_priority` is 0 or not, we have to check. + * Value `0` of `group->intr_priority` means "unknown", NOT "unspecified"! + */ + if (intr_priority != (group->intr_priority)) { + /* intr_priority conflicts! */ + priority_conflict = true; + } + } + /* + * user did not specify intr_priority, then keep the old priority + * We'll use the `RMT_INTR_ALLOC_FLAG | RMT_ALLOW_INTR_PRIORITY_MASK`, + * which should always success + */ + } + + /* + * The `group->intr_priority` will not change any longer, even though another task tries to + * modify it. So we could exit critical here safely. + */ + k_spin_unlock(&group->spinlock, key); + return priority_conflict; +} + +int rmt_isr_priority_to_flags(rmt_group_t *group) +{ + int isr_flags = 0; + + if (group->intr_priority) { + /* Use user-specified priority bit */ + isr_flags |= (1 << (group->intr_priority)); + } else { + /* Allow all LOWMED priority bits */ + isr_flags |= RMT_ALLOW_INTR_PRIORITY_MASK; + } + + return isr_flags; +} + +#if SOC_RMT_SUPPORT_SLEEP_RETENTION +static int rmt_create_sleep_retention_link_cb(void *arg) +{ + rmt_group_t *group = (rmt_group_t *)arg; + + if (!sleep_retention_entries_create( + rmt_reg_retention_info[group->group_id].regdma_entry_array, + rmt_reg_retention_info[group->group_id].array_size, REGDMA_LINK_PRI_RMT, + rmt_reg_retention_info[group->group_id].module)) { + return -EINVAL; + } + + return 0; +} + +void rmt_create_retention_module(rmt_group_t *group) +{ + sleep_retention_module_t module = rmt_reg_retention_info[group->group_id].module; + + s_platform.key = irq_lock(); + if (sleep_retention_is_module_inited(module) && + !sleep_retention_is_module_created(module)) { + if (sleep_retention_module_allocate(module) != ESP_OK) { + /** + * Even though the sleep retention module create failed, + * RMT driver should still work, so just warning here + */ + LOG_WRN("Create retention link failed, " + "power domain will not be turned off during sleep"); + } + } + irq_unlock(s_platform.key); +} +#endif diff --git a/drivers/misc/espressif_rmt/rmt_encoder.c b/drivers/misc/espressif_rmt/rmt_encoder.c new file mode 100644 index 0000000000000..939e727c7ca1b --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_encoder.c @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "rmt_private.h" + +#include +#include + +LOG_MODULE_DECLARE(espressif_rmt); + +int rmt_del_encoder(rmt_encoder_handle_t encoder) +{ + if (!encoder) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + return encoder->del(encoder); +} + +int rmt_encoder_reset(rmt_encoder_handle_t encoder) +{ + if (!encoder) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + return encoder->reset(encoder); +} + +void *rmt_alloc_encoder_mem(size_t size) +{ + return k_calloc(1, size); +} diff --git a/drivers/misc/espressif_rmt/rmt_encoder_bytes.c b/drivers/misc/espressif_rmt/rmt_encoder_bytes.c new file mode 100644 index 0000000000000..ce1d0f5e631ef --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_encoder_bytes.c @@ -0,0 +1,198 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "rmt_private.h" +#include "hal/hal_utils.h" + +#include +#include +#include + +LOG_MODULE_DECLARE(espressif_rmt); + +typedef struct rmt_bytes_encoder_t { + /**< Encoder base class */ + rmt_encoder_t base; + /**< Index of the encoding bit position in the encoding byte */ + size_t last_bit_index; + /**< Index of the encoding byte in the primary stream */ + size_t last_byte_index; + /**< Bit zero representing */ + rmt_symbol_word_t bit0; + /**< Bit one representing */ + rmt_symbol_word_t bit1; + struct { + /**< Encode MSB firstly */ + uint32_t msb_first: 1; + } flags; +} rmt_bytes_encoder_t; + +static int rmt_bytes_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_bytes_encoder_t *bytes_encoder = __containerof(encoder, rmt_bytes_encoder_t, base); + + /* reset index to zero */ + bytes_encoder->last_bit_index = 0; + bytes_encoder->last_byte_index = 0; + + return 0; +} + +static size_t IRAM_ATTR rmt_encode_bytes(rmt_encoder_t *encoder, rmt_channel_handle_t channel, + const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_bytes_encoder_t *bytes_encoder = __containerof(encoder, rmt_bytes_encoder_t, base); + rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); + const uint8_t *raw_data = (const uint8_t *)primary_data; + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t byte_index = bytes_encoder->last_byte_index; + size_t bit_index = bytes_encoder->last_bit_index; + /* how many symbols will be generated by the encoder */ + size_t mem_want = (data_size - byte_index - 1) * 8 + (8 - bit_index); + /* how many symbols we can save for this round */ + size_t symbol_off = tx_chan->mem_off_bytes / sizeof(rmt_symbol_word_t); + size_t mem_have = tx_chan->mem_end - symbol_off; + /* where to put the encoded symbols? DMA buffer or RMT HW memory */ +#if SOC_RMT_SUPPORT_DMA + rmt_symbol_word_t *mem_to_nc = channel->dma_dev ? + channel->dma_mem_base : channel->hw_mem_base; +#else + rmt_symbol_word_t *mem_to_nc = channel->hw_mem_base; +#endif + /* how many symbols will be encoded in this round */ + size_t encode_len = MIN(mem_want, mem_have); + bool encoding_truncated = mem_have < mem_want; + bool encoding_space_free = mem_have > mem_want; + size_t len; +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + len = encode_len; + while (len > 0) { + /* start from last time truncated encoding */ + uint8_t cur_byte = raw_data[byte_index]; + /* bit-wise reverse */ + if (bytes_encoder->flags.msb_first) { + cur_byte = hal_utils_bitwise_reverse8(cur_byte); + } + while ((len > 0) && (bit_index < 8)) { + if (cur_byte & (1 << bit_index)) { + mem_to_nc[symbol_off++] = bytes_encoder->bit1; + } else { + mem_to_nc[symbol_off++] = bytes_encoder->bit0; + } + len--; + bit_index++; + } + if (bit_index >= 8) { + byte_index++; + bit_index = 0; + } + } + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, + (uint32_t)channel->dma_mem_base, 0, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return 0; + } + } +#endif + + if (encoding_truncated) { + /* this encoding has not finished yet, save the truncated position */ + bytes_encoder->last_bit_index = bit_index; + bytes_encoder->last_byte_index = byte_index; + } else { + /* reset internal index if encoding session has finished */ + bytes_encoder->last_bit_index = 0; + bytes_encoder->last_byte_index = 0; + state |= RMT_ENCODING_COMPLETE; + } + + if (!encoding_space_free) { + /* no more free memory, the caller should yield */ + state |= RMT_ENCODING_MEM_FULL; + } + + /* reset offset pointer when exceeds maximum range */ + if (symbol_off >= tx_chan->ping_pong_symbols * 2) { +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, + (uint32_t)channel->dma_mem_base, 0, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return 0; + } + } +#endif + tx_chan->mem_off_bytes = 0; + } else { + tx_chan->mem_off_bytes = symbol_off * sizeof(rmt_symbol_word_t); + } + + *ret_state = state; + return encode_len; +} + +static int rmt_del_bytes_encoder(rmt_encoder_t *encoder) +{ + rmt_bytes_encoder_t *bytes_encoder; + + bytes_encoder = __containerof(encoder, rmt_bytes_encoder_t, base); + k_free(bytes_encoder); + + return 0; +} + +int rmt_new_bytes_encoder(const rmt_bytes_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder) +{ + rmt_bytes_encoder_t *encoder; + + if (!(config && ret_encoder)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + encoder = rmt_alloc_encoder_mem(sizeof(rmt_bytes_encoder_t)); + if (!encoder) { + LOG_ERR("Unable to allocate memory for encoder"); + return -ENOMEM; + } + encoder->base.encode = rmt_encode_bytes; + encoder->base.del = rmt_del_bytes_encoder; + encoder->base.reset = rmt_bytes_encoder_reset; + encoder->bit0 = config->bit0; + encoder->bit1 = config->bit1; + encoder->flags.msb_first = config->flags.msb_first; + + /* return general encoder handle */ + *ret_encoder = &encoder->base; + LOG_DBG("new bytes encoder @%p", encoder); + + return 0; +} + +int rmt_bytes_encoder_update_config(rmt_encoder_handle_t bytes_encoder, + const rmt_bytes_encoder_config_t *config) +{ + rmt_bytes_encoder_t *encoder; + + if (!(bytes_encoder && config)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + encoder = __containerof(bytes_encoder, rmt_bytes_encoder_t, base); + encoder->bit0 = config->bit0; + encoder->bit1 = config->bit1; + encoder->flags.msb_first = config->flags.msb_first; + + return 0; +} diff --git a/drivers/misc/espressif_rmt/rmt_encoder_copy.c b/drivers/misc/espressif_rmt/rmt_encoder_copy.c new file mode 100644 index 0000000000000..2c04978d216b8 --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_encoder_copy.c @@ -0,0 +1,145 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "rmt_private.h" + +#include +#include +#include + +LOG_MODULE_DECLARE(espressif_rmt); + +typedef struct rmt_copy_encoder_t { + /**< Encoder base class */ + rmt_encoder_t base; + /**< Index of symbol position in the primary stream */ + size_t last_symbol_index; +} rmt_copy_encoder_t; + +static int rmt_copy_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_copy_encoder_t *copy_encoder = __containerof(encoder, rmt_copy_encoder_t, base); + + copy_encoder->last_symbol_index = 0; + + return 0; +} + +static size_t IRAM_ATTR rmt_encode_copy(rmt_encoder_t *encoder, rmt_channel_handle_t channel, + const void *input_symbols, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_copy_encoder_t *copy_encoder = __containerof(encoder, rmt_copy_encoder_t, base); + rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); + rmt_symbol_word_t *symbols = (rmt_symbol_word_t *)input_symbols; + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t symbol_index = copy_encoder->last_symbol_index; + /* how many symbols will be copied by the encoder */ + size_t mem_want = (data_size / 4 - symbol_index); + /* how many symbols we can save for this round */ + size_t symbol_off = tx_chan->mem_off_bytes / sizeof(rmt_symbol_word_t); + size_t mem_have = tx_chan->mem_end - symbol_off; + /* where to put the encoded symbols? DMA buffer or RMT HW memory */ +#if SOC_RMT_SUPPORT_DMA + rmt_symbol_word_t *mem_to_nc = channel->dma_dev ? + channel->dma_mem_base : channel->hw_mem_base; +#else + rmt_symbol_word_t *mem_to_nc = channel->hw_mem_base; +#endif + /* how many symbols will be encoded in this round */ + size_t encode_len = MIN(mem_want, mem_have); + bool encoding_truncated = mem_have < mem_want; + bool encoding_space_free = mem_have > mem_want; + size_t len; +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + len = encode_len; + while (len > 0) { + mem_to_nc[symbol_off++] = symbols[symbol_index++]; + len--; + } + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, + (uint32_t)channel->dma_mem_base, 0, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return 0; + } + } +#endif + + if (encoding_truncated) { + /* this encoding has not finished yet, save the truncated position */ + copy_encoder->last_symbol_index = symbol_index; + } else { + /* reset internal index if encoding session has finished */ + copy_encoder->last_symbol_index = 0; + state |= RMT_ENCODING_COMPLETE; + } + + if (!encoding_space_free) { + /* no more free memory, the caller should yield */ + state |= RMT_ENCODING_MEM_FULL; + } + + /* reset offset pointer when exceeds maximum range */ + if (symbol_off >= tx_chan->ping_pong_symbols * 2) { +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, + (uint32_t)channel->dma_mem_base, 0, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return 0; + } + } +#endif + tx_chan->mem_off_bytes = 0; + } else { + tx_chan->mem_off_bytes = symbol_off * sizeof(rmt_symbol_word_t); + } + + *ret_state = state; + return encode_len; +} + +static int rmt_del_copy_encoder(rmt_encoder_t *encoder) +{ + rmt_copy_encoder_t *copy_encoder; + + copy_encoder = __containerof(encoder, rmt_copy_encoder_t, base); + k_free(copy_encoder); + + return 0; +} + +int rmt_new_copy_encoder(const rmt_copy_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder) +{ + rmt_copy_encoder_t *encoder; + + if (!(config && ret_encoder)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + encoder = rmt_alloc_encoder_mem(sizeof(rmt_copy_encoder_t)); + if (!encoder) { + LOG_ERR("Unable to allocate memory for encoder"); + return -ENOMEM; + } + encoder->base.encode = rmt_encode_copy; + encoder->base.del = rmt_del_copy_encoder; + encoder->base.reset = rmt_copy_encoder_reset; + + /* return general encoder handle */ + *ret_encoder = &encoder->base; + LOG_DBG("new copy encoder @%p", encoder); + + return 0; +} diff --git a/drivers/misc/espressif_rmt/rmt_encoder_simple.c b/drivers/misc/espressif_rmt/rmt_encoder_simple.c new file mode 100644 index 0000000000000..db215f809ec2c --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_encoder_simple.c @@ -0,0 +1,253 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "rmt_private.h" + +#include +#include +#include + +LOG_MODULE_DECLARE(espressif_rmt); + +typedef struct rmt_simple_encoder_t { + /**< Encoder base class */ + rmt_encoder_t base; + /**< Index of symbol position in the primary stream */ + size_t last_symbol_index; + /**< Callback to call to encode */ + rmt_encode_simple_cb_t callback; + /**< Opaque callback argument */ + void *arg; + /**< Overflow buffer */ + rmt_symbol_word_t *ovf_buf; + /**< Size, in elements, of overflow buffer */ + size_t ovf_buf_size; + /**< How much actual info the overflow buffer has */ + size_t ovf_buf_fill_len; + /**< Up to where we moved info from the ovf buf to the rmt */ + size_t ovf_buf_parsed_pos; + /**< True if we can't call the callback for more data anymore */ + bool callback_done; +} rmt_simple_encoder_t; + +static int rmt_simple_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_simple_encoder_t *simple_encoder = __containerof(encoder, rmt_simple_encoder_t, base); + + simple_encoder->last_symbol_index = 0; + simple_encoder->ovf_buf_fill_len = 0; + simple_encoder->ovf_buf_parsed_pos = 0; + simple_encoder->callback_done = false; + + return 0; +} + +static size_t rmt_encode_simple(rmt_encoder_t *encoder, rmt_channel_handle_t channel, + const void *data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_simple_encoder_t *simple_encoder = __containerof(encoder, rmt_simple_encoder_t, base); + rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t symbol_off = tx_chan->mem_off_bytes / sizeof(rmt_symbol_word_t); + size_t encode_len = 0; /* Total amount of symbols written to RMT memory */ + bool is_done = false; + /* where to put the encoded symbols? DMA buffer or RMT HW memory */ +#if SOC_RMT_SUPPORT_DMA + rmt_symbol_word_t *mem_to_nc = channel->dma_dev ? + channel->dma_mem_base : channel->hw_mem_base; +#else + rmt_symbol_word_t *mem_to_nc = channel->hw_mem_base; +#endif +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + /* + * While we're not done, we need to use the callback to fill the RMT memory until it is + * exactly entirely full. We cannot do that if the RMT memory still has N free spaces + * but the encoder callback needs more than N spaces to properly encode a symbol. + * In order to work around that, if we detect that situation we let the encoder + * encode into an overflow buffer, then we use the contents of that buffer to fill + * those last N spaces. On the next call, we will first output the rest of the + * overflow buffer before again using the callback to continue filling the RMT + * buffer. + */ + /* + * Note the next code is in a while loop to properly handle 'unsure' callbacks that + * e.g. return 0 with a free buffer size of M, but then return less than M symbols + * when then called with a larger buffer. + */ + while (symbol_off < tx_chan->mem_end) { + if (simple_encoder->ovf_buf_parsed_pos < simple_encoder->ovf_buf_fill_len) { + /* + * Overflow buffer has data from the previous encoding call. + * Copy one entry from that. + */ + mem_to_nc[symbol_off++] = + simple_encoder->ovf_buf[simple_encoder->ovf_buf_parsed_pos++]; + encode_len++; + } else { + /* Overflow buffer is empty, so we don't need to empty that first. */ + if (simple_encoder->callback_done) { + /* + * We cannot call the callback anymore and the overflow buffer + * is empty, so we're done with the transaction. + */ + is_done = true; + break; + } + /* Try to have the callback write the data directly into RMT memory. */ + size_t enc_size = simple_encoder->callback(data, data_size, + simple_encoder->last_symbol_index, + tx_chan->mem_end - symbol_off, &mem_to_nc[symbol_off], + &is_done, simple_encoder->arg); + encode_len += enc_size; + symbol_off += enc_size; + simple_encoder->last_symbol_index += enc_size; + if (is_done) { + /* we're done, no more data to write to RMT memory. */ + break; + } + if (enc_size == 0) { + /* + * The encoder does not have enough space in RMT memory to encode + * its thing, but the RMT memory is not filled out entirely. Encode + * into the overflow buffer so the next iterations of the loop can + * fill out the RMT buffer from that. + */ + enc_size = simple_encoder->callback(data, data_size, + simple_encoder->last_symbol_index, + simple_encoder->ovf_buf_size, simple_encoder->ovf_buf, + &is_done, simple_encoder->arg); + simple_encoder->last_symbol_index += enc_size; + /* + * Note we do *not* update encode_len here as the data isn't going + * to the RMT yet. + */ + simple_encoder->ovf_buf_fill_len = enc_size; + simple_encoder->ovf_buf_parsed_pos = 0; + if (is_done) { + /* + * If the encoder is done, we cannot call the callback + * anymore, but we still need to handle any data in the + * overflow buffer. + */ + simple_encoder->callback_done = true; + } else { + if (enc_size == 0) { + /* + * According to the callback docs, this is illegal. + * Report this. EARLY_LOGE as we're running from an + * ISR. + */ + LOG_ERR("rmt_encoder_simple: encoder callback " + "returned 0 when fed a buffer of " + "config::min_chunk_size!"); + /* Then abort the transaction. */ + is_done = true; + break; + } + } + } + } + } + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, + (uint32_t)channel->dma_mem_base, 0, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return 0; + } + } +#endif + + if (is_done) { + /* reset internal index if encoding session has finished */ + simple_encoder->last_symbol_index = 0; + state |= RMT_ENCODING_COMPLETE; + } else { + /* no more free memory, the caller should yield */ + state |= RMT_ENCODING_MEM_FULL; + } + + /* reset offset pointer when exceeds maximum range */ + if (symbol_off >= tx_chan->ping_pong_symbols * 2) { +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, + (uint32_t)channel->dma_mem_base, 0, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return 0; + } + } +#endif + tx_chan->mem_off_bytes = 0; + } else { + tx_chan->mem_off_bytes = symbol_off * sizeof(rmt_symbol_word_t); + } + + *ret_state = state; + return encode_len; +} + +static int rmt_del_simple_encoder(rmt_encoder_t *encoder) +{ + rmt_simple_encoder_t *simple_encoder = __containerof(encoder, rmt_simple_encoder_t, base); + + if (simple_encoder->ovf_buf) { + k_free(simple_encoder->ovf_buf); + } + k_free(simple_encoder); + + return 0; +} + +int rmt_new_simple_encoder(const rmt_simple_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder) +{ + rmt_simple_encoder_t *encoder = NULL; + + if (!(config && ret_encoder)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + encoder = rmt_alloc_encoder_mem(sizeof(rmt_simple_encoder_t)); + if (!encoder) { + LOG_ERR("Unable to allocate memory for encoder"); + return -ENOMEM; + } + encoder->base.encode = rmt_encode_simple; + encoder->base.del = rmt_del_simple_encoder; + encoder->base.reset = rmt_simple_encoder_reset; + encoder->callback = config->callback; + encoder->arg = config->arg; + + size_t min_chunk_size = config->min_chunk_size; + + if (min_chunk_size == 0) { + min_chunk_size = 64; + } + encoder->ovf_buf = rmt_alloc_encoder_mem(min_chunk_size * sizeof(rmt_symbol_word_t)); + if (!encoder->ovf_buf) { + LOG_ERR("Unable to allocate memory for overflow buffer"); + if (encoder) { + k_free(encoder); + } + return -ENOMEM; + } + encoder->ovf_buf_size = min_chunk_size; + encoder->ovf_buf_fill_len = 0; + encoder->ovf_buf_parsed_pos = 0; + + /* return general encoder handle */ + *ret_encoder = &encoder->base; + LOG_DBG("new simple encoder @%p", encoder); + + return 0; +} diff --git a/drivers/misc/espressif_rmt/rmt_private.h b/drivers/misc/espressif_rmt/rmt_private.h new file mode 100644 index 0000000000000..ac6e23ac7cfe5 --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_private.h @@ -0,0 +1,325 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_PRIVATE_H_ +#define ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_PRIVATE_H_ + +#include "soc/soc_caps.h" +#include "hal/rmt_types.h" +#include "hal/rmt_hal.h" +#include "hal/rmt_ll.h" +#include "hal/rmt_periph.h" +#include "hal/dma_types.h" +#include "esp_intr_alloc.h" +#include "esp_heap_caps.h" +#include "esp_clk_tree.h" +#include "esp_pm.h" +#include "esp_attr.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* RMT driver object is per-channel, the interrupt source is shared between channels */ +#if CONFIG_ESPRESSIF_RMT_TX_ISR_CACHE_SAFE +#define RMT_TX_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM) +#else +#define RMT_TX_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED) +#endif +#if CONFIG_ESPRESSIF_RMT_RX_ISR_CACHE_SAFE +#define RMT_RX_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM) +#else +#define RMT_RX_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED) +#endif + +/* Hopefully the channel offset won't change in other targets */ +#define RMT_TX_CHANNEL_OFFSET_IN_GROUP (0) +#define RMT_RX_CHANNEL_OFFSET_IN_GROUP \ + (RMT_LL_GET(CHANS_PER_INST) - RMT_LL_GET(TX_CANDIDATES_PER_INST)) + +#define RMT_ALLOW_INTR_PRIORITY_MASK ESP_INTR_FLAG_LOWMED + +/* DMA buffer size must align to `rmt_symbol_word_t` */ +#define RMT_DMA_DESC_BUF_MAX_SIZE \ + (DMA_DESCRIPTOR_BUFFER_MAX_SIZE & ~(sizeof(rmt_symbol_word_t) - 1)) + +/* two nodes ping-pong */ +#define RMT_DMA_NODES_PING_PONG (2) + +#if CONFIG_ESPRESSIF_RMT_PM +/* maximal length of PM lock name */ +#define RMT_PM_LOCK_NAME_LEN_MAX (16) +#endif + +/* Uninitialized priotity value */ +#define RMT_GROUP_INTR_PRIORITY_UNINITIALIZED (-1) + +typedef struct { + struct { + rmt_symbol_word_t symbols[SOC_RMT_MEM_WORDS_PER_CHANNEL]; + } channels[RMT_LL_GET(CHANS_PER_INST)]; +} rmt_block_mem_t; + +/* RMTMEM address is declared in .peripherals.ld */ +extern rmt_block_mem_t RMTMEM; + +typedef enum { + RMT_CHANNEL_DIRECTION_TX, + RMT_CHANNEL_DIRECTION_RX, +} rmt_channel_direction_t; + +typedef enum { + RMT_FSM_INIT, + RMT_FSM_ENABLE, + RMT_FSM_RUN, + RMT_FSM_WAIT, +} rmt_fsm_t; + +enum { + RMT_TX_QUEUE_READY, + RMT_TX_QUEUE_PROGRESS, + RMT_TX_QUEUE_COMPLETE, + RMT_TX_QUEUE_MAX, +}; + +typedef struct rmt_group_t rmt_group_t; +typedef struct rmt_channel_t rmt_channel_t; +typedef struct rmt_tx_channel_t rmt_tx_channel_t; +typedef struct rmt_rx_channel_t rmt_rx_channel_t; +typedef struct rmt_sync_manager_t rmt_sync_manager_t; + +struct rmt_group_t { + /**< Group ID, index from 0 */ + int group_id; + /**< To protect per-group register level concurrent access */ + struct k_spinlock spinlock; + /**< Hal layer for each group */ + rmt_hal_context_t hal; + /**< Record the group clock source, group clock is shared by all channels */ + rmt_clock_source_t clk_src; + /**< Resolution of group clock */ + uint32_t resolution_hz; + /**< A set bit in the mask indicates the channel is not available */ + uint32_t occupy_mask; + /**< Array of RMT TX channels */ + rmt_tx_channel_t *tx_channels[RMT_LL_GET(TX_CANDIDATES_PER_INST)]; + /**< Array of RMT RX channels */ + rmt_rx_channel_t *rx_channels[RMT_LL_GET(RX_CANDIDATES_PER_INST)]; + /**< Sync manager, this can be extended into an array + * if there're more sync controllers in one RMT group + */ + rmt_sync_manager_t *sync_manager; + /**< RMT interrupt priority */ + int intr_priority; +}; + +struct rmt_channel_t { + /**< Channel ID, index from 0 */ + int channel_id; + /**< Mask of the memory blocks that occupied by the channel */ + uint32_t channel_mask; + /**< Number of occupied RMT memory blocks */ + size_t mem_block_num; + /**< Which group the channel belongs to */ + rmt_group_t *group; + /**< Prevent channel resource accessing by user and interrupt concurrently */ + struct k_spinlock spinlock; + /**< Channel clock resolution */ + uint32_t resolution_hz; + /**< Allocated interrupt handle for each channel */ + intr_handle_t intr; + /**< Channel life cycle specific FSM */ + atomic_t fsm; + /**< Channel direction */ + rmt_channel_direction_t direction; + /**< Base address of RMT channel hardware memory */ + rmt_symbol_word_t *hw_mem_base; + /**< Base address of RMT channel DMA buffer */ + rmt_symbol_word_t *dma_mem_base; + /**< Size of RMT channel DMA buffer */ + size_t dma_mem_size; + /**< Channel used with DMA capability */ + bool with_dma; + /**< DMA instance */ + const struct device *dma_dev; + /**< DMA channel */ + uint8_t dma_channel; +#if CONFIG_ESPRESSIF_RMT_PM + /**< PM lock */ + esp_pm_lock_handle_t pm_lock; + /**< PM lock name */ + char pm_lock_name[RMT_PM_LOCK_NAME_LEN_MAX]; +#endif + /* RMT channel common interface */ + /* The following IO functions will have per-implementation for TX and RX channel */ + int (*del)(rmt_channel_t *channel); + int (*set_carrier_action)(rmt_channel_t *channel, const rmt_carrier_config_t *config); + int (*enable)(rmt_channel_t *channel); + int (*disable)(rmt_channel_t *channel); +}; + +typedef struct { + /**< Encode user payload into RMT symbols */ + rmt_encoder_handle_t encoder; + /**< Encoder payload */ + const void *payload; + /**< Payload size */ + size_t payload_bytes; + /**< Transaction can be continued in a loop for specific times */ + int loop_count; + /**< User required loop count may exceed hardware limitation, + * the driver will transfer them in batches + */ + int remain_loop_count; + /**< Track the number of transmitted symbols */ + size_t transmitted_symbol_num; + struct { + /**< Set the output level for the "End Of Transmission" */ + uint32_t eot_level : 1; + /**< Indicate whether the encoding has finished + * (not the encoding of transmission) + */ + uint32_t encoding_done: 1; + /**< Indicate whether need to insert an EOF mark + * (a special RMT symbol) + */ + uint32_t need_eof_mark: 1; + } flags; +} rmt_tx_trans_desc_t; + +struct rmt_tx_channel_t { + /**< Channel base class */ + rmt_channel_t base; + /**< Runtime argument, indicating the next writing position in the RMT hardware memory */ + size_t mem_off_bytes; + /**< Runtime argument, indicating the end of current writing region */ + size_t mem_end; + /**< Ping-pong size (half of the RMT channel memory) */ + size_t ping_pong_symbols; + /**< Size of transaction queue */ + size_t queue_size; + /**< Indicates the number of transactions that are undergoing but not recycled to + * ready_queue + */ + size_t num_trans_inflight; + /**< Transaction queues */ + struct k_msgq trans_queues[RMT_TX_QUEUE_MAX]; + /**< Memory to store the static structure for trans_queues */ + struct msg *trans_queue_structs[RMT_TX_QUEUE_MAX]; + /**< Points to current transaction */ + rmt_tx_trans_desc_t *cur_trans; + /**< User context */ + void *user_data; + /**< Callback, invoked on trans done */ + rmt_tx_done_callback_t on_trans_done; + /**< Transfer descriptor pool */ + rmt_tx_trans_desc_t trans_desc_pool[]; +}; + +typedef struct { + /**< Buffer for saving the received symbols */ + void *buffer; + /**< Size of the buffer, in bytes */ + size_t buffer_size; + /**< Track the number of received symbols */ + size_t received_symbol_num; + /**< Tracking offset in the copy destination */ + size_t copy_dest_off; + struct { + /**< Packet is too long, we need to notify the user to process the data piece by + * piece, in a ping-pong approach + */ + uint32_t en_partial_rx: 1; + } flags; +} rmt_rx_trans_desc_t; + +struct rmt_rx_channel_t { + /**< Channel base class */ + rmt_channel_t base; + /**< Filter clock resolution, in Hz */ + uint32_t filter_clock_resolution_hz; + /**< Starting offset to fetch the symbols in RMT-MEM */ + size_t mem_off; + /**< Ping-pong size (half of the RMT channel memory) */ + size_t ping_pong_symbols; + /**< Callback, invoked on receive done */ + rmt_rx_done_callback_t on_recv_done; + /**< User context */ + void *user_data; + /**< Transaction description */ + rmt_rx_trans_desc_t trans_desc; + /**< Number of DMA nodes, determined by how big the memory block that user configures */ + size_t num_dma_nodes; +}; + +/** + * @brief Acquire RMT group handle. + * + * @param group_id Group ID. + * @retval RMT group handle. + */ +rmt_group_t *rmt_acquire_group_handle(int group_id); + +/** + * @brief Release RMT group handle. + * + * @param group RMT group handle, returned from `rmt_acquire_group_handle`. + */ +void rmt_release_group_handle(rmt_group_t *group); + +/** + * @brief Set clock source for RMT peripheral + * + * @param chan RMT channel handle. + * @param clk_src Clock source. + * @param expect_channel_resolution Expected channel resolution. + * @retval 0 If successful. + * @retval -EINVAL if setting clock source failed because the clk_src is not supported. + * @retval -ENODEV if setting clock source failed because the clk_src is different from other RMT + * channel. + * @retval -ENODEV if setting clock source failed because of other error. + */ +int rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t clk_src, + uint32_t expect_channel_resolution); + +/** + * @brief Set interrupt priority to RMT group. + * + * @param group RMT group to set interrupt priority to. + * @param intr_priority User-specified interrupt priority (in num, not bitmask). + * @retval false if interrupt priority set successfully. + * @retval true if interrupt priority conflict with previous specified. + */ +bool rmt_set_intr_priority_to_group(rmt_group_t *group, int intr_priority); + +/** + * @brief Convert the interrupt priority to flags + * + * @param group RMT group. + * @retval ISR flags value. + */ +int rmt_isr_priority_to_flags(rmt_group_t *group); + +#if SOC_RMT_SUPPORT_SLEEP_RETENTION + +/** + * @brief Create sleep retention link + * + * @param group RMT group. + */ +void rmt_create_retention_module(rmt_group_t *group); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_PRIVATE_H_ */ diff --git a/drivers/misc/espressif_rmt/rmt_rx.c b/drivers/misc/espressif_rmt/rmt_rx.c new file mode 100644 index 0000000000000..7847edaae28c0 --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_rx.c @@ -0,0 +1,1013 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "esp_memory_utils.h" +#if SOC_RMT_SUPPORT_DMA +#include +#include +#endif +#include "rmt_private.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SOC_SERIES_ESP32 +#include +#elif defined(CONFIG_SOC_SERIES_ESP32S2) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32S3) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32C3) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32C6) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#include +#endif + +LOG_MODULE_DECLARE(espressif_rmt); + +#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + +/* RMT RX Channel ID from pinmux configuration */ +#define RMT_RX_CHANNEL_ID(pinmux) \ + ESP32_PIN_SIGI(pinmux) - ESP_RMT_SIG_IN0 + +static int rmt_del_rx_channel(rmt_channel_handle_t channel); +static int rmt_rx_demodulate_carrier(rmt_channel_handle_t channel, const rmt_carrier_config_t + *config); +static int rmt_rx_enable(rmt_channel_handle_t channel); +static int rmt_rx_disable(rmt_channel_handle_t channel); +static void rmt_rx_default_isr(void *args); + +#if SOC_RMT_SUPPORT_DMA +static void rmt_dma_rx_eof_cb(const struct device *dma_dev, void *user_data, uint32_t dma_channel, + int status); + +static int rmt_rx_init_dma_link(const struct device *dev, rmt_rx_channel_t *rx_channel, + const rmt_rx_channel_config_t *config) +{ + const struct espressif_rmt_config *cfg = dev->config; + rmt_symbol_word_t *dma_mem_base; + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int rc; + + /* Check DMA device is available */ + if (!cfg->dma_dev) { + LOG_ERR("DMA device is not available"); + return -ENODEV; + } + + /* Allocate memory */ + dma_mem_base = k_aligned_alloc(sizeof(uint32_t), sizeof(rmt_symbol_word_t) + * config->mem_block_symbols); + if (!dma_mem_base) { + LOG_ERR("no mem for rx DMA buffer"); + return -ENOMEM; + } + rx_channel->base.dma_mem_base = dma_mem_base; + rx_channel->base.dma_mem_size = sizeof(rmt_symbol_word_t) * config->mem_block_symbols; + + /* Configure DMA */ + dma_blk.block_size = rx_channel->base.dma_mem_size; + dma_blk.dest_address = (uint32_t)rx_channel->base.dma_mem_base; + dma_blk.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + dma_cfg.dma_slot = ESP_GDMA_TRIG_PERIPH_RMT; + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.user_data = (void *)rx_channel; + dma_cfg.dma_callback = rmt_dma_rx_eof_cb; + rc = dma_config(cfg->dma_dev, cfg->rx_dma_channel, &dma_cfg); + if (rc) { + LOG_ERR("Failed to configure DMA channel: %" PRIu32" (%d)", cfg->rx_dma_channel, + rc); + return rc; + } + rx_channel->base.dma_dev = cfg->dma_dev; + rx_channel->base.dma_channel = cfg->rx_dma_channel; + + return 0; +} +#endif + +static int rmt_rx_register_to_group(rmt_rx_channel_t *rx_channel, + const rmt_rx_channel_config_t *config) +{ + k_spinlock_key_t key; + size_t mem_block_num = 0; + /* + * start to search for a free channel + * a channel can take up its neighbour's memory block, + * so the neighbour channel won't work, we should skip these "invaded" ones + */ + int channel_scan_start = RMT_RX_CHANNEL_OFFSET_IN_GROUP; + int channel_scan_end = RMT_RX_CHANNEL_OFFSET_IN_GROUP + RMT_LL_GET(RX_CANDIDATES_PER_INST); + uint32_t channel_mask; + rmt_group_t *group = NULL; + int wanted_channel_id; + int channel_id = -1; + +#if SOC_RMT_SUPPORT_DMA + if (rx_channel->base.with_dma) { + /* + * for DMA mode, the memory block number is always 1; + * for non-DMA mode, memory block number is configured by user + */ + mem_block_num = 1; + /* Only the last channel has the DMA capability */ + channel_scan_start = RMT_RX_CHANNEL_OFFSET_IN_GROUP + + RMT_LL_GET(RX_CANDIDATES_PER_INST) - 1; + rx_channel->ping_pong_symbols = 0; /* with DMA, we don't need to do ping-pong */ + } else { +#endif + /* one channel can occupy multiple memory blocks */ + mem_block_num = config->mem_block_symbols / SOC_RMT_MEM_WORDS_PER_CHANNEL; + if (mem_block_num * SOC_RMT_MEM_WORDS_PER_CHANNEL < config->mem_block_symbols) { + mem_block_num++; + } + rx_channel->ping_pong_symbols = mem_block_num * SOC_RMT_MEM_WORDS_PER_CHANNEL / 2; +#if SOC_RMT_SUPPORT_DMA + } +#endif + rx_channel->base.mem_block_num = mem_block_num; + + /* search free channel and then register to the group */ + /* memory blocks used by one channel must be continuous */ + channel_mask = (1 << mem_block_num) - 1; + for (int i = 0; i < RMT_LL_GET(INST_NUM); i++) { + group = rmt_acquire_group_handle(i); + if (!group) { + LOG_ERR("Unable to allocate memory for group"); + return -ENOMEM; + } + key = k_spin_lock(&group->spinlock); + wanted_channel_id = RMT_RX_CHANNEL_ID(config->gpio_pinmux); + for (int j = channel_scan_start; j < channel_scan_end; j++) { + if ((!(group->occupy_mask & (channel_mask << j))) + && (wanted_channel_id == j - RMT_RX_CHANNEL_OFFSET_IN_GROUP)) { + group->occupy_mask |= (channel_mask << j); + /* the channel ID should index from 0 */ + channel_id = j - RMT_RX_CHANNEL_OFFSET_IN_GROUP; + group->rx_channels[channel_id] = rx_channel; + break; + } + } + k_spin_unlock(&group->spinlock, key); + if (channel_id < 0) { + /* + * didn't find a capable channel in the group, + * don't forget to release the group handle + */ + rmt_release_group_handle(group); + } else { + rx_channel->base.channel_id = channel_id; + rx_channel->base.channel_mask = channel_mask; + rx_channel->base.group = group; + break; + } + } + if (channel_id < 0) { + LOG_ERR("No rx channel available"); + return -ENOMEM; + } + + return 0; +} + +static void rmt_rx_unregister_from_group(rmt_channel_t *channel, rmt_group_t *group) +{ + k_spinlock_key_t key; + + key = k_spin_lock(&group->spinlock); + group->rx_channels[channel->channel_id] = NULL; + group->occupy_mask &= ~(channel->channel_mask + << (channel->channel_id + RMT_RX_CHANNEL_OFFSET_IN_GROUP)); + k_spin_unlock(&group->spinlock, key); + /* channel has a reference on group, release it now */ + rmt_release_group_handle(group); +} + +static int rmt_rx_destroy(rmt_rx_channel_t *rx_channel) +{ + esp_err_t ret; +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + if (rx_channel->base.intr) { + ret = esp_intr_free(rx_channel->base.intr); + if (ret) { + LOG_ERR("delete interrupt service failed"); + return -ENODEV; + } + } +#if CONFIG_ESPRESSIF_RMT_PM + if (rx_channel->base.pm_lock) { + ret = esp_pm_lock_delete(rx_channel->base.pm_lock); + if (ret) { + LOG_ERR("delete pm_lock failed"); + return -ENODEV; + } + } +#endif +#if SOC_RMT_SUPPORT_DMA + if (rx_channel->base.dma_dev) { + rc = dma_stop(rx_channel->base.dma_dev, rx_channel->base.dma_channel); + if (rc) { + LOG_ERR("Stopping DMA channel failed"); + return rc; + } + } + if (rx_channel->base.dma_mem_base) { + k_free(rx_channel->base.dma_mem_base); + } +#endif + if (rx_channel->base.group) { + /* de-register channel from RMT group */ + rmt_rx_unregister_from_group(&rx_channel->base, rx_channel->base.group); + } + k_free(rx_channel); + + return 0; +} + +int rmt_new_rx_channel(const struct device *dev, const rmt_rx_channel_config_t *config, + rmt_channel_handle_t *ret_chan) +{ +#if SOC_RMT_SUPPORT_DMA + const struct espressif_rmt_config *cfg = dev->config; +#endif + rmt_rx_channel_t *rx_channel = NULL; +#if SOC_RMT_SUPPORT_DMA + bool with_dma; + size_t num_dma_nodes = 0; +#endif + k_spinlock_key_t key; + esp_err_t ret; + int rc; + + /* Check if priority is valid */ + if (config->intr_priority) { + if (!(config->intr_priority > 0) + || !(1 << (config->intr_priority) & RMT_ALLOW_INTR_PRIORITY_MASK)) { + LOG_ERR("Invalid interrupt priority: %d", config->intr_priority); + return -EINVAL; + } + } + if (!(config && ret_chan && config->resolution_hz)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + if (!((config->mem_block_symbols & 0x01) == 0 + && config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL)) { + LOG_ERR("Parameter mem_block_symbols must be even and at least %d", + SOC_RMT_MEM_WORDS_PER_CHANNEL); + return -EINVAL; + } +#if SOC_RMT_SUPPORT_DMA + /* Only the last channel has DMA support */ + with_dma = (cfg->dma_dev) + && (cfg->rx_dma_channel != ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED) + && (RMT_RX_CHANNEL_ID(config->gpio_pinmux) == + RMT_LL_GET(RX_CANDIDATES_PER_INST) - 1); + /* Compute number of DMA nodes */ + if (with_dma) { + num_dma_nodes = config->mem_block_symbols + * sizeof(rmt_symbol_word_t) / RMT_DMA_DESC_BUF_MAX_SIZE + 1; + } +#endif +#if !SOC_RMT_SUPPORT_SLEEP_RETENTION + if (config->flags.allow_pd) { + LOG_ERR("Not able to power down in light sleep"); + return -EINVAL; + } +#endif + /* malloc channel memory */ +#if SOC_RMT_SUPPORT_DMA + rx_channel = k_calloc(1, sizeof(rmt_rx_channel_t) + num_dma_nodes + * sizeof(dma_descriptor_t)); +#else + rx_channel = k_calloc(1, sizeof(rmt_rx_channel_t)); +#endif + if (!rx_channel) { + LOG_ERR("Unable to allocate memory for rx channel"); + return -ENOMEM; + } +#if SOC_RMT_SUPPORT_DMA + rx_channel->base.with_dma = with_dma; + rx_channel->num_dma_nodes = num_dma_nodes; +#endif + + /* register the channel to group */ + rc = rmt_rx_register_to_group(rx_channel, config); + if (rc) { + LOG_ERR("Unable to register channel"); + goto err; + } + + rmt_group_t *group = rx_channel->base.group; + rmt_hal_context_t *hal = &group->hal; + int channel_id = rx_channel->base.channel_id; + +#if SOC_RMT_SUPPORT_SLEEP_RETENTION + if (config->flags.allow_pd != 0) { + rmt_create_retention_module(group); + } +#endif + + /* reset channel, make sure the RX engine is not working, and events are cleared */ + key = k_spin_lock(&group->spinlock); + rmt_hal_rx_channel_reset(hal, channel_id); + k_spin_unlock(&group->spinlock, key); + + /* When channel receives an end-maker, a DMA in_suc_eof interrupt will be generated */ + /* So we don't rely on RMT interrupt any more, GDMA event callback is sufficient */ +#if SOC_RMT_SUPPORT_DMA + if (with_dma) { + rc = rmt_rx_init_dma_link(dev, rx_channel, config); + if (rc) { + LOG_ERR("install rx DMA failed"); + goto err; + } + } else { +#endif + /* + * RMT interrupt is mandatory if the channel doesn't use DMA + * --- install interrupt service + * interrupt is mandatory to run basic RMT transactions, so it's not lazy + * installed in `rmt_tx_register_event_callbacks()` + */ + /* 1-- Set user specified priority to `group->intr_priority` */ + if (rmt_set_intr_priority_to_group(group, config->intr_priority)) { + LOG_ERR("intr_priority conflict"); + rc = -ENODEV; + goto err; + } + /* 2-- Get interrupt allocation flag */ + int isr_flags = rmt_isr_priority_to_flags(group) | RMT_RX_INTR_ALLOC_FLAG; + /* 3-- Allocate interrupt using isr_flag */ + ret = esp_intr_alloc_intrstatus(soc_rmt_signals[group->group_id].irq, + isr_flags, (uint32_t)rmt_ll_get_interrupt_status_reg(hal->regs), + RMT_LL_EVENT_RX_MASK(channel_id), rmt_rx_default_isr, rx_channel, + &rx_channel->base.intr); + if (ret) { + LOG_ERR("install rx interrupt failed"); + rc = -ENODEV; + goto err; + } +#if SOC_RMT_SUPPORT_DMA + } +#endif + + rx_channel->base.direction = RMT_CHANNEL_DIRECTION_RX; + /* select the clock source and set clock resolution */ + rc = rmt_select_periph_clock(&rx_channel->base, config->clk_src, config->resolution_hz); + if (rc) { + LOG_ERR("set group clock failed"); + goto err; + } + rx_channel->filter_clock_resolution_hz = group->resolution_hz; + /* + * On esp32 and esp32s2, the counting clock used by the RX filter always comes from + * APB clock no matter what the clock source is used by the RMT channel as the "core" + * clock + */ +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) + esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_APB, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, + &rx_channel->filter_clock_resolution_hz); +#endif + + rmt_ll_rx_set_mem_blocks(hal->regs, channel_id, rx_channel->base.mem_block_num); + rmt_ll_rx_set_mem_owner(hal->regs, channel_id, RMT_LL_MEM_OWNER_HW); +#if SOC_RMT_SUPPORT_RX_PINGPONG + rmt_ll_rx_set_limit(hal->regs, channel_id, rx_channel->ping_pong_symbols); + /* always enable rx wrap, both DMA mode and ping-pong mode rely this feature */ + rmt_ll_rx_enable_wrap(hal->regs, channel_id, true); +#endif +#if RMT_LL_SUPPORT(RX_DEMODULATION) + /* disable carrier demodulation by default, can reenable by `rmt_apply_carrier()` */ + rmt_ll_rx_enable_carrier_demodulation(hal->regs, channel_id, false); +#endif + + /* initialize other members of rx channel */ + rx_channel->base.fsm = ATOMIC_INIT(RMT_FSM_INIT); + rx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + + RMT_RX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; + /* polymorphic methods */ + rx_channel->base.del = rmt_del_rx_channel; + rx_channel->base.set_carrier_action = rmt_rx_demodulate_carrier; + rx_channel->base.enable = rmt_rx_enable; + rx_channel->base.disable = rmt_rx_disable; + /* return general channel handle */ + *ret_chan = &rx_channel->base; + LOG_DBG("new rx channel(%d,%d) at %p, gpio=%d, res=%"PRIu32"Hz, hw_mem_base=%p, " + "ping_pong_size=%d", group->group_id, channel_id, rx_channel, + ESP32_PIN_NUM(config->gpio_pinmux), rx_channel->base.resolution_hz, + rx_channel->base.hw_mem_base, rx_channel->ping_pong_symbols); + + return 0; + +err: + if (rx_channel) { + rmt_rx_destroy(rx_channel); + } + + return rc; +} + +static int rmt_del_rx_channel(rmt_channel_handle_t channel) +{ + rmt_rx_channel_t *rx_chan = __containerof(channel, rmt_rx_channel_t, base); + rmt_group_t *group = channel->group; + int rc; + + if (atomic_get(&channel->fsm) != RMT_FSM_INIT) { + LOG_ERR("channel not in init state"); + return -ENODEV; + } + + /* recycle memory resource */ + LOG_DBG("del rx channel(%d,%d)", group->group_id, channel->channel_id); + rc = rmt_rx_destroy(rx_chan); + if (rc) { + LOG_ERR("destroy rx channel failed"); + return rc; + } + + return 0; +} + +int rmt_rx_register_event_callbacks(rmt_channel_handle_t channel, + const rmt_rx_event_callbacks_t *cbs, void *user_data) +{ + rmt_rx_channel_t *rx_chan; + + if (!(channel && cbs)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + if (channel->direction != RMT_CHANNEL_DIRECTION_RX) { + LOG_ERR("Invalid channel direction"); + return -EINVAL; + } + rx_chan = __containerof(channel, rmt_rx_channel_t, base); + +#if CONFIG_ESPRESSIF_RMT_RX_ISR_CACHE_SAFE + if (cbs->on_recv_done) { + if (!esp_ptr_in_iram(cbs->on_recv_done)) { + LOG_ERR("on_recv_done callback not in IRAM"); + return -EINVAL; + } + } + if (user_data) { + if (!esp_ptr_internal(user_data)) { + LOG_ERR("user context not in internal RAM"); + return -EINVAL; + } + } +#endif + + rx_chan->on_recv_done = cbs->on_recv_done; + rx_chan->user_data = user_data; + + return 0; +} + +int rmt_receive(rmt_channel_handle_t channel, void *buffer, size_t buffer_size, + const rmt_receive_config_t *config) +{ + rmt_rx_channel_t *rx_chan; + k_spinlock_key_t key; +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + if (!(channel && buffer && buffer_size && config)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + if (channel->direction != RMT_CHANNEL_DIRECTION_RX) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } +#if !SOC_RMT_SUPPORT_RX_PINGPONG + if (config->flags.en_partial_rx) { + LOG_ERR("partial receive not supported"); + return -EINVAL; + } +#endif + rx_chan = __containerof(channel, rmt_rx_channel_t, base); + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + if (!esp_ptr_internal(buffer)) { + LOG_ERR("Buffer must locate in internal RAM for DMA use"); + return -EINVAL; + } + if (!(buffer_size <= rx_chan->num_dma_nodes * RMT_DMA_DESC_BUF_MAX_SIZE)) { + LOG_ERR("buffer size exceeds DMA capacity"); + return -EINVAL; + } + } +#endif + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + uint32_t filter_reg_value = ((uint64_t)rx_chan->filter_clock_resolution_hz + * config->signal_range_min_ns) / 1000000000UL; + uint32_t idle_reg_value = ((uint64_t)channel->resolution_hz + * config->signal_range_max_ns) / 1000000000UL; + + if (filter_reg_value > RMT_LL_MAX_FILTER_VALUE) { + LOG_ERR("signal_range_min_ns too big"); + return -EINVAL; + } + if (idle_reg_value > RMT_LL_MAX_IDLE_VALUE) { + LOG_ERR("signal_range_max_ns too big"); + return -EINVAL; + } + + /* check if we're in a proper state to start the receiver */ + if (!atomic_cas(&channel->fsm, RMT_FSM_ENABLE, RMT_FSM_WAIT)) { + LOG_ERR("channel not in enable state"); + return -ENODEV; + } + + /* fill in the transaction descriptor */ + rmt_rx_trans_desc_t *t = &rx_chan->trans_desc; + + t->buffer = buffer; + t->buffer_size = buffer_size; + t->received_symbol_num = 0; + t->copy_dest_off = 0; + t->flags.en_partial_rx = config->flags.en_partial_rx; + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, 0, + (uint32_t)channel->dma_mem_base, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return -ENODEV; + } + rc = dma_start(channel->dma_dev, channel->dma_channel); + if (rc) { + LOG_ERR("Starting DMA channel failed"); + return -ENODEV; + } + } +#endif + + rx_chan->mem_off = 0; + key = k_spin_lock(&channel->spinlock); + /* reset memory writer offset */ + rmt_ll_rx_reset_pointer(hal->regs, channel->channel_id); + rmt_ll_rx_set_mem_owner(hal->regs, channel->channel_id, RMT_LL_MEM_OWNER_HW); + /* set sampling parameters of incoming signals */ + rmt_ll_rx_set_filter_thres(hal->regs, channel->channel_id, filter_reg_value); + rmt_ll_rx_enable_filter(hal->regs, channel->channel_id, config->signal_range_min_ns != 0); + rmt_ll_rx_set_idle_thres(hal->regs, channel->channel_id, idle_reg_value); + /* turn on RMT RX machine */ + rmt_ll_rx_enable(hal->regs, channel->channel_id, true); + k_spin_unlock(&channel->spinlock, key); + + /* saying we're in running state, this state will last until the receiving is done */ + /* i.e., we will switch back to the enable state in the receive done interrupt handler */ + atomic_set(&channel->fsm, RMT_FSM_RUN); + + return 0; +} + +static int rmt_rx_demodulate_carrier(rmt_channel_handle_t channel, + const rmt_carrier_config_t *config) +{ +#if !RMT_LL_SUPPORT(RX_DEMODULATION) + LOG_ERR("rx demodulation not supported"); + return -ENODEV; +#else + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + uint32_t real_frequency = 0; + k_spinlock_key_t key; + + if (config && config->frequency_hz) { + /* + * carrier demodulation module works base on channel clock + * (this is different from TX carrier modulation mode) + * Note this division operation will lose precision + */ + uint32_t total_ticks = channel->resolution_hz / config->frequency_hz; + uint32_t high_ticks = total_ticks * config->duty_cycle / 1000; + uint32_t low_ticks = total_ticks - high_ticks; + + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_set_carrier_level(hal->regs, channel->channel_id, + !config->flags.polarity_active_low); + rmt_ll_rx_set_carrier_high_low_ticks(hal->regs, channel->channel_id, high_ticks, + low_ticks); + k_spin_unlock(&channel->spinlock, key); + /* save real carrier frequency */ + real_frequency = channel->resolution_hz / (high_ticks + low_ticks); + } + + /* enable/disable carrier demodulation */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_enable_carrier_demodulation(hal->regs, channel->channel_id, real_frequency > 0); + k_spin_unlock(&channel->spinlock, key); + + if (real_frequency > 0) { + LOG_DBG("enable carrier demodulation for channel(%d,%d), freq=%"PRIu32"Hz", + group->group_id, channel->channel_id, real_frequency); + } else { + LOG_DBG("disable carrier demodulation for channel(%d, %d)", group->group_id, + channel->channel_id); + } + + return 0; +#endif +} + +static int rmt_rx_enable(rmt_channel_handle_t channel) +{ + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + k_spinlock_key_t key; + + /* can only enable the channel when it's in "init" state */ + if (!atomic_cas(&channel->fsm, RMT_FSM_INIT, RMT_FSM_WAIT)) { + LOG_ERR("channel not in init state"); + return -ENODEV; + } + +#if CONFIG_ESPRESSIF_RMT_PM + /* acquire power manager lock */ + if (channel->pm_lock) { + esp_pm_lock_acquire(channel->pm_lock); + } +#endif +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + /* enable the DMA access mode */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_enable_dma(hal->regs, channel->channel_id, true); + k_spin_unlock(&channel->spinlock, key); + } else { +#endif + key = k_spin_lock(&group->spinlock); + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_RX_MASK(channel->channel_id), true); + k_spin_unlock(&group->spinlock, key); +#if SOC_RMT_SUPPORT_DMA + } +#endif + + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + + return 0; +} + +static int rmt_rx_disable(rmt_channel_handle_t channel) +{ + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + bool valid_state = false; + k_spinlock_key_t key; +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + if (atomic_cas(&channel->fsm, RMT_FSM_ENABLE, RMT_FSM_WAIT)) { + valid_state = true; + } + if (atomic_cas(&channel->fsm, RMT_FSM_RUN, RMT_FSM_WAIT)) { + valid_state = true; + } + if (!valid_state) { + LOG_ERR("Channel can't be disabled in current state"); + return -ENODEV; + } + + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_enable(hal->regs, channel->channel_id, false); + k_spin_unlock(&channel->spinlock, key); + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_stop(channel->dma_dev, channel->dma_channel); + if (rc) { + LOG_ERR("Stopping DMA channel failed"); + return rc; + } + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_enable_dma(hal->regs, channel->channel_id, false); + k_spin_unlock(&channel->spinlock, key); + } else { +#endif + key = k_spin_lock(&group->spinlock); + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_RX_MASK(channel->channel_id), + false); + rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_RX_MASK(channel->channel_id)); + k_spin_unlock(&group->spinlock, key); +#if SOC_RMT_SUPPORT_DMA + } +#endif + +#if CONFIG_ESPRESSIF_RMT_PM + /* release power manager lock */ + if (channel->pm_lock) { + esp_pm_lock_release(channel->pm_lock); + } +#endif + + /* now we can switch the state to init */ + atomic_set(&channel->fsm, RMT_FSM_INIT); + + return 0; +} + +static bool IRAM_ATTR rmt_isr_handle_rx_done(rmt_rx_channel_t *rx_chan) +{ + rmt_channel_t *channel = &rx_chan->base; + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + rmt_rx_trans_desc_t *trans_desc = &rx_chan->trans_desc; + bool need_yield = false; + + rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_RX_DONE(channel->channel_id)); + + k_spinlock_key_t key = k_spin_lock(&channel->spinlock); + /* + * disable the RX engine, + * it will be enabled again when next time user calls `rmt_receive()` + */ + rmt_ll_rx_enable(hal->regs, channel->channel_id, false); + k_spin_unlock(&channel->spinlock, key); + +#if !RMT_LL_SUPPORT(ASYNC_STOP) + /* + * This is a workaround for ESP32. + * The RX engine can not be disabled once it is enabled in ESP32 + * If the state isn't RMT_FSM_RUN, it means the RX engine was disabled + * and we shouldn't process the data. + */ + if (atomic_get(&channel->fsm) != RMT_FSM_RUN) { + return false; + } +#endif + + uint32_t offset = rmt_ll_rx_get_memory_writer_offset(hal->regs, channel->channel_id); + + /* + * Start from C6, the actual pulse count is the number of input pulses N - 1. + * Resulting in the last threshold interrupts may not be triggered correctly when the + * number of received symbols is a multiple of the memory block size. + * As shown in the figure below, So we special handle the offset + * + * mem_off (should be updated here in the last threshold interrupt, but interrupt lost) + * | + * V + * |________|________| + * | | + * offset mem_off(actually here now) + */ + + size_t mem_want = (((offset >= rx_chan->mem_off) ? (offset - rx_chan->mem_off) + : (rx_chan->mem_off - offset))) * sizeof(rmt_symbol_word_t); + size_t mem_have = trans_desc->buffer_size - trans_desc->copy_dest_off; + size_t copy_size = mem_want; + + if (mem_want > mem_have) { + /* check partial receive is enabled or not */ + if (trans_desc->flags.en_partial_rx) { + /* + * Notify the user to process the received symbols + * if the buffer is going to be full + */ + if (trans_desc->received_symbol_num) { + if (rx_chan->on_recv_done) { + rmt_rx_done_event_data_t edata = { + .received_symbols = trans_desc->buffer, + .num_symbols = trans_desc->received_symbol_num, + .flags.is_last = false, + }; + if (rx_chan->on_recv_done(channel, &edata, + rx_chan->user_data)) { + need_yield = true; + } + } + trans_desc->copy_dest_off = 0; + trans_desc->received_symbol_num = 0; + mem_have = trans_desc->buffer_size; + + /** + * Even user process the partial received data, the remain buffer + * may still be insufficient + */ + if (mem_want > mem_have) { + LOG_DBG("User buffer too small, received symbols " + "truncated"); + copy_size = mem_have; + } + } + } else { + LOG_DBG("User buffer too small, received symbols truncated"); + copy_size = mem_have; + } + } + + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_set_mem_owner(hal->regs, channel->channel_id, RMT_LL_MEM_OWNER_SW); + /* copy the symbols to user space */ + memcpy((uint8_t *)trans_desc->buffer + trans_desc->copy_dest_off, + channel->hw_mem_base + rx_chan->mem_off, copy_size); + rmt_ll_rx_set_mem_owner(hal->regs, channel->channel_id, RMT_LL_MEM_OWNER_HW); + k_spin_unlock(&channel->spinlock, key); + +#if !SOC_RMT_SUPPORT_RX_PINGPONG + /* + * for chips doesn't support ping-pong RX, we should check whether the receiver has + * encountered with a long frame, whose length is longer than the channel capacity + */ + if (rmt_ll_rx_get_interrupt_status_raw(hal->regs, channel->channel_id) + & RMT_LL_EVENT_RX_ERROR(channel->channel_id)) { + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_reset_pointer(hal->regs, channel->channel_id); + k_spin_unlock(&channel->spinlock, key); + /* + * this clear operation can only take effect after we copy out the received + * data and reset the pointer + */ + rmt_ll_clear_interrupt_status(hal->regs, + RMT_LL_EVENT_RX_ERROR(channel->channel_id)); + LOG_ERR("hw buffer too small, received symbols truncated"); + } +#endif + + trans_desc->copy_dest_off += copy_size; + trans_desc->received_symbol_num += copy_size / sizeof(rmt_symbol_word_t); + /* + * switch back to the enable state, then user can call `rmt_receive` to start + * a new receive + */ + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + + /* notify the user with receive RMT symbols */ + if (rx_chan->on_recv_done) { + rmt_rx_done_event_data_t edata = { + .received_symbols = trans_desc->buffer, + .num_symbols = trans_desc->received_symbol_num, + }; + if (rx_chan->on_recv_done(channel, &edata, rx_chan->user_data)) { + need_yield = true; + } + } + + return need_yield; +} + +#if SOC_RMT_SUPPORT_RX_PINGPONG +static bool IRAM_ATTR rmt_isr_handle_rx_threshold(rmt_rx_channel_t *rx_chan) +{ + bool need_yield = false; + rmt_channel_t *channel = &rx_chan->base; + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + rmt_rx_trans_desc_t *trans_desc = &rx_chan->trans_desc; + k_spinlock_key_t key; + + rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_RX_THRES(channel->channel_id)); + + size_t mem_want = rx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t); + size_t mem_have = trans_desc->buffer_size - trans_desc->copy_dest_off; + size_t copy_size = mem_want; + + if (mem_want > mem_have) { + if (trans_desc->flags.en_partial_rx) { + /** + * Notify the user to process the received symbols if the buffer is going + * to be full + */ + if (trans_desc->received_symbol_num) { + if (rx_chan->on_recv_done) { + rmt_rx_done_event_data_t edata = { + .received_symbols = trans_desc->buffer, + .num_symbols = trans_desc->received_symbol_num, + .flags.is_last = false, + }; + if (rx_chan->on_recv_done(channel, &edata, + rx_chan->user_data)) { + need_yield = true; + } + } + trans_desc->copy_dest_off = 0; + trans_desc->received_symbol_num = 0; + mem_have = trans_desc->buffer_size; + + /** + * Even user process the partial received data, the remain buffer + * size still insufficient + */ + if (mem_want > mem_have) { + LOG_DBG("User buffer too small, received symbols " + "truncated"); + copy_size = mem_have; + } + } + } else { + LOG_DBG("User buffer too small, received symbols truncated"); + copy_size = mem_have; + } + } + + key = k_spin_lock(&channel->spinlock); + rmt_ll_rx_set_mem_owner(hal->regs, channel->channel_id, RMT_LL_MEM_OWNER_SW); + /* copy the symbols to user space */ + memcpy((uint8_t *)trans_desc->buffer + trans_desc->copy_dest_off, + channel->hw_mem_base + rx_chan->mem_off, copy_size); + rmt_ll_rx_set_mem_owner(hal->regs, channel->channel_id, RMT_LL_MEM_OWNER_HW); + k_spin_unlock(&channel->spinlock, key); + + trans_desc->copy_dest_off += copy_size; + trans_desc->received_symbol_num += copy_size / sizeof(rmt_symbol_word_t); + + /* update the hw memory offset, where stores the next RMT symbols to copy */ + rx_chan->mem_off = rx_chan->ping_pong_symbols - rx_chan->mem_off; + + return need_yield; +} +#endif + +static void IRAM_ATTR rmt_rx_default_isr(void *args) +{ + rmt_rx_channel_t *rx_chan = (rmt_rx_channel_t *)args; + rmt_channel_t *channel = &rx_chan->base; + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + uint32_t status = rmt_ll_rx_get_interrupt_status(hal->regs, channel->channel_id); + +#if SOC_RMT_SUPPORT_RX_PINGPONG + /* RX threshold interrupt */ + if (status & RMT_LL_EVENT_RX_THRES(channel->channel_id)) { + rmt_isr_handle_rx_threshold(rx_chan); + } +#endif + + /* RX end interrupt */ + if (status & RMT_LL_EVENT_RX_DONE(channel->channel_id)) { + rmt_isr_handle_rx_done(rx_chan); + } +} + +#if SOC_RMT_SUPPORT_DMA +static void rmt_dma_rx_eof_cb(const struct device *dma_dev, void *user_data, uint32_t dma_channel, + int status) +{ + bool need_yield = false; + rmt_rx_channel_t *rx_chan = (rmt_rx_channel_t *)user_data; + rmt_channel_t *channel = &rx_chan->base; + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + gdma_hal_context_t *dma_hal = dma_dev->data; + dma_descriptor_t *desc; + + k_spinlock_key_t key = k_spin_lock(&channel->spinlock); + /* disable the RX engine, it will be enabled again in the next `rmt_receive()` */ + rmt_ll_rx_enable(hal->regs, channel->channel_id, false); + k_spin_unlock(&channel->spinlock, key); + + /* + * switch back to the enable state, then user can call `rmt_receive` to start + * a new receive + */ + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + + if (rx_chan->on_recv_done) { + /* Get actual transferred bytes from DMA descriptor */ + desc = (dma_descriptor_t *)gdma_ll_rx_get_success_eof_desc_addr(dma_hal->dev, + dma_channel / 2); + if (!desc) { + LOG_ERR("DMA descriptor not found"); + return; + } + rmt_rx_done_event_data_t edata = { + .received_symbols = rx_chan->base.dma_mem_base, + .num_symbols = desc->dw0.length / sizeof(uint32_t) + }; + if (rx_chan->on_recv_done(channel, &edata, rx_chan->user_data)) { + need_yield = true; + } + } +} +#endif diff --git a/drivers/misc/espressif_rmt/rmt_tx.c b/drivers/misc/espressif_rmt/rmt_tx.c new file mode 100644 index 0000000000000..5ffbe4524095b --- /dev/null +++ b/drivers/misc/espressif_rmt/rmt_tx.c @@ -0,0 +1,1321 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "esp_memory_utils.h" +#include "rmt_private.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SOC_SERIES_ESP32 +#include +#elif defined(CONFIG_SOC_SERIES_ESP32S2) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32S3) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32C3) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32C6) +#include +#elif defined(CONFIG_SOC_SERIES_ESP32H2) +#include +#endif + +LOG_MODULE_DECLARE(espressif_rmt); + +/* RMT TX Channel ID from pinmux configuration */ +#define RMT_TX_CHANNEL_ID(pinmux) \ + ESP32_PIN_SIGO(pinmux) - ESP_RMT_SIG_OUT0 + +struct rmt_sync_manager_t { + /**< Which group the synchro belongs to */ + rmt_group_t *group; + /**< Mask of channels that are managed */ + uint32_t channel_mask; + /**< Size of the `tx_channel_array` */ + size_t array_size; + /**< Array of TX channels that are managed */ + rmt_channel_handle_t tx_channel_array[]; +}; + +static int rmt_del_tx_channel(rmt_channel_handle_t channel); +static int rmt_tx_modulate_carrier(rmt_channel_handle_t channel, + const rmt_carrier_config_t *config); +static int rmt_tx_enable(rmt_channel_handle_t channel); +static int rmt_tx_disable(rmt_channel_handle_t channel); +static void rmt_tx_default_isr(void *args); +static void rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t *t); + +#if SOC_RMT_SUPPORT_DMA +static void rmt_dma_tx_eof_cb(const struct device *dma_dev, void *user_data, uint32_t dma_channel, + int status); + +static int rmt_tx_init_dma_link(const struct device *dev, rmt_tx_channel_t *tx_channel, + const rmt_tx_channel_config_t *config) +{ + const struct espressif_rmt_config *cfg = dev->config; + rmt_symbol_word_t *dma_mem_base; + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int rc; + + /* Allocate memory */ + dma_mem_base = k_aligned_alloc(sizeof(uint32_t), sizeof(rmt_symbol_word_t) + * config->mem_block_symbols); + if (!dma_mem_base) { + LOG_ERR("no mem for tx DMA buffer"); + return -ENOMEM; + } + tx_channel->base.dma_mem_base = dma_mem_base; + tx_channel->base.dma_mem_size = sizeof(rmt_symbol_word_t) * config->mem_block_symbols; + + /* Configure DMA */ + dma_blk.block_size = tx_channel->base.dma_mem_size; + dma_blk.source_address = (uint32_t)tx_channel->base.dma_mem_base; + dma_blk.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + dma_cfg.dma_slot = ESP_GDMA_TRIG_PERIPH_RMT; + dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.user_data = (void *)tx_channel; + dma_cfg.dma_callback = rmt_dma_tx_eof_cb; + rc = dma_config(cfg->dma_dev, cfg->tx_dma_channel, &dma_cfg); + if (rc) { + LOG_ERR("Failed to configure DMA channel: %" PRIu32" (%d)", cfg->tx_dma_channel, + rc); + return rc; + } + tx_channel->base.dma_dev = cfg->dma_dev; + tx_channel->base.dma_channel = cfg->tx_dma_channel; + + return 0; +} +#endif + +static int rmt_tx_register_to_group(rmt_tx_channel_t *tx_channel, + const rmt_tx_channel_config_t *config) +{ + /* + * start to search for a free channel + * a channel can take up its neighbour's memory block, so the neighbour channel won't work, + * we should skip these "invaded" ones + */ + int channel_scan_start = RMT_TX_CHANNEL_OFFSET_IN_GROUP; + int channel_scan_end = RMT_TX_CHANNEL_OFFSET_IN_GROUP + RMT_LL_GET(TX_CANDIDATES_PER_INST); + size_t mem_block_num = 0; + uint32_t channel_mask; + rmt_group_t *group = NULL; + int wanted_channel_id; + int channel_id = -1; + k_spinlock_key_t key; + +#if SOC_RMT_SUPPORT_DMA + if (tx_channel->base.with_dma) { + /* + * for DMA mode, the memory block number is always 1; + * for non-DMA mode, memory block number is configured by user + */ + mem_block_num = 1; + /* Only the last channel has the DMA capability */ + channel_scan_start = RMT_TX_CHANNEL_OFFSET_IN_GROUP + + RMT_LL_GET(TX_CANDIDATES_PER_INST) - 1; + tx_channel->ping_pong_symbols = config->mem_block_symbols / 2; + } else { +#endif + /* one channel can occupy multiple memory blocks */ + mem_block_num = config->mem_block_symbols / SOC_RMT_MEM_WORDS_PER_CHANNEL; + if (mem_block_num * SOC_RMT_MEM_WORDS_PER_CHANNEL < config->mem_block_symbols) { + mem_block_num++; + } + tx_channel->ping_pong_symbols = mem_block_num * SOC_RMT_MEM_WORDS_PER_CHANNEL / 2; +#if SOC_RMT_SUPPORT_DMA + } +#endif + tx_channel->base.mem_block_num = mem_block_num; + + /* search free channel and then register to the group */ + /* memory blocks used by one channel must be continuous */ + channel_mask = (1 << mem_block_num) - 1; + for (int i = 0; i < RMT_LL_GET(INST_NUM); i++) { + group = rmt_acquire_group_handle(i); + if (!group) { + LOG_ERR("No memory available for group: %d", i); + return -ENOMEM; + } + key = k_spin_lock(&group->spinlock); + wanted_channel_id = RMT_TX_CHANNEL_ID(config->gpio_pinmux); + for (int j = channel_scan_start; j < channel_scan_end; j++) { + if ((!(group->occupy_mask & (channel_mask << j))) + && (wanted_channel_id == j - RMT_TX_CHANNEL_OFFSET_IN_GROUP)) { + group->occupy_mask |= (channel_mask << j); + /* the channel ID should index from 0 */ + channel_id = j - RMT_TX_CHANNEL_OFFSET_IN_GROUP; + group->tx_channels[channel_id] = tx_channel; + break; + } + } + k_spin_unlock(&group->spinlock, key); + if (channel_id < 0) { + /* + * didn't find a capable channel in the group, don't forget to release + * the group handle + */ + rmt_release_group_handle(group); + } else { + tx_channel->base.channel_id = channel_id; + tx_channel->base.channel_mask = channel_mask; + tx_channel->base.group = group; + break; + } + } + if (channel_id < 0) { + LOG_ERR("No tx channel available"); + return -ENOMEM; + } + + return 0; +} + +static void rmt_tx_unregister_from_group(rmt_channel_t *channel, rmt_group_t *group) +{ + k_spinlock_key_t key; + + key = k_spin_lock(&group->spinlock); + group->tx_channels[channel->channel_id] = NULL; + group->occupy_mask &= ~(channel->channel_mask << (channel->channel_id + + RMT_TX_CHANNEL_OFFSET_IN_GROUP)); + k_spin_unlock(&group->spinlock, key); + /* channel has a reference on group, release it now */ + rmt_release_group_handle(group); +} + +static int rmt_tx_create_trans_queue(rmt_tx_channel_t *tx_channel, + const rmt_tx_channel_config_t *config) +{ + rmt_tx_trans_desc_t *p_trans_desc = NULL; + int rc; + + tx_channel->queue_size = config->trans_queue_depth; + for (int i = 0; i < RMT_TX_QUEUE_MAX; i++) { + tx_channel->trans_queue_structs[i] = k_malloc(sizeof(rmt_tx_trans_desc_t *) + * config->trans_queue_depth); + if (!tx_channel->trans_queue_structs[i]) { + LOG_ERR("Unable to allocate memory for queue storage"); + return -ENOMEM; + } + k_msgq_init(&tx_channel->trans_queues[i], + (char *)tx_channel->trans_queue_structs[i], sizeof(rmt_tx_trans_desc_t *), + config->trans_queue_depth); + } + + /* initialize the ready queue */ + for (int i = 0; i < config->trans_queue_depth; i++) { + p_trans_desc = &tx_channel->trans_desc_pool[i]; + rc = k_msgq_put(&tx_channel->trans_queues[RMT_TX_QUEUE_READY], &p_trans_desc, + K_NO_WAIT); + if (rc) { + LOG_ERR("Ready queue is full"); + return rc; + } + } + + return 0; +} + +static int rmt_tx_destroy(rmt_tx_channel_t *tx_channel) +{ + esp_err_t ret; +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + if (tx_channel->base.intr) { + ret = esp_intr_free(tx_channel->base.intr); + if (ret) { + LOG_ERR("delete interrupt service failed"); + return -ENODEV; + } + } +#if CONFIG_ESPRESSIF_RMT_PM + if (tx_channel->base.pm_lock) { + ret = esp_pm_lock_delete(tx_channel->base.pm_lock); + if (ret) { + LOG_ERR("delete pm_lock failed"); + return -ENODEV; + } + } +#endif +#if SOC_RMT_SUPPORT_DMA + if (tx_channel->base.dma_dev) { + rc = dma_stop(tx_channel->base.dma_dev, tx_channel->base.dma_channel); + if (rc) { + LOG_ERR("Stopping DMA channel failed"); + return rc; + } + } +#endif + for (int i = 0; i < RMT_TX_QUEUE_MAX; i++) { + k_msgq_cleanup(&tx_channel->trans_queues[i]); + } + for (int i = 0; i < RMT_TX_QUEUE_MAX; i++) { + if (tx_channel->trans_queue_structs[i]) { + k_free(tx_channel->trans_queue_structs[i]); + } + } +#if SOC_RMT_SUPPORT_DMA + if (tx_channel->base.dma_mem_base) { + k_free(tx_channel->base.dma_mem_base); + } +#endif + if (tx_channel->base.group) { + /* de-register channel from RMT group */ + rmt_tx_unregister_from_group(&tx_channel->base, tx_channel->base.group); + } + k_free(tx_channel); + + return 0; +} + +int rmt_new_tx_channel(const struct device *dev, const rmt_tx_channel_config_t *config, + rmt_channel_handle_t *ret_chan) +{ +#if SOC_RMT_SUPPORT_DMA + const struct espressif_rmt_config *cfg = dev->config; +#endif + rmt_tx_channel_t *tx_channel = NULL; +#if SOC_RMT_SUPPORT_DMA + bool with_dma; +#endif + k_spinlock_key_t key; + esp_err_t ret; + int rc; + + /* Check if priority is valid */ + if (config->intr_priority) { + if (!(config->intr_priority > 0) + || !(1 << (config->intr_priority) & RMT_ALLOW_INTR_PRIORITY_MASK)) { + LOG_ERR("Invalid interrupt priority: %d", config->intr_priority); + return -EINVAL; + } + } + if (!(config && ret_chan && config->resolution_hz && config->trans_queue_depth)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + if (!(((config->mem_block_symbols & 0x01) == 0) + && (config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL))) { + LOG_ERR("Parameter mem_block_symbols must be even and at least: %d", + SOC_RMT_MEM_WORDS_PER_CHANNEL); + return -EINVAL; + } +#if SOC_RMT_SUPPORT_DMA + /* Only the last channel has DMA support */ + with_dma = (cfg->dma_dev) + && (cfg->tx_dma_channel != ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED) + && (RMT_TX_CHANNEL_ID(config->gpio_pinmux) + == RMT_LL_GET(TX_CANDIDATES_PER_INST) - 1); + /* + * We only support 2 nodes ping-pong, if the configured memory block size needs more than + * two DMA descriptors, should treat it as invalid + */ + if (!(config->mem_block_symbols <= RMT_DMA_DESC_BUF_MAX_SIZE * RMT_DMA_NODES_PING_PONG + / sizeof(rmt_symbol_word_t))) { + LOG_ERR("Parameter mem_block_symbols can't exceed: %d", RMT_DMA_DESC_BUF_MAX_SIZE + * RMT_DMA_NODES_PING_PONG / sizeof(rmt_symbol_word_t)); + return -EINVAL; + } +#endif + +#if !SOC_RMT_SUPPORT_SLEEP_RETENTION + if (config->flags.allow_pd) { + LOG_ERR("Not able to power down in light sleep"); + return -EINVAL; + } +#endif + + /* malloc channel memory */ + tx_channel = k_calloc(1, sizeof(rmt_tx_channel_t) + sizeof(rmt_tx_trans_desc_t) + * config->trans_queue_depth); + if (!tx_channel) { + LOG_ERR("Unable to allocate tx channel"); + return -ENOMEM; + } +#if SOC_RMT_SUPPORT_DMA + tx_channel->base.with_dma = with_dma; +#endif + /* create transaction queues */ + rc = rmt_tx_create_trans_queue(tx_channel, config); + if (rc) { + LOG_ERR("Unable to install transaction queues"); + goto err; + } + /* register the channel to group */ + rc = rmt_tx_register_to_group(tx_channel, config); + if (rc) { + LOG_ERR("Unable to register tx channel"); + goto err; + } + + rmt_group_t *group = tx_channel->base.group; + rmt_hal_context_t *hal = &group->hal; + int channel_id = tx_channel->base.channel_id; + +#if SOC_RMT_SUPPORT_SLEEP_RETENTION + if (config->flags.allow_pd != 0) { + rmt_create_retention_module(group); + } +#endif + + /* reset channel, make sure the TX engine is not working, and events are cleared */ + key = k_spin_lock(&group->spinlock); + rmt_hal_tx_channel_reset(hal, channel_id); + k_spin_unlock(&group->spinlock, key); + /* install tx interrupt + * --- install interrupt service + * interrupt is mandatory to run basic RMT transactions, so it's not lazy installed in + * `rmt_tx_register_event_callbacks()` + */ + /* 1-- Set user specified priority to `group->intr_priority` */ + if (rmt_set_intr_priority_to_group(group, config->intr_priority)) { + LOG_ERR("Parameter intr_priority conflict"); + rc = -EINVAL; + goto err; + } + /* 2-- Get interrupt allocation flag */ + int isr_flags = rmt_isr_priority_to_flags(group) | RMT_TX_INTR_ALLOC_FLAG; + /* 3-- Allocate interrupt using isr_flag */ + ret = esp_intr_alloc_intrstatus(soc_rmt_signals[group->group_id].irq, isr_flags, + (uint32_t)rmt_ll_get_interrupt_status_reg(hal->regs), + RMT_LL_EVENT_TX_MASK(channel_id), rmt_tx_default_isr, tx_channel, + &tx_channel->base.intr); + if (ret) { + LOG_ERR("Installation of tx interrupt failed"); + rc = -ENODEV; + goto err; + } +#if SOC_RMT_SUPPORT_DMA + /* install DMA service */ + if (with_dma) { + rc = rmt_tx_init_dma_link(dev, tx_channel, config); + if (rc) { + LOG_ERR("Installation of tx DMA failed"); + goto err; + } + } +#endif + tx_channel->base.direction = RMT_CHANNEL_DIRECTION_TX; + /* select the clock source and set clock resolution */ + rc = rmt_select_periph_clock(&tx_channel->base, config->clk_src, config->resolution_hz); + if (rc) { + LOG_ERR("Configuration of clock source failed"); + goto err; + } + + rmt_ll_tx_set_mem_blocks(hal->regs, channel_id, tx_channel->base.mem_block_num); + /* + * set limit threshold, after transmit ping_pong_symbols size, an interrupt event + * would be generated + */ + rmt_ll_tx_set_limit(hal->regs, channel_id, tx_channel->ping_pong_symbols); + /* disable carrier modulation by default, can reenable by `rmt_apply_carrier()` */ + rmt_ll_tx_enable_carrier_modulation(hal->regs, channel_id, false); + /* idle level is determined by register value */ + rmt_ll_tx_fix_idle_level(hal->regs, channel_id, 0, true); + /* always enable tx wrap, both DMA mode and ping-pong mode rely this feature */ + rmt_ll_tx_enable_wrap(hal->regs, channel_id, true); + + tx_channel->base.fsm = ATOMIC_INIT(RMT_FSM_INIT); + tx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + + RMT_TX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; + /* polymorphic methods */ + tx_channel->base.del = rmt_del_tx_channel; + tx_channel->base.set_carrier_action = rmt_tx_modulate_carrier; + tx_channel->base.enable = rmt_tx_enable; + tx_channel->base.disable = rmt_tx_disable; + /* return general channel handle */ + *ret_chan = &tx_channel->base; + LOG_DBG("New tx channel(%d,%d) at %p, gpio=%d, res=%"PRIu32"Hz, hw_mem_base=%p, " + "dma_mem_base=%p, ping_pong_size=%zu, queue_depth=%zu", + group->group_id, channel_id, tx_channel, ESP32_PIN_NUM(config->gpio_pinmux), + tx_channel->base.resolution_hz, tx_channel->base.hw_mem_base, + tx_channel->base.dma_mem_base, tx_channel->ping_pong_symbols, + tx_channel->queue_size); + + return 0; + +err: + if (tx_channel) { + rmt_tx_destroy(tx_channel); + } + + return rc; +} + +static int rmt_del_tx_channel(rmt_channel_handle_t channel) +{ + rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); + rmt_group_t *group = channel->group; + + if (atomic_get(&channel->fsm) != RMT_FSM_INIT) { + LOG_ERR("Channel not initialized"); + return -ENODEV; + } + + /* recycle memory resource */ + LOG_DBG("del tx channel(%d,%d)", group->group_id, channel->channel_id); + return rmt_tx_destroy(tx_chan); +} + +int rmt_new_sync_manager(const rmt_sync_manager_config_t *config, + rmt_sync_manager_handle_t *ret_synchro) +{ +#if !RMT_LL_SUPPORT(TX_SYNCHRO) + LOG_ERR("Sync manager not supported"); + return -ENODEV; +#else + rmt_sync_manager_t *synchro = NULL; + uint32_t channel_mask = 0; + rmt_channel_handle_t channel = NULL; + bool new_synchro = false; + k_spinlock_key_t key; + int rc; + + if (!(config && ret_synchro && config->tx_channel_array && config->array_size)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + synchro = k_calloc(1, sizeof(rmt_sync_manager_t) + sizeof(rmt_channel_handle_t) + * config->array_size); + if (!synchro) { + LOG_ERR("Unable to allocate memory for sync manager"); + return -ENOMEM; + } + for (size_t i = 0; i < config->array_size; i++) { + synchro->tx_channel_array[i] = config->tx_channel_array[i]; + } + synchro->array_size = config->array_size; + + /* acquire group handle, increase reference count */ + rmt_group_t *group = rmt_acquire_group_handle(config->tx_channel_array[0]->group->group_id); + /* sanity check */ + assert(group); + synchro->group = group; + /* calculate the mask of the channels to be managed */ + for (size_t i = 0; i < config->array_size; i++) { + channel = config->tx_channel_array[i]; + if (channel->direction != RMT_CHANNEL_DIRECTION_TX) { + LOG_ERR("sync manager supports TX channel only"); + rc = -EINVAL; + goto err; + } + if (channel->group != group) { + LOG_ERR("Channels to be managed should locate in the same group"); + rc = -EINVAL; + goto err; + } + if (atomic_get(&channel->fsm) != RMT_FSM_ENABLE) { + LOG_ERR("Channel not in enable state"); + rc = -ENODEV; + goto err; + } + channel_mask |= 1 << channel->channel_id; + } + synchro->channel_mask = channel_mask; + + /* search and register sync manager to group */ + key = k_spin_lock(&group->spinlock); + if (group->sync_manager == NULL) { + group->sync_manager = synchro; + new_synchro = true; + } + k_spin_unlock(&group->spinlock, key); + if (!new_synchro) { + LOG_ERR("No free sync manager in the group"); + rc = -ENOMEM; + goto err; + } + + /* enable sync manager */ + key = k_spin_lock(&group->spinlock); + rmt_ll_tx_enable_sync(group->hal.regs, true); + rmt_ll_tx_sync_group_add_channels(group->hal.regs, channel_mask); + rmt_ll_tx_reset_channels_clock_div(group->hal.regs, channel_mask); + /* ensure the reading cursor of each channel is pulled back to the starting line */ + for (size_t i = 0; i < config->array_size; i++) { + rmt_ll_tx_reset_pointer(group->hal.regs, config->tx_channel_array[i]->channel_id); + } + k_spin_unlock(&group->spinlock, key); + + *ret_synchro = synchro; + LOG_DBG("new sync manager at %p, with channel mask:%02"PRIx32, synchro, + synchro->channel_mask); + + return 0; + +err: + if (synchro) { + if (synchro->group) { + rmt_release_group_handle(synchro->group); + } + k_free(synchro); + } + + return rc; +#endif +} + +int rmt_sync_reset(rmt_sync_manager_handle_t synchro) +{ +#if !RMT_LL_SUPPORT(TX_SYNCHRO) + LOG_ERR("Sync manager not supported"); + return -ENODEV; +#else + rmt_group_t *group; + k_spinlock_key_t key; + + if (!synchro) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + group = synchro->group; + key = k_spin_lock(&group->spinlock); + rmt_ll_tx_reset_channels_clock_div(group->hal.regs, synchro->channel_mask); + for (size_t i = 0; i < synchro->array_size; i++) { + rmt_ll_tx_reset_pointer(group->hal.regs, synchro->tx_channel_array[i]->channel_id); + } + k_spin_unlock(&group->spinlock, key); + + return 0; +#endif +} + +int rmt_del_sync_manager(rmt_sync_manager_handle_t synchro) +{ +#if !RMT_LL_SUPPORT(TX_SYNCHRO) + LOG_ERR("Sync manager not supported"); + return -ENODEV; +#else + rmt_group_t *group; + k_spinlock_key_t key; + + if (!synchro) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + group = synchro->group; + + /* disable sync manager */ + key = k_spin_lock(&group->spinlock); + group->sync_manager = NULL; + rmt_ll_tx_enable_sync(group->hal.regs, false); + rmt_ll_tx_sync_group_remove_channels(group->hal.regs, synchro->channel_mask); + k_spin_unlock(&group->spinlock, key); + k_free(synchro); + LOG_DBG("del sync manager in group(%d)", group->group_id); + rmt_release_group_handle(group); + + return 0; +#endif +} + +int rmt_tx_register_event_callbacks(rmt_channel_handle_t channel, + const rmt_tx_event_callbacks_t *cbs, void *user_data) +{ + rmt_tx_channel_t *tx_chan; + + if (!(channel && cbs)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + if (channel->direction != RMT_CHANNEL_DIRECTION_TX) { + LOG_ERR("invalid channel direction"); + return -EINVAL; + } + tx_chan = __containerof(channel, rmt_tx_channel_t, base); + +#if CONFIG_ESPRESSIF_RMT_TX_ISR_CACHE_SAFE + if (cbs->on_trans_done) { + if (!esp_ptr_in_iram(cbs->on_trans_done)) { + LOG_ERR("on_trans_done callback not in IRAM"); + return -EINVAL; + } + } + if (user_data) { + if (!esp_ptr_internal(user_data)) { + LOG_ERR("user context not in internal RAM"); + return -EINVAL; + } + } +#endif + + tx_chan->on_trans_done = cbs->on_trans_done; + tx_chan->user_data = user_data; + + return 0; +} + +int rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, const void *payload, + size_t payload_bytes, const rmt_transmit_config_t *config) +{ + rmt_tx_channel_t *tx_chan; + rmt_tx_trans_desc_t *t = NULL; + int rc; + + if (!(channel && encoder && payload && payload_bytes && config)) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + if (channel->direction != RMT_CHANNEL_DIRECTION_TX) { + LOG_ERR("Invalid channel direction"); + return -EINVAL; + } + tx_chan = __containerof(channel, rmt_tx_channel_t, base); + +#if !SOC_RMT_SUPPORT_TX_LOOP_COUNT + if (config->loop_count > 0) { + LOG_ERR("Loop count is not supported"); + return -EINVAL; + } +#endif +#if CONFIG_ESPRESSIF_RMT_TX_ISR_CACHE_SAFE + /* + * Payload is retrieved by the encoder, we should make sure it's still accessible + * even when the cache is disabled + */ + if (!esp_ptr_internal(payload)) { + LOG_ERR("Payload not in internal RAM"); + return -EINVAL; + } +#endif + + /* acquire one transaction description from ready queue or complete queue */ + if (k_msgq_get(&tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, K_NO_WAIT) != 0) { + if (k_msgq_get(&tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, + config->flags.queue_nonblocking ? K_NO_WAIT : K_FOREVER) == 0) { + tx_chan->num_trans_inflight--; + } + } + if (!t) { + LOG_ERR("No free transaction descriptor, please consider increasing " + "trans_queue_depth"); + return -ENODEV; + } + + /* fill in the transaction descriptor */ + memset(t, 0, sizeof(rmt_tx_trans_desc_t)); + t->encoder = encoder; + t->payload = payload; + t->payload_bytes = payload_bytes; + t->loop_count = config->loop_count; + t->remain_loop_count = t->loop_count; + t->flags.eot_level = config->flags.eot_level; + + /* send the transaction descriptor to queue */ + if (k_msgq_put(&tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, K_NO_WAIT) == 0) { + tx_chan->num_trans_inflight++; + } else { + /* put the trans descriptor back to ready_queue */ + rc = k_msgq_put(&tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, K_NO_WAIT); + if (rc) { + LOG_ERR("ready queue full"); + return -ENODEV; + } + } + + /* check if we need to start one pending transaction */ + if (atomic_cas(&channel->fsm, RMT_FSM_ENABLE, RMT_FSM_WAIT)) { + /* check if we need to start one transaction */ + if (k_msgq_get(&tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, K_NO_WAIT) == 0) { + atomic_set(&channel->fsm, RMT_FSM_RUN); + rmt_tx_do_transaction(tx_chan, t); + } else { + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + } + } + + return 0; +} + +int rmt_tx_wait_all_done(rmt_channel_handle_t channel, k_timeout_t wait_ticks) +{ + rmt_tx_channel_t *tx_chan; + rmt_tx_trans_desc_t *t = NULL; + size_t num_trans_inflight; + int rc; + + if (!channel) { + LOG_ERR("Invalid argument"); + return -EINVAL; + } + tx_chan = __containerof(channel, rmt_tx_channel_t, base); + + /* recycle all transaction that are on the fly */ + num_trans_inflight = tx_chan->num_trans_inflight; + for (size_t i = 0; i < num_trans_inflight; i++) { + rc = k_msgq_get(&tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, wait_ticks); + if (rc) { + LOG_ERR("Flush timeout"); + return -ETIMEDOUT; + } + rc = k_msgq_put(&tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, K_NO_WAIT); + if (rc) { + LOG_ERR("Ready queue full"); + return -ENODEV; + } + tx_chan->num_trans_inflight--; + } + + return 0; +} + +static size_t IRAM_ATTR rmt_tx_mark_eof(rmt_tx_channel_t *tx_chan, bool need_eof_marker) +{ + rmt_channel_t *channel = &tx_chan->base; + rmt_group_t *group = channel->group; +#if SOC_RMT_SUPPORT_DMA + rmt_symbol_word_t *mem_to_nc = channel->dma_dev ? + channel->dma_mem_base : channel->hw_mem_base; +#else + rmt_symbol_word_t *mem_to_nc = channel->hw_mem_base; +#endif + size_t symbol_off = tx_chan->mem_off_bytes / sizeof(rmt_symbol_word_t); + rmt_tx_trans_desc_t *cur_trans = tx_chan->cur_trans; + k_spinlock_key_t key; + + if (need_eof_marker) { + /* a RMT word whose duration is zero means a "stop" pattern */ + mem_to_nc[symbol_off++] = (rmt_symbol_word_t) { + .duration0 = 0, + .level0 = cur_trans->flags.eot_level, + .duration1 = 0, + .level1 = cur_trans->flags.eot_level, + }; + tx_chan->mem_off_bytes += sizeof(rmt_symbol_word_t); + } + + if (!channel->dma_dev) { + key = k_spin_lock(&group->spinlock); + /* + * This is the end of a sequence of encoding sessions, disable the threshold + * interrupt as no more data will be put into RMT memory block + */ + rmt_ll_enable_interrupt(group->hal.regs, RMT_LL_EVENT_TX_THRES(channel->channel_id), + false); + k_spin_unlock(&group->spinlock, key); + } + + return need_eof_marker ? 1 : 0; +} + +static size_t IRAM_ATTR rmt_encode_check_result(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t *t) +{ + rmt_encode_state_t encode_state = RMT_ENCODING_RESET; + rmt_encoder_handle_t encoder = t->encoder; + size_t encoded_symbols; + + encoded_symbols = encoder->encode(encoder, &tx_chan->base, t->payload, t->payload_bytes, + &encode_state); + if (encode_state & RMT_ENCODING_COMPLETE) { + t->flags.encoding_done = true; + /* inserting EOF symbol if there's extra space */ + if (!(encode_state & RMT_ENCODING_MEM_FULL)) { + encoded_symbols += rmt_tx_mark_eof(tx_chan, + !(encode_state & RMT_ENCODING_WITH_EOF)); + } + } + + /* for loop transaction, the memory block should accommodate all encoded RMT symbols */ + if (t->loop_count != 0) { + if (unlikely(encoded_symbols > tx_chan->base.mem_block_num + * SOC_RMT_MEM_WORDS_PER_CHANNEL)) { + LOG_ERR("encoding artifacts can't exceed hw memory block for loop " + "transmission"); + } + } + + return encoded_symbols; +} + +static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t *t) +{ + rmt_channel_t *channel = &tx_chan->base; + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + k_spinlock_key_t key; +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT + uint32_t this_loop_count; +#endif +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + /* update current transaction */ + tx_chan->cur_trans = t; + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_reload(channel->dma_dev, channel->dma_channel, + (uint32_t)channel->dma_mem_base, 0, channel->dma_mem_size); + if (rc) { + LOG_ERR("Reloading DMA channel failed"); + return; + } + } +#endif + + /* set transaction specific parameters */ + key = k_spin_lock(&channel->spinlock); + /* reset pointer for new transaction */ + rmt_ll_tx_reset_pointer(hal->regs, channel->channel_id); + rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, t->loop_count != 0); +#if SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP + rmt_ll_tx_enable_loop_autostop(hal->regs, channel->channel_id, true); +#endif +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT + rmt_ll_tx_reset_loop_count(hal->regs, channel->channel_id); + rmt_ll_tx_enable_loop_count(hal->regs, channel->channel_id, t->loop_count > 0); + /* transfer loops in batches */ + if (t->remain_loop_count > 0) { + this_loop_count = MIN(t->remain_loop_count, RMT_LL_MAX_LOOP_COUNT_PER_BATCH); + rmt_ll_tx_set_loop_count(hal->regs, channel->channel_id, this_loop_count); + t->remain_loop_count -= this_loop_count; + } +#endif + k_spin_unlock(&channel->spinlock, key); + + /* enable/disable specific interrupts */ + key = k_spin_lock(&group->spinlock); +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel->channel_id), + t->loop_count > 0); +#endif + /* + * in DMA mode, DMA eof event plays the similar functionality to this threshold interrupt, + * so only enable it for non-DMA mode + */ + if (!channel->dma_dev) { + /* + * don't enable threshold interrupt with loop mode on + * threshold interrupt will be disabled in `rmt_encode_eof()` + */ + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_THRES(channel->channel_id), + t->loop_count == 0); + /* + * Threshold interrupt will be generated by accident, + * clear it before starting new transmission + */ + rmt_ll_clear_interrupt_status(hal->regs, + RMT_LL_EVENT_TX_THRES(channel->channel_id)); + } + /* don't generate trans done event for loop transmission */ + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel->channel_id), + t->loop_count == 0); + k_spin_unlock(&group->spinlock, key); + + /* at the beginning of a new transaction, encoding memory offset should start from zero. */ + /* It will increase in the encode function e.g. `rmt_encode_copy()` */ + tx_chan->mem_off_bytes = 0; + /* use the full memory block for the beginning encoding session */ + tx_chan->mem_end = tx_chan->ping_pong_symbols * 2; + /* perform the encoding session, return the number of encoded symbols */ + t->transmitted_symbol_num = rmt_encode_check_result(tx_chan, t); + /* + * We're going to perform ping-pong operation, so the next encoding end position is + * the middle + */ + tx_chan->mem_end = tx_chan->ping_pong_symbols; + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + rc = dma_start(channel->dma_dev, channel->dma_channel); + if (rc) { + LOG_ERR("Starting DMA channel failed"); + return; + } + /* delay a while, wait for DMA data going to RMT memory block */ + k_busy_wait(1); + } +#endif + /* turn on the TX machine */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_fix_idle_level(hal->regs, channel->channel_id, t->flags.eot_level, true); + rmt_ll_tx_start(hal->regs, channel->channel_id); + k_spin_unlock(&channel->spinlock, key); +} + +static int rmt_tx_enable(rmt_channel_handle_t channel) +{ + rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); + rmt_tx_trans_desc_t *t = NULL; +#if SOC_RMT_SUPPORT_DMA + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + k_spinlock_key_t key; +#endif + + /* Can enable the channel when it's in "init" state */ + if (!atomic_cas(&channel->fsm, RMT_FSM_INIT, RMT_FSM_WAIT)) { + LOG_ERR("Channel not initialized"); + return -ENODEV; + } + +#if CONFIG_ESPRESSIF_RMT_PM + /* acquire power manager lock */ + if (channel->pm_lock) { + esp_pm_lock_acquire(channel->pm_lock); + } +#endif + +#if SOC_RMT_SUPPORT_DMA + if (channel->dma_dev) { + /* enable the DMA access mode */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_enable_dma(hal->regs, channel->channel_id, true); + k_spin_unlock(&channel->spinlock, key); + } +#endif + + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + + /* check if we need to start one pending transaction */ + if (atomic_cas(&channel->fsm, RMT_FSM_ENABLE, RMT_FSM_WAIT)) { + if (k_msgq_get(&tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, K_NO_WAIT) == 0) { + /* sanity check */ + assert(t); + atomic_set(&channel->fsm, RMT_FSM_RUN); + rmt_tx_do_transaction(tx_chan, t); + } else { + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + } + } + + return 0; +} + +static int rmt_tx_disable(rmt_channel_handle_t channel) +{ +#if CONFIG_ESPRESSIF_RMT_PM + esp_err_t ret; +#endif + rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + bool valid_state = false; + k_spinlock_key_t key; +#if SOC_RMT_SUPPORT_DMA + int rc; +#endif + + /* can disable the channel when it's in `enable` or `run` state */ + if (atomic_cas(&channel->fsm, RMT_FSM_ENABLE, RMT_FSM_WAIT)) { + valid_state = true; + } + if (atomic_cas(&channel->fsm, RMT_FSM_RUN, RMT_FSM_WAIT)) { + valid_state = true; + /* disable the hardware */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, false); +#if RMT_LL_SUPPORT(ASYNC_STOP) + rmt_ll_tx_stop(hal->regs, channel->channel_id); +#endif + k_spin_unlock(&channel->spinlock, key); + key = k_spin_lock(&group->spinlock); + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_MASK(channel->channel_id), + false); +#if !RMT_LL_SUPPORT(ASYNC_STOP) + /* + * We do a trick to stop the undergoing transmission stop interrupt, + * insert EOF marker to the RMT memory, polling the trans_done event + */ + memset(channel->hw_mem_base, 0, channel->mem_block_num + * SOC_RMT_MEM_WORDS_PER_CHANNEL * sizeof(rmt_symbol_word_t)); + while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel->channel_id) + & RMT_LL_EVENT_TX_DONE(channel->channel_id))) { + } +#endif + rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel->channel_id)); + k_spin_unlock(&group->spinlock, key); + } + if (!valid_state) { + LOG_ERR("Channel can't be disabled in current state"); + return -ENODEV; + } + +#if SOC_RMT_SUPPORT_DMA + /* disable the DMA */ + if (channel->dma_dev) { + rc = dma_stop(channel->dma_dev, channel->dma_channel); + if (rc) { + LOG_ERR("Stopping DMA channel failed"); + return rc; + } + /* disable DMA access mode */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_enable_dma(hal->regs, channel->channel_id, false); + k_spin_unlock(&channel->spinlock, key); + } +#endif + + /* recycle the interrupted transaction */ + if (tx_chan->cur_trans) { + k_msgq_put(&tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &tx_chan->cur_trans, + K_NO_WAIT); + /* reset corresponding encoder */ + rmt_encoder_reset(tx_chan->cur_trans->encoder); + } + tx_chan->cur_trans = NULL; + +#if CONFIG_ESPRESSIF_RMT_PM + /* release power manager lock */ + if (channel->pm_lock) { + ret = esp_pm_lock_release(channel->pm_lock); + if (ret) { + LOG_ERR("Release pm_lock failed"); + return -ENODEV; + } + } +#endif + + /* finally we switch to the INIT state */ + atomic_set(&channel->fsm, RMT_FSM_INIT); + + return 0; +} + +static int rmt_tx_modulate_carrier(rmt_channel_handle_t channel, + const rmt_carrier_config_t *config) +{ + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + uint32_t real_frequency = 0; + k_spinlock_key_t key; + + if (config && config->frequency_hz) { + /* + * Carrier module works base on group clock + * Note this division operation will lose precision + */ + uint32_t total_ticks = group->resolution_hz / config->frequency_hz; + uint32_t high_ticks = total_ticks * config->duty_cycle / 1000; + uint32_t low_ticks = total_ticks - high_ticks; + + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_set_carrier_level(hal->regs, channel->channel_id, + !config->flags.polarity_active_low); + rmt_ll_tx_set_carrier_high_low_ticks(hal->regs, channel->channel_id, high_ticks, + low_ticks); + rmt_ll_tx_enable_carrier_always_on(hal->regs, channel->channel_id, + config->flags.always_on); + k_spin_unlock(&channel->spinlock, key); + /* save real carrier frequency */ + real_frequency = group->resolution_hz / total_ticks; + } + + /* enable/disable carrier modulation */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_enable_carrier_modulation(hal->regs, channel->channel_id, real_frequency > 0); + k_spin_unlock(&channel->spinlock, key); + + if (real_frequency > 0) { + LOG_DBG("enable carrier modulation for channel(%d,%d), freq=%"PRIu32"Hz", + group->group_id, channel->channel_id, real_frequency); + } else { + LOG_DBG("disable carrier modulation for channel(%d,%d)", group->group_id, + channel->channel_id); + } + return 0; +} + +static bool IRAM_ATTR rmt_isr_handle_tx_threshold(rmt_tx_channel_t *tx_chan) +{ + /* continue ping-pong transmission */ + rmt_tx_trans_desc_t *t = tx_chan->cur_trans; + size_t encoded_symbols = t->transmitted_symbol_num; + + /* encoding finished, only need to send the EOF symbol */ + if (t->flags.encoding_done) { + encoded_symbols += rmt_tx_mark_eof(tx_chan, t->flags.need_eof_mark); + } else { + encoded_symbols += rmt_encode_check_result(tx_chan, t); + } + t->transmitted_symbol_num = encoded_symbols; + /* mem_end equals to either ping_pong_symbols or ping_pong_symbols * 2 */ + tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; + + return false; +} + +static bool IRAM_ATTR rmt_isr_handle_tx_done(rmt_tx_channel_t *tx_chan) +{ + rmt_channel_t *channel = &tx_chan->base; + rmt_tx_trans_desc_t *trans_desc = NULL; + bool need_yield = false; + + if (atomic_cas(&channel->fsm, RMT_FSM_RUN, RMT_FSM_WAIT)) { + trans_desc = tx_chan->cur_trans; + /* move current finished transaction to the complete queue */ + if (k_msgq_put(&tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, + K_NO_WAIT) == 0) { + need_yield = true; + } + tx_chan->cur_trans = NULL; + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + + /* invoke callback */ + if (tx_chan->on_trans_done) { + rmt_tx_done_event_data_t edata = { + .num_symbols = trans_desc->transmitted_symbol_num, + }; + if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) { + need_yield = true; + } + } + } + + /* let's try start the next pending transaction */ + if (atomic_cas(&channel->fsm, RMT_FSM_ENABLE, RMT_FSM_WAIT)) { + if (k_msgq_get(&tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, + K_NO_WAIT) == 0) { + /* sanity check */ + assert(trans_desc); + atomic_set(&channel->fsm, RMT_FSM_RUN); + /* begin a new transaction */ + rmt_tx_do_transaction(tx_chan, trans_desc); + need_yield = true; + } else { + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + } + } + + return need_yield; +} + +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT +static bool IRAM_ATTR rmt_isr_handle_tx_loop_end(rmt_tx_channel_t *tx_chan) +{ + rmt_channel_t *channel = &tx_chan->base; + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + rmt_tx_trans_desc_t *trans_desc = tx_chan->cur_trans; + bool need_yield = false; + uint32_t this_loop_count; + k_spinlock_key_t key; + + if (trans_desc) { +#if !SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP + /* + * This is a workaround for chips that don't support loop auto stop + * Although we stop the transaction immediately in ISR handler, + * it's still possible that some rmt symbols have sneaked out + */ + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_stop(hal->regs, channel->channel_id); + k_spin_unlock(&channel->spinlock, key); +#endif + + /* continue unfinished loop transaction */ + if (trans_desc->remain_loop_count) { + this_loop_count = MIN(trans_desc->remain_loop_count, + RMT_LL_MAX_LOOP_COUNT_PER_BATCH); + trans_desc->remain_loop_count -= this_loop_count; + key = k_spin_lock(&channel->spinlock); + rmt_ll_tx_set_loop_count(hal->regs, channel->channel_id, this_loop_count); + rmt_ll_tx_reset_pointer(hal->regs, channel->channel_id); + /* + * continue the loop transmission, don't need to fill the RMT symbols again, + * just restart the engine + */ + rmt_ll_tx_start(hal->regs, channel->channel_id); + k_spin_unlock(&channel->spinlock, key); + return need_yield; + } + + /* loop transaction finished */ + if (atomic_cas(&channel->fsm, RMT_FSM_RUN, RMT_FSM_WAIT)) { + /* move current finished transaction to the complete queue */ + if (k_msgq_put(&tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, + K_NO_WAIT) == 0) { + need_yield = true; + } + tx_chan->cur_trans = NULL; + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + + /* invoke callback */ + if (tx_chan->on_trans_done) { + rmt_tx_done_event_data_t edata = { + .num_symbols = trans_desc->transmitted_symbol_num, + }; + if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) { + need_yield = true; + } + } + } + + /* let's try start the next pending transaction */ + if (atomic_cas(&channel->fsm, RMT_FSM_ENABLE, RMT_FSM_WAIT)) { + if (k_msgq_get(&tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, + K_NO_WAIT) == 0) { + /* sanity check */ + assert(trans_desc); + atomic_set(&channel->fsm, RMT_FSM_RUN); + /* begin a new transaction */ + rmt_tx_do_transaction(tx_chan, trans_desc); + need_yield = true; + } else { + atomic_set(&channel->fsm, RMT_FSM_ENABLE); + } + } + } + + return need_yield; +} +#endif + +static void IRAM_ATTR rmt_tx_default_isr(void *args) +{ + rmt_tx_channel_t *tx_chan = (rmt_tx_channel_t *)args; + rmt_channel_t *channel = &tx_chan->base; + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + uint32_t status; + + status = rmt_ll_tx_get_interrupt_status(hal->regs, channel->channel_id); + rmt_ll_clear_interrupt_status(hal->regs, status); + + /* Tx threshold interrupt */ + if (status & RMT_LL_EVENT_TX_THRES(channel->channel_id)) { + rmt_isr_handle_tx_threshold(tx_chan); + } + + /* Tx end interrupt */ + if (status & RMT_LL_EVENT_TX_DONE(channel->channel_id)) { + rmt_isr_handle_tx_done(tx_chan); + } + +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT + /* Tx loop end interrupt */ + if (status & RMT_LL_EVENT_TX_LOOP_END(channel->channel_id)) { + rmt_isr_handle_tx_loop_end(tx_chan); + } +#endif +} + +#if SOC_RMT_SUPPORT_DMA +static void rmt_dma_tx_eof_cb(const struct device *dma_dev, void *user_data, uint32_t dma_channel, + int status) +{ + /* Nothing to do */ +} +#endif diff --git a/dts/bindings/dma/espressif,esp32-gdma.yaml b/dts/bindings/dma/espressif,esp32-gdma.yaml index ecbdc58057cd2..d432501143117 100644 --- a/dts/bindings/dma/espressif,esp32-gdma.yaml +++ b/dts/bindings/dma/espressif,esp32-gdma.yaml @@ -35,7 +35,7 @@ description: | * AES (Not Supported yet) * SHA (Not Supported yet) * ADC - * RMT (Not Supported yet) + * RMT compatible: "espressif,esp32-gdma" diff --git a/dts/bindings/misc/espressif,esp32-rmt-device.yaml b/dts/bindings/misc/espressif,esp32-rmt-device.yaml new file mode 100644 index 0000000000000..e048e1b7b1dfa --- /dev/null +++ b/dts/bindings/misc/espressif,esp32-rmt-device.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +# Common fields for Espressif RMT devices + +include: [base.yaml] + +on-bus: "espressif,esp32-rmt" + +properties: + reg: + required: true diff --git a/dts/bindings/misc/espressif,esp32-rmt.yaml b/dts/bindings/misc/espressif,esp32-rmt.yaml new file mode 100644 index 0000000000000..0fd5d96833b58 --- /dev/null +++ b/dts/bindings/misc/espressif,esp32-rmt.yaml @@ -0,0 +1,76 @@ +# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +description: | + Espressif Remote Control Transceiver (RMT) + + The RMT (Remote Control Transceiver) peripheral was designed to act as an infrared transceiver. + However, due to the flexibility of its data format, RMT can be extended to a versatile and + general-purpose transceiver, transmitting or receiving many other types of signals. + + pinctrl is used to configure RMT channels and GPIO to be used. + When using ESP32 or ESP32S2 series, each RMT channel should be used once (eg. RMT_OUT0_GPIOxx + and RMT_IN0_GPIOxx can't be used at the same time, etc.). An error is displayed when trying to + create channels with such configuration. + This limitation is due to the number of channels available. See + `RMT_LL_GET(TX_CANDIDATES_PER_INST)`, `RMT_LL_GET(RX_CANDIDATES_PER_INST)` and + `RMT_LL_GET(CHANS_PER_INST)` for more details. + + DMA feature is available only on ESP32S3 and with only one "tx" and one "rx" DMA channels + available. DMA channels are optional. Using DMA channels is activated configuring DMA channels + in the RMT peripheral and configuring pinctrl to use DMA capable RMT channels + (eg. RMT_OUT3_GPIOxx and RMT_OUT3_GPIOxx on ESP32S3). + + Here is an example ESP32 configuration with a RMT device: + + &pinctrl { + rmt_default: rmt_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; + }; + + rmt: rmt@60016000 { + compatible = "espressif,esp32-rmt"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60016000 0x1000>; + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + dmas = <&dma 8>, <&dma 9>; + dma-names = "rx", "tx"; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_RMT_MODULE>; + status = "okay"; + }; + +compatible: "espressif,esp32-rmt" + +include: [base.yaml, pinctrl-device.yaml] + +bus: "espressif,esp32-rmt" + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + clocks: + required: true + + interrupts: + required: true + + interrupt-parent: + required: true diff --git a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi index 6af47335a1682..b1acb82cc332b 100644 --- a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi +++ b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi @@ -357,5 +357,16 @@ clocks = <&clock ESP32_AES_MODULE>; status = "okay"; }; + + rmt: rmt@60016000 { + compatible = "espressif,esp32-rmt"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60016000 0x1000>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_RMT_MODULE>; + status = "disabled"; + }; }; }; diff --git a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi index 340d28c931e16..32b946670fb8a 100644 --- a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi +++ b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi @@ -450,5 +450,16 @@ clocks = <&clock ESP32_AES_MODULE>; status = "okay"; }; + + rmt: rmt@60006000 { + compatible = "espressif,esp32-rmt"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60006000 0x1000>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_RMT_MODULE>; + status = "disabled"; + }; }; }; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi index 240741aa32e4b..4ac749787ce91 100644 --- a/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi +++ b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi @@ -374,5 +374,16 @@ clocks = <&clock ESP32_AES_MODULE>; status = "okay"; }; + + rmt: rmt@60007000 { + compatible = "espressif,esp32-rmt"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60007000 0x1000>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_RMT_MODULE>; + status = "disabled"; + }; }; }; diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index 44e8c2715e54b..cbff26629ee62 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -583,5 +583,16 @@ clocks = <&clock ESP32_AES_MODULE>; status = "okay"; }; + + rmt: rmt@3ff56000 { + compatible = "espressif,esp32-rmt"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3ff56000 0x1000>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_RMT_MODULE>; + status = "disabled"; + }; }; }; diff --git a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi index c2cf779e305a3..d0790eeb9e62a 100644 --- a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi +++ b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi @@ -453,5 +453,16 @@ clocks = <&clock ESP32_AES_MODULE>; status = "okay"; }; + + rmt: rmt@3f416000 { + compatible = "espressif,esp32-rmt"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3f416000 0x1000>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_RMT_MODULE>; + status = "disabled"; + }; }; }; diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi index 570f828e4734e..ffe3e2b772e7e 100644 --- a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi +++ b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi @@ -632,5 +632,16 @@ clocks = <&clock ESP32_AES_MODULE>; status = "okay"; }; + + rmt: rmt@60016000 { + compatible = "espressif,esp32-rmt"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60016000 0x1000>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&clock ESP32_RMT_MODULE>; + status = "disabled"; + }; }; }; diff --git a/include/zephyr/drivers/misc/espressif_rmt/rmt.h b/include/zephyr/drivers/misc/espressif_rmt/rmt.h new file mode 100644 index 0000000000000..489f3a643be18 --- /dev/null +++ b/include/zephyr/drivers/misc/espressif_rmt/rmt.h @@ -0,0 +1,77 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Espressif RMT public API + */ + +#ifndef ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_H_ +#define ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_H_ + +/** + * @brief Espressif RMT. + * @defgroup espressif_rmt Espressif RMT + * @ingroup misc_interfaces + * @{ + */ + +#include +#include + +#include "hal/rmt_hal.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Undefined Tx/Rx DMA channel */ +#define ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED (0xFF) + +/** + * @brief Espressif RMT config + */ +struct espressif_rmt_config { + /** Reference to the pinctrl */ + const struct pinctrl_dev_config *pcfg; + /** Reference to the DMA device */ + const struct device *dma_dev; + /** TX DMA channel, ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED if not defined */ + uint8_t tx_dma_channel; + /** RX DMA channel, ESPRESSIF_RMT_DMA_CHANNEL_UNDEFINED if not defined */ + uint8_t rx_dma_channel; + /** Reference to the clock device */ + const struct device *clock_dev; + /** Reference to the clock controller */ + const clock_control_subsys_t clock_subsys; + /** RMT IRQ source */ + int irq_source; + /** RMT IRQ priority */ + int irq_priority; + /** RMT IRQ flags */ + int irq_flags; +}; + +/** + * @brief Espressif RMT data + */ +struct espressif_rmt_data { + /** Reference to HAL */ + rmt_hal_context_t hal; +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_H_ */ diff --git a/include/zephyr/drivers/misc/espressif_rmt/rmt_common.h b/include/zephyr/drivers/misc/espressif_rmt/rmt_common.h new file mode 100644 index 0000000000000..f0fb42481fca2 --- /dev/null +++ b/include/zephyr/drivers/misc/espressif_rmt/rmt_common.h @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Espressif RMT Common public API + */ + +#ifndef ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_COMMON_H_ +#define ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_COMMON_H_ + +/** + * @brief Espressif RMT common functions. + * @defgroup espressif_rmt_common_interface Espressif RMT Common interface + * @ingroup espressif_rmt + * @{ + */ + +#include +#include "rmt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Delete an RMT channel. + * + * @param channel RMT generic channel that created by `rmt_new_tx_channel()` or + * `rmt_new_rx_channel()`. + * @retval 0 If successful. + * @retval -EINVAL Delete RMT channel failed because of invalid argument. + * @retval -ENODEV Delete RMT channel failed because it is still in working, or other error. + */ +int rmt_del_channel(rmt_channel_handle_t channel); + +/** + * @brief Apply modulation feature for TX channel or demodulation feature for RX channel. + * + * @param channel RMT generic channel that created by `rmt_new_tx_channel()` or + * `rmt_new_rx_channel()`. + * @param config Carrier configuration. Specially, a NULL config means to disable the carrier + * modulation or demodulation feature. + * @retval 0 If successful. + * @retval -EINVAL Apply carrier configuration failed because of invalid argument. + * @retval -ENODEV Apply carrier configuration failed because of other error. + */ +int rmt_apply_carrier(rmt_channel_handle_t channel, const rmt_carrier_config_t *config); + +/** + * @brief Enable the RMT channel. + * + * @note This function will acquire a PM lock that might be installed during channel allocation. + * + * @param channel RMT generic channel that created by `rmt_new_tx_channel()` or + * `rmt_new_rx_channel()`. + * @retval 0 If successful. + * @retval -EINVAL if enabling RMT channel failed because of invalid argument. + * @retval -ENODEV if enabling RMT channel failed because it's enabled already, or other error. + */ +int rmt_enable(rmt_channel_handle_t channel); + +/** + * @brief Disable the RMT channel. + * + * @note This function will release a PM lock that might be installed during channel allocation. + * + * @param channel RMT generic channel that created by `rmt_new_tx_channel()` or + * `rmt_new_rx_channel()`. + * @retval 0 If successful. + * @retval -EINVAL if disabling RMT channel failed because of invalid argument. + * @retval -ENODEV if disabling RMT channel failed because it's not enabled yet, or other error. + */ +int rmt_disable(rmt_channel_handle_t channel); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_COMMON_H_ */ diff --git a/include/zephyr/drivers/misc/espressif_rmt/rmt_encoder.h b/include/zephyr/drivers/misc/espressif_rmt/rmt_encoder.h new file mode 100644 index 0000000000000..50664cf63be50 --- /dev/null +++ b/include/zephyr/drivers/misc/espressif_rmt/rmt_encoder.h @@ -0,0 +1,259 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Espressif RMT encoder public API + */ + +#ifndef ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_ENCODER_H_ +#define ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_ENCODER_H_ + +/** + * @brief Espressif RMT encoder functions. + * @defgroup espressif_rmt_encoder_interface Espressif RMT Encoder interface + * @ingroup espressif_rmt + * @{ + */ + +#include +#include "hal/rmt_types.h" +#include "rmt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond */ +typedef struct rmt_encoder_t rmt_encoder_t; +/** @endcond */ + +/** + * @brief RMT encoding state + */ +typedef enum { + /** The encoding session is in reset state */ + RMT_ENCODING_RESET = 0, + /** The encoding session is finished, the caller can continue with subsequent encoding */ + RMT_ENCODING_COMPLETE = (1 << 0), + /** The encoding artifact memory is full, the caller should return from current encoding + * session + */ + RMT_ENCODING_MEM_FULL = (1 << 1), + /** The encoding session has inserted the EOF marker to the symbol stream */ + RMT_ENCODING_WITH_EOF = (1 << 2), +} rmt_encode_state_t; + +/** + * @brief Interface of RMT encoder + */ +struct rmt_encoder_t { + /** + * @brief Encode the user data into RMT symbols and write into RMT memory. + * + * @note The encoding function will also be called from an ISR context, thus the function + * must not call any blocking API. + * @note It's recommended to put this function implementation in the IRAM, to achieve a high + * performance and less interrupt latency. + * + * @param encoder Encoder handle. + * @param tx_channel RMT TX channel handle, returned from `rmt_new_tx_channel()`. + * @param primary_data App data to be encoded into RMT symbols. + * @param data_size Size of primary_data, in bytes. + * @param ret_state Returned current encoder's state. + * @retval Number of RMT symbols that the primary data has been encoded into. + */ + size_t (*encode)(rmt_encoder_t *encoder, rmt_channel_handle_t tx_channel, + const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state); + + /** + * @brief Reset encoding state. + * + * @param encoder Encoder handle. + * @retval 0 If successful. + * @retval -ENODEV if reset encoder failed. + */ + int (*reset)(rmt_encoder_t *encoder); + + /** + * @brief Delete encoder object. + * + * @param encoder Encoder handle. + * @retval 0 If successful. + * @retval -ENODEV if delete encoder failed. + */ + int (*del)(rmt_encoder_t *encoder); +}; + +/** + * @brief Callback for simple callback encoder. + * + * This will get called to encode the data stream of given length (as passed to + * rmt_transmit by the user) into symbols to be sent by the hardware. + * + * The callback will be initially called with symbol_pos=0. If the callback + * encodes N symbols and finishes, the next callback will always be with + * symbols_written=N. If the callback then encodes M symbols, the next callback + * will always be with symbol_pos=N+M, etc. The only exception is when the + * encoder is reset (e.g. to begin a new transaction) in which case + * symbol_pos will always restart at 0. + * + * If the amount of free space in the symbol buffer (as indicated by + * symbols_free) is too low, the function can return 0 as result and + * the RMT will call the function again once there is more space available. + * Note that the callback should eventually return non-0 if called with + * free space of rmt_simple_encoder_config_t::min_chunk_size or more. It + * is acceptable to return 0 for a given free space N, then on the next + * call (possibly with a larger free buffer space) return less or more + * than N symbols. + * + * When the transaction is done (all data_size data is encoded), the callback + * can indicate this by setting *done to true. This can either happen on the + * last callback call that returns an amount of symbols encoded, or on a + * callback that returns zero. In either case, the callback will not be + * called again for this transaction. + * + * @param data Data pointer, as passed to rmt_transmit(). + * @param data_size Size of the data, as passed to rmt_transmit(). + * @param symbols_written Current position in encoded stream, in symbols. + * @param symbols_free The maximum amount of symbols that can be written into the `symbols` + * buffer. + * @param symbols Symbols to be sent to the RMT hardware. + * @param done Setting this to true marks this transaction as finished. + * @param arg Opaque argument. + * @return Amount of symbols encoded in this callback round. 0 if more space is needed. + */ +typedef size_t (*rmt_encode_simple_cb_t)(const void *data, size_t data_size, + size_t symbols_written, size_t symbols_free, rmt_symbol_word_t *symbols, bool *done, + void *arg); + +/** + * @brief Bytes encoder configuration + */ +typedef struct { + /** How to represent BIT0 in RMT symbol */ + rmt_symbol_word_t bit0; + /** How to represent BIT1 in RMT symbol */ + rmt_symbol_word_t bit1; + /** Encoder config flag */ + struct { + /** Whether to encode MSB bit first */ + uint32_t msb_first: 1; + } flags; +} rmt_bytes_encoder_config_t; + +/** + * @brief Copy encoder configuration + */ +typedef struct { +} rmt_copy_encoder_config_t; + +/** + * @brief Simple callback encoder configuration. + */ +typedef struct { + /** Callback to call for encoding data into RMT items */ + rmt_encode_simple_cb_t callback; + /** Opaque user-supplied argument for callback */ + void *arg; + /** Minimum amount of free space, in RMT symbols, the encoder needs in order to guarantee + * it always returns non-zero. Defaults to 64 if zero / not given. + */ + size_t min_chunk_size; +} rmt_simple_encoder_config_t; + +/** + * @brief Create RMT bytes encoder, which can encode byte stream into RMT symbols. + * + * @param config Bytes encoder configuration. + * @param ret_encoder Returned encoder handle. + * @retval 0 If successful. + * @retval -EINVAL Create RMT bytes encoder failed because of invalid argument. + * @retval -ENOMEM Create RMT bytes encoder failed because out of memory. + * @retval -ENODEV Create RMT bytes encoder failed because of other error. + */ +int rmt_new_bytes_encoder(const rmt_bytes_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder); + +/** + * @brief Update the configuration of the bytes encoder. + * + * @note The configurations of the bytes encoder is also set up by `rmt_new_bytes_encoder()`. + * This function is used to update the configuration of the bytes encoder at runtime. + * + * @param bytes_encoder Bytes encoder handle, created by e.g `rmt_new_bytes_encoder()`. + * @param config Bytes encoder configuration. + * @retval 0 If successful. + * @retval -EINVAL Update RMT bytes encoder failed because of invalid argument. + * @retval -ENODEV Update RMT bytes encoder failed because of other error. + */ +int rmt_bytes_encoder_update_config(rmt_encoder_handle_t bytes_encoder, + const rmt_bytes_encoder_config_t *config); + +/** + * @brief Create RMT copy encoder, which copies the given RMT symbols into RMT memory. + * + * @param config Copy encoder configuration. + * @param ret_encoder Returned encoder handle. + * @retval 0 If successful. + * @retval -EINVAL Create RMT copy encoder failed because of invalid argument. + * @retval -ENOMEM Create RMT copy encoder failed because out of memory. + * @retval -ENODEV Create RMT copy encoder failed because of other error. + */ +int rmt_new_copy_encoder(const rmt_copy_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder); + +/** + * @brief Create RMT simple callback encoder, which uses a callback to convert incoming data into + * RMT symbols. + * + * @param config Simple callback encoder configuration. + * @param ret_encoder Returned encoder handle. + * @retval 0 If successful. + * @retval -EINVAL Create RMT simple encoder failed because of invalid argument. + * @retval -ENOMEM Create RMT simple encoder failed because out of memory. + * @retval -ENODEV Create RMT simple encoder failed because of other error. + */ +int rmt_new_simple_encoder(const rmt_simple_encoder_config_t *config, + rmt_encoder_handle_t *ret_encoder); + +/** + * @brief Delete RMT encoder. + * + * @param encoder RMT encoder handle, created by e.g `rmt_new_bytes_encoder()`. + * @retval 0 If successful. + * @retval -EINVAL Delete RMT encoder failed because of invalid argument. + * @retval -ENODEV Delete RMT encoder failed because of other error. + */ +int rmt_del_encoder(rmt_encoder_handle_t encoder); + +/** + * @brief Reset RMT encoder. + * + * @param encoder RMT encoder handle, created by e.g `rmt_new_bytes_encoder()`. + * @retval 0 If successful. + * @retval -EINVAL Reset RMT encoder failed because of invalid argument. + * @retval -ENODEV Reset RMT encoder failed because of other error. + */ +int rmt_encoder_reset(rmt_encoder_handle_t encoder); + +/** + * @brief A helper function to allocate a proper memory for RMT encoder. + * + * @param size Size of memory to be allocated. + * @retval Pointer to the allocated memory if the allocation is successful, NULL otherwise. + */ +void *rmt_alloc_encoder_mem(size_t size); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_ENCODER_H_ */ diff --git a/include/zephyr/drivers/misc/espressif_rmt/rmt_rx.h b/include/zephyr/drivers/misc/espressif_rmt/rmt_rx.h new file mode 100644 index 0000000000000..20ad14c22e980 --- /dev/null +++ b/include/zephyr/drivers/misc/espressif_rmt/rmt_rx.h @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Espressif RMT RX public API + */ + +#ifndef ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_RX_H_ +#define ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_RX_H_ + +/** + * @brief Espressif RMT RX functions. + * @defgroup espressif_rmt_rx_interface Espressif RMT RX interface + * @ingroup espressif_rmt + * @{ + */ + +#include +#include +#include "rmt_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Group of RMT RX callbacks + * @note The callbacks are all running under ISR environment + * @note When CONFIG_ESPRESSIF_RMT_RX_ISR_CACHE_SAFE is enabled, the callback itself and functions + * called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. + */ +typedef struct { + /** Event callback, invoked when one RMT channel receiving transaction completes */ + rmt_rx_done_callback_t on_recv_done; +} rmt_rx_event_callbacks_t; + +/** + * @brief RMT RX channel specific configuration + */ +typedef struct { + /** GPIO pinmux used by RMT RX channel */ + int gpio_pinmux; + /** Clock source of RMT RX channel, channels in the same group must use the same clock + * source + */ + rmt_clock_source_t clk_src; + /** Channel clock resolution, in Hz */ + uint32_t resolution_hz; + /** Size of memory block, in number of `rmt_symbol_word_t`, must be an even. + * In the DMA mode, this field controls the DMA buffer size, it can be set to a large value + * (e.g. 1024); + * In the normal mode, this field controls the number of RMT memory block that will be used + * by the channel. + */ + size_t mem_block_symbols; + /** RMT interrupt priority, if set to 0, the driver will try to allocate an interrupt with + * a relative low priority (1,2,3) + */ + int intr_priority; + /** RX channel config flags */ + struct { + /** If set, driver allows the power domain to be powered off when system enters + * sleep mode. This can save power, but at the expense of more RAM being consumed to + * save register context. + */ + uint32_t allow_pd: 1; + } flags; +} rmt_rx_channel_config_t; + +/** + * @brief RMT receive specific configuration + */ +typedef struct { + /** A pulse whose width is smaller than this threshold will be treated as glitch and + * ignored + */ + uint32_t signal_range_min_ns; + /** RMT will stop receiving if one symbol level has kept more than + * `signal_range_max_ns` + */ + uint32_t signal_range_max_ns; + /** Receive specific config flags */ + struct { + /** Set this flag if the incoming data is very long, and the driver can only receive + * the data piece by piece, because the user buffer is not sufficient to save all + * the data. + */ + uint32_t en_partial_rx: 1; + } flags; +} rmt_receive_config_t; + +/** + * @brief Create a RMT RX channel. + * + * @param dev RMT device instance. + * @param config RX channel configurations. + * @param ret_chan Returned generic RMT channel handle. + * @retval 0 If successful. + * @retval -EINVAL Create RMT RX channel failed because of invalid argument. + * @retval -ENOMEM Create RMT RX channel failed because out of memory. + * @retval -ENODEV Create RMT RX channel failed because all RMT channels are used up and no more + * free one, or some feature is not supported by hardware, e.g. DMA feature is not + * supported by hardware, or other error. + */ +int rmt_new_rx_channel(const struct device *dev, const rmt_rx_channel_config_t *config, + rmt_channel_handle_t *ret_chan); + +/** + * @brief Initiate a receive job for RMT RX channel. + * + * @note This function is non-blocking, it initiates a new receive job and then returns. + * User should check the received data from the `on_recv_done` callback that registered by + * `rmt_rx_register_event_callbacks()`. + * @note This function can also be called in ISR context. + * + * @param rx_channel RMT RX channel that created by `rmt_new_rx_channel()`. + * @param buffer The buffer to store the received RMT symbols. + * @param buffer_size size of the `buffer`, in bytes. + * @param config Receive specific configurations. + * @retval 0 If successful. + * @retval -EINVAL Initiate receive job failed because of invalid argument. + * @retval -ENODEV Initiate receive job failed because channel is not enabled, or other error. + */ +int rmt_receive(rmt_channel_handle_t rx_channel, void *buffer, size_t buffer_size, + const rmt_receive_config_t *config); + +/** + * @brief Set callbacks for RMT RX channel. + * + * @note User can deregister a previously registered callback by calling this function and setting + * the callback member in the `cbs` structure to NULL. + * @note When CONFIG_ESPRESSIF_RMT_RX_ISR_CACHE_SAFE is enabled, the callback itself and functions + * called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. The `user_data` should + * also reside in SRAM. + * + * @param rx_channel RMT generic channel that created by `rmt_new_rx_channel()`. + * @param cbs Group of callback functions. + * @param user_data User data, which will be passed to callback functions directly. + * @retval 0 If successful. + * @retval -EINVAL Set event callbacks failed because of invalid argument. + * @retval -ENODEV Set event callbacks failed because of other error. + */ +int rmt_rx_register_event_callbacks(rmt_channel_handle_t rx_channel, + const rmt_rx_event_callbacks_t *cbs, void *user_data); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_RX_H_ */ diff --git a/include/zephyr/drivers/misc/espressif_rmt/rmt_tx.h b/include/zephyr/drivers/misc/espressif_rmt/rmt_tx.h new file mode 100644 index 0000000000000..98df8b61462e2 --- /dev/null +++ b/include/zephyr/drivers/misc/espressif_rmt/rmt_tx.h @@ -0,0 +1,232 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Espressif RMT TX public API + */ + +#ifndef ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_TX_H_ +#define ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_TX_H_ + +/** + * @brief Espressif RMT TX functions. + * @defgroup espressif_rmt_tx_interface Espressif RMT TX interface + * @ingroup espressif_rmt + * @{ + */ + +#include +#include +#include "rmt_common.h" +#include "rmt_encoder.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Group of RMT TX callbacks + * @note The callbacks are all running under ISR environment + * @note When CONFIG_ESPRESSIF_RMT_TX_ISR_CACHE_SAFE is enabled, the callback itself and functions + * called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. + */ +typedef struct { + /** Event callback, invoked when transmission is finished */ + rmt_tx_done_callback_t on_trans_done; +} rmt_tx_event_callbacks_t; + +/** + * @brief RMT TX channel specific configuration + */ +typedef struct { + /** GPIO pinmux used by RMT TX channel */ + int gpio_pinmux; + /** Clock source of RMT TX channel, channels in the same group must use the same clock + * source + */ + rmt_clock_source_t clk_src; + /** Channel clock resolution, in Hz */ + uint32_t resolution_hz; + /** Size of memory block, in number of `rmt_symbol_word_t`, must be an even. + * In the DMA mode, this field controls the DMA buffer size, it can be set to a large value; + * In the normal mode, this field controls the number of RMT memory block that will be used + * by the channel. + */ + size_t mem_block_symbols; + /** Depth of internal transfer queue, increase this value can support more transfers + * pending in the background + */ + size_t trans_queue_depth; + /** RMT interrupt priority, if set to 0, the driver will try to allocate an interrupt with + * a relative low priority (1,2,3) + */ + int intr_priority; + /** TX channel config flags */ + struct { + /** If set, driver allows the power domain to be powered off when system enters + * sleep mode. This can save power, but at the expense of more RAM being consumed to + * save register context. + */ + uint32_t allow_pd: 1; + } flags; +} rmt_tx_channel_config_t; + +/** + * @brief RMT transmit specific configuration + */ +typedef struct { + /** Specify the times of transmission in a loop, -1 means transmitting in an infinite + * loop + */ + int loop_count; + /** Transmit specific config flags */ + struct { + /** Set the output level for the "End Of Transmission" */ + uint32_t eot_level : 1; + /** If set, when the transaction queue is full, driver will not block the thread + * but return directly + */ + uint32_t queue_nonblocking : 1; + } flags; +} rmt_transmit_config_t; + +/** + * @brief Synchronous manager configuration + */ +typedef struct { + /** Array of TX channels that are about to be managed by a synchronous controller */ + const rmt_channel_handle_t *tx_channel_array; + /** Size of the `tx_channel_array` */ + size_t array_size; +} rmt_sync_manager_config_t; + +/** + * @brief Create a RMT TX channel. + * + * @param dev RMT device instance. + * @param config TX channel configurations. + * @param ret_chan Returned generic RMT channel handle. + * @retval 0 If successful. + * @retval -EINVAL if creating RMT TX channel failed because of invalid argument. + * @retval -ENOMEM if creating RMT TX channel failed because out of memory, or all RMT channels + * are used up and no more free one. + * @retval -ENODEV if creating RMT TX channel failed because some feature is not supported by + * hardware, e.g. DMA feature is not supported by hardware, or other error. + */ +int rmt_new_tx_channel(const struct device *dev, const rmt_tx_channel_config_t *config, + rmt_channel_handle_t *ret_chan); + +/** + * @brief Transmit data by RMT TX channel. + * + * @note This function constructs a transaction descriptor then pushes to a queue. + * The transaction will not start immediately if there's another one under processing. + * Based on the setting of `rmt_transmit_config_t::queue_nonblocking`, + * if there're too many transactions pending in the queue, this function can block until it + * has free slot, otherwise just return quickly. + * @note The data to be transmitted will be encoded into RMT symbols by the specific `encoder`. + * + * @param tx_channel RMT TX channel that created by `rmt_new_tx_channel()`. + * @param encoder RMT encoder that created by various factory APIs like `rmt_new_bytes_encoder()`. + * @param payload The raw data to be encoded into RMT symbols. + * @param payload_bytes Size of the `payload` in bytes. + * @param config Transmission specific configuration. + * @retval 0 If successful. + * @retval -EINVAL Transmit data failed because of invalid argument. + * @retval -ENODEV Transmit data failed because channel is not enabled, or some feature is not + * supported by hardware, e.g. unsupported loop count, or other error. + */ +int rmt_transmit(rmt_channel_handle_t tx_channel, rmt_encoder_handle_t encoder, + const void *payload, size_t payload_bytes, const rmt_transmit_config_t *config); + +/** + * @brief Wait for all pending TX transactions done. + * + * @note This function will block forever if the pending transaction can't be finished within a + * limited time (e.g. an infinite loop transaction). + * See also `rmt_disable()` for how to terminate a working channel. + * + * @param tx_channel RMT TX channel that created by `rmt_new_tx_channel()`. + * @param timeout_ms Wait timeout, in ms. Specially, -1 means to wait forever. + * @retval 0 If successful. + * @retval -EINVAL Flush transactions failed because of invalid argument. + * @retval -ETIMEDOUT Flush transactions failed because of timeout. + * @retval -ENODEV Flush transactions failed because of other error. + */ +int rmt_tx_wait_all_done(rmt_channel_handle_t tx_channel, k_timeout_t timeout_ms); + +/** + * @brief Set event callbacks for RMT TX channel. + * + * @note User can deregister a previously registered callback by calling this function and setting + * the callback member in the `cbs` structure to NULL. + * @note When CONFIG_ESPRESSIF_RMT_TX_ISR_CACHE_SAFE is enabled, the callback itself and functions + * called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. The `user_data` should + * also reside in SRAM. + * + * @param tx_channel RMT generic channel that created by `rmt_new_tx_channel()`. + * @param cbs Group of callback functions. + * @param user_data User data, which will be passed to callback functions directly. + * @retval 0 If successful. + * @retval -EINVAL Set event callbacks failed because of invalid argument. + * @retval -ENODEV Set event callbacks failed because of other error. + */ +int rmt_tx_register_event_callbacks(rmt_channel_handle_t tx_channel, + const rmt_tx_event_callbacks_t *cbs, void *user_data); + +/** + * @brief Create a synchronization manager for multiple TX channels, so that the managed channel + * can start transmitting at the same time. + * + * @note All the channels to be managed should be enabled by `rmt_enable()` before put them into + * sync manager. + * + * @param config Synchronization manager configuration. + * @param ret_synchro Returned synchronization manager handle. + * @retval 0 If successful. + * @retval -EINVAL Create sync manager failed because of invalid argument. + * @retval -ENOMEM Create sync manager failed because out of memory, or all sync controllers are + * used up and no more free one. + * @retval -ENODEV Create sync manager failed because it is not supported by hardware, or not all + * channels are enabled, or other error. + */ +int rmt_new_sync_manager(const rmt_sync_manager_config_t *config, + rmt_sync_manager_handle_t *ret_synchro); + +/** + * @brief Delete synchronization manager. + * + * @param synchro Synchronization manager handle returned from `rmt_new_sync_manager()`. + * @retval 0 If successful. + * @retval -EINVAL delete the synchronization manager failed because of invalid argument. + * @retval -ENODEV delete the synchronization manager failed because of other error. + */ +int rmt_del_sync_manager(rmt_sync_manager_handle_t synchro); + +/** + * @brief Reset synchronization manager. + * + * @param synchro Synchronization manager handle returned from `rmt_new_sync_manager()`. + * @retval 0 If successful. + * @retval -EINVAL reset the synchronization manager failed because of invalid argument. + * @retval -ENODEV reset the synchronization manager failed because of other error. + */ +int rmt_sync_reset(rmt_sync_manager_handle_t synchro); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_TX_H_ */ diff --git a/include/zephyr/drivers/misc/espressif_rmt/rmt_types.h b/include/zephyr/drivers/misc/espressif_rmt/rmt_types.h new file mode 100644 index 0000000000000..ad55257a8e108 --- /dev/null +++ b/include/zephyr/drivers/misc/espressif_rmt/rmt_types.h @@ -0,0 +1,124 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Espressif RMT Types public API + */ + +#ifndef ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_TYPES_H_ +#define ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_TYPES_H_ + +/** + * @brief Espressif RMT types. + * @defgroup espressif_rmt_types Espressif RMT types + * @ingroup espressif_rmt + * @{ + */ + +#include +#include +#include +#include "hal/rmt_types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of RMT channel handle + */ +typedef struct rmt_channel_t *rmt_channel_handle_t; + +/** + * @brief Type of RMT synchronization manager handle + */ +typedef struct rmt_sync_manager_t *rmt_sync_manager_handle_t; + +/** + * @brief Type of RMT encoder handle + */ +typedef struct rmt_encoder_t *rmt_encoder_handle_t; + +/** + * @brief Type of RMT TX done event data + */ +typedef struct { + /** The number of transmitted RMT symbols, including one EOF symbol, which is appended by + * the driver to mark the end of a transmission. + * For a loop transmission, this value only counts for one round. + */ + size_t num_symbols; +} rmt_tx_done_event_data_t; + +/** + * @brief Prototype of RMT event callback + * @param tx_chan RMT channel handle, created from `rmt_new_tx_channel()` + * @param edata Point to RMT event data. The lifecycle of this pointer memory is inside this + * function, user should copy it into static memory if used outside this function. + * @param user_ctx User registered context, passed from `rmt_tx_register_event_callbacks()` + * + * @return Whether a high priority task has been waken up by this callback function + */ +typedef bool (*rmt_tx_done_callback_t)(rmt_channel_handle_t tx_chan, + const rmt_tx_done_event_data_t *edata, void *user_ctx); + +/** + * @brief Type of RMT RX done event data + */ +typedef struct { + /** Point to the received RMT symbols */ + rmt_symbol_word_t *received_symbols; + /** The number of received RMT symbols */ + size_t num_symbols; + /** Extra flags */ + struct { + /** Indicating if the current received data are the last part of the transaction */ + uint32_t is_last: 1; + } flags; +} rmt_rx_done_event_data_t; + +/** + * @brief Prototype of RMT event callback + * + * @param rx_chan RMT channel handle, created from `rmt_new_rx_channel()` + * @param edata Point to RMT event data. The lifecycle of this pointer memory is inside this + * function, user should copy it into static memory if used outside this function. + * @param user_ctx User registered context, passed from `rmt_rx_register_event_callbacks()` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*rmt_rx_done_callback_t)(rmt_channel_handle_t rx_chan, + const rmt_rx_done_event_data_t *edata, void *user_ctx); + +/** + * @brief RMT carrier wave configuration (for either modulation or demodulation) + */ +typedef struct { + /** Carrier wave frequency, in Hz, 0 means disabling the carrier */ + uint32_t frequency_hz; + /** Carrier wave duty cycle (0~100% by step of 0.1%) */ + uint16_t duty_cycle; + /** Carrier config flags */ + struct { + /** Specify the polarity of carrier, by default it's modulated to base signal's + * high level + */ + uint32_t polarity_active_low: 1; + /** If set, the carrier can always exist even there's not transfer undergoing */ + uint32_t always_on: 1; + } flags; +} rmt_carrier_config_t; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_DRIVERS_MISC_ESPRESSIF_RMT_RMT_TYPES_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32-pinctrl.h index 50bb625d77fe7..1142e962a2a50 100644 --- a/include/zephyr/dt-bindings/pinctrl/esp32-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/esp32-pinctrl.h @@ -3716,6 +3716,742 @@ #define PCNT7_CH1SIG_GPIO39 ESP32_PINMUX(39, ESP_PCNT_SIG_CH1_IN7, ESP_NOSIG) /** @} */ +/** + * @name RMT_IN0 + * @{ + */ +#define RMT_IN0_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN0, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN1 + * @{ + */ +#define RMT_IN1_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN1, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN2 + * @{ + */ +#define RMT_IN2_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN2, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN3 + * @{ + */ +#define RMT_IN3_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN3, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN4 + * @{ + */ +#define RMT_IN4_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN4, ESP_NOSIG) +#define RMT_IN4_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN4, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN5 + * @{ + */ +#define RMT_IN5_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN5, ESP_NOSIG) +#define RMT_IN5_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN5, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN6 + * @{ + */ +#define RMT_IN6_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN6, ESP_NOSIG) +#define RMT_IN6_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN6, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN7 + * @{ + */ +#define RMT_IN7_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN7, ESP_NOSIG) +#define RMT_IN7_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN7, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_OUT0 + * @{ + */ +#define RMT_OUT0_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT0) +/** @} */ + +/** + * @name RMT_OUT1 + * @{ + */ +#define RMT_OUT1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT1) +/** @} */ + +/** + * @name RMT_OUT2 + * @{ + */ +#define RMT_OUT2_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT2) +/** @} */ + +/** + * @name RMT_OUT3 + * @{ + */ +#define RMT_OUT3_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT3) +/** @} */ + +/** + * @name RMT_OUT4 + * @{ + */ +#define RMT_OUT4_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT4) +#define RMT_OUT4_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT4) +/** @} */ + +/** + * @name RMT_OUT5 + * @{ + */ +#define RMT_OUT5_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT5) +#define RMT_OUT5_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT5) +/** @} */ + +/** + * @name RMT_OUT6 + * @{ + */ +#define RMT_OUT6_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT6) +#define RMT_OUT6_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT6) +/** @} */ + +/** + * @name RMT_OUT7 + * @{ + */ +#define RMT_OUT7_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT7) +#define RMT_OUT7_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT7) +/** @} */ + /** * @name SDHC0_CD * @{ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32c3-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32c3-pinctrl.h index 9de9b75e60383..11df586ab86e4 100644 --- a/include/zephyr/dt-bindings/pinctrl/esp32c3-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/esp32c3-pinctrl.h @@ -472,6 +472,118 @@ #define LEDC_CH5_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) /** @} */ +/** + * @name RMT_IN0 + * @{ + */ +#define RMT_IN0_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN0, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN1 + * @{ + */ +#define RMT_IN1_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN1, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_OUT0 + * @{ + */ +#define RMT_OUT0_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT0) +/** @} */ + +/** + * @name RMT_OUT1 + * @{ + */ +#define RMT_OUT1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT1) +/** @} */ + /** * @name SPIM2_CSEL * @{ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h index 0e8c11585d5a4..30076ca1b25e4 100644 --- a/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h @@ -1432,6 +1432,126 @@ #define PCNT3_CH1SIG_GPIO23 ESP32_PINMUX(23, ESP_PCNT_SIG_CH1_IN3, ESP_NOSIG) /** @} */ +/** + * @name RMT_IN0 + * @{ + */ +#define RMT_IN0_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN0, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN1 + * @{ + */ +#define RMT_IN1_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN1, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_OUT0 + * @{ + */ +#define RMT_OUT0_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT0) +/** @} */ + +/** + * @name RMT_OUT1 + * @{ + */ +#define RMT_OUT1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT1) +/** @} */ + /** * @name SPIM2_CSEL * @{ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h index 77de197d04476..41252cb72ab7b 100644 --- a/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/esp32h2-pinctrl.h @@ -1252,6 +1252,142 @@ #define PCNT3_CH1SIG_GPIO27 ESP32_PINMUX(27, ESP_PCNT_SIG_CH1_IN3, ESP_NOSIG) /** @} */ +/** + * @name RMT_IN0 + * @{ + */ +#define RMT_IN0_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN0, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN1 + * @{ + */ +#define RMT_IN1_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN1, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_OUT0 + * @{ + */ +#define RMT_OUT0_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT0) +/** @} */ + +/** + * @name RMT_OUT1 + * @{ + */ +#define RMT_OUT1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT1) +/** @} */ + /** * @name SPIM2_CSEL * @{ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32s2-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32s2-pinctrl.h index 32060a0e2d0f7..8f618c03dcd66 100644 --- a/include/zephyr/dt-bindings/pinctrl/esp32s2-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/esp32s2-pinctrl.h @@ -1754,6 +1754,430 @@ #define PCNT3_CH1SIG_GPIO46 ESP32_PINMUX(46, ESP_PCNT_SIG_CH1_IN3, ESP_NOSIG) /** @} */ +/** + * @name RMT_IN0 + * @{ + */ +#define RMT_IN0_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN0, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN1 + * @{ + */ +#define RMT_IN1_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN1, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN2 + * @{ + */ +#define RMT_IN2_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN2, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN3 + * @{ + */ +#define RMT_IN3_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN3, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_OUT0 + * @{ + */ +#define RMT_OUT0_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT0) +/** @} */ + +/** + * @name RMT_OUT1 + * @{ + */ +#define RMT_OUT1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT1) +/** @} */ + +/** + * @name RMT_OUT2 + * @{ + */ +#define RMT_OUT2_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT2) +/** @} */ + +/** + * @name RMT_OUT3 + * @{ + */ +#define RMT_OUT3_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT3) +/** @} */ + /** * @name SPIM2_CSEL * @{ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32s3-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32s3-pinctrl.h index 8b0094e85b949..a89cc9a770227 100644 --- a/include/zephyr/dt-bindings/pinctrl/esp32s3-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/esp32s3-pinctrl.h @@ -5866,6 +5866,446 @@ #define PCNT3_CH1SIG_GPIO48 ESP32_PINMUX(48, ESP_PCNT_SIG_CH1_IN3, ESP_NOSIG) /** @} */ +/** + * @name RMT_IN0 + * @{ + */ +#define RMT_IN0_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO47 ESP32_PINMUX(47, ESP_RMT_SIG_IN0, ESP_NOSIG) +#define RMT_IN0_GPIO48 ESP32_PINMUX(48, ESP_RMT_SIG_IN0, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN1 + * @{ + */ +#define RMT_IN1_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO47 ESP32_PINMUX(47, ESP_RMT_SIG_IN1, ESP_NOSIG) +#define RMT_IN1_GPIO48 ESP32_PINMUX(48, ESP_RMT_SIG_IN1, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN2 + * @{ + */ +#define RMT_IN2_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO47 ESP32_PINMUX(47, ESP_RMT_SIG_IN2, ESP_NOSIG) +#define RMT_IN2_GPIO48 ESP32_PINMUX(48, ESP_RMT_SIG_IN2, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_IN3 + * @{ + */ +#define RMT_IN3_GPIO0 ESP32_PINMUX(0, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO1 ESP32_PINMUX(1, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO2 ESP32_PINMUX(2, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO3 ESP32_PINMUX(3, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO4 ESP32_PINMUX(4, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO5 ESP32_PINMUX(5, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO6 ESP32_PINMUX(6, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO7 ESP32_PINMUX(7, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO8 ESP32_PINMUX(8, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO9 ESP32_PINMUX(9, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO10 ESP32_PINMUX(10, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO11 ESP32_PINMUX(11, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO12 ESP32_PINMUX(12, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO13 ESP32_PINMUX(13, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO14 ESP32_PINMUX(14, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO15 ESP32_PINMUX(15, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO16 ESP32_PINMUX(16, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO17 ESP32_PINMUX(17, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO18 ESP32_PINMUX(18, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO19 ESP32_PINMUX(19, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO20 ESP32_PINMUX(20, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO21 ESP32_PINMUX(21, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO22 ESP32_PINMUX(22, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO23 ESP32_PINMUX(23, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO24 ESP32_PINMUX(24, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO25 ESP32_PINMUX(25, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO26 ESP32_PINMUX(26, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO27 ESP32_PINMUX(27, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO28 ESP32_PINMUX(28, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO29 ESP32_PINMUX(29, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO30 ESP32_PINMUX(30, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO31 ESP32_PINMUX(31, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO32 ESP32_PINMUX(32, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO33 ESP32_PINMUX(33, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO34 ESP32_PINMUX(34, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO35 ESP32_PINMUX(35, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO36 ESP32_PINMUX(36, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO37 ESP32_PINMUX(37, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO38 ESP32_PINMUX(38, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO39 ESP32_PINMUX(39, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO40 ESP32_PINMUX(40, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO41 ESP32_PINMUX(41, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO42 ESP32_PINMUX(42, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO43 ESP32_PINMUX(43, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO44 ESP32_PINMUX(44, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO45 ESP32_PINMUX(45, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO46 ESP32_PINMUX(46, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO47 ESP32_PINMUX(47, ESP_RMT_SIG_IN3, ESP_NOSIG) +#define RMT_IN3_GPIO48 ESP32_PINMUX(48, ESP_RMT_SIG_IN3, ESP_NOSIG) +/** @} */ + +/** + * @name RMT_OUT0 + * @{ + */ +#define RMT_OUT0_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO47 ESP32_PINMUX(47, ESP_NOSIG, ESP_RMT_SIG_OUT0) +#define RMT_OUT0_GPIO48 ESP32_PINMUX(48, ESP_NOSIG, ESP_RMT_SIG_OUT0) +/** @} */ + +/** + * @name RMT_OUT1 + * @{ + */ +#define RMT_OUT1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO47 ESP32_PINMUX(47, ESP_NOSIG, ESP_RMT_SIG_OUT1) +#define RMT_OUT1_GPIO48 ESP32_PINMUX(48, ESP_NOSIG, ESP_RMT_SIG_OUT1) +/** @} */ + +/** + * @name RMT_OUT2 + * @{ + */ +#define RMT_OUT2_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO47 ESP32_PINMUX(47, ESP_NOSIG, ESP_RMT_SIG_OUT2) +#define RMT_OUT2_GPIO48 ESP32_PINMUX(48, ESP_NOSIG, ESP_RMT_SIG_OUT2) +/** @} */ + +/** + * @name RMT_OUT3 + * @{ + */ +#define RMT_OUT3_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO24 ESP32_PINMUX(24, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO25 ESP32_PINMUX(25, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO26 ESP32_PINMUX(26, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO27 ESP32_PINMUX(27, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO28 ESP32_PINMUX(28, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO29 ESP32_PINMUX(29, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO30 ESP32_PINMUX(30, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO31 ESP32_PINMUX(31, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO32 ESP32_PINMUX(32, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO33 ESP32_PINMUX(33, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO34 ESP32_PINMUX(34, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO35 ESP32_PINMUX(35, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO36 ESP32_PINMUX(36, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO37 ESP32_PINMUX(37, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO38 ESP32_PINMUX(38, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO39 ESP32_PINMUX(39, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO40 ESP32_PINMUX(40, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO41 ESP32_PINMUX(41, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO42 ESP32_PINMUX(42, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO44 ESP32_PINMUX(44, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO45 ESP32_PINMUX(45, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO46 ESP32_PINMUX(46, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO47 ESP32_PINMUX(47, ESP_NOSIG, ESP_RMT_SIG_OUT3) +#define RMT_OUT3_GPIO48 ESP32_PINMUX(48, ESP_NOSIG, ESP_RMT_SIG_OUT3) +/** @} */ + /** * @name SDHC0_CD * @{ diff --git a/samples/drivers/misc/espressif_rmt/README.rst b/samples/drivers/misc/espressif_rmt/README.rst new file mode 100644 index 0000000000000..dbbaaa653e54a --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/README.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: espressif_rmt + :name: Espressif RMT + :show-listing: + + These samples demonstrate how to use the Espressif RMT driver API. diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/CMakeLists.txt b/samples/drivers/misc/espressif_rmt/bytes_encoder/CMakeLists.txt new file mode 100644 index 0000000000000..ffac1c4ebe2a8 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(espressif_rmt) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/README.rst b/samples/drivers/misc/espressif_rmt/bytes_encoder/README.rst new file mode 100644 index 0000000000000..43651e8ecb2fe --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/README.rst @@ -0,0 +1,51 @@ +.. zephyr:code-sample:: espressif_rmt_bytes_encoder + :name: Espressif RMT with bytes encoder + :relevant-api: espressif_rmt + + Espressif RMT loopback application to demonstrate API usage with bytes encoder. + +Overview +******** + +This sample sends a RMT signal on one pin and read it back on another pin using Espressif RMT and bytes encoder. +Demonstration is done with and without DMA support. + +Requirements +************ + +To use this sample, an ESP32 DevKitC/M supporting RMT is required. + +Wiring +****** + +Pins 13 (Tx) and 12 (Rx) of the board must be connected together to establish the loopback. + +Building and Running +******************** + +To build the sample on ESP32-S3-DevKitC: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/misc/espressif_rmt/bytes_encoder + :board: esp32s3_devkitc/esp32s3/procpu + :goals: flash + :compact: + +The following logs will be available: + +.. code-block:: console + + Enable RMT RX channel + Enable RMT TX channel + RMT TX value 0x00 + RMT RX value 0x00 + RMT TX value 0x01 + RMT RX value 0x01 + RMT TX value 0x02 + RMT RX value 0x02 + RMT TX value 0x03 + RMT RX value 0x03 + RMT TX value 0x04 + RMT RX value 0x04 + +.. _Espressif RMT: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/rmt.html diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32_devkitc_procpu.overlay b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32_devkitc_procpu.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32_devkitc_procpu.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32c3_devkitc.overlay b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32c3_devkitc.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32c3_devkitc.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32c6_devkitc_hpcore.overlay b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32c6_devkitc_hpcore.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32c6_devkitc_hpcore.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32h2_devkitm.overlay b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32h2_devkitm.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32h2_devkitm.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32s2_devkitc.overlay b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32s2_devkitc.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32s2_devkitc.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32s3_devkitc_procpu.overlay b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32s3_devkitc_procpu.overlay new file mode 100644 index 0000000000000..04d3c59e9cae1 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/boards/esp32s3_devkitc_procpu.overlay @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + dmas = <&dma 8>, <&dma 9>; + dma-names = "rx", "tx"; + status = "okay"; +}; + +&dma { + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/prj.conf b/samples/drivers/misc/espressif_rmt/bytes_encoder/prj.conf new file mode 100644 index 0000000000000..b2a4ba591044e --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/sample.yaml b/samples/drivers/misc/espressif_rmt/bytes_encoder/sample.yaml new file mode 100644 index 0000000000000..774035a3ff54d --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/sample.yaml @@ -0,0 +1,13 @@ +sample: + name: espressif_rmt +tests: + sample.drivers.misc.espressif_rmt.bytes_encoder: + platform_allow: + - esp32_devkitc/esp32/procpu + - esp32c3_devkitc/esp32c3 + - esp32c6_devkitc/esp32c6/hpcore + - esp32h2_devkitm/esp32h2 + - esp32s2_devkitc/esp32s2 + - esp32s3_devkitc/esp32s3/procpu + tags: + - drivers diff --git a/samples/drivers/misc/espressif_rmt/bytes_encoder/src/main.c b/samples/drivers/misc/espressif_rmt/bytes_encoder/src/main.c new file mode 100644 index 0000000000000..52f1afa5e371c --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/bytes_encoder/src/main.c @@ -0,0 +1,329 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Sample application for Espressif RMT. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RMT_NODE DT_NODELABEL(rmt) + +static const struct device *rmt_dev = DEVICE_DT_GET(RMT_NODE); + +/* Set the number of block symbol */ +#define MEM_BLOCK_SYMBOL (64) + +/* 10MHz resolution, 1 tick = 0.1us */ +#define RESOLUTION_HZ (10000000) + +/* Set the number of transactions that can be pending in the background */ +#define TRANS_QUEUE_DEPTH (4) + +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; +} rmt_example_encoder_t; + +rmt_tx_channel_config_t tx_chan_config; +rmt_rx_channel_config_t rx_chan_config; +rmt_channel_handle_t tx_chan; +rmt_channel_handle_t rx_chan; + +rmt_encoder_handle_t tx_encoder; + +rmt_symbol_word_t raw_symbols[64]; +rmt_receive_config_t receive_config = { + .signal_range_min_ns = 125, + .signal_range_max_ns = 2500000, +}; + +static size_t example_encoder_encode(rmt_encoder_t *encoder, + rmt_channel_handle_t channel, const void *primary_data, size_t data_size, + rmt_encode_state_t *ret_state) +{ + rmt_example_encoder_t *example_encoder = + __containerof(encoder, rmt_example_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = example_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = example_encoder->copy_encoder; + rmt_encode_state_t session_state = RMT_ENCODING_RESET; + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t encoded_symbols = 0; + + switch (example_encoder->state) { + case 0: /* send data */ + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, + data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + /* switch to next state when current encoding session finished */ + example_encoder->state = 1; + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; /* yield if there's no free space for encoding artifacts */ + } + /* fall-through */ + case 1: /* send reset code */ + encoded_symbols += copy_encoder->encode(copy_encoder, channel, + &example_encoder->reset_code, sizeof(example_encoder->reset_code), + &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + /* back to the initial encoding session */ + example_encoder->state = RMT_ENCODING_RESET; + state |= RMT_ENCODING_COMPLETE; + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; /* yield if there's no free space for encoding artifacts */ + } + break; + default: + break; + } +out: + *ret_state = state; + return encoded_symbols; +} + +static int example_encoder_del(rmt_encoder_t *encoder) +{ + rmt_example_encoder_t *example_encoder = + __containerof(encoder, rmt_example_encoder_t, base); + + rmt_del_encoder(example_encoder->bytes_encoder); + rmt_del_encoder(example_encoder->copy_encoder); + k_free(example_encoder); + return 0; +} + +static int example_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_example_encoder_t *example_encoder = + __containerof(encoder, rmt_example_encoder_t, base); + + rmt_encoder_reset(example_encoder->bytes_encoder); + rmt_encoder_reset(example_encoder->copy_encoder); + example_encoder->state = RMT_ENCODING_RESET; + return 0; +} + +static int example_encoder_new(rmt_encoder_handle_t *ret_encoder) +{ + rmt_example_encoder_t *example_encoder = NULL; + rmt_copy_encoder_config_t copy_encoder_config; + int rc; + + if (!ret_encoder) { + printk("Invalid argument\n"); + return -EINVAL; + } + example_encoder = rmt_alloc_encoder_mem(sizeof(rmt_example_encoder_t)); + if (!example_encoder) { + printk("Unable to allocate memory for example encoder\n"); + return -ENOMEM; + } + example_encoder->base.encode = example_encoder_encode; + example_encoder->base.del = example_encoder_del; + example_encoder->base.reset = example_encoder_reset; + rmt_bytes_encoder_config_t bytes_encoder_config = { + .bit0 = { + .level0 = 1, + .duration0 = 10 * RESOLUTION_HZ / 1000000, /* T0H=10us */ + .level1 = 0, + .duration1 = 90 * RESOLUTION_HZ / 1000000, /* T0L=90us */ + }, + .bit1 = { + .level0 = 1, + .duration0 = 90 * RESOLUTION_HZ / 1000000, /* T1H=90us */ + .level1 = 0, + .duration1 = 10 * RESOLUTION_HZ / 1000000, /* T1L=10us */ + }, + .flags.msb_first = 1 + }; + rc = rmt_new_bytes_encoder(&bytes_encoder_config, &example_encoder->bytes_encoder); + if (rc) { + printk("Create bytes encoder failed\n"); + goto err; + } + rc = rmt_new_copy_encoder(©_encoder_config, &example_encoder->copy_encoder); + if (rc) { + printk("Create copy encoder failed\n"); + goto err; + } + + /* reset code duration defaults to 500us */ + uint32_t reset_ticks = RESOLUTION_HZ / 1000000 * 500 / 2; + + example_encoder->reset_code = (rmt_symbol_word_t) { + .level0 = 0, + .duration0 = reset_ticks, + .level1 = 0, + .duration1 = reset_ticks, + }; + *ret_encoder = &example_encoder->base; + return 0; + +err: + if (example_encoder) { + if (example_encoder->bytes_encoder) { + rmt_del_encoder(example_encoder->bytes_encoder); + } + if (example_encoder->copy_encoder) { + rmt_del_encoder(example_encoder->copy_encoder); + } + k_free(example_encoder); + } + return rc; +} + +static bool rmt_rx_done_callback(rmt_channel_handle_t channel, + const rmt_rx_done_event_data_t *edata, void *user_data) +{ + uint8_t val = 0; + int rc; + + /* Compute received value */ + if (edata->num_symbols > 0) { + for (int i = 0; i < edata->num_symbols; i++) { + rmt_symbol_word_t symbol = edata->received_symbols[i]; + /* Threshold=50us */ + if (symbol.level0 == 1 + && symbol.duration0 > 50 * RESOLUTION_HZ / 1000000) { + val |= 1 << (edata->num_symbols - i - 1); + } else if (symbol.level1 == 1 + && symbol.duration1 > 50 * RESOLUTION_HZ / 1000000) { + val |= 1 << (edata->num_symbols - i - 1); + } + } + printk("RMT RX value 0x%02x\n", val); + } + + /* Restart reception */ + rc = rmt_receive(channel, raw_symbols, sizeof(raw_symbols), &receive_config); + if (rc) { + printk("Unable to start RMT RX channel\n"); + } + + return false; +} + +int main(void) +{ + const struct espressif_rmt_config *cfg = rmt_dev->config; + uint8_t counter = 0; + void *buffer = &counter; + size_t buf_len = sizeof(uint8_t); + int rc; + + if (!device_is_ready(rmt_dev)) { + printk("Espressif RMT device is not ready\n"); + return -EINVAL; + } + + /* RMT Rx channel configuration */ + rx_chan_config.clk_src = RMT_CLK_SRC_DEFAULT; + rx_chan_config.mem_block_symbols = MEM_BLOCK_SYMBOL; + rx_chan_config.resolution_hz = RESOLUTION_HZ; + rx_chan_config.gpio_pinmux = cfg->pcfg->states[0].pins[1].pinmux; + rc = rmt_new_rx_channel(rmt_dev, &rx_chan_config, &rx_chan); + if (rc) { + printk("RMT RX channel creation failed\n"); + return rc; + } + rmt_rx_event_callbacks_t cbs = { + .on_recv_done = rmt_rx_done_callback, + }; + rc = rmt_rx_register_event_callbacks(rx_chan, &cbs, NULL); + if (rc) { + printk("Unable to register RX callback\n"); + return rc; + } + + /* RMT Tx channel configuration */ + tx_chan_config.clk_src = RMT_CLK_SRC_DEFAULT; + tx_chan_config.mem_block_symbols = MEM_BLOCK_SYMBOL; + tx_chan_config.resolution_hz = RESOLUTION_HZ; + tx_chan_config.trans_queue_depth = TRANS_QUEUE_DEPTH; + tx_chan_config.gpio_pinmux = cfg->pcfg->states[0].pins[0].pinmux; + rc = rmt_new_tx_channel(rmt_dev, &tx_chan_config, &tx_chan); + if (rc) { + printk("RMT TX channel creation failed\n"); + return rc; + } + rc = example_encoder_new(&tx_encoder); + if (rc) { + printk("Unable to create encoder\n"); + return rc; + } + + /* Enable channels */ + printk("Enable RMT RX channel\n"); + rc = rmt_enable(rx_chan); + if (rc) { + printk("Unable to enable RMT RX channel\n"); + return rc; + } + printk("Enable RMT TX channel\n"); + rc = rmt_enable(tx_chan); + if (rc) { + printk("Unable to enable RMT TX channel\n"); + return rc; + } + + /* Start reception */ + rc = rmt_receive(rx_chan, raw_symbols, sizeof(raw_symbols), &receive_config); + if (rc) { + printk("Unable to start RMT RX channel\n"); + return rc; + } + + while (counter < 5) { + + rmt_transmit_config_t tx_config = { + .loop_count = 0, /* no transfer loop */ + }; + + /* Transmit data */ + printk("RMT TX value 0x%02x\n", counter); + rc = rmt_transmit(tx_chan, tx_encoder, buffer, buf_len, &tx_config); + if (rc) { + printk("Unable to transmit data over TX channel\n"); + return rc; + } + rc = rmt_tx_wait_all_done(tx_chan, K_FOREVER); + if (rc) { + printk("Waiting until all done failed\n"); + return rc; + } + + k_sleep(K_MSEC(500)); + + /* Increment counter for next transmission */ + counter++; + } + + /* Disable and delete channels */ + rmt_disable(tx_chan); + rmt_disable(rx_chan); + rmt_del_channel(tx_chan); + rmt_del_channel(rx_chan); + + /* Delete encoder */ + rmt_del_encoder(tx_encoder); + + return 0; +} diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/CMakeLists.txt b/samples/drivers/misc/espressif_rmt/simple_encoder/CMakeLists.txt new file mode 100644 index 0000000000000..ffac1c4ebe2a8 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(espressif_rmt) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/README.rst b/samples/drivers/misc/espressif_rmt/simple_encoder/README.rst new file mode 100644 index 0000000000000..7b8f5c5b94acc --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/README.rst @@ -0,0 +1,51 @@ +.. zephyr:code-sample:: espressif_rmt_simple_encoder + :name: Espressif RMT with simple encoder + :relevant-api: espressif_rmt + + Espressif RMT loopback application to demonstrate API usage with simple encoder. + +Overview +******** + +This sample sends a RMT signal on one pin and read it back on another pin using Espressif RMT and simple encoder. +Demonstration is done with and without DMA support. + +Requirements +************ + +To use this sample, an ESP32 DevKitC/M supporting RMT is required. + +Wiring +****** + +Pins 13 (Tx) and 12 (Rx) of the board must be connected together to establish the loopback. + +Building and Running +******************** + +To build the sample on ESP32-S3-DevKitC: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/misc/espressif_rmt/simple_encoder + :board: esp32s3_devkitc/esp32s3/procpu + :goals: flash + :compact: + +The following logs will be available: + +.. code-block:: console + + Enable RMT RX channel + Enable RMT TX channel + RMT TX value 0x00 + RMT RX value 0x00 + RMT TX value 0x01 + RMT RX value 0x01 + RMT TX value 0x02 + RMT RX value 0x02 + RMT TX value 0x03 + RMT RX value 0x03 + RMT TX value 0x04 + RMT RX value 0x04 + +.. _Espressif RMT: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/rmt.html diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32_devkitc_procpu.overlay b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32_devkitc_procpu.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32_devkitc_procpu.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32c3_devkitc.overlay b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32c3_devkitc.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32c3_devkitc.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32c6_devkitc_hpcore.overlay b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32c6_devkitc_hpcore.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32c6_devkitc_hpcore.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32h2_devkitm.overlay b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32h2_devkitm.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32h2_devkitm.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32s2_devkitc.overlay b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32s2_devkitc.overlay new file mode 100644 index 0000000000000..5127516d1f8c5 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32s2_devkitc.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32s3_devkitc_procpu.overlay b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32s3_devkitc_procpu.overlay new file mode 100644 index 0000000000000..04d3c59e9cae1 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/boards/esp32s3_devkitc_procpu.overlay @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rmt { + pinctrl-0 = <&rmt_default>; + pinctrl-names = "default"; + dmas = <&dma 8>, <&dma 9>; + dma-names = "rx", "tx"; + status = "okay"; +}; + +&dma { + status = "okay"; +}; diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/prj.conf b/samples/drivers/misc/espressif_rmt/simple_encoder/prj.conf new file mode 100644 index 0000000000000..b2a4ba591044e --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/sample.yaml b/samples/drivers/misc/espressif_rmt/simple_encoder/sample.yaml new file mode 100644 index 0000000000000..063f162577c54 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/sample.yaml @@ -0,0 +1,13 @@ +sample: + name: espressif_rmt +tests: + sample.drivers.misc.espressif_rmt.simple_encoder: + platform_allow: + - esp32_devkitc/esp32/procpu + - esp32c3_devkitc/esp32c3 + - esp32c6_devkitc/esp32c6/hpcore + - esp32h2_devkitm/esp32h2 + - esp32s2_devkitc/esp32s2 + - esp32s3_devkitc/esp32s3/procpu + tags: + - drivers diff --git a/samples/drivers/misc/espressif_rmt/simple_encoder/src/main.c b/samples/drivers/misc/espressif_rmt/simple_encoder/src/main.c new file mode 100644 index 0000000000000..5e61b91c534b2 --- /dev/null +++ b/samples/drivers/misc/espressif_rmt/simple_encoder/src/main.c @@ -0,0 +1,269 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Sample application for Espressif RMT. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RMT_NODE DT_NODELABEL(rmt) + +static const struct device *rmt_dev = DEVICE_DT_GET(RMT_NODE); + +/* Set the number of block symbol */ +#define MEM_BLOCK_SYMBOL (64) + +/* 10MHz resolution, 1 tick = 0.1us */ +#define RESOLUTION_HZ (10000000) + +/* Set the number of transactions that can be pending in the background */ +#define TRANS_QUEUE_DEPTH (4) + +rmt_tx_channel_config_t tx_chan_config; +rmt_rx_channel_config_t rx_chan_config; +rmt_channel_handle_t tx_chan; +rmt_channel_handle_t rx_chan; + +rmt_encoder_handle_t tx_encoder; + +rmt_symbol_word_t raw_symbols[64]; +rmt_receive_config_t receive_config = { + .signal_range_min_ns = 125, + .signal_range_max_ns = 2500000, +}; + +static const rmt_symbol_word_t symbol_zero = { + .level0 = 1, + .duration0 = 10 * RESOLUTION_HZ / 1000000, /* T0H=10us */ + .level1 = 0, + .duration1 = 90 * RESOLUTION_HZ / 1000000, /* T0L=90us */ +}; + +static const rmt_symbol_word_t symbol_one = { + .level0 = 1, + .duration0 = 90 * RESOLUTION_HZ / 1000000, /* T0L=90us */ + .level1 = 0, + .duration1 = 10 * RESOLUTION_HZ / 1000000, /* T0H=10us */ +}; + +/* reset code duration defaults to 500us */ +static const rmt_symbol_word_t symbol_reset = { + .level0 = 0, + .duration0 = RESOLUTION_HZ / 1000000 * 500 / 2, + .level1 = 0, + .duration1 = RESOLUTION_HZ / 1000000 * 500 / 2, +}; + +static size_t encoder_callback(const void *data, size_t data_size, size_t symbols_written, + size_t symbols_free, rmt_symbol_word_t *symbols, bool *done, void *arg) +{ + size_t data_pos = symbols_written / 8; + uint8_t *data_bytes = (uint8_t *)data; + size_t symbol_pos = 0; + + /* + * We need a minimum of 8 symbol spaces to encode a byte. We only + * need one to encode a reset, but it's simpler to simply demand that + * there are 8 symbol spaces free to write anything. + */ + if (symbols_free < 8) { + return 0; + } + + /* + * We can calculate where in the data we are from the symbol pos. + * Alternatively, we could use some counter referenced by the arg + * parameter to keep track of this. + */ + if (data_pos < data_size) { + /* Encode a byte */ + for (int bitmask = 0x80; bitmask != 0; bitmask >>= 1) { + if (data_bytes[data_pos] & bitmask) { + symbols[symbol_pos++] = symbol_one; + } else { + symbols[symbol_pos++] = symbol_zero; + } + } + /* We're done; we should have written 8 symbols. */ + return symbol_pos; + } + + /* + * All bytes already are encoded. + * Encode the reset, and we're done. + */ + symbols[0] = symbol_reset; + *done = 1; /* Indicate end of the transaction. */ + return 1; /* We only wrote one symbol */ +} + +static int example_encoder_new(rmt_encoder_handle_t *ret_encoder) +{ + rmt_simple_encoder_config_t simple_encoder_config; + int rc; + + if (!ret_encoder) { + printk("Invalid argument\n"); + return -EINVAL; + } + simple_encoder_config.callback = encoder_callback; + simple_encoder_config.arg = NULL; + simple_encoder_config.min_chunk_size = 64; + rc = rmt_new_simple_encoder(&simple_encoder_config, ret_encoder); + if (rc) { + printk("Create simple encoder failed %d\n", rc); + return rc; + } + + return 0; +} + +static bool rmt_rx_done_callback(rmt_channel_handle_t channel, + const rmt_rx_done_event_data_t *edata, void *user_data) +{ + uint8_t val = 0; + int rc; + + /* Compute received value */ + if (edata->num_symbols > 0) { + for (int i = 0; i < edata->num_symbols; i++) { + rmt_symbol_word_t symbol = edata->received_symbols[i]; + /* Threshold=50us */ + if (symbol.level0 == 1 + && symbol.duration0 > 50 * RESOLUTION_HZ / 1000000) { + val |= 1 << (edata->num_symbols - i - 1); + } else if (symbol.level1 == 1 + && symbol.duration1 > 50 * RESOLUTION_HZ / 1000000) { + val |= 1 << (edata->num_symbols - i - 1); + } + } + printk("RMT RX value 0x%02x\n", val); + } + + /* Restart reception */ + rc = rmt_receive(channel, raw_symbols, sizeof(raw_symbols), &receive_config); + if (rc) { + printk("Unable to start RMT RX channel\n"); + } + + return false; +} + +int main(void) +{ + const struct espressif_rmt_config *cfg = rmt_dev->config; + uint8_t counter = 0; + void *buffer = &counter; + size_t buf_len = sizeof(uint8_t); + int rc; + + if (!device_is_ready(rmt_dev)) { + printk("Espressif RMT device is not ready\n"); + return -EINVAL; + } + + /* RMT Rx channel configuration */ + rx_chan_config.clk_src = RMT_CLK_SRC_DEFAULT; + rx_chan_config.mem_block_symbols = MEM_BLOCK_SYMBOL; + rx_chan_config.resolution_hz = RESOLUTION_HZ; + rx_chan_config.gpio_pinmux = cfg->pcfg->states[0].pins[1].pinmux; + rc = rmt_new_rx_channel(rmt_dev, &rx_chan_config, &rx_chan); + if (rc) { + printk("RMT RX channel creation failed\n"); + return rc; + } + rmt_rx_event_callbacks_t cbs = { + .on_recv_done = rmt_rx_done_callback, + }; + rc = rmt_rx_register_event_callbacks(rx_chan, &cbs, NULL); + if (rc) { + printk("Unable to register RX callback\n"); + return rc; + } + + /* RMT Tx channel configuration */ + tx_chan_config.clk_src = RMT_CLK_SRC_DEFAULT; + tx_chan_config.mem_block_symbols = MEM_BLOCK_SYMBOL; + tx_chan_config.resolution_hz = RESOLUTION_HZ; + tx_chan_config.trans_queue_depth = TRANS_QUEUE_DEPTH; + tx_chan_config.gpio_pinmux = cfg->pcfg->states[0].pins[0].pinmux; + rc = rmt_new_tx_channel(rmt_dev, &tx_chan_config, &tx_chan); + if (rc) { + printk("RMT TX channel creation failed\n"); + return rc; + } + rc = example_encoder_new(&tx_encoder); + if (rc) { + printk("Unable to create encoder\n"); + return rc; + } + + /* Enable channels */ + printk("Enable RMT RX channel\n"); + rc = rmt_enable(rx_chan); + if (rc) { + printk("Unable to enable RMT RX channel\n"); + return rc; + } + printk("Enable RMT TX channel\n"); + rc = rmt_enable(tx_chan); + if (rc) { + printk("Unable to enable RMT TX channel\n"); + return rc; + } + + /* Start reception */ + rc = rmt_receive(rx_chan, raw_symbols, sizeof(raw_symbols), &receive_config); + if (rc) { + printk("Unable to start RMT RX channel\n"); + return rc; + } + + while (counter < 5) { + + rmt_transmit_config_t tx_config = { + .loop_count = 0, /* no transfer loop */ + }; + + /* Transmit data */ + printk("RMT TX value 0x%02x\n", counter); + rc = rmt_transmit(tx_chan, tx_encoder, buffer, buf_len, &tx_config); + if (rc) { + printk("Unable to transmit data over TX channel\n"); + return rc; + } + rc = rmt_tx_wait_all_done(tx_chan, K_FOREVER); + if (rc) { + printk("Waiting until all done failed\n"); + return rc; + } + + k_sleep(K_MSEC(500)); + + /* Increment counter for next transmission */ + counter++; + } + + /* Disable and delete channels */ + rmt_disable(tx_chan); + rmt_disable(rx_chan); + rmt_del_channel(tx_chan); + rmt_del_channel(rx_chan); + + /* Delete encoder */ + rmt_del_encoder(tx_encoder); + + return 0; +} diff --git a/west.yml b/west.yml index f6c201d593893..0b9e258999e5a 100644 --- a/west.yml +++ b/west.yml @@ -172,7 +172,7 @@ manifest: groups: - hal - name: hal_espressif - revision: d73843b864463def35d99b29e61001874151d8a6 + revision: pull/510/head path: modules/hal/espressif west-commands: west/west-commands.yml groups: