This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 7b590f9c4352e6d94acdf8e50b903b9482fb8a1b Author: Piyush Patle <[email protected]> AuthorDate: Tue Mar 31 03:21:46 2026 +0530 espressif/rmt: replace rmtchar with arch-specific lirc adapter Replace the ESP-specific rmtchar upper-half with arch-local esp_lirc adapters for Xtensa and RISC-V. This moves the RMT upper-half out of drivers/rmt, registers LIRC devices from the ESP board bring-up paths, and removes the old common rmtchar driver and headers. Also update the ESP Kconfig and build wiring to build esp_lirc when ESP_RMT and DRIVERS_RC are enabled. Fixes discovered during hardware validation: - register TX as /dev/lirc1 so RX and TX do not collide - parse the RX worker thread argument from the correct argv slot - keep RX devices from advertising TX capability Signed-off-by: Piyush Patle <[email protected]> --- arch/risc-v/src/common/espressif/Kconfig | 13 +- arch/risc-v/src/common/espressif/Make.defs | 3 + arch/risc-v/src/common/espressif/esp_lirc.c | 399 +++++++++++++++++++ arch/risc-v/src/common/espressif/esp_lirc.h | 48 +++ arch/risc-v/src/common/espressif/esp_rmt.c | 1 - arch/risc-v/src/common/espressif/esp_rmt.h | 32 ++ arch/risc-v/src/common/espressif/esp_ws2812.c | 1 - arch/xtensa/src/common/espressif/Kconfig | 13 +- arch/xtensa/src/common/espressif/Make.defs | 3 + arch/xtensa/src/common/espressif/esp_lirc.c | 441 +++++++++++++++++++++ arch/xtensa/src/common/espressif/esp_lirc.h | 56 +++ arch/xtensa/src/common/espressif/esp_rmt.c | 1 - arch/xtensa/src/common/espressif/esp_rmt.h | 32 ++ arch/xtensa/src/common/espressif/esp_ws2812.c | 1 - boards/risc-v/esp32c3/common/src/esp_board_rmt.c | 18 +- .../esp32c3/esp32c3-devkit/configs/rmt/defconfig | 8 +- boards/risc-v/esp32c6/common/src/esp_board_rmt.c | 18 +- .../esp32c6/esp32c6-devkitc/configs/rmt/defconfig | 8 +- .../esp32c6/esp32c6-devkitm/configs/rmt/defconfig | 8 +- boards/risc-v/esp32h2/common/src/esp_board_rmt.c | 18 +- .../esp32h2/esp32h2-devkit/configs/rmt/defconfig | 8 +- boards/risc-v/esp32p4/common/src/esp_board_rmt.c | 18 +- .../configs/rmt/defconfig | 8 +- boards/xtensa/esp32/common/src/esp32_board_rmt.c | 19 +- .../esp32/esp32-devkitc/configs/rmt/defconfig | 7 +- .../xtensa/esp32s2/common/src/esp32s2_board_rmt.c | 10 +- .../esp32s2/esp32s2-saola-1/configs/rmt/defconfig | 7 +- .../xtensa/esp32s3/common/src/esp32s3_board_rmt.c | 18 +- .../esp32s3/esp32s3-devkit/configs/rmt/defconfig | 8 +- drivers/Kconfig | 1 - drivers/rmt/CMakeLists.txt | 10 +- drivers/rmt/Kconfig | 43 -- drivers/rmt/Make.defs | 11 - drivers/rmt/rmtchar.c | 341 ---------------- include/nuttx/rmt/rmt.h | 98 ----- include/nuttx/rmt/rmtchar.h | 94 ----- 36 files changed, 1124 insertions(+), 699 deletions(-) diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index 2c888d55f1b..b09c4674268 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -1288,13 +1288,24 @@ config ESPRESSIF_BROWNOUT_DET config ESP_RMT bool "Remote Control Module (RMT)" default n - depends on RMT + select DRIVERS_RC ---help--- 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. +if ESP_RMT + +config RMT_DEFAULT_RX_BUFFER_SIZE + int "Default RX buffer size" + default 100 + ---help--- + The RMT RX default buffer size. This is the expected buffer size + that should be returned on a receive operation. + +endif # ESP_RMT + config ESP_SDM bool "Sigma-Delta Modulation (SDM) Module" default n diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index 9a204c4d7df..84c7ae7b30d 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -94,6 +94,9 @@ endif ifeq ($(CONFIG_ESP_RMT),y) CHIP_CSRCS += esp_rmt.c + ifeq ($(CONFIG_DRIVERS_RC),y) + CHIP_CSRCS += esp_lirc.c + endif ifeq ($(CONFIG_WS2812_NON_SPI_DRIVER),y) CHIP_CSRCS += esp_ws2812.c endif diff --git a/arch/risc-v/src/common/espressif/esp_lirc.c b/arch/risc-v/src/common/espressif/esp_lirc.c new file mode 100644 index 00000000000..51c7198f42d --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_lirc.c @@ -0,0 +1,399 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_lirc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <nuttx/circbuf.h> +#include <nuttx/kmalloc.h> +#include <nuttx/kthread.h> +#include <nuttx/lirc.h> +#include <nuttx/rc/lirc_dev.h> +#include <nuttx/semaphore.h> + +#include "hal/rmt_types.h" + +#include "esp_rmt.h" +#include "esp_lirc.h" + +#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RMT channel clock: 10 MHz → 1 tick = 0.1 µs */ + +#define RMT_TICK_TO_US(t) ((t) / 10) +#define RMT_US_TO_TICK(u) ((u) * 10) + +/* DMA receive scratch buffer size (in bytes, must be multiple of 4) */ + +#define LIRC_RX_BUF_BYTES CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE + +/* Stack size for the RX worker thread */ + +#define LIRC_RX_THREAD_STACK 2048 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct esp_lirc_dev_s +{ + struct lirc_lowerhalf_s lower; /* Must be first — lirc upper-half iface */ + FAR struct rmt_dev_s *rmt; /* ESP RMT lower-half */ + volatile bool running; /* RX thread keep-alive flag */ + pid_t rxpid; /* RX worker thread PID */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int esp_lirc_open(FAR struct lirc_lowerhalf_s *lower); +static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower); +static int esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower, + FAR unsigned int *txbuf, unsigned int n); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct lirc_ops_s g_esp_lirc_rx_ops = +{ + .driver_type = LIRC_DRIVER_IR_RAW, + .open = esp_lirc_open, + .close = esp_lirc_close, +}; + +static const struct lirc_ops_s g_esp_lirc_tx_ops = +{ + .driver_type = LIRC_DRIVER_IR_RAW_TX, + .open = esp_lirc_open, + .close = esp_lirc_close, + .tx_ir = esp_lirc_tx_ir, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_lirc_rx_thread + ****************************************************************************/ + +static int esp_lirc_rx_thread(int argc, FAR char *argv[]) +{ + FAR struct esp_lirc_dev_s *priv; + FAR const char *arg; + FAR char *rxbuf; + FAR rmt_symbol_word_t *sym; + unsigned int sample; + int nbytes; + int nsyms; + int i; + + DEBUGASSERT(argc >= 2 && argv[argc - 1] != NULL); + + arg = argv[argc - 1]; + priv = (FAR struct esp_lirc_dev_s *)(uintptr_t)strtoul(arg, NULL, 16); + + rxbuf = kmm_malloc(LIRC_RX_BUF_BYTES); + if (rxbuf == NULL) + { + rcerr("ERROR: out of memory for RX buffer\n"); + return -ENOMEM; + } + + while (priv->running) + { + if (priv->rmt->ops->read) + { + priv->rmt->ops->read(priv->rmt, rxbuf, LIRC_RX_BUF_BYTES); + } + + nxsem_wait_uninterruptible(priv->rmt->recvsem); + + if (!priv->running) + { + break; + } + + while ((nbytes = circbuf_read(priv->rmt->circbuf, + rxbuf, LIRC_RX_BUF_BYTES)) > 0) + { + nsyms = nbytes / sizeof(rmt_symbol_word_t); + sym = (FAR rmt_symbol_word_t *)rxbuf; + + for (i = 0; i < nsyms; i++) + { + uint16_t dur0 = sym[i].duration0; + uint8_t lvl0 = sym[i].level0; + uint16_t dur1 = sym[i].duration1; + uint8_t lvl1 = sym[i].level1; + + if (dur0 > 0) + { + sample = lvl0 ? + LIRC_PULSE(RMT_TICK_TO_US(dur0)) : + LIRC_SPACE(RMT_TICK_TO_US(dur0)); + lirc_sample_event(&priv->lower, sample); + } + + if (dur1 > 0) + { + sample = lvl1 ? + LIRC_PULSE(RMT_TICK_TO_US(dur1)) : + LIRC_SPACE(RMT_TICK_TO_US(dur1)); + lirc_sample_event(&priv->lower, sample); + } + } + } + } + + kmm_free(rxbuf); + return OK; +} + +/**************************************************************************** + * Name: esp_lirc_open + ****************************************************************************/ + +static int esp_lirc_open(FAR struct lirc_lowerhalf_s *lower) +{ + FAR struct esp_lirc_dev_s *priv = + (FAR struct esp_lirc_dev_s *)lower; + FAR char *argv[3]; + char addrstr[20]; + int ret = OK; + + if (priv->rxpid > 0) + { + return OK; + } + + if (priv->rmt->recvsem != NULL) + { + priv->running = true; + + snprintf(addrstr, sizeof(addrstr), "%lx", + (unsigned long)(uintptr_t)priv); + argv[0] = "esp_lirc_rx"; + argv[1] = addrstr; + argv[2] = NULL; + + ret = kthread_create("esp_lirc_rx", SCHED_PRIORITY_DEFAULT, + LIRC_RX_THREAD_STACK, + esp_lirc_rx_thread, argv); + if (ret < 0) + { + priv->running = false; + rcerr("ERROR: kthread_create failed: %d\n", ret); + return ret; + } + + priv->rxpid = ret; + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: esp_lirc_close + ****************************************************************************/ + +static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower) +{ + FAR struct esp_lirc_dev_s *priv = + (FAR struct esp_lirc_dev_s *)lower; + + if (priv->rxpid > 0) + { + priv->running = false; + + if (priv->rmt->recvsem != NULL) + { + nxsem_post(priv->rmt->recvsem); + } + + priv->rxpid = -1; + } +} + +/**************************************************************************** + * Name: esp_lirc_tx_ir + ****************************************************************************/ + +static int esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower, + FAR unsigned int *txbuf, unsigned int n) +{ + FAR struct esp_lirc_dev_s *priv = + (FAR struct esp_lirc_dev_s *)lower; + FAR rmt_symbol_word_t *items; + unsigned int nwords; + unsigned int i; + int ret; + + if (!priv->rmt->ops->write) + { + return -ENOSYS; + } + + nwords = (n + 1) / 2; + items = kmm_zalloc(nwords * sizeof(rmt_symbol_word_t)); + if (items == NULL) + { + return -ENOMEM; + } + + for (i = 0; i < n; i++) + { + uint32_t us = LIRC_VALUE(txbuf[i]); + uint8_t lvl = LIRC_IS_PULSE(txbuf[i]) ? 1 : 0; + uint16_t tks = (uint16_t)RMT_US_TO_TICK(us); + + if ((i & 1) == 0) + { + items[i / 2].duration0 = tks; + items[i / 2].level0 = lvl; + } + else + { + items[i / 2].duration1 = tks; + items[i / 2].level1 = lvl; + } + } + + ret = priv->rmt->ops->write(priv->rmt, + (FAR const char *)items, + nwords * sizeof(rmt_symbol_word_t)); + + kmm_free(items); + return (ret < 0) ? ret : (int)n; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_lirc_rx_initialize + * + * Description: + * Register a pre-initialized RMT RX channel as a LIRC raw IR device. + * + * Input Parameters: + * devno - The LIRC device number (e.g. 0 for /dev/lirc0) + * rmt - An already-initialized RMT RX lower-half handle + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt) +{ + FAR struct esp_lirc_dev_s *priv; + int ret; + + DEBUGASSERT(rmt != NULL); + + priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s)); + if (priv == NULL) + { + return -ENOMEM; + } + + priv->lower.ops = &g_esp_lirc_rx_ops; + priv->lower.buffer_bytes = LIRC_RX_BUF_BYTES; + priv->lower.rx_resolution = 100; /* 0.1 µs = 100 ns */ + priv->rmt = rmt; + priv->rxpid = -1; + + ret = lirc_register(&priv->lower, devno); + if (ret < 0) + { + rcerr("ERROR: lirc_register failed: %d\n", ret); + kmm_free(priv); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_lirc_tx_initialize + * + * Description: + * Register a pre-initialized RMT TX channel as a LIRC raw TX device. + * + * Input Parameters: + * devno - The LIRC device number (e.g. 0 for /dev/lirc0) + * rmt - An already-initialized RMT TX lower-half handle + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt) +{ + FAR struct esp_lirc_dev_s *priv; + int ret; + + DEBUGASSERT(rmt != NULL); + + priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s)); + if (priv == NULL) + { + return -ENOMEM; + } + + priv->lower.ops = &g_esp_lirc_tx_ops; + priv->lower.tx_resolution = 100; /* 0.1 µs = 100 ns */ + priv->rmt = rmt; + priv->rxpid = -1; + + ret = lirc_register(&priv->lower, devno); + if (ret < 0) + { + rcerr("ERROR: lirc_register failed: %d\n", ret); + kmm_free(priv); + return ret; + } + + return OK; +} + +#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */ diff --git a/arch/risc-v/src/common/espressif/esp_lirc.h b/arch/risc-v/src/common/espressif/esp_lirc.h new file mode 100644 index 00000000000..2289f587c80 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_lirc.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_lirc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_LIRC_H +#define __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_LIRC_H + +#include <nuttx/config.h> + +#include "esp_rmt.h" + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC) + +int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt); +int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt); + +#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */ + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_LIRC_H */ diff --git a/arch/risc-v/src/common/espressif/esp_rmt.c b/arch/risc-v/src/common/espressif/esp_rmt.c index 83b47e9e9a2..5e7b17451e6 100644 --- a/arch/risc-v/src/common/espressif/esp_rmt.c +++ b/arch/risc-v/src/common/espressif/esp_rmt.c @@ -39,7 +39,6 @@ #include <arch/board/board.h> #include <nuttx/irq.h> #include <nuttx/arch.h> -#include <nuttx/rmt/rmt.h> #include <nuttx/spinlock.h> #include <nuttx/circbuf.h> diff --git a/arch/risc-v/src/common/espressif/esp_rmt.h b/arch/risc-v/src/common/espressif/esp_rmt.h index 2956db80b4b..ca40802f6d2 100644 --- a/arch/risc-v/src/common/espressif/esp_rmt.h +++ b/arch/risc-v/src/common/espressif/esp_rmt.h @@ -29,6 +29,10 @@ #include <nuttx/config.h> #include <semaphore.h> +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <nuttx/circbuf.h> #include <nuttx/spinlock.h> /**************************************************************************** @@ -51,6 +55,34 @@ * Public Types ****************************************************************************/ +/* The RMT peripheral vtable */ + +struct rmt_dev_s; + +struct rmt_ops_s +{ + CODE int (*open)(FAR struct rmt_dev_s *dev); + CODE int (*close)(FAR struct rmt_dev_s *dev); + CODE ssize_t (*write)(FAR struct rmt_dev_s *dev, + FAR const char *buffer, + size_t buflen); + CODE ssize_t (*read)(FAR struct rmt_dev_s *dev, + FAR char *buffer, + size_t buflen); +}; + +/* RMT device structure — initial fields visible to upper-half drivers. + * The ESP lower-half extends this with hardware-specific fields. + */ + +struct rmt_dev_s +{ + FAR const struct rmt_ops_s *ops; + FAR struct circbuf_s *circbuf; + sem_t *recvsem; + int minor; +}; + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/risc-v/src/common/espressif/esp_ws2812.c b/arch/risc-v/src/common/espressif/esp_ws2812.c index 1e4f74d9186..df1af76d1cd 100644 --- a/arch/risc-v/src/common/espressif/esp_ws2812.c +++ b/arch/risc-v/src/common/espressif/esp_ws2812.c @@ -31,7 +31,6 @@ #include <nuttx/kmalloc.h> #include <nuttx/signal.h> #include <nuttx/leds/ws2812.h> -#include <nuttx/rmt/rmt.h> #include "hal/rmt_types.h" diff --git a/arch/xtensa/src/common/espressif/Kconfig b/arch/xtensa/src/common/espressif/Kconfig index 91c097d614e..4200e515de3 100644 --- a/arch/xtensa/src/common/espressif/Kconfig +++ b/arch/xtensa/src/common/espressif/Kconfig @@ -71,13 +71,24 @@ endmenu # Interrupt Configuration config ESP_RMT bool "Remote Control Module (RMT)" default n - depends on RMT + select DRIVERS_RC ---help--- 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. +if ESP_RMT + +config RMT_DEFAULT_RX_BUFFER_SIZE + int "Default RX buffer size" + default 100 + ---help--- + The RMT RX default buffer size. This is the expected buffer size + that should be returned on a receive operation. + +endif # ESP_RMT + config ESP_MCPWM bool "Motor Control PWM (MCPWM)" default n diff --git a/arch/xtensa/src/common/espressif/Make.defs b/arch/xtensa/src/common/espressif/Make.defs index 2b6f5161a80..57d8dad6a2d 100644 --- a/arch/xtensa/src/common/espressif/Make.defs +++ b/arch/xtensa/src/common/espressif/Make.defs @@ -26,6 +26,9 @@ CFLAGS += -Wno-shadow -Wno-undef ifeq ($(CONFIG_ESP_RMT),y) CHIP_CSRCS += esp_rmt.c +ifeq ($(CONFIG_DRIVERS_RC),y) +CHIP_CSRCS += esp_lirc.c +endif ifeq ($(CONFIG_WS2812_NON_SPI_DRIVER),y) CHIP_CSRCS += esp_ws2812.c endif diff --git a/arch/xtensa/src/common/espressif/esp_lirc.c b/arch/xtensa/src/common/espressif/esp_lirc.c new file mode 100644 index 00000000000..b0a2076310f --- /dev/null +++ b/arch/xtensa/src/common/espressif/esp_lirc.c @@ -0,0 +1,441 @@ +/**************************************************************************** + * arch/xtensa/src/common/espressif/esp_lirc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <nuttx/circbuf.h> +#include <nuttx/kmalloc.h> +#include <nuttx/kthread.h> +#include <nuttx/lirc.h> +#include <nuttx/rc/lirc_dev.h> +#include <nuttx/semaphore.h> + +#include "hal/rmt_types.h" + +#include "esp_rmt.h" +#include "esp_lirc.h" + +#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RMT channel clock: 10 MHz → 1 tick = 0.1 µs */ + +#define RMT_TICK_TO_US(t) ((t) / 10) +#define RMT_US_TO_TICK(u) ((u) * 10) + +/* DMA receive scratch buffer size (in bytes, must be multiple of 4) */ + +#define LIRC_RX_BUF_BYTES CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE + +/* Stack size for the RX worker thread */ + +#define LIRC_RX_THREAD_STACK 2048 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct esp_lirc_dev_s +{ + struct lirc_lowerhalf_s lower; /* Must be first — lirc upper-half iface */ + FAR struct rmt_dev_s *rmt; /* ESP RMT lower-half */ + volatile bool running; /* RX thread keep-alive flag */ + pid_t rxpid; /* RX worker thread PID */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int esp_lirc_open(FAR struct lirc_lowerhalf_s *lower); +static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower); +static int esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower, + FAR unsigned int *txbuf, unsigned int n); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct lirc_ops_s g_esp_lirc_rx_ops = +{ + .driver_type = LIRC_DRIVER_IR_RAW, + .open = esp_lirc_open, + .close = esp_lirc_close, +}; + +static const struct lirc_ops_s g_esp_lirc_tx_ops = +{ + .driver_type = LIRC_DRIVER_IR_RAW_TX, + .open = esp_lirc_open, + .close = esp_lirc_close, + .tx_ir = esp_lirc_tx_ir, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_lirc_rx_thread + * + * Description: + * Kernel thread that continuously arms the RMT receiver, waits for + * received symbols, converts rmt_symbol_word_t items to LIRC pulse/space + * samples, and pushes them upstream via lirc_sample_event(). + * + * RMT clock is 10 MHz → 1 tick = 0.1 µs. + * rmt_symbol_word_t layout: + * bits [0:14] duration0 (RMT ticks) + * bit [15] level0 (1 = pulse, 0 = space) + * bits [16:30] duration1 (RMT ticks) + * bit [31] level1 + * + ****************************************************************************/ + +static int esp_lirc_rx_thread(int argc, FAR char *argv[]) +{ + FAR struct esp_lirc_dev_s *priv; + FAR const char *arg; + FAR char *rxbuf; + FAR rmt_symbol_word_t *sym; + unsigned int sample; + int nbytes; + int nsyms; + int i; + + DEBUGASSERT(argc >= 2 && argv[argc - 1] != NULL); + + arg = argv[argc - 1]; + priv = (FAR struct esp_lirc_dev_s *)(uintptr_t)strtoul(arg, NULL, 16); + + rxbuf = kmm_malloc(LIRC_RX_BUF_BYTES); + if (rxbuf == NULL) + { + rcerr("ERROR: out of memory for RX buffer\n"); + return -ENOMEM; + } + + while (priv->running) + { + /* Arm the RMT receiver — uses rxbuf as DMA scratch buffer. + * The actual received symbols land in priv->rmt->circbuf via + * the rmt_rx_done_callback in esp_rmt.c. + */ + + if (priv->rmt->ops->read) + { + priv->rmt->ops->read(priv->rmt, rxbuf, LIRC_RX_BUF_BYTES); + } + + /* Wait until the callback posts the semaphore */ + + nxsem_wait_uninterruptible(priv->rmt->recvsem); + + if (!priv->running) + { + break; + } + + /* Drain the circular buffer */ + + while ((nbytes = circbuf_read(priv->rmt->circbuf, + rxbuf, LIRC_RX_BUF_BYTES)) > 0) + { + nsyms = nbytes / sizeof(rmt_symbol_word_t); + sym = (FAR rmt_symbol_word_t *)rxbuf; + + for (i = 0; i < nsyms; i++) + { + uint16_t dur0 = sym[i].duration0; + uint8_t lvl0 = sym[i].level0; + uint16_t dur1 = sym[i].duration1; + uint8_t lvl1 = sym[i].level1; + + /* First half-symbol */ + + if (dur0 > 0) + { + sample = lvl0 ? + LIRC_PULSE(RMT_TICK_TO_US(dur0)) : + LIRC_SPACE(RMT_TICK_TO_US(dur0)); + lirc_sample_event(&priv->lower, sample); + } + + /* Second half-symbol (duration1 == 0 marks end of burst) */ + + if (dur1 > 0) + { + sample = lvl1 ? + LIRC_PULSE(RMT_TICK_TO_US(dur1)) : + LIRC_SPACE(RMT_TICK_TO_US(dur1)); + lirc_sample_event(&priv->lower, sample); + } + } + } + } + + kmm_free(rxbuf); + return OK; +} + +/**************************************************************************** + * Name: esp_lirc_open + ****************************************************************************/ + +static int esp_lirc_open(FAR struct lirc_lowerhalf_s *lower) +{ + FAR struct esp_lirc_dev_s *priv = + (FAR struct esp_lirc_dev_s *)lower; + FAR char *argv[3]; + char addrstr[20]; + int ret = OK; + + if (priv->rxpid > 0) + { + return OK; /* Already open */ + } + + if (priv->rmt->recvsem != NULL) + { + /* RX-capable device: start the receiver thread */ + + priv->running = true; + + snprintf(addrstr, sizeof(addrstr), "%lx", + (unsigned long)(uintptr_t)priv); + argv[0] = "esp_lirc_rx"; + argv[1] = addrstr; + argv[2] = NULL; + + ret = kthread_create("esp_lirc_rx", SCHED_PRIORITY_DEFAULT, + LIRC_RX_THREAD_STACK, + esp_lirc_rx_thread, argv); + if (ret < 0) + { + priv->running = false; + rcerr("ERROR: kthread_create failed: %d\n", ret); + return ret; + } + + priv->rxpid = ret; + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: esp_lirc_close + ****************************************************************************/ + +static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower) +{ + FAR struct esp_lirc_dev_s *priv = + (FAR struct esp_lirc_dev_s *)lower; + + if (priv->rxpid > 0) + { + priv->running = false; + + /* Wake the blocked thread so it can exit */ + + if (priv->rmt->recvsem != NULL) + { + nxsem_post(priv->rmt->recvsem); + } + + priv->rxpid = -1; + } +} + +/**************************************************************************** + * Name: esp_lirc_tx_ir + * + * Description: + * Transmit raw IR pulse/space data. Converts LIRC mode2 unsigned int + * samples (each a LIRC_PULSE or LIRC_SPACE with duration in µs) to pairs + * of rmt_symbol_word_t items and writes them to the RMT TX channel. + * + * The RMT clock is 10 MHz so 1 µs = 10 ticks. + * + ****************************************************************************/ + +static int esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower, + FAR unsigned int *txbuf, unsigned int n) +{ + FAR struct esp_lirc_dev_s *priv = + (FAR struct esp_lirc_dev_s *)lower; + FAR rmt_symbol_word_t *items; + unsigned int nwords; + unsigned int i; + int ret; + + if (!priv->rmt->ops->write) + { + return -ENOSYS; + } + + /* Each pair of LIRC samples (pulse + space) maps to one rmt_symbol_word_t. + * For an odd count we pad the last word with a zero second half-symbol. + */ + + nwords = (n + 1) / 2; + items = kmm_zalloc(nwords * sizeof(rmt_symbol_word_t)); + if (items == NULL) + { + return -ENOMEM; + } + + for (i = 0; i < n; i++) + { + uint32_t us = LIRC_VALUE(txbuf[i]); + uint8_t lvl = LIRC_IS_PULSE(txbuf[i]) ? 1 : 0; + uint16_t tks = (uint16_t)RMT_US_TO_TICK(us); + + if ((i & 1) == 0) + { + items[i / 2].duration0 = tks; + items[i / 2].level0 = lvl; + } + else + { + items[i / 2].duration1 = tks; + items[i / 2].level1 = lvl; + } + } + + ret = priv->rmt->ops->write(priv->rmt, + (FAR const char *)items, + nwords * sizeof(rmt_symbol_word_t)); + + kmm_free(items); + return (ret < 0) ? ret : (int)n; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_lirc_rx_initialize + * + * Description: + * Register a pre-initialized RMT RX channel as a LIRC raw IR device. + * + * Input Parameters: + * devno - The LIRC device number (e.g. 0 for /dev/lirc0) + * rmt - An already-initialized RMT RX lower-half handle + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt) +{ + FAR struct esp_lirc_dev_s *priv; + int ret; + + DEBUGASSERT(rmt != NULL); + + priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s)); + if (priv == NULL) + { + return -ENOMEM; + } + + priv->lower.ops = &g_esp_lirc_rx_ops; + priv->lower.buffer_bytes = LIRC_RX_BUF_BYTES; + priv->lower.rx_resolution = 100; /* 0.1 µs = 100 ns */ + priv->rmt = rmt; + priv->rxpid = -1; + + ret = lirc_register(&priv->lower, devno); + if (ret < 0) + { + rcerr("ERROR: lirc_register failed: %d\n", ret); + kmm_free(priv); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_lirc_tx_initialize + * + * Description: + * Register a pre-initialized RMT TX channel as a LIRC raw TX device. + * + * Input Parameters: + * devno - The LIRC device number (e.g. 0 for /dev/lirc0) + * rmt - An already-initialized RMT TX lower-half handle + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt) +{ + FAR struct esp_lirc_dev_s *priv; + int ret; + + DEBUGASSERT(rmt != NULL); + + priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s)); + if (priv == NULL) + { + return -ENOMEM; + } + + priv->lower.ops = &g_esp_lirc_tx_ops; + priv->lower.tx_resolution = 100; /* 0.1 µs = 100 ns */ + priv->rmt = rmt; + priv->rxpid = -1; + + ret = lirc_register(&priv->lower, devno); + if (ret < 0) + { + rcerr("ERROR: lirc_register failed: %d\n", ret); + kmm_free(priv); + return ret; + } + + return OK; +} + +#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */ diff --git a/arch/xtensa/src/common/espressif/esp_lirc.h b/arch/xtensa/src/common/espressif/esp_lirc.h new file mode 100644 index 00000000000..b7b970e056b --- /dev/null +++ b/arch/xtensa/src/common/espressif/esp_lirc.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * arch/xtensa/src/common/espressif/esp_lirc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_LIRC_H +#define __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_LIRC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include "esp_rmt.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC) + +int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt); +int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt); + +#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */ + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_LIRC_H */ diff --git a/arch/xtensa/src/common/espressif/esp_rmt.c b/arch/xtensa/src/common/espressif/esp_rmt.c index 2108962474a..8e57f8b3f1f 100644 --- a/arch/xtensa/src/common/espressif/esp_rmt.c +++ b/arch/xtensa/src/common/espressif/esp_rmt.c @@ -39,7 +39,6 @@ #include <arch/board/board.h> #include <nuttx/irq.h> #include <nuttx/arch.h> -#include <nuttx/rmt/rmt.h> #include <nuttx/spinlock.h> #include <nuttx/circbuf.h> diff --git a/arch/xtensa/src/common/espressif/esp_rmt.h b/arch/xtensa/src/common/espressif/esp_rmt.h index 943db6a88ba..84bcc626352 100644 --- a/arch/xtensa/src/common/espressif/esp_rmt.h +++ b/arch/xtensa/src/common/espressif/esp_rmt.h @@ -29,6 +29,10 @@ #include <nuttx/config.h> #include <semaphore.h> +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <nuttx/circbuf.h> #include <nuttx/spinlock.h> /**************************************************************************** @@ -51,6 +55,34 @@ * Public Types ****************************************************************************/ +/* The RMT peripheral vtable */ + +struct rmt_dev_s; + +struct rmt_ops_s +{ + CODE int (*open)(FAR struct rmt_dev_s *dev); + CODE int (*close)(FAR struct rmt_dev_s *dev); + CODE ssize_t (*write)(FAR struct rmt_dev_s *dev, + FAR const char *buffer, + size_t buflen); + CODE ssize_t (*read)(FAR struct rmt_dev_s *dev, + FAR char *buffer, + size_t buflen); +}; + +/* RMT device structure — initial fields visible to upper-half drivers. + * The ESP lower-half extends this with hardware-specific fields. + */ + +struct rmt_dev_s +{ + FAR const struct rmt_ops_s *ops; + FAR struct circbuf_s *circbuf; + sem_t *recvsem; + int minor; +}; + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/xtensa/src/common/espressif/esp_ws2812.c b/arch/xtensa/src/common/espressif/esp_ws2812.c index c6104e357c0..638ad1b6338 100644 --- a/arch/xtensa/src/common/espressif/esp_ws2812.c +++ b/arch/xtensa/src/common/espressif/esp_ws2812.c @@ -31,7 +31,6 @@ #include <nuttx/kmalloc.h> #include <nuttx/signal.h> #include <nuttx/leds/ws2812.h> -#include <nuttx/rmt/rmt.h> #include "hal/rmt_types.h" #include "soc/soc.h" diff --git a/boards/risc-v/esp32c3/common/src/esp_board_rmt.c b/boards/risc-v/esp32c3/common/src/esp_board_rmt.c index ddac1b988bd..aeb12505cdc 100644 --- a/boards/risc-v/esp32c3/common/src/esp_board_rmt.c +++ b/boards/risc-v/esp32c3/common/src/esp_board_rmt.c @@ -31,7 +31,7 @@ #include <stdio.h> #include <nuttx/kmalloc.h> -#include <nuttx/rmt/rmtchar.h> +#include "espressif/esp_lirc.h" #ifdef CONFIG_WS2812_NON_SPI_DRIVER #include <nuttx/leds/ws2812.h> @@ -87,13 +87,19 @@ int board_rmt_rxinitialize(int pin) { int ret; + struct rmt_dev_s *rmt; - struct rmt_dev_s *rmt = esp_rmt_rx_init(pin); + rmt = esp_rmt_rx_init(pin); + if (rmt == NULL) + { + rmterr("ERROR: esp_rmt_rx_init failed\n"); + return -ENODEV; + } - ret = rmtchar_register(rmt); + ret = esp_lirc_rx_initialize(0, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret); return ret; } @@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin) return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_tx_initialize(1, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret); return ret; } diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig index 01335a518b4..c5109e75db7 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig +++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig @@ -23,11 +23,8 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=15000 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2" -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_FS_PROCFS=y CONFIG_IDLETHREAD_STACKSIZE=2048 @@ -42,9 +39,6 @@ CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y CONFIG_NSH_STRERROR=y CONFIG_PREALLOC_TIMERS=0 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_BACKTRACE=y CONFIG_SCHED_WAITPID=y diff --git a/boards/risc-v/esp32c6/common/src/esp_board_rmt.c b/boards/risc-v/esp32c6/common/src/esp_board_rmt.c index 8094242d2c3..a92a445c604 100644 --- a/boards/risc-v/esp32c6/common/src/esp_board_rmt.c +++ b/boards/risc-v/esp32c6/common/src/esp_board_rmt.c @@ -31,7 +31,7 @@ #include <stdio.h> #include <nuttx/kmalloc.h> -#include <nuttx/rmt/rmtchar.h> +#include "espressif/esp_lirc.h" #ifdef CONFIG_WS2812_NON_SPI_DRIVER #include <nuttx/leds/ws2812.h> @@ -87,13 +87,19 @@ int board_rmt_rxinitialize(int pin) { int ret; + struct rmt_dev_s *rmt; - struct rmt_dev_s *rmt = esp_rmt_rx_init(pin); + rmt = esp_rmt_rx_init(pin); + if (rmt == NULL) + { + rmterr("ERROR: esp_rmt_rx_init failed\n"); + return -ENODEV; + } - ret = rmtchar_register(rmt); + ret = esp_lirc_rx_initialize(0, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret); return ret; } @@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin) return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_tx_initialize(1, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret); return ret; } diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig index 8a4aa0b3094..c45f9a4f442 100644 --- a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig +++ b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig @@ -23,11 +23,8 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=15000 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2" -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_FS_PROCFS=y CONFIG_IDLETHREAD_STACKSIZE=2048 @@ -42,9 +39,6 @@ CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y CONFIG_NSH_STRERROR=y CONFIG_PREALLOC_TIMERS=0 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_BACKTRACE=y CONFIG_SCHED_WAITPID=y diff --git a/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig index b7b9accc8a5..4f7f903e870 100644 --- a/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig +++ b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig @@ -23,11 +23,8 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=15000 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2" -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_FS_PROCFS=y CONFIG_IDLETHREAD_STACKSIZE=2048 @@ -42,9 +39,6 @@ CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y CONFIG_NSH_STRERROR=y CONFIG_PREALLOC_TIMERS=0 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_BACKTRACE=y CONFIG_SCHED_WAITPID=y diff --git a/boards/risc-v/esp32h2/common/src/esp_board_rmt.c b/boards/risc-v/esp32h2/common/src/esp_board_rmt.c index 8c56a262bc0..514fa6d5d17 100644 --- a/boards/risc-v/esp32h2/common/src/esp_board_rmt.c +++ b/boards/risc-v/esp32h2/common/src/esp_board_rmt.c @@ -31,7 +31,7 @@ #include <stdio.h> #include <nuttx/kmalloc.h> -#include <nuttx/rmt/rmtchar.h> +#include "espressif/esp_lirc.h" #ifdef CONFIG_WS2812_NON_SPI_DRIVER #include <nuttx/leds/ws2812.h> @@ -87,13 +87,19 @@ int board_rmt_rxinitialize(int pin) { int ret; + struct rmt_dev_s *rmt; - struct rmt_dev_s *rmt = esp_rmt_rx_init(pin); + rmt = esp_rmt_rx_init(pin); + if (rmt == NULL) + { + rmterr("ERROR: esp_rmt_rx_init failed\n"); + return -ENODEV; + } - ret = rmtchar_register(rmt); + ret = esp_lirc_rx_initialize(0, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret); return ret; } @@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin) return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_tx_initialize(1, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret); return ret; } diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig b/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig index 53e39e2658b..1d4f9bfee37 100644 --- a/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig +++ b/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig @@ -22,11 +22,8 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=15000 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2" -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_FS_PROCFS=y CONFIG_IDLETHREAD_STACKSIZE=2048 @@ -41,9 +38,6 @@ CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y CONFIG_NSH_STRERROR=y CONFIG_PREALLOC_TIMERS=0 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_BACKTRACE=y CONFIG_SCHED_WAITPID=y diff --git a/boards/risc-v/esp32p4/common/src/esp_board_rmt.c b/boards/risc-v/esp32p4/common/src/esp_board_rmt.c index 2f5ded7a937..e432c914885 100644 --- a/boards/risc-v/esp32p4/common/src/esp_board_rmt.c +++ b/boards/risc-v/esp32p4/common/src/esp_board_rmt.c @@ -31,7 +31,7 @@ #include <stdio.h> #include <nuttx/kmalloc.h> -#include <nuttx/rmt/rmtchar.h> +#include "espressif/esp_lirc.h" #ifdef CONFIG_WS2812_NON_SPI_DRIVER #include <nuttx/leds/ws2812.h> @@ -87,13 +87,19 @@ int board_rmt_rxinitialize(int pin) { int ret; + struct rmt_dev_s *rmt; - struct rmt_dev_s *rmt = esp_rmt_rx_init(pin); + rmt = esp_rmt_rx_init(pin); + if (rmt == NULL) + { + rmterr("ERROR: esp_rmt_rx_init failed\n"); + return -ENODEV; + } - ret = rmtchar_register(rmt); + ret = esp_lirc_rx_initialize(0, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret); return ret; } @@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin) return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_tx_initialize(1, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret); return ret; } diff --git a/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig b/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig index 05184fcebc6..f6da07a9bb1 100644 --- a/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig +++ b/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig @@ -21,11 +21,8 @@ CONFIG_ARCH_RISCV=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=15000 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt4" -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_EXPERIMENTAL=y CONFIG_FS_PROCFS=y @@ -41,9 +38,6 @@ CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y CONFIG_NSH_STRERROR=y CONFIG_PREALLOC_TIMERS=0 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_BACKTRACE=y CONFIG_SCHED_WAITPID=y diff --git a/boards/xtensa/esp32/common/src/esp32_board_rmt.c b/boards/xtensa/esp32/common/src/esp32_board_rmt.c index 24c3effb9d5..4e8c8864453 100644 --- a/boards/xtensa/esp32/common/src/esp32_board_rmt.c +++ b/boards/xtensa/esp32/common/src/esp32_board_rmt.c @@ -33,7 +33,7 @@ #include "xtensa.h" #include <nuttx/kmalloc.h> -#include <nuttx/rmt/rmtchar.h> +#include "espressif/esp_lirc.h" #ifdef CONFIG_WS2812_NON_SPI_DRIVER #include <nuttx/leds/ws2812.h> @@ -89,13 +89,19 @@ int board_rmt_rxinitialize(int pin) { int ret; + struct rmt_dev_s *rmt; - struct rmt_dev_s *rmt = esp_rmt_rx_init(pin); + rmt = esp_rmt_rx_init(pin); + if (rmt == NULL) + { + rmterr("ERROR: esp_rmt_rx_init failed\n"); + return -ENODEV; + } - ret = rmtchar_register(rmt); + ret = esp_lirc_rx_initialize(0, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret); return ret; } @@ -125,17 +131,16 @@ int board_rmt_txinitialize(int pin) #endif rmt = esp_rmt_tx_init(pin); - if (rmt == NULL) { rmterr("ERROR: esp_rmt_tx_init failed\n"); return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_tx_initialize(1, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret); return ret; } diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig index 3b39a416e34..8eee4b00833 100644 --- a/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig +++ b/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig @@ -22,11 +22,9 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_XTENSA=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP32_UART0=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y @@ -44,9 +42,6 @@ CONFIG_NSH_READLINE=y CONFIG_PREALLOC_TIMERS=4 CONFIG_RAM_SIZE=114688 CONFIG_RAM_START=0x20000000 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=256 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_WAITPID=y CONFIG_START_DAY=6 diff --git a/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c b/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c index 5b06382a579..710af33ebde 100644 --- a/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c +++ b/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c @@ -33,7 +33,7 @@ #include "xtensa.h" #include <nuttx/kmalloc.h> -#include <nuttx/rmt/rmtchar.h> +#include "espressif/esp_lirc.h" #ifdef CONFIG_WS2812_NON_SPI_DRIVER #include <nuttx/leds/ws2812.h> @@ -98,10 +98,10 @@ int board_rmt_rxinitialize(int pin) return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_rx_initialize(0, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret); return ret; } @@ -137,10 +137,10 @@ int board_rmt_txinitialize(int pin) return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_tx_initialize(1, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret); return ret; } diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig index 9b31d333be9..6811b4c8e0a 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig @@ -24,11 +24,9 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_XTENSA=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP32S2_UART0=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y @@ -45,9 +43,6 @@ CONFIG_NSH_READLINE=y CONFIG_PREALLOC_TIMERS=4 CONFIG_RAM_SIZE=114688 CONFIG_RAM_START=0x20000000 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=256 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_WAITPID=y CONFIG_START_DAY=6 diff --git a/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c b/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c index 6c6bd982d24..3d96b8613d3 100644 --- a/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c +++ b/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c @@ -33,7 +33,7 @@ #include "xtensa.h" #include <nuttx/kmalloc.h> -#include <nuttx/rmt/rmtchar.h> +#include "espressif/esp_lirc.h" #ifdef CONFIG_WS2812_NON_SPI_DRIVER #include <nuttx/leds/ws2812.h> @@ -89,13 +89,19 @@ int board_rmt_rxinitialize(int pin) { int ret; + struct rmt_dev_s *rmt; - struct rmt_dev_s *rmt = esp_rmt_rx_init(pin); + rmt = esp_rmt_rx_init(pin); + if (rmt == NULL) + { + rmterr("ERROR: esp_rmt_rx_init failed\n"); + return -ENODEV; + } - ret = rmtchar_register(rmt); + ret = esp_lirc_rx_initialize(0, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret); return ret; } @@ -131,10 +137,10 @@ int board_rmt_txinitialize(int pin) return -ENODEV; } - ret = rmtchar_register(rmt); + ret = esp_lirc_tx_initialize(1, rmt); if (ret < 0) { - rmterr("ERROR: rmtchar_register failed: %d\n", ret); + rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret); return ret; } diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig index 80fbd79aa00..075cfe1a330 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig @@ -25,12 +25,9 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_XTENSA=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y +CONFIG_DRIVERS_RC=y CONFIG_ESP32S3_UART0=y CONFIG_ESP_RMT=y -CONFIG_EXAMPLES_RMTCHAR=y -CONFIG_EXAMPLES_RMTCHAR_RX=y -CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt4" -CONFIG_EXAMPLES_RMTCHAR_TX=y CONFIG_EXAMPLES_WS2812=y CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y @@ -47,9 +44,6 @@ CONFIG_NSH_READLINE=y CONFIG_PREALLOC_TIMERS=4 CONFIG_RAM_SIZE=114688 CONFIG_RAM_START=0x20000000 -CONFIG_RMT=y -CONFIG_RMTCHAR=y -CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=256 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_WAITPID=y CONFIG_START_DAY=6 diff --git a/drivers/Kconfig b/drivers/Kconfig index 7f4cdacba3f..20e77b4a971 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -39,7 +39,6 @@ source "drivers/pinctrl/Kconfig" source "drivers/pipes/Kconfig" source "drivers/power/Kconfig" source "drivers/regmap/Kconfig" -source "drivers/rmt/Kconfig" source "drivers/rpmsg/Kconfig" source "drivers/rptun/Kconfig" source "drivers/sensors/Kconfig" diff --git a/drivers/rmt/CMakeLists.txt b/drivers/rmt/CMakeLists.txt index 8978f4c4d4a..41f66775498 100644 --- a/drivers/rmt/CMakeLists.txt +++ b/drivers/rmt/CMakeLists.txt @@ -20,12 +20,4 @@ # # ############################################################################## -if(CONFIG_RMT) - set(SRCS) - - if(CONFIG_RMTCHAR) - list(APPEND SRCS rmtchar.c) - endif() - - target_sources(drivers PRIVATE ${SRCS}) -endif() +# RMT character driver removed; RMT upper-half is now arch/espressif/esp_lirc.c diff --git a/drivers/rmt/Kconfig b/drivers/rmt/Kconfig index fa7b2891f01..f72f3c094ce 100644 --- a/drivers/rmt/Kconfig +++ b/drivers/rmt/Kconfig @@ -2,46 +2,3 @@ # For a description of the syntax of this configuration file, # see the file kconfig-language.txt in the NuttX tools repository. # - -menuconfig RMT - bool "RMT (Remote Control) Driver Support" - default n - ---help--- - This option selects common RMT (Remote Control) options and should be - enabled by the platforms that implement a Remote Control Peripheral. - -if RMT - -config RMTCHAR - bool "RMT character driver (for testing only)" - default n - ---help--- - The RMT character driver is a simple character driver that supports - RMT transfers via read() and write(). This driver is primarily - intended to support RMT testing. It is not suitable for use in any - real driver application in its current form because its buffer - management heuristics are dependent on the lower half driver - (device-specific). Applications that use the RMT peripheral to - implement protocols such as NEC (for Remote Control), or use this - driver to implement other 1-wire protocols such as WS2812 LED must - provide their specific driver implementation. - -config RMT_DEFAULT_RX_BUFFER_SIZE - int "Default RX buffer size" - default 100 - ---help--- - The RMT RX default buffer size. This is the expected buffer size - that should be returned on a `read()` operation. - -config RMT_LOOP_TEST_MODE - bool "RMT character driver loopback test mode (for testing only)" - depends on EXPERIMENTAL - default n - ---help--- - This enables a lower-half driver-specific loopback test - mode that attaches the transmitter to the receiver, being - able to test the RMT peripheral without any external - connection. This feature depends on lower-half driver - implementation. - -endif # RMT diff --git a/drivers/rmt/Make.defs b/drivers/rmt/Make.defs index 3e4e6691723..5f6b700ac29 100644 --- a/drivers/rmt/Make.defs +++ b/drivers/rmt/Make.defs @@ -19,14 +19,3 @@ # under the License. # ############################################################################ - -ifeq ($(CONFIG_RMT),y) - -ifeq ($(CONFIG_RMTCHAR),y) -CSRCS += rmtchar.c -endif - -DEPPATH += --dep-path rmt -VPATH += :rmt - -endif diff --git a/drivers/rmt/rmtchar.c b/drivers/rmt/rmtchar.c deleted file mode 100644 index 5f477471c3c..00000000000 --- a/drivers/rmt/rmtchar.c +++ /dev/null @@ -1,341 +0,0 @@ -/**************************************************************************** - * drivers/rmt/rmtchar.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> - -#include <stdint.h> -#include <stdio.h> -#include <fcntl.h> -#include <string.h> -#include <assert.h> -#include <debug.h> -#include <errno.h> - -#include <nuttx/fs/fs.h> -#include <nuttx/kmalloc.h> -#include <nuttx/circbuf.h> -#include <nuttx/mutex.h> -#include <nuttx/rmt/rmt.h> - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define DEVNAME_FMT "/dev/rmt%d" -#define DEVNAME_FMTLEN (8 + 3 + 1) - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct rmt_driver_s -{ - /* The lower half RMT driver */ - - FAR struct rmt_dev_s *rmt; - - /* The minor identification of the driver. It's provided by the lower half - * driver and it can represent the channel being used. - */ - - int minor; - - mutex_t lock; /* Assures mutually exclusive access */ -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static int rmt_open(FAR struct file *filep); -static int rmt_close(FAR struct file *filep); -static ssize_t rmt_read(FAR struct file *filep, FAR char *buffer, - size_t buflen); -static ssize_t rmt_write(FAR struct file *filep, FAR const char *buffer, - size_t buflen); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const struct file_operations g_rmt_channel_fops = -{ - rmt_open, /* open */ - rmt_close, /* close */ - rmt_read, /* read */ - rmt_write, /* write */ - NULL, /* seek */ - NULL, /* ioctl */ -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: rmt_open - * - * Description: - * Prepare the RMT peripheral for use. This method just calls the lower - * half `open` routine if it exists. - * - * Input Parameters: - * filep - Pointer system file data - * - * Returned Value: - * The return code of the lower half `open` routine if it exists. - * Please check device-specific driver for more information. - * - ****************************************************************************/ - -static int rmt_open(FAR struct file *filep) -{ - FAR struct inode *inode; - FAR struct rmt_driver_s *priv; - int ret = OK; - - /* Get our private data structure */ - - inode = filep->f_inode; - - priv = inode->i_private; - DEBUGASSERT(priv); - - if (priv->rmt->ops->open) - { - ret = priv->rmt->ops->open(priv->rmt); - } - - return ret; -} - -/**************************************************************************** - * Name: rmt_close - * - * Description: - * Close the RMT peripheral after use. This method just calls the lower - * half `close` routine if it exists. - * - * Input Parameters: - * filep - Pointer system file data - * - * Returned Value: - * The return code of the lower half `close` routine if it exists. - * Please check device-specific driver for more information. - * - ****************************************************************************/ - -static int rmt_close(FAR struct file *filep) -{ - FAR struct inode *inode; - FAR struct rmt_driver_s *priv; - int ret = OK; - - /* Get our private data structure */ - - inode = filep->f_inode; - - priv = inode->i_private; - DEBUGASSERT(priv); - - if (priv->rmt->ops->close) - { - ret = priv->rmt->ops->close(priv->rmt); - } - - return ret; -} - -/**************************************************************************** - * Name: rmt_read - * - * Description: - * This function reads data from the RMT device into the provided buffer. - * The read operation is performed by the read function pointer in the - * RMT device's operations structure, if it exists. - * - * Input Parameters: - * filep - Pointer to the file structure. - * buffer - Pointer to the buffer where the read data should be stored. - * buflen - The maximum amount of data to be read. - * - * Returned Value: - * Returns the number of bytes read from the RMT device; a negated errno - * value is returned on any failure. - * - ****************************************************************************/ - -static ssize_t rmt_read(FAR struct file *filep, FAR char *buffer, - size_t buflen) -{ - FAR struct inode *inode; - FAR struct rmt_driver_s *priv; - ssize_t nread = 0; - - /* Get our private data structure */ - - inode = filep->f_inode; - - priv = inode->i_private; - DEBUGASSERT(priv); - - if (priv->rmt->ops->read) - { - int ret = priv->rmt->ops->read(priv->rmt, buffer, buflen); - if (ret < 0) - { - return ret; - } - - for (; ; ) - { - nread = circbuf_read(priv->rmt->circbuf , buffer, buflen); - if (nread != 0 || (filep->f_oflags & O_NONBLOCK)) - { - break; - } - - while (circbuf_is_empty(priv->rmt->circbuf)) - { - nxsem_wait_uninterruptible(priv->rmt->recvsem); - } - } - } - - return nread; -} - -/**************************************************************************** - * Name: rmt_write - * - * Description: - * Write to the RMT peripheral. This method just calls the lower half - * `write` routine if it exists. - * - * Input Parameters: - * filep - Pointer system file data - * buffer - Data to write to the RMT device - * buflen - Number of bytes requested to write - * - * Returned Value: - * Number of bytes that has been successfully written, or 0 when no - * bytes could be written for any reason. - * - ****************************************************************************/ - -static ssize_t rmt_write(FAR struct file *filep, FAR const char *buffer, - size_t buflen) -{ - FAR struct inode *inode; - FAR struct rmt_driver_s *priv; - ssize_t nwritten = 0; - - /* Get our private data structure */ - - inode = filep->f_inode; - - priv = inode->i_private; - DEBUGASSERT(priv); - - if (priv->rmt->ops->write) - { - nwritten = priv->rmt->ops->write(priv->rmt, buffer, buflen); - } - - return nwritten; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: rmtchar_register - * - * Description: - * Create and register the RMT character driver. - * - * The RMT character driver is a simple character driver that supports RMT - * transfers via read() and write(). This driver is primarily intended to - * support RMT testing. It is not suitable for use in any real driver - * application in its current form because its buffer management heuristics - * are dependent on the lower half driver (device-specific). - * - * Input Parameters: - * rmt - An instance of the lower half RMT driver - * - * Returned Value: - * OK if the driver was successfully registered; A negated errno value is - * returned on any failure. - * - ****************************************************************************/ - -int rmtchar_register(FAR struct rmt_dev_s *rmt) -{ - FAR struct rmt_driver_s *priv; - char devname[DEVNAME_FMTLEN]; - size_t dev_size = sizeof(struct rmt_driver_s); - int ret; - - /* Sanity check */ - - DEBUGASSERT(rmt != NULL && (unsigned)rmt->minor < 1000); - - /* Allocate a RMT character device structure */ - - priv = kmm_zalloc(dev_size); - if (priv) - { - /* Initialize the RMT character device structure */ - - priv->rmt = rmt; - priv->minor = rmt->minor; - nxmutex_init(&priv->lock); - - /* Create the character device name */ - - snprintf(devname, sizeof(devname), DEVNAME_FMT, priv->minor); - ret = register_driver(devname, &g_rmt_channel_fops, 0666, priv); - if (ret < 0) - { - /* Free the device structure if we failed to create the character - * device. - */ - - nxmutex_destroy(&priv->lock); - kmm_free(priv); - return ret; - } - - /* Return the result of the registration */ - - return ret; - } - - return -ENOMEM; -} diff --git a/include/nuttx/rmt/rmt.h b/include/nuttx/rmt/rmt.h deleted file mode 100644 index 5afb391d5c1..00000000000 --- a/include/nuttx/rmt/rmt.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - * include/nuttx/rmt/rmt.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __INCLUDE_NUTTX_RMT_RMT_H -#define __INCLUDE_NUTTX_RMT_RMT_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> - -#ifdef CONFIG_RMT - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -struct rmt_dev_s; - -/* The RMT peripheral vtable */ - -struct rmt_ops_s -{ - CODE int (*open)(FAR struct rmt_dev_s *dev); - CODE int (*close)(FAR struct rmt_dev_s *dev); - CODE ssize_t (*write)(FAR struct rmt_dev_s *dev, - FAR const char *buffer, - size_t buflen); - CODE ssize_t (*read)(FAR struct rmt_dev_s *dev, - FAR char *buffer, - size_t buflen); -}; - -/* RMT private data. This structure only defines the initial fields of the - * structure visible to the RMT client. The specific implementation may - * add additional, device-specific fields. - */ - -struct rmt_dev_s -{ - FAR const struct rmt_ops_s *ops; - FAR struct circbuf_s *circbuf; - sem_t *recvsem; - int minor; -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Functions Prototypes - ****************************************************************************/ - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* CONFIG_RMT */ -#endif /* __INCLUDE_NUTTX_RMT_RMT_H */ diff --git a/include/nuttx/rmt/rmtchar.h b/include/nuttx/rmt/rmtchar.h deleted file mode 100644 index af462ff11e8..00000000000 --- a/include/nuttx/rmt/rmtchar.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - * include/nuttx/rmt/rmtchar.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __INCLUDE_NUTTX_RMT_RMTCHAR_H -#define __INCLUDE_NUTTX_RMT_RMTCHAR_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> - -#include <nuttx/rmt/rmt.h> - -#ifdef CONFIG_RMTCHAR - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Functions Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: rmtchar_register - * - * Description: - * Create and register the RMT character driver. - * - * The RMT character driver is a simple character driver that supports RMT - * transfers via read() and write(). This driver is primarily intended to - * support RMT testing. It is not suitable for use in any real driver - * application in its current form because its buffer management heuristics - * are dependent on the lower half driver (device-specific). - * - * Input Parameters: - * rmt - An instance of the lower half RMT driver - * - * Returned Value: - * OK if the driver was successfully registered; A negated errno value is - * returned on any failure. - * - ****************************************************************************/ - -int rmtchar_register(FAR struct rmt_dev_s *rmt); - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* CONFIG_RMT */ -#endif /* __INCLUDE_NUTTX_RMT_RMTCHAR_H */
