remove(legacy_rmt): remove legacy rmt driver in IDF v6.0

This commit is contained in:
Chen Jichang
2025-06-23 19:58:22 +08:00
parent ab2829d65f
commit 883ead113d
45 changed files with 27 additions and 4333 deletions

View File

@@ -21,11 +21,6 @@ if(CONFIG_SOC_I2C_SUPPORTED)
list(APPEND srcs "i2c/i2c.c")
endif()
# RMT legacy driver
if(CONFIG_SOC_RMT_SUPPORTED)
list(APPEND srcs "deprecated/rmt_legacy.c")
endif()
# Touch Sensor related source files
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED)
if(CONFIG_SOC_TOUCH_SENSOR_VERSION LESS 3)

View File

@@ -2,23 +2,6 @@ menu "Legacy Driver Configurations"
orsource "./twai/Kconfig.twai"
menu "Legacy RMT Driver Configurations"
depends on SOC_RMT_SUPPORTED
config RMT_SUPPRESS_DEPRECATE_WARN
bool "Suppress legacy driver deprecated warning"
default n
help
Whether to suppress the deprecation warnings when using legacy rmt driver (driver/rmt.h).
If you want to continue using the legacy driver, and don't want to see related deprecation warnings,
you can enable this option.
config RMT_SKIP_LEGACY_CONFLICT_CHECK
bool "Skip legacy conflict check"
default n
help
This configuration option allows the user to bypass the conflict check mechanism with legacy code.
endmenu # Legacy RMT Driver Configurations
menu "Legacy I2C Driver Configurations"
depends on SOC_I2C_SUPPORTED
config I2C_SKIP_LEGACY_CONFLICT_CHECK

View File

@@ -1,749 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/ringbuf.h"
#include "driver/rmt_types_legacy.h"
#if !CONFIG_RMT_SUPPRESS_DEPRECATE_WARN
#warning "The legacy RMT driver is deprecated, please use driver/rmt_tx.h and/or driver/rmt_rx.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set RMT clock divider, channel clock is divided from source clock.
*
* @param channel RMT channel
* @param div_cnt RMT counter clock divider
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_clk_div(rmt_channel_t channel, uint8_t div_cnt);
/**
* @brief Get RMT clock divider, channel clock is divided from source clock.
*
* @param channel RMT channel
* @param div_cnt pointer to accept RMT counter divider
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_clk_div(rmt_channel_t channel, uint8_t *div_cnt);
/**
* @brief Set RMT RX idle threshold value
*
* In receive mode, when no edge is detected on the input signal
* for longer than idle_thres channel clock cycles,
* the receive process is finished.
*
* @param channel RMT channel
* @param thresh RMT RX idle threshold
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_rx_idle_thresh(rmt_channel_t channel, uint16_t thresh);
/**
* @brief Get RMT idle threshold value.
*
* In receive mode, when no edge is detected on the input signal
* for longer than idle_thres channel clock cycles,
* the receive process is finished.
*
* @param channel RMT channel
* @param thresh pointer to accept RMT RX idle threshold value
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_rx_idle_thresh(rmt_channel_t channel, uint16_t *thresh);
/**
* @brief Set RMT memory block number for RMT channel
*
* This function is used to configure the amount of memory blocks allocated to channel n
* The 8 channels share a 512x32-bit RAM block which can be read and written
* by the processor cores over the APB bus, as well as read by the transmitters
* and written by the receivers.
*
* The RAM address range for channel n is start_addr_CHn to end_addr_CHn, which are defined by:
* Memory block start address is RMT_CHANNEL_MEM(n) (in soc/rmt_reg.h),
* that is, start_addr_chn = RMT base address + 0x800 + 64 4 n, and
* end_addr_chn = RMT base address + 0x800 + 64 4 n + 64 4 RMT_MEM_SIZE_CHn mod 512 4
*
* @note
* If memory block number of one channel is set to a value greater than 1, this channel will occupy the memory
* block of the next channel.
* Channel 0 can use at most 8 blocks of memory, accordingly channel 7 can only use one memory block.
*
* @param channel RMT channel
* @param rmt_mem_num RMT RX memory block number, one block has 64 * 32 bits.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_mem_block_num(rmt_channel_t channel, uint8_t rmt_mem_num);
/**
* @brief Get RMT memory block number
*
* @param channel RMT channel
* @param rmt_mem_num Pointer to accept RMT RX memory block number
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_mem_block_num(rmt_channel_t channel, uint8_t *rmt_mem_num);
/**
* @brief Configure RMT carrier for TX signal.
*
* Set different values for carrier_high and carrier_low to set different frequency of carrier.
* The unit of carrier_high/low is the source clock tick, not the divided channel counter clock.
*
* @param channel RMT channel
* @param carrier_en Whether to enable output carrier.
* @param high_level High level duration of carrier
* @param low_level Low level duration of carrier.
* @param carrier_level Configure the way carrier wave is modulated for channel.
* - 1'b1:transmit on low output level
* - 1'b0:transmit on high output level
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t high_level, uint16_t low_level, rmt_carrier_level_t carrier_level);
/**
* @brief Set RMT memory in low power mode.
*
* Reduce power consumed by memory. 1:memory is in low power state.
*
* @param channel RMT channel
* @param pd_en RMT memory low power enable.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en);
/**
* @brief Check if the RMT memory is force powered down
*
* @param channel RMT channel (actually this function is configured for all channels)
* @param pd_en Pointer to accept the result
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool *pd_en);
/**
* @brief Set RMT start sending data from memory.
*
* @param channel RMT channel
* @param tx_idx_rst Set true to reset memory index for TX.
* Otherwise, transmitter will continue sending from the last index in memory.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_tx_start(rmt_channel_t channel, bool tx_idx_rst);
/**
* @brief Set RMT stop sending.
*
* @param channel RMT channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_tx_stop(rmt_channel_t channel);
/**
* @brief Set RMT start receiving data.
*
* @param channel RMT channel
* @param rx_idx_rst Set true to reset memory index for receiver.
* Otherwise, receiver will continue receiving data to the last index in memory.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_rx_start(rmt_channel_t channel, bool rx_idx_rst);
/**
* @brief Set RMT stop receiving data.
*
* @param channel RMT channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_rx_stop(rmt_channel_t channel);
/**
* @brief Reset RMT TX memory
*
* @param channel RMT channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_tx_memory_reset(rmt_channel_t channel);
/**
* @brief Reset RMT RX memory
*
* @param channel RMT channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_rx_memory_reset(rmt_channel_t channel);
/**
* @brief Set RMT memory owner.
* @note Setting memory is only valid for RX channel.
*
* @param channel RMT channel
* @param owner To set when the transmitter or receiver can process the memory of channel.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_memory_owner(rmt_channel_t channel, rmt_mem_owner_t owner);
/**
* @brief Get RMT memory owner.
*
* @param channel RMT channel
* @param owner Pointer to get memory owner.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_memory_owner(rmt_channel_t channel, rmt_mem_owner_t *owner);
/**
* @brief Set RMT tx loop mode.
*
* @param channel RMT channel
* @param loop_en Enable RMT transmitter loop sending mode.
* If set true, transmitter will continue sending from the first data
* to the last data in channel over and over again in a loop.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_tx_loop_mode(rmt_channel_t channel, bool loop_en);
/**
* @brief Get RMT tx loop mode.
*
* @param channel RMT channel
* @param loop_en Pointer to accept RMT transmitter loop sending mode.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_tx_loop_mode(rmt_channel_t channel, bool *loop_en);
/**
* @brief Set RMT RX filter.
*
* In receive mode, channel will ignore input pulse when the pulse width is smaller than threshold.
* Counted in source clock, not divided counter clock.
*
* @param channel RMT channel
* @param rx_filter_en To enable RMT receiver filter.
* @param thresh Threshold of pulse width for receiver.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_rx_filter(rmt_channel_t channel, bool rx_filter_en, uint8_t thresh);
/**
* @brief Set RMT source clock
*
* RMT module has two clock sources:
* 1. APB clock which is 80Mhz
* 2. REF tick clock, which would be 1Mhz (not supported in this version).
*
* @param channel RMT channel
* @param base_clk To choose source clock for RMT module.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk);
/**
* @brief Get RMT source clock
*
* RMT module has two clock sources:
* 1. APB clock which is 80Mhz
* 2. REF tick clock, which would be 1Mhz (not supported in this version).
*
* @param channel RMT channel
* @param src_clk Pointer to accept source clock for RMT module.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_source_clk(rmt_channel_t channel, rmt_source_clk_t *src_clk);
/**
* @brief Set RMT idle output level for transmitter
*
* @param channel RMT channel
* @param idle_out_en To enable idle level output.
* @param level To set the output signal's level for channel in idle state.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_idle_level(rmt_channel_t channel, bool idle_out_en, rmt_idle_level_t level);
/**
* @brief Get RMT idle output level for transmitter
*
* @param channel RMT channel
* @param idle_out_en Pointer to accept value of enable idle.
* @param level Pointer to accept value of output signal's level in idle state for specified channel.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool *idle_out_en, rmt_idle_level_t *level);
/**
* @brief Get RMT status
*
* @param channel RMT channel
* @param status Pointer to accept channel status.
* Please refer to RMT_CHnSTATUS_REG(n=0~7) in `rmt_reg.h` for more details of each field.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_status(rmt_channel_t channel, uint32_t *status);
/**
* @brief Set RMT RX interrupt enable
*
* @param channel RMT channel
* @param en enable or disable RX interrupt.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_rx_intr_en(rmt_channel_t channel, bool en);
/**
* @brief Set RMT RX error interrupt enable
*
* @param channel RMT channel
* @param en enable or disable RX err interrupt.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_err_intr_en(rmt_channel_t channel, bool en);
/**
* @brief Set RMT TX interrupt enable
*
* @param channel RMT channel
* @param en enable or disable TX interrupt.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_tx_intr_en(rmt_channel_t channel, bool en);
/**
* @brief Set RMT TX threshold event interrupt enable
*
* An interrupt will be triggered when the number of transmitted items reaches the threshold value
*
* @param channel RMT channel
* @param en enable or disable TX event interrupt.
* @param evt_thresh RMT event interrupt threshold value
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_tx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_thresh);
/**
* @brief Configure the GPIO used by RMT channel
*
* @param channel RMT channel
* @param mode RMT mode, either RMT_MODE_TX or RMT_MODE_RX
* @param gpio_num GPIO number, which is connected with certain RMT signal
* @param invert_signal Invert RMT signal physically by GPIO matrix
*
* @return
* - ESP_ERR_INVALID_ARG Configure RMT GPIO failed because of wrong parameter
* - ESP_OK Configure RMT GPIO successfully
*/
esp_err_t rmt_set_gpio(rmt_channel_t channel, rmt_mode_t mode, gpio_num_t gpio_num, bool invert_signal);
/**
* @brief Configure RMT parameters
*
* @param rmt_param RMT parameter struct
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_config(const rmt_config_t *rmt_param);
/**
* @brief Register RMT interrupt handler, the handler is an ISR.
*
* The handler will be attached to the same CPU core that this function is running on.
*
* @note If you already called rmt_driver_install to use system RMT driver,
* please do not register ISR handler again.
*
* @param fn Interrupt handler function.
* @param arg Parameter for the handler function
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param handle If non-zero, a handle to later clean up the ISR gets stored here.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Function pointer error.
* - ESP_FAIL System driver installed, can not register ISR handler for RMT
*/
esp_err_t rmt_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, rmt_isr_handle_t *handle);
/**
* @brief Deregister previously registered RMT interrupt handler
*
* @param handle Handle obtained from rmt_isr_register
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Handle invalid
*/
esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle);
/**
* @brief Fill memory data of channel with given RMT items.
*
* @param channel RMT channel
* @param item Pointer of items.
* @param item_num RMT sending items number.
* @param mem_offset Index offset of memory.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_fill_tx_items(rmt_channel_t channel, const rmt_item32_t *item, uint16_t item_num, uint16_t mem_offset);
/**
* @brief Initialize RMT driver
*
* @param channel RMT channel
* @param rx_buf_size Size of RMT RX ringbuffer. Can be 0 if the RX ringbuffer is not used.
* @param intr_alloc_flags Flags for the RMT driver interrupt handler. Pass 0 for default flags. See esp_intr_alloc.h for details.
* If ESP_INTR_FLAG_IRAM is used, please do not use the memory allocated from psram when calling rmt_write_items.
*
* @return
* - ESP_ERR_INVALID_STATE Driver is already installed, call rmt_driver_uninstall first.
* - ESP_ERR_NO_MEM Memory allocation failure
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr_alloc_flags);
/**
* @brief Uninstall RMT driver.
*
* @param channel RMT channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_driver_uninstall(rmt_channel_t channel);
/**
* @brief Get the current status of eight channels.
*
* @note Do not call this function if it is possible that `rmt_driver_uninstall` will be called at the same time.
*
* @param[out] channel_status store the current status of each channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter is NULL
* - ESP_OK Success
*/
esp_err_t rmt_get_channel_status(rmt_channel_status_result_t *channel_status);
/**
* @brief Get speed of channel's internal counter clock.
*
* @param channel RMT channel
* @param[out] clock_hz counter clock speed, in hz
*
* @return
* - ESP_ERR_INVALID_ARG Parameter is NULL
* - ESP_OK Success
*/
esp_err_t rmt_get_counter_clock(rmt_channel_t channel, uint32_t *clock_hz);
/**
* @brief RMT send waveform from rmt_item array.
*
* This API allows user to send waveform with any length.
*
* @param channel RMT channel
* @param rmt_item head point of RMT items array.
* If ESP_INTR_FLAG_IRAM is used, please do not use the memory allocated from psram when calling rmt_write_items.
* @param item_num RMT data item number.
* @param wait_tx_done
* - If set 1, it will block the task and wait for sending done.
* - If set 0, it will not wait and return immediately.
*
* @note
* This function will not copy data, instead, it will point to the original items,
* and send the waveform items.
* If wait_tx_done is set to true, this function will block and will not return until
* all items have been sent out.
* If wait_tx_done is set to false, this function will return immediately, and the driver
* interrupt will continue sending the items. We must make sure the item data will not be
* damaged when the driver is still sending items in driver interrupt.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, int item_num, bool wait_tx_done);
/**
* @brief Wait RMT TX finished.
*
* @param channel RMT channel
* @param wait_time Maximum time in ticks to wait for transmission to be complete. If set 0, return immediately with ESP_ERR_TIMEOUT if TX is busy (polling).
*
* @return
* - ESP_OK RMT Tx done successfully
* - ESP_ERR_TIMEOUT Exceeded the 'wait_time' given
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_FAIL Driver not installed
*/
esp_err_t rmt_wait_tx_done(rmt_channel_t channel, TickType_t wait_time);
/**
* @brief Get ringbuffer from RMT.
*
* Users can get the RMT RX ringbuffer handle, and process the RX data.
*
* @param channel RMT channel
* @param buf_handle Pointer to buffer handle to accept RX ringbuffer handle.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t *buf_handle);
/**
* @brief Init rmt translator and register user callback.
* The callback will convert the raw data that needs to be sent to rmt format.
* If a channel is initialized more than once, the user callback will be replaced by the later.
*
* @param channel RMT channel .
* @param fn Point to the data conversion function.
*
* @return
* - ESP_FAIL Init fail.
* - ESP_OK Init success.
*/
esp_err_t rmt_translator_init(rmt_channel_t channel, sample_to_rmt_t fn);
/**
* @brief Set user context for the translator of specific channel
*
* @param channel RMT channel number
* @param context User context
*
* @return
* - ESP_FAIL Set context fail
* - ESP_OK Set context success
*/
esp_err_t rmt_translator_set_context(rmt_channel_t channel, void *context);
/**
* @brief Get the user context set by 'rmt_translator_set_context'
*
* @note This API must be invoked in the RMT translator callback function,
* and the first argument must be the actual parameter 'item_num' you got in that callback function.
*
* @param item_num Address of the memory which contains the number of translated items (It's from driver's internal memory)
* @param context Returned User context
*
* @return
* - ESP_FAIL Get context fail
* - ESP_OK Get context success
*/
esp_err_t rmt_translator_get_context(const size_t *item_num, void **context);
/**
* @brief Translate uint8_t type of data into rmt format and send it out.
* Requires rmt_translator_init to init the translator first.
*
* @param channel RMT channel .
* @param src Pointer to the raw data.
* @param src_size The size of the raw data.
* @param wait_tx_done Set true to wait all data send done.
*
* @return
* - ESP_FAIL Send fail
* - ESP_OK Send success
*/
esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src_size, bool wait_tx_done);
/**
* @brief Registers a callback that will be called when transmission ends.
*
* Called by rmt_driver_isr_default in interrupt context.
*
* @note Requires rmt_driver_install to install the default ISR handler.
*
* @param function Function to be called from the default interrupt handler or NULL.
* @param arg Argument which will be provided to the callback when it is called.
*
* @return the previous callback settings (members will be set to NULL if there was none)
*/
rmt_tx_end_callback_t rmt_register_tx_end_callback(rmt_tx_end_fn_t function, void *arg);
#if SOC_RMT_SUPPORT_RX_PINGPONG
/**
* @brief Set RMT RX threshold event interrupt enable
*
* An interrupt will be triggered when the number of received items reaches the threshold value
*
* @param channel RMT channel
* @param en enable or disable RX event interrupt.
* @param evt_thresh RMT event interrupt threshold value
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_rx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_thresh);
#endif
#if SOC_RMT_SUPPORT_TX_SYNCHRO
/**
* @brief Add channel into a synchronous group (channels in the same group can start transaction simultaneously)
*
* @param channel RMT channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_add_channel_to_group(rmt_channel_t channel);
/**
* @brief Remove channel out of a group
*
* @param channel RMT channel
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel);
#endif
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
/**
* @brief Set loop count threshold value for RMT TX channel
*
* When tx loop count reaches this value, an ISR callback will notify user
*
* @param channel RMT channel
* @param count loop count, 1 ~ 1023
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count);
/**
* @brief Enable or disable the feature that when loop count reaches the threshold, RMT will stop transmitting.
*
* - When the loop auto-stop feature is enabled will halt RMT transmission after the loop count reaches a certain threshold
* - When disabled, the RMT transmission continue indefinitely until halted by the users
*
* @note The auto-stop feature is implemented in hardware on particular targets (i.e. those with SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP defined).
* Otherwise, the auto-stop feature is implemented in software via the interrupt.
*
* @param channel RMT channel
* @param en enable bit
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_enable_tx_loop_autostop(rmt_channel_t channel, bool en);
#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
#ifdef __cplusplus
}
#endif

View File

@@ -1,278 +0,0 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/clk_tree_defs.h"
#include "driver/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RMT_CHANNEL_FLAGS_AWARE_DFS (1 << 0) /*!< Channel can work during APB clock scaling */
#define RMT_CHANNEL_FLAGS_INVERT_SIG (1 << 1) /*!< Invert RMT signal */
/**
* @brief Define memory space of each RMT channel (in words = 4 bytes)
*/
#define RMT_MEM_ITEM_NUM SOC_RMT_MEM_WORDS_PER_CHANNEL
/**
* @brief Definition of RMT item
*/
typedef struct {
union {
struct {
uint32_t duration0 : 15; /*!< Duration of level0 */
uint32_t level0 : 1; /*!< Level of the first part */
uint32_t duration1 : 15; /*!< Duration of level1 */
uint32_t level1 : 1; /*!< Level of the second part */
};
uint32_t val; /*!< Equivalent unsigned value for the RMT item */
};
} rmt_item32_t;
#if SOC_RMT_SUPPORTED
/**
* @brief RMT hardware memory layout
*/
typedef struct {
struct {
volatile rmt_item32_t data32[SOC_RMT_MEM_WORDS_PER_CHANNEL];
} chan[SOC_RMT_CHANNELS_PER_GROUP];
} rmt_mem_t;
#endif // SOC_RMT_SUPPORTED
/**
* @brief RMT channel ID
*/
typedef enum {
RMT_CHANNEL_0, /*!< RMT channel number 0 */
RMT_CHANNEL_1, /*!< RMT channel number 1 */
RMT_CHANNEL_2, /*!< RMT channel number 2 */
RMT_CHANNEL_3, /*!< RMT channel number 3 */
#if SOC_RMT_CHANNELS_PER_GROUP > 4
RMT_CHANNEL_4, /*!< RMT channel number 4 */
RMT_CHANNEL_5, /*!< RMT channel number 5 */
RMT_CHANNEL_6, /*!< RMT channel number 6 */
RMT_CHANNEL_7, /*!< RMT channel number 7 */
#endif
RMT_CHANNEL_MAX /*!< Number of RMT channels */
} rmt_channel_t;
/**
* @brief RMT Internal Memory Owner
*/
typedef enum {
RMT_MEM_OWNER_TX, /*!< RMT RX mode, RMT transmitter owns the memory block*/
RMT_MEM_OWNER_RX, /*!< RMT RX mode, RMT receiver owns the memory block*/
RMT_MEM_OWNER_MAX,
} rmt_mem_owner_t;
/**
* @brief Clock Source of RMT Channel
*/
#if SOC_RMT_SUPPORTED
typedef soc_periph_rmt_clk_src_legacy_t rmt_source_clk_t;
#else
typedef int rmt_source_clk_t;
#endif // SOC_RMT_SUPPORTED
/**
* @brief RMT Data Mode
*
* @note We highly recommended to use MEM mode not FIFO mode since there will be some gotcha in FIFO mode.
*/
typedef enum {
RMT_DATA_MODE_FIFO, /*<! RMT memory access in FIFO mode */
RMT_DATA_MODE_MEM, /*<! RMT memory access in memory mode */
RMT_DATA_MODE_MAX,
} rmt_data_mode_t;
/**
* @brief RMT Channel Working Mode (TX or RX)
*/
typedef enum {
RMT_MODE_TX, /*!< RMT TX mode */
RMT_MODE_RX, /*!< RMT RX mode */
RMT_MODE_MAX
} rmt_mode_t;
/**
* @brief RMT Idle Level
*
*/
typedef enum {
RMT_IDLE_LEVEL_LOW, /*!< RMT TX idle level: low Level */
RMT_IDLE_LEVEL_HIGH, /*!< RMT TX idle level: high Level */
RMT_IDLE_LEVEL_MAX,
} rmt_idle_level_t;
/**
* @brief RMT Carrier Level
*/
typedef enum {
RMT_CARRIER_LEVEL_LOW, /*!< RMT carrier wave is modulated for low Level output */
RMT_CARRIER_LEVEL_HIGH, /*!< RMT carrier wave is modulated for high Level output */
RMT_CARRIER_LEVEL_MAX
} rmt_carrier_level_t;
/**
* @brief RMT Channel Status
*/
typedef enum {
RMT_CHANNEL_UNINIT, /*!< RMT channel uninitialized */
RMT_CHANNEL_IDLE, /*!< RMT channel status idle */
RMT_CHANNEL_BUSY, /*!< RMT channel status busy */
} rmt_channel_status_t;
/**
* @brief Data struct of RMT channel status
*/
typedef struct {
rmt_channel_status_t status[RMT_CHANNEL_MAX]; /*!< Store the current status of each channel */
} rmt_channel_status_result_t;
/**
* @brief Data struct of RMT TX configure parameters
*/
typedef struct {
uint32_t carrier_freq_hz; /*!< RMT carrier frequency */
rmt_carrier_level_t carrier_level; /*!< Level of the RMT output, when the carrier is applied */
rmt_idle_level_t idle_level; /*!< RMT idle level */
uint8_t carrier_duty_percent; /*!< RMT carrier duty (%) */
uint32_t loop_count; /*!< Maximum loop count, only take effect for chips that is capable of `SOC_RMT_SUPPORT_TX_LOOP_COUNT` */
bool carrier_en; /*!< RMT carrier enable */
bool loop_en; /*!< Enable sending RMT items in a loop */
bool idle_output_en; /*!< RMT idle level output enable */
} rmt_tx_config_t;
/**
* @brief Data struct of RMT RX configure parameters
*/
typedef struct {
uint16_t idle_threshold; /*!< RMT RX idle threshold */
uint8_t filter_ticks_thresh; /*!< RMT filter tick number */
bool filter_en; /*!< RMT receiver filter enable */
#if SOC_RMT_SUPPORT_RX_DEMODULATION
bool rm_carrier; /*!< RMT receiver remove carrier enable */
uint32_t carrier_freq_hz; /*!< RMT carrier frequency */
uint8_t carrier_duty_percent; /*!< RMT carrier duty (%) */
rmt_carrier_level_t carrier_level; /*!< The level to remove the carrier */
#endif
} rmt_rx_config_t;
/**
* @brief Data struct of RMT configure parameters
*/
typedef struct {
rmt_mode_t rmt_mode; /*!< RMT mode: transmitter or receiver */
rmt_channel_t channel; /*!< RMT channel */
gpio_num_t gpio_num; /*!< RMT GPIO number */
uint8_t clk_div; /*!< RMT channel counter divider */
uint8_t mem_block_num; /*!< RMT memory block number */
uint32_t flags; /*!< RMT channel extra configurations, OR'd with RMT_CHANNEL_FLAGS_[*] */
union {
rmt_tx_config_t tx_config; /*!< RMT TX parameter */
rmt_rx_config_t rx_config; /*!< RMT RX parameter */
};
} rmt_config_t;
#if CONFIG_IDF_TARGET_ESP32H2
#define RMT_DEFAULT_CLK_DIV 32
#else
#define RMT_DEFAULT_CLK_DIV 80
#endif
/**
* @brief Default configuration for Tx channel
*
*/
#define RMT_DEFAULT_CONFIG_TX(gpio, channel_id) \
{ \
.rmt_mode = RMT_MODE_TX, \
.channel = channel_id, \
.gpio_num = gpio, \
.clk_div = RMT_DEFAULT_CLK_DIV, \
.mem_block_num = 1, \
.flags = 0, \
.tx_config = { \
.carrier_freq_hz = 38000, \
.carrier_level = RMT_CARRIER_LEVEL_HIGH, \
.idle_level = RMT_IDLE_LEVEL_LOW, \
.carrier_duty_percent = 33, \
.loop_count = 0, \
.carrier_en = false, \
.loop_en = false, \
.idle_output_en = true, \
} \
}
/**
* @brief Default configuration for RX channel
*
*/
#define RMT_DEFAULT_CONFIG_RX(gpio, channel_id) \
{ \
.rmt_mode = RMT_MODE_RX, \
.channel = channel_id, \
.gpio_num = gpio, \
.clk_div = RMT_DEFAULT_CLK_DIV, \
.mem_block_num = 1, \
.flags = 0, \
.rx_config = { \
.idle_threshold = 12000, \
.filter_ticks_thresh = 100, \
.filter_en = true, \
} \
}
/**
* @brief RMT interrupt handle
*/
typedef intr_handle_t rmt_isr_handle_t;
/**
* @brief Type of RMT Tx End callback function
*/
typedef void (*rmt_tx_end_fn_t)(rmt_channel_t channel, void *arg);
/**
* @brief Structure encapsulating a RMT TX end callback
*/
typedef struct {
rmt_tx_end_fn_t function; /*!< Function which is called on RMT TX end */
void *arg; /*!< Optional argument passed to function */
} rmt_tx_end_callback_t;
/**
* @brief User callback function to convert uint8_t type data to rmt format(rmt_item32_t).
*
* This function may be called from an ISR, so, the code should be short and efficient.
*
* @param src Pointer to the buffer storing the raw data that needs to be converted to rmt format.
* @param[out] dest Pointer to the buffer storing the rmt format data.
* @param src_size The raw data size.
* @param wanted_num The number of rmt format data that wanted to get.
* @param[out] translated_size The size of the raw data that has been converted to rmt format,
* it should return 0 if no data is converted in user callback.
* @param[out] item_num The number of the rmt format data that actually converted to,
* it can be less than wanted_num if there is not enough raw data, but cannot exceed wanted_num.
* it should return 0 if no data was converted.
*
* @note
* In fact, item_num should be a multiple of translated_size, e.g. :
* When we convert each byte of uint8_t type data to rmt format data,
* the relation between item_num and translated_size should be `item_num = translated_size*8`.
*/
typedef void (*sample_to_rmt_t)(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num);
#ifdef __cplusplus
}
#endif

View File

@@ -8,12 +8,6 @@ components/driver/test_apps/legacy_i2c_driver:
temporary: false
reason: disable target test for legacy i2c driver.
components/driver/test_apps/legacy_rmt_driver:
disable:
- if: SOC_RMT_SUPPORTED != 1
depends_filepatterns:
- components/driver/deprecated/**/*rmt*
components/driver/test_apps/legacy_twai:
disable:
- if: SOC_TWAI_SUPPORTED != 1 or SOC_TWAI_SUPPORT_FD == 1

View File

@@ -1,8 +0,0 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.22)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(legacy_rmt_test)

View File

@@ -1,2 +0,0 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |

View File

@@ -1,8 +0,0 @@
set(component_srcs "src/ir_builder_rmt_nec.c"
"src/ir_builder_rmt_rc5.c"
"src/ir_parser_rmt_nec.c"
"src/ir_parser_rmt_rc5.c")
idf_component_register(SRCS "${component_srcs}"
INCLUDE_DIRS "include"
PRIV_REQUIRES "driver")

View File

@@ -1,35 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Timings for NEC protocol
*
*/
#define NEC_LEADING_CODE_HIGH_US (9000)
#define NEC_LEADING_CODE_LOW_US (4500)
#define NEC_PAYLOAD_ONE_HIGH_US (560)
#define NEC_PAYLOAD_ONE_LOW_US (1690)
#define NEC_PAYLOAD_ZERO_HIGH_US (560)
#define NEC_PAYLOAD_ZERO_LOW_US (560)
#define NEC_REPEAT_CODE_HIGH_US (9000)
#define NEC_REPEAT_CODE_LOW_US (2250)
#define NEC_ENDING_CODE_HIGH_US (560)
/**
* @brief Timings for RC5 protocol
*
*/
#define RC5_PULSE_DURATION_US (889)
#ifdef __cplusplus
}
#endif

View File

@@ -1,266 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define IR_TOOLS_FLAGS_PROTO_EXT (1 << 0) /*!< Enable Extended IR protocol */
#define IR_TOOLS_FLAGS_INVERSE (1 << 1) /*!< Inverse the IR signal, i.e. take high level as low, and vice versa */
/**
* @brief IR device type
*
*/
typedef void *ir_dev_t;
/**
* @brief IR builder type
*
*/
typedef struct ir_builder_s ir_builder_t;
/**
* @brief IR parser type
*
*/
typedef struct ir_parser_s ir_parser_t;
/**
* @brief Type definition of IR builder
*
*/
struct ir_builder_s {
/**
* @brief Period time of sending repeat code
*
*/
uint32_t repeat_period_ms;
/**
* @brief Build frame header
*
* @param[in] builder: Handle of IR builder
*
* @return
* - ESP_OK: Build frame header successfully
* - ESP_FAIL: Build frame header failed because some error occurred
*/
esp_err_t (*make_head)(ir_builder_t *builder);
/**
* @brief Build logic bit zero
*
* @param[in] builder: Handle of IR builder
*
* @return
* - ESP_OK: Build logic bit zero successfully
* - ESP_FAIL: Build logic bit zero failed because some error occurred
*/
esp_err_t (*make_logic0)(ir_builder_t *builder);
/**
* @brief Build logic bit one
*
* @param[in] builder: Handle of IR builder
*
* @return
* ESP_OK: Build logic bit one successfully
* ESP_FAIL: Build logic bit one failed because some error occurred
*/
esp_err_t (*make_logic1)(ir_builder_t *builder);
/**
* @brief Build frame tail
*
* @param[in] builder: Handle of IR builder
*
* @return
* - ESP_OK: Build frame tail successfully
* - ESP_FAIL: Build frame tail failed because some error occurred
*/
esp_err_t (*make_end)(ir_builder_t *builder);
/**
* @brief Build a complete frame
*
* @param[in] builder: Handle of IR builder
*
* @return
* - ESP_OK: Build a complete frame successfully
* - ESP_FAIL: Build a complete frame failed because some error occurred
*/
esp_err_t (*build_frame)(ir_builder_t *builder, uint32_t address, uint32_t command);
/**
* @brief Build a repeat frame
*
* @param[in] builder: Handle of IR builder
*
* @return
* - ESP_OK: Build a repeat frame successfully
* - ESP_FAIL: Build a repeat frame failed because some error occurred
*/
esp_err_t (*build_repeat_frame)(ir_builder_t *builder);
/**
* @brief Get the result frame after a series of building steps
*
* @param[in] builder: Handle of IR builder
* @param[out] result: Result of frame building, which contains all of the raw data that could be send directly
* @param[out] length: Length of result data
*
* @return
* - ESP_OK: Get result data successfully
* - ESP_ERR_INVALID_ARG: Get result data failed because of invalid arguments
* - ESP_FAIL: Get result data failed because some other errors occurred
*/
esp_err_t (*get_result)(ir_builder_t *builder, void *result, size_t *length);
/**
* @brief Free resources used by IR builder
*
* @param[in] builder: Handle of IR builder
*
* @return
* - ESP_OK: Free resources successfully
* - ESP_FAIL: Free resources failed because some error occurred
*/
esp_err_t (*del)(ir_builder_t *builder);
};
/**
* @brief Type definition of IR parser
*
*/
struct ir_parser_s {
/**
* @brief Input raw data to IR parser
*
* @param[in] parser: Handle of IR parser
* @param[in] raw_data: Raw data which need decoding by IR parser
* @param[in] length: Length of raw data
*
* @return
* - ESP_OK: Input raw data successfully
* - ESP_ERR_INVALID_ARG: Input raw data failed because of invalid argument
* - ESP_FAIL: Input raw data failed because some other error occurred
*/
esp_err_t (*input)(ir_parser_t *parser, void *raw_data, uint32_t length);
/**
* @brief Get the scan code after decoding of raw data
*
* @param[in] parser: Handle of IR parser
* @param[out] address: Address of the scan code
* @param[out] command: Command of the scan code
* @param[out] repeat: Indicate if it's a repeat code
*
* @return
* - ESP_OK: Get scan code successfully
* - ESP_ERR_INVALID_ARG: Get scan code failed because of invalid arguments
* - ESP_FAIL: Get scan code failed because some error occurred
*/
esp_err_t (*get_scan_code)(ir_parser_t *parser, uint32_t *address, uint32_t *command, bool *repeat);
/**
* @brief Free resources used by IR parser
*
* @param[in] parser: Handle of IR parser
*
* @return
* - ESP_OK: Free resource successfully
* - ESP_FAIL: Free resources fail failed because some error occurred
*/
esp_err_t (*del)(ir_parser_t *parser);
};
/**
* @brief Configuration type of IR builder
*
*/
typedef struct {
uint32_t buffer_size; /*!< Size of the internal buffer used by IR builder */
ir_dev_t dev_hdl; /*!< IR device handle */
uint32_t flags; /*!< Flags for IR builder, different flags will enable different features */
} ir_builder_config_t;
/**
* @brief Configuration type of IR parser
*
*/
typedef struct {
ir_dev_t dev_hdl; /*!< IR device handle */
uint32_t flags; /*!< Flags for IR parser, different flags will enable different features */
uint32_t margin_us; /*!< Timing parameter, indicating the tolerance to environment noise */
} ir_parser_config_t;
/**
* @brief Default configuration for IR builder
*
*/
#define IR_BUILDER_DEFAULT_CONFIG(dev) \
{ \
.buffer_size = 64, \
.dev_hdl = dev, \
.flags = 0, \
}
/**
* @brief Default configuration for IR parser
*
*/
#define IR_PARSER_DEFAULT_CONFIG(dev) \
{ \
.dev_hdl = dev, \
.flags = 0, \
.margin_us = 200, \
}
/**
* @brief Creat a NEC protocol builder
*
* @param config: configuration of NEC builder
* @return
* Handle of NEC builder or NULL
*/
ir_builder_t *ir_builder_rmt_new_nec(const ir_builder_config_t *config);
/**
* @brief Creat a RC5 protocol builder
*
* @param config: configuration of RC5 builder
* @return
* Handle of RC5 builder or NULL
*/
ir_builder_t *ir_builder_rmt_new_rc5(const ir_builder_config_t *config);
/**
* @brief Creat a NEC protocol parser
*
* @param config: configuration of NEC parser
* @return
* Handle of NEC parser or NULL
*/
ir_parser_t *ir_parser_rmt_new_nec(const ir_parser_config_t *config);
/**
* @brief Creat a RC5 protocol parser
*
* @param config: configuration of RC5 parser
* @return
* Handle of RC5 parser or NULL
*/
ir_parser_t *ir_parser_rmt_new_rc5(const ir_parser_config_t *config);
#ifdef __cplusplus
}
#endif

View File

@@ -1,198 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/cdefs.h>
#include "esp_log.h"
#include "ir_tools.h"
#include "ir_timings.h"
#include "driver/rmt.h"
static const char *TAG = "nec_builder";
#define NEC_CHECK(a, str, goto_tag, ret_value, ...) \
do \
{ \
if (!(a)) \
{ \
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
ret = ret_value; \
goto goto_tag; \
} \
} while (0)
typedef struct {
ir_builder_t parent;
uint32_t buffer_size;
uint32_t cursor;
uint32_t flags;
uint32_t leading_code_high_ticks;
uint32_t leading_code_low_ticks;
uint32_t repeat_code_high_ticks;
uint32_t repeat_code_low_ticks;
uint32_t payload_logic0_high_ticks;
uint32_t payload_logic0_low_ticks;
uint32_t payload_logic1_high_ticks;
uint32_t payload_logic1_low_ticks;
uint32_t ending_code_high_ticks;
uint32_t ending_code_low_ticks;
bool inverse;
rmt_item32_t buffer[0];
} nec_builder_t;
static esp_err_t nec_builder_make_head(ir_builder_t *builder)
{
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
nec_builder->cursor = 0;
nec_builder->buffer[nec_builder->cursor].level0 = !nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration0 = nec_builder->leading_code_high_ticks;
nec_builder->buffer[nec_builder->cursor].level1 = nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration1 = nec_builder->leading_code_low_ticks;
nec_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t nec_builder_make_logic0(ir_builder_t *builder)
{
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
nec_builder->buffer[nec_builder->cursor].level0 = !nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration0 = nec_builder->payload_logic0_high_ticks;
nec_builder->buffer[nec_builder->cursor].level1 = nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration1 = nec_builder->payload_logic0_low_ticks;
nec_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t nec_builder_make_logic1(ir_builder_t *builder)
{
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
nec_builder->buffer[nec_builder->cursor].level0 = !nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration0 = nec_builder->payload_logic1_high_ticks;
nec_builder->buffer[nec_builder->cursor].level1 = nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration1 = nec_builder->payload_logic1_low_ticks;
nec_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t nec_builder_make_end(ir_builder_t *builder)
{
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
nec_builder->buffer[nec_builder->cursor].level0 = !nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration0 = nec_builder->ending_code_high_ticks;
nec_builder->buffer[nec_builder->cursor].level1 = nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration1 = nec_builder->ending_code_low_ticks;
nec_builder->cursor += 1;
nec_builder->buffer[nec_builder->cursor].val = 0;
nec_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t nec_build_frame(ir_builder_t *builder, uint32_t address, uint32_t command)
{
esp_err_t ret = ESP_OK;
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
if (!nec_builder->flags & IR_TOOLS_FLAGS_PROTO_EXT) {
uint8_t low_byte = address & 0xFF;
uint8_t high_byte = (address >> 8) & 0xFF;
NEC_CHECK(low_byte == (~high_byte & 0xFF), "address not match standard NEC protocol", err, ESP_ERR_INVALID_ARG);
low_byte = command & 0xFF;
high_byte = (command >> 8) & 0xFF;
NEC_CHECK(low_byte == (~high_byte & 0xFF), "command not match standard NEC protocol", err, ESP_ERR_INVALID_ARG);
}
builder->make_head(builder);
// LSB -> MSB
for (int i = 0; i < 16; i++) {
if (address & (1 << i)) {
builder->make_logic1(builder);
} else {
builder->make_logic0(builder);
}
}
for (int i = 0; i < 16; i++) {
if (command & (1 << i)) {
builder->make_logic1(builder);
} else {
builder->make_logic0(builder);
}
}
builder->make_end(builder);
return ESP_OK;
err:
return ret;
}
static esp_err_t nec_build_repeat_frame(ir_builder_t *builder)
{
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
nec_builder->cursor = 0;
nec_builder->buffer[nec_builder->cursor].level0 = !nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration0 = nec_builder->repeat_code_high_ticks;
nec_builder->buffer[nec_builder->cursor].level1 = nec_builder->inverse;
nec_builder->buffer[nec_builder->cursor].duration1 = nec_builder->repeat_code_low_ticks;
nec_builder->cursor += 1;
nec_builder_make_end(builder);
return ESP_OK;
}
static esp_err_t nec_builder_get_result(ir_builder_t *builder, void *result, size_t *length)
{
esp_err_t ret = ESP_OK;
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
NEC_CHECK(result && length, "result and length can't be null", err, ESP_ERR_INVALID_ARG);
*(rmt_item32_t **)result = nec_builder->buffer;
*length = nec_builder->cursor;
return ESP_OK;
err:
return ret;
}
static esp_err_t nec_builder_del(ir_builder_t *builder)
{
nec_builder_t *nec_builder = __containerof(builder, nec_builder_t, parent);
free(nec_builder);
return ESP_OK;
}
ir_builder_t *ir_builder_rmt_new_nec(const ir_builder_config_t *config)
{
ir_builder_t *ret = NULL;
NEC_CHECK(config, "nec configuration can't be null", err, NULL);
NEC_CHECK(config->buffer_size, "buffer size can't be zero", err, NULL);
uint32_t builder_size = sizeof(nec_builder_t) + config->buffer_size * sizeof(rmt_item32_t);
nec_builder_t *nec_builder = calloc(1, builder_size);
NEC_CHECK(nec_builder, "request memory for nec_builder failed", err, NULL);
nec_builder->buffer_size = config->buffer_size;
nec_builder->flags = config->flags;
if (config->flags & IR_TOOLS_FLAGS_INVERSE) {
nec_builder->inverse = true;
}
uint32_t counter_clk_hz = 0;
NEC_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev_hdl, &counter_clk_hz) == ESP_OK,
"get rmt counter clock failed", err, NULL);
float ratio = (float)counter_clk_hz / 1e6;
nec_builder->leading_code_high_ticks = (uint32_t)(ratio * NEC_LEADING_CODE_HIGH_US);
nec_builder->leading_code_low_ticks = (uint32_t)(ratio * NEC_LEADING_CODE_LOW_US);
nec_builder->repeat_code_high_ticks = (uint32_t)(ratio * NEC_REPEAT_CODE_HIGH_US);
nec_builder->repeat_code_low_ticks = (uint32_t)(ratio * NEC_REPEAT_CODE_LOW_US);
nec_builder->payload_logic0_high_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ZERO_HIGH_US);
nec_builder->payload_logic0_low_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ZERO_LOW_US);
nec_builder->payload_logic1_high_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ONE_HIGH_US);
nec_builder->payload_logic1_low_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ONE_LOW_US);
nec_builder->ending_code_high_ticks = (uint32_t)(ratio * NEC_ENDING_CODE_HIGH_US);
nec_builder->ending_code_low_ticks = 0x7FFF;
nec_builder->parent.make_head = nec_builder_make_head;
nec_builder->parent.make_logic0 = nec_builder_make_logic0;
nec_builder->parent.make_logic1 = nec_builder_make_logic1;
nec_builder->parent.make_end = nec_builder_make_end;
nec_builder->parent.build_frame = nec_build_frame;
nec_builder->parent.build_repeat_frame = nec_build_repeat_frame;
nec_builder->parent.get_result = nec_builder_get_result;
nec_builder->parent.del = nec_builder_del;
nec_builder->parent.repeat_period_ms = 110;
return &nec_builder->parent;
err:
return ret;
}

View File

@@ -1,182 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <sys/cdefs.h>
#include "esp_log.h"
#include "ir_tools.h"
#include "ir_timings.h"
#include "driver/rmt.h"
static const char *TAG = "rc5_builder";
#define RC5_CHECK(a, str, goto_tag, ret_value, ...) \
do \
{ \
if (!(a)) \
{ \
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
ret = ret_value; \
goto goto_tag; \
} \
} while (0)
typedef struct {
ir_builder_t parent;
uint32_t buffer_size;
uint32_t cursor;
uint32_t pulse_duration_ticks;
uint32_t flags;
bool toggle;
bool s2_bit;
bool inverse;
rmt_item32_t buffer[0];
} rc5_builder_t;
static esp_err_t rc5_builder_make_head(ir_builder_t *builder)
{
rc5_builder_t *rc5_builder = __containerof(builder, rc5_builder_t, parent);
rc5_builder->cursor = 0;
rc5_builder->toggle = !rc5_builder->toggle;
// S1 default (not inverse) is 0
rc5_builder->buffer[rc5_builder->cursor].level0 = rc5_builder->inverse;
rc5_builder->buffer[rc5_builder->cursor].duration0 = rc5_builder->pulse_duration_ticks;
rc5_builder->buffer[rc5_builder->cursor].level1 = !rc5_builder->inverse;
rc5_builder->buffer[rc5_builder->cursor].duration1 = rc5_builder->pulse_duration_ticks;
rc5_builder->cursor += 1;
// S2 default (not inverse) is depend on whether use extended protocol
rc5_builder->buffer[rc5_builder->cursor].level0 = rc5_builder->s2_bit ^ rc5_builder->inverse;
rc5_builder->buffer[rc5_builder->cursor].duration0 = rc5_builder->pulse_duration_ticks;
rc5_builder->buffer[rc5_builder->cursor].level1 = !(rc5_builder->s2_bit ^ rc5_builder->inverse);
rc5_builder->buffer[rc5_builder->cursor].duration1 = rc5_builder->pulse_duration_ticks;
rc5_builder->cursor += 1;
// T
rc5_builder->buffer[rc5_builder->cursor].level0 = rc5_builder->toggle;
rc5_builder->buffer[rc5_builder->cursor].duration0 = rc5_builder->pulse_duration_ticks;
rc5_builder->buffer[rc5_builder->cursor].level1 = !rc5_builder->toggle;
rc5_builder->buffer[rc5_builder->cursor].duration1 = rc5_builder->pulse_duration_ticks;
rc5_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t rc5_builder_make_logic0(ir_builder_t *builder)
{
rc5_builder_t *rc5_builder = __containerof(builder, rc5_builder_t, parent);
rc5_builder->buffer[rc5_builder->cursor].level0 = !rc5_builder->inverse;
rc5_builder->buffer[rc5_builder->cursor].duration0 = rc5_builder->pulse_duration_ticks;
rc5_builder->buffer[rc5_builder->cursor].level1 = rc5_builder->inverse;
rc5_builder->buffer[rc5_builder->cursor].duration1 = rc5_builder->pulse_duration_ticks;
rc5_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t rc5_builder_make_logic1(ir_builder_t *builder)
{
rc5_builder_t *rc5_builder = __containerof(builder, rc5_builder_t, parent);
rc5_builder->buffer[rc5_builder->cursor].level0 = rc5_builder->inverse;
rc5_builder->buffer[rc5_builder->cursor].duration0 = rc5_builder->pulse_duration_ticks;
rc5_builder->buffer[rc5_builder->cursor].level1 = !rc5_builder->inverse;
rc5_builder->buffer[rc5_builder->cursor].duration1 = rc5_builder->pulse_duration_ticks;
rc5_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t rc5_builder_make_end(ir_builder_t *builder)
{
rc5_builder_t *rc5_builder = __containerof(builder, rc5_builder_t, parent);
rc5_builder->buffer[rc5_builder->cursor].val = 0;
rc5_builder->cursor += 1;
return ESP_OK;
}
static esp_err_t rc5_build_frame(ir_builder_t *builder, uint32_t address, uint32_t command)
{
rc5_builder_t *rc5_builder = __containerof(builder, rc5_builder_t, parent);
if (rc5_builder->flags & IR_TOOLS_FLAGS_PROTO_EXT) {
// RC5-extended protocol uses S2 bit as a 7th command bit (MSB of a command)
if (command > 63) {
rc5_builder->s2_bit = true;
} else {
rc5_builder->s2_bit = false;
}
}
builder->make_head(builder);
// MSB -> LSB
for (int i = 4; i >= 0; i--) {
if (address & (1 << i)) {
builder->make_logic1(builder);
} else {
builder->make_logic0(builder);
}
}
for (int i = 5; i >= 0; i--) {
if (command & (1 << i)) {
builder->make_logic1(builder);
} else {
builder->make_logic0(builder);
}
}
builder->make_end(builder);
return ESP_OK;
}
static esp_err_t rc5_build_repeat_frame(ir_builder_t *builder)
{
// repeat frame is just the latest build frame, so do nothing here
return ESP_OK;
}
static esp_err_t rc5_builder_get_result(ir_builder_t *builder, void *result, size_t *length)
{
esp_err_t ret = ESP_OK;
rc5_builder_t *rc5_builder = __containerof(builder, rc5_builder_t, parent);
RC5_CHECK(result && length, "result and length can't be null", err, ESP_ERR_INVALID_ARG);
*(rmt_item32_t **)result = rc5_builder->buffer;
*length = rc5_builder->cursor;
return ESP_OK;
err:
return ret;
}
static esp_err_t rc5_builder_del(ir_builder_t *builder)
{
rc5_builder_t *rc5_builder = __containerof(builder, rc5_builder_t, parent);
free(rc5_builder);
return ESP_OK;
}
ir_builder_t *ir_builder_rmt_new_rc5(const ir_builder_config_t *config)
{
ir_builder_t *ret = NULL;
RC5_CHECK(config, "rc5 configuration can't be null", err, NULL);
RC5_CHECK(config->buffer_size, "buffer size can't be zero", err, NULL);
uint32_t builder_size = sizeof(rc5_builder_t) + config->buffer_size * sizeof(rmt_item32_t);
rc5_builder_t *rc5_builder = calloc(1, builder_size);
RC5_CHECK(rc5_builder, "request memory for rc5_builder failed", err, NULL);
rc5_builder->buffer_size = config->buffer_size;
rc5_builder->flags = config->flags;
if (config->flags & IR_TOOLS_FLAGS_INVERSE) {
rc5_builder->inverse = true;
}
uint32_t counter_clk_hz = 0;
RC5_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev_hdl, &counter_clk_hz) == ESP_OK,
"get rmt counter clock failed", err, NULL);
float ratio = (float)counter_clk_hz / 1e6;
rc5_builder->pulse_duration_ticks = (uint32_t)(ratio * RC5_PULSE_DURATION_US);
rc5_builder->parent.make_head = rc5_builder_make_head;
rc5_builder->parent.make_logic0 = rc5_builder_make_logic0;
rc5_builder->parent.make_logic1 = rc5_builder_make_logic1;
rc5_builder->parent.make_end = rc5_builder_make_end;
rc5_builder->parent.build_frame = rc5_build_frame;
rc5_builder->parent.build_repeat_frame = rc5_build_repeat_frame;
rc5_builder->parent.get_result = rc5_builder_get_result;
rc5_builder->parent.del = rc5_builder_del;
rc5_builder->parent.repeat_period_ms = 114;
return &rc5_builder->parent;
err:
return ret;
}

View File

@@ -1,210 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <sys/cdefs.h>
#include "esp_log.h"
#include "ir_tools.h"
#include "ir_timings.h"
#include "driver/rmt.h"
static const char *TAG = "nec_parser";
#define NEC_CHECK(a, str, goto_tag, ret_value, ...) \
do \
{ \
if (!(a)) \
{ \
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
ret = ret_value; \
goto goto_tag; \
} \
} while (0)
#define NEC_DATA_FRAME_RMT_WORDS (34)
#define NEC_REPEAT_FRAME_RMT_WORDS (2)
typedef struct {
ir_parser_t parent;
uint32_t flags;
uint32_t leading_code_high_ticks;
uint32_t leading_code_low_ticks;
uint32_t repeat_code_high_ticks;
uint32_t repeat_code_low_ticks;
uint32_t payload_logic0_high_ticks;
uint32_t payload_logic0_low_ticks;
uint32_t payload_logic1_high_ticks;
uint32_t payload_logic1_low_ticks;
uint32_t margin_ticks;
rmt_item32_t *buffer;
uint32_t cursor;
uint32_t last_address;
uint32_t last_command;
bool repeat;
bool inverse;
} nec_parser_t;
static inline bool nec_check_in_range(uint32_t raw_ticks, uint32_t target_ticks, uint32_t margin_ticks)
{
return (raw_ticks < (target_ticks + margin_ticks)) && (raw_ticks > (target_ticks - margin_ticks));
}
static bool nec_parse_head(nec_parser_t *nec_parser)
{
nec_parser->cursor = 0;
rmt_item32_t item = nec_parser->buffer[nec_parser->cursor];
bool ret = (item.level0 == nec_parser->inverse) && (item.level1 != nec_parser->inverse) &&
nec_check_in_range(item.duration0, nec_parser->leading_code_high_ticks, nec_parser->margin_ticks) &&
nec_check_in_range(item.duration1, nec_parser->leading_code_low_ticks, nec_parser->margin_ticks);
nec_parser->cursor += 1;
return ret;
}
static bool nec_parse_logic0(nec_parser_t *nec_parser)
{
rmt_item32_t item = nec_parser->buffer[nec_parser->cursor];
bool ret = (item.level0 == nec_parser->inverse) && (item.level1 != nec_parser->inverse) &&
nec_check_in_range(item.duration0, nec_parser->payload_logic0_high_ticks, nec_parser->margin_ticks) &&
nec_check_in_range(item.duration1, nec_parser->payload_logic0_low_ticks, nec_parser->margin_ticks);
return ret;
}
static bool nec_parse_logic1(nec_parser_t *nec_parser)
{
rmt_item32_t item = nec_parser->buffer[nec_parser->cursor];
bool ret = (item.level0 == nec_parser->inverse) && (item.level1 != nec_parser->inverse) &&
nec_check_in_range(item.duration0, nec_parser->payload_logic1_high_ticks, nec_parser->margin_ticks) &&
nec_check_in_range(item.duration1, nec_parser->payload_logic1_low_ticks, nec_parser->margin_ticks);
return ret;
}
static esp_err_t nec_parse_logic(ir_parser_t *parser, bool *logic)
{
esp_err_t ret = ESP_FAIL;
bool logic_value = false;
nec_parser_t *nec_parser = __containerof(parser, nec_parser_t, parent);
if (nec_parse_logic0(nec_parser)) {
logic_value = false;
ret = ESP_OK;
} else if (nec_parse_logic1(nec_parser)) {
logic_value = true;
ret = ESP_OK;
}
if (ret == ESP_OK) {
*logic = logic_value;
}
nec_parser->cursor += 1;
return ret;
}
static bool nec_parse_repeat_frame(nec_parser_t *nec_parser)
{
nec_parser->cursor = 0;
rmt_item32_t item = nec_parser->buffer[nec_parser->cursor];
bool ret = (item.level0 == nec_parser->inverse) && (item.level1 != nec_parser->inverse) &&
nec_check_in_range(item.duration0, nec_parser->repeat_code_high_ticks, nec_parser->margin_ticks) &&
nec_check_in_range(item.duration1, nec_parser->repeat_code_low_ticks, nec_parser->margin_ticks);
nec_parser->cursor += 1;
return ret;
}
static esp_err_t nec_parser_input(ir_parser_t *parser, void *raw_data, uint32_t length)
{
esp_err_t ret = ESP_OK;
nec_parser_t *nec_parser = __containerof(parser, nec_parser_t, parent);
NEC_CHECK(raw_data, "input data can't be null", err, ESP_ERR_INVALID_ARG);
nec_parser->buffer = raw_data;
// Data Frame costs 34 items and Repeat Frame costs 2 items
if (length == NEC_DATA_FRAME_RMT_WORDS) {
nec_parser->repeat = false;
} else if (length == NEC_REPEAT_FRAME_RMT_WORDS) {
nec_parser->repeat = true;
} else {
ret = ESP_FAIL;
}
return ret;
err:
return ret;
}
static esp_err_t nec_parser_get_scan_code(ir_parser_t *parser, uint32_t *address, uint32_t *command, bool *repeat)
{
esp_err_t ret = ESP_FAIL;
uint32_t addr = 0;
uint32_t cmd = 0;
bool logic_value = false;
nec_parser_t *nec_parser = __containerof(parser, nec_parser_t, parent);
NEC_CHECK(address && command && repeat, "address, command and repeat can't be null", out, ESP_ERR_INVALID_ARG);
if (nec_parser->repeat) {
if (nec_parse_repeat_frame(nec_parser)) {
*address = nec_parser->last_address;
*command = nec_parser->last_command;
*repeat = true;
ret = ESP_OK;
}
} else {
if (nec_parse_head(nec_parser)) {
for (int i = 0; i < 16; i++) {
if (nec_parse_logic(parser, &logic_value) == ESP_OK) {
addr |= (logic_value << i);
}
}
for (int i = 0; i < 16; i++) {
if (nec_parse_logic(parser, &logic_value) == ESP_OK) {
cmd |= (logic_value << i);
}
}
*address = addr;
*command = cmd;
*repeat = false;
// keep it as potential repeat code
nec_parser->last_address = addr;
nec_parser->last_command = cmd;
ret = ESP_OK;
}
}
out:
return ret;
}
static esp_err_t nec_parser_del(ir_parser_t *parser)
{
nec_parser_t *nec_parser = __containerof(parser, nec_parser_t, parent);
free(nec_parser);
return ESP_OK;
}
ir_parser_t *ir_parser_rmt_new_nec(const ir_parser_config_t *config)
{
ir_parser_t *ret = NULL;
NEC_CHECK(config, "nec configuration can't be null", err, NULL);
nec_parser_t *nec_parser = calloc(1, sizeof(nec_parser_t));
NEC_CHECK(nec_parser, "request memory for nec_parser failed", err, NULL);
nec_parser->flags = config->flags;
if (config->flags & IR_TOOLS_FLAGS_INVERSE) {
nec_parser->inverse = true;
}
uint32_t counter_clk_hz = 0;
NEC_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev_hdl, &counter_clk_hz) == ESP_OK,
"get rmt counter clock failed", err, NULL);
float ratio = (float)counter_clk_hz / 1e6;
nec_parser->leading_code_high_ticks = (uint32_t)(ratio * NEC_LEADING_CODE_HIGH_US);
nec_parser->leading_code_low_ticks = (uint32_t)(ratio * NEC_LEADING_CODE_LOW_US);
nec_parser->repeat_code_high_ticks = (uint32_t)(ratio * NEC_REPEAT_CODE_HIGH_US);
nec_parser->repeat_code_low_ticks = (uint32_t)(ratio * NEC_REPEAT_CODE_LOW_US);
nec_parser->payload_logic0_high_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ZERO_HIGH_US);
nec_parser->payload_logic0_low_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ZERO_LOW_US);
nec_parser->payload_logic1_high_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ONE_HIGH_US);
nec_parser->payload_logic1_low_ticks = (uint32_t)(ratio * NEC_PAYLOAD_ONE_LOW_US);
nec_parser->margin_ticks = (uint32_t)(ratio * config->margin_us);
nec_parser->parent.input = nec_parser_input;
nec_parser->parent.get_scan_code = nec_parser_get_scan_code;
nec_parser->parent.del = nec_parser_del;
return &nec_parser->parent;
err:
return ret;
}

View File

@@ -1,157 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <sys/cdefs.h>
#include "esp_log.h"
#include "ir_tools.h"
#include "ir_timings.h"
#include "driver/rmt.h"
static const char *TAG = "rc5_parser";
#define RC5_CHECK(a, str, goto_tag, ret_value, ...) \
do \
{ \
if (!(a)) \
{ \
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
ret = ret_value; \
goto goto_tag; \
} \
} while (0)
#define RC5_MAX_FRAME_RMT_WORDS (14) // S1+S2+T+ADDR(5)+CMD(6)
typedef struct {
ir_parser_t parent;
uint32_t flags;
uint32_t pulse_duration_ticks;
uint32_t margin_ticks;
rmt_item32_t *buffer;
uint32_t buffer_len;
uint32_t last_command;
uint32_t last_address;
bool last_t_bit;
} rc5_parser_t;
static inline bool rc5_check_in_range(uint32_t raw_ticks, uint32_t target_ticks, uint32_t margin_ticks)
{
return (raw_ticks < (target_ticks + margin_ticks)) && (raw_ticks > (target_ticks - margin_ticks));
}
static esp_err_t rc5_parser_input(ir_parser_t *parser, void *raw_data, uint32_t length)
{
esp_err_t ret = ESP_OK;
rc5_parser_t *rc5_parser = __containerof(parser, rc5_parser_t, parent);
rc5_parser->buffer = raw_data;
rc5_parser->buffer_len = length;
if (length > RC5_MAX_FRAME_RMT_WORDS) {
ret = ESP_FAIL;
}
return ret;
}
static inline bool rc5_duration_one_unit(rc5_parser_t *rc5_parser, uint32_t duration)
{
return (duration < (rc5_parser->pulse_duration_ticks + rc5_parser->margin_ticks)) &&
(duration > (rc5_parser->pulse_duration_ticks - rc5_parser->margin_ticks));
}
static inline bool rc5_duration_two_unit(rc5_parser_t *rc5_parser, uint32_t duration)
{
return (duration < (rc5_parser->pulse_duration_ticks * 2 + rc5_parser->margin_ticks)) &&
(duration > (rc5_parser->pulse_duration_ticks * 2 - rc5_parser->margin_ticks));
}
static esp_err_t rc5_parser_get_scan_code(ir_parser_t *parser, uint32_t *address, uint32_t *command, bool *repeat)
{
esp_err_t ret = ESP_FAIL;
uint32_t parse_result = 0; // 32 bit is enough to hold the parse result of one RC5 frame
uint32_t addr = 0;
uint32_t cmd = 0;
bool s1 = true;
bool s2 = true;
bool t = false;
bool exchange = false;
rc5_parser_t *rc5_parser = __containerof(parser, rc5_parser_t, parent);
RC5_CHECK(address && command && repeat, "address, command and repeat can't be null", out, ESP_ERR_INVALID_ARG);
for (int i = 0; i < rc5_parser->buffer_len; i++) {
if (rc5_duration_one_unit(rc5_parser, rc5_parser->buffer[i].duration0)) {
parse_result <<= 1;
parse_result |= exchange;
if (rc5_duration_two_unit(rc5_parser, rc5_parser->buffer[i].duration1)) {
exchange = !exchange;
}
} else if (rc5_duration_two_unit(rc5_parser, rc5_parser->buffer[i].duration0)) {
parse_result <<= 1;
parse_result |= rc5_parser->buffer[i].level0;
parse_result <<= 1;
parse_result |= !rc5_parser->buffer[i].level0;
if (rc5_duration_one_unit(rc5_parser, rc5_parser->buffer[i].duration1)) {
exchange = !exchange;
}
} else {
goto out;
}
}
if (!(rc5_parser->flags & IR_TOOLS_FLAGS_INVERSE)) {
parse_result = ~parse_result;
}
s1 = ((parse_result & 0x2000) >> 13) & 0x01;
s2 = ((parse_result & 0x1000) >> 12) & 0x01;
t = ((parse_result & 0x800) >> 11) & 0x01;
// Check S1, must be 1
if (s1) {
if (!(rc5_parser->flags & IR_TOOLS_FLAGS_PROTO_EXT) && !s2) {
// Not standard RC5 protocol, but S2 is 0
goto out;
}
addr = (parse_result & 0x7C0) >> 6;
cmd = (parse_result & 0x3F);
if (!s2) {
cmd |= 1 << 6;
}
*repeat = (t == rc5_parser->last_t_bit && addr == rc5_parser->last_address && cmd == rc5_parser->last_command);
*address = addr;
*command = cmd;
rc5_parser->last_address = addr;
rc5_parser->last_command = cmd;
rc5_parser->last_t_bit = t;
ret = ESP_OK;
}
out:
return ret;
}
static esp_err_t rc5_parser_del(ir_parser_t *parser)
{
rc5_parser_t *rc5_parser = __containerof(parser, rc5_parser_t, parent);
free(rc5_parser);
return ESP_OK;
}
ir_parser_t *ir_parser_rmt_new_rc5(const ir_parser_config_t *config)
{
ir_parser_t *ret = NULL;
RC5_CHECK(config, "rc5 configuration can't be null", err, NULL);
rc5_parser_t *rc5_parser = calloc(1, sizeof(rc5_parser_t));
RC5_CHECK(rc5_parser, "request memory for rc5_parser failed", err, NULL);
rc5_parser->flags = config->flags;
uint32_t counter_clk_hz = 0;
RC5_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev_hdl, &counter_clk_hz) == ESP_OK,
"get rmt counter clock failed", err, NULL);
float ratio = (float)counter_clk_hz / 1e6;
rc5_parser->pulse_duration_ticks = (uint32_t)(ratio * RC5_PULSE_DURATION_US);
rc5_parser->margin_ticks = (uint32_t)(ratio * config->margin_us);
rc5_parser->parent.input = rc5_parser_input;
rc5_parser->parent.get_scan_code = rc5_parser_get_scan_code;
rc5_parser->parent.del = rc5_parser_del;
return &rc5_parser->parent;
err:
return ret;
}

View File

@@ -1,6 +0,0 @@
set(srcs "test_app_main.c"
"test_legacy_rmt.c")
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity driver infrared_tools
WHOLE_ARCHIVE)

View File

@@ -1,40 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_runner.h"
#include "esp_heap_caps.h"
#define TEST_MEMORY_LEAK_THRESHOLD (-600)
static size_t before_free_8bit;
static size_t before_free_32bit;
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
}
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT");
check_leak(before_free_32bit, after_free_32bit, "32BIT");
}
void app_main(void)
{
unity_run_menu();
}

View File

@@ -1,644 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "hal/gpio_hal.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_cpu.h"
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_rom_gpio.h"
#include "ir_tools.h"
#include "driver/rmt.h"
#include "soc/rmt_periph.h"
#include "esp_private/gpio.h"
#define RMT_RX_CHANNEL_ENCODING_START (SOC_RMT_CHANNELS_PER_GROUP-SOC_RMT_TX_CANDIDATES_PER_GROUP)
#define RMT_TX_CHANNEL_ENCODING_END (SOC_RMT_TX_CANDIDATES_PER_GROUP-1)
// CI ONLY: Don't connect any other signals to this GPIO
#define RMT_DATA_IO (0) // bind signal RMT_SIG_OUT0_IDX and RMT_SIG_IN0_IDX on the same GPIO
#define RMT_TESTBENCH_FLAGS_ALWAYS_ON (1<<0)
#define RMT_TESTBENCH_FLAGS_CARRIER_ON (1<<1)
#define RMT_TESTBENCH_FLAGS_LOOP_ON (1<<2)
static const char *TAG = "RMT.test";
static ir_builder_t *s_ir_builder = NULL;
static ir_parser_t *s_ir_parser = NULL;
static void rmt_setup_testbench(int tx_channel, int rx_channel, uint32_t flags)
{
// RMT channel configuration
if (tx_channel >= 0) {
rmt_config_t tx_config = RMT_DEFAULT_CONFIG_TX(RMT_DATA_IO, tx_channel);
if (flags & RMT_TESTBENCH_FLAGS_ALWAYS_ON) {
tx_config.flags |= RMT_CHANNEL_FLAGS_AWARE_DFS;
}
if (flags & RMT_TESTBENCH_FLAGS_CARRIER_ON) {
tx_config.tx_config.carrier_en = true;
}
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
if (flags & RMT_TESTBENCH_FLAGS_LOOP_ON) {
tx_config.tx_config.loop_en = true;
tx_config.tx_config.loop_count = 10;
}
#endif
TEST_ESP_OK(rmt_config(&tx_config));
}
if (rx_channel >= 0) {
rmt_config_t rx_config = RMT_DEFAULT_CONFIG_RX(RMT_DATA_IO, rx_channel);
if (flags & RMT_TESTBENCH_FLAGS_ALWAYS_ON) {
rx_config.flags |= RMT_CHANNEL_FLAGS_AWARE_DFS;
}
#if SOC_RMT_SUPPORT_RX_DEMODULATION
if (flags & RMT_TESTBENCH_FLAGS_CARRIER_ON) {
rx_config.rx_config.rm_carrier = true;
rx_config.rx_config.carrier_freq_hz = 38000;
rx_config.rx_config.carrier_duty_percent = 33;
rx_config.rx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;
}
#endif
TEST_ESP_OK(rmt_config(&rx_config));
}
// Routing internal signals by IO Matrix (bind rmt tx and rx signal on the same GPIO)
gpio_func_sel(RMT_DATA_IO, PIN_FUNC_GPIO);
TEST_ESP_OK(gpio_set_direction(RMT_DATA_IO, GPIO_MODE_INPUT_OUTPUT));
if (tx_channel >= 0) {
esp_rom_gpio_connect_out_signal(RMT_DATA_IO, rmt_periph_signals.groups[0].channels[tx_channel].tx_sig, 0, 0);
}
if (rx_channel >= 0) {
esp_rom_gpio_connect_in_signal(RMT_DATA_IO, rmt_periph_signals.groups[0].channels[rx_channel].rx_sig, 0);
}
// install driver
if (tx_channel >= 0) {
TEST_ESP_OK(rmt_driver_install(tx_channel, 0, 0));
ir_builder_config_t ir_builder_config = IR_BUILDER_DEFAULT_CONFIG((ir_dev_t)tx_channel);
ir_builder_config.flags = IR_TOOLS_FLAGS_PROTO_EXT;
s_ir_builder = ir_builder_rmt_new_nec(&ir_builder_config);
TEST_ASSERT_NOT_NULL(s_ir_builder);
}
if (rx_channel >= 0) {
TEST_ESP_OK(rmt_driver_install(rx_channel, 3000, 0));
ir_parser_config_t ir_parser_config = IR_PARSER_DEFAULT_CONFIG((ir_dev_t)rx_channel);
ir_parser_config.flags = IR_TOOLS_FLAGS_PROTO_EXT | IR_TOOLS_FLAGS_INVERSE;
s_ir_parser = ir_parser_rmt_new_nec(&ir_parser_config);
TEST_ASSERT_NOT_NULL(s_ir_parser);
}
}
static void rmt_clean_testbench(int tx_channel, int rx_channel)
{
if (tx_channel >= 0) {
TEST_ESP_OK(rmt_driver_uninstall(tx_channel));
TEST_ESP_OK(s_ir_builder->del(s_ir_builder));
s_ir_builder = NULL;
}
if (rx_channel >= 0) {
TEST_ESP_OK(rmt_driver_uninstall(rx_channel));
TEST_ESP_OK(s_ir_parser->del(s_ir_parser));
s_ir_parser = NULL;
}
}
TEST_CASE("RMT wrong configuration", "[rmt]")
{
rmt_config_t correct_config = RMT_DEFAULT_CONFIG_TX(RMT_DATA_IO, 0);
rmt_config_t wrong_config = correct_config;
wrong_config.clk_div = 0;
TEST_ASSERT(rmt_config(&wrong_config) == ESP_ERR_INVALID_ARG);
wrong_config = correct_config;
wrong_config.channel = SOC_RMT_CHANNELS_PER_GROUP;
TEST_ASSERT(rmt_config(&wrong_config) == ESP_ERR_INVALID_ARG);
wrong_config = correct_config;
wrong_config.channel = 2;
wrong_config.mem_block_num = 8;
TEST_ASSERT(rmt_config(&wrong_config) == ESP_ERR_INVALID_ARG);
TEST_ASSERT(rmt_set_mem_block_num(wrong_config.channel, -1) == ESP_ERR_INVALID_ARG);
}
TEST_CASE("RMT miscellaneous functions", "[rmt]")
{
rmt_channel_t channel = 0;
uint8_t div_cnt;
rmt_source_clk_t src_clk;
uint8_t memNum;
uint16_t idle_thres;
rmt_mem_owner_t owner;
// TX related functions
rmt_setup_testbench(channel, -1, 0);
TEST_ESP_OK(rmt_set_mem_block_num(channel, 2));
TEST_ESP_OK(rmt_get_mem_block_num(channel, &memNum));
TEST_ASSERT_EQUAL_UINT8(2, memNum);
TEST_ESP_OK(rmt_set_clk_div(channel, 160));
TEST_ESP_OK(rmt_get_clk_div(channel, &div_cnt));
TEST_ASSERT_EQUAL_UINT8(160, div_cnt);
#if SOC_RMT_SUPPORT_REF_TICK
TEST_ESP_OK(rmt_set_source_clk(channel, RMT_BASECLK_REF));
TEST_ESP_OK(rmt_get_source_clk(channel, &src_clk));
TEST_ASSERT_EQUAL_INT(RMT_BASECLK_REF, src_clk);
#endif
#if SOC_RMT_SUPPORT_XTAL
TEST_ESP_OK(rmt_set_source_clk(channel, RMT_BASECLK_XTAL));
TEST_ESP_OK(rmt_get_source_clk(channel, &src_clk));
TEST_ASSERT_EQUAL_INT(RMT_BASECLK_XTAL, src_clk);
#endif
TEST_ESP_OK(rmt_set_tx_carrier(channel, 0, 10, 10, 1));
TEST_ESP_OK(rmt_set_idle_level(channel, 1, 0));
rmt_clean_testbench(channel, -1);
// RX related functions
channel = RMT_RX_CHANNEL_ENCODING_START;
rmt_setup_testbench(-1, channel, 0);
TEST_ESP_OK(rmt_set_rx_idle_thresh(channel, 200));
TEST_ESP_OK(rmt_get_rx_idle_thresh(channel, &idle_thres));
TEST_ASSERT_EQUAL_UINT16(200, idle_thres);
TEST_ESP_OK(rmt_set_rx_filter(channel, 1, 100));
TEST_ESP_OK(rmt_set_memory_owner(channel, RMT_MEM_OWNER_RX));
TEST_ESP_OK(rmt_get_memory_owner(channel, &owner));
TEST_ASSERT_EQUAL_INT(RMT_MEM_OWNER_RX, owner);
rmt_clean_testbench(-1, channel);
}
TEST_CASE("RMT multiple channels", "[rmt]")
{
rmt_config_t tx_cfg = RMT_DEFAULT_CONFIG_TX(RMT_DATA_IO, 0);
for (int i = 0; i < SOC_RMT_TX_CANDIDATES_PER_GROUP; i++) {
tx_cfg.channel = i;
TEST_ESP_OK(rmt_config(&tx_cfg));
TEST_ESP_OK(rmt_driver_install(tx_cfg.channel, 0, 0));
}
for (int i = 0; i < SOC_RMT_TX_CANDIDATES_PER_GROUP; i++) {
TEST_ESP_OK(rmt_driver_uninstall(i));
}
rmt_config_t rx_cfg = RMT_DEFAULT_CONFIG_RX(RMT_DATA_IO, RMT_RX_CHANNEL_ENCODING_START);
for (int i = RMT_RX_CHANNEL_ENCODING_START; i < SOC_RMT_CHANNELS_PER_GROUP; i++) {
rx_cfg.channel = i;
TEST_ESP_OK(rmt_config(&rx_cfg));
TEST_ESP_OK(rmt_driver_install(rx_cfg.channel, 0, 0));
}
for (int i = RMT_RX_CHANNEL_ENCODING_START; i < SOC_RMT_CHANNELS_PER_GROUP; i++) {
TEST_ESP_OK(rmt_driver_uninstall(i));
}
}
TEST_CASE("RMT install/uninstall test", "[rmt]")
{
rmt_config_t tx_cfg = RMT_DEFAULT_CONFIG_TX(RMT_DATA_IO, RMT_TX_CHANNEL_ENCODING_END);
// uninstall function is allowed to be called at any time
TEST_ESP_OK(rmt_driver_uninstall(tx_cfg.channel));
TEST_ESP_OK(rmt_config(&tx_cfg));
for (int i = 0; i < 100; i++) {
TEST_ESP_OK(rmt_driver_install(tx_cfg.channel, 1000, 0));
TEST_ESP_OK(rmt_driver_uninstall(tx_cfg.channel));
}
TEST_ESP_OK(rmt_driver_uninstall(tx_cfg.channel));
rmt_config_t rx_cfg = RMT_DEFAULT_CONFIG_RX(RMT_DATA_IO, RMT_RX_CHANNEL_ENCODING_START);
TEST_ESP_OK(rmt_config(&rx_cfg));
for (int i = 0; i < 100; i++) {
TEST_ESP_OK(rmt_driver_install(rx_cfg.channel, 1000, 0));
TEST_ESP_OK(rmt_driver_uninstall(rx_cfg.channel));
}
}
static void test_rmt_translator(const void *src, rmt_item32_t *dest, size_t src_size,
size_t wanted_num, size_t *translated_size, size_t *item_num)
{
const rmt_item32_t bit0 = {{{ 10, 1, 20, 0 }}}; //Logical 0
const rmt_item32_t bit1 = {{{ 20, 1, 10, 0 }}}; //Logical 1
size_t size = 0;
size_t num = 0;
uint8_t *psrc = (uint8_t *)src;
rmt_item32_t *pdest = dest;
while (size < src_size && num < wanted_num) {
for (int i = 0; i < 8; i++) {
// MSB first
if (*psrc & (1 << (7 - i))) {
pdest->val = bit1.val;
} else {
pdest->val = bit0.val;
}
num++;
pdest++;
}
size++;
psrc++;
}
*translated_size = size;
*item_num = num;
int *user_data = NULL;
rmt_translator_get_context(item_num, (void **)&user_data);
esp_rom_printf("user data=%d\r\n", *user_data);
*user_data = 100;
}
TEST_CASE("RMT translator with user context", "[rmt]")
{
rmt_config_t tx_cfg = RMT_DEFAULT_CONFIG_TX(RMT_DATA_IO, 0);
TEST_ESP_OK(rmt_config(&tx_cfg));
TEST_ESP_OK(rmt_driver_install(tx_cfg.channel, 0, 0));
rmt_translator_init(tx_cfg.channel, test_rmt_translator);
int user_data = 999;
rmt_translator_set_context(tx_cfg.channel, &user_data);
uint8_t test_buf[] = {1, 2, 3, 4, 5, 6};
rmt_write_sample(tx_cfg.channel, test_buf, sizeof(test_buf), true);
vTaskDelay(pdMS_TO_TICKS(100));
TEST_ASSERT_EQUAL(100, user_data);
TEST_ESP_OK(rmt_driver_uninstall(tx_cfg.channel));
}
static void do_nec_tx_rx(uint32_t flags)
{
RingbufHandle_t rb = NULL;
rmt_item32_t *items = NULL;
size_t length = 0;
uint32_t addr = 0x10;
uint32_t cmd = 0x20;
bool repeat = false;
int tx_channel = 0;
int rx_channel = RMT_RX_CHANNEL_ENCODING_START + 1;
// test on different flags combinations
rmt_setup_testbench(tx_channel, rx_channel, flags);
// get ready to receive
TEST_ESP_OK(rmt_get_ringbuf_handle(rx_channel, &rb));
TEST_ASSERT_NOT_NULL(rb);
TEST_ESP_OK(rmt_rx_start(rx_channel, true));
vTaskDelay(pdMS_TO_TICKS(1000));
// build NEC codes
cmd = 0x20;
while (cmd <= 0x30) {
ESP_LOGI(TAG, "Send command 0x%"PRIx32" to address 0x%"PRIx32, cmd, addr);
// Send new key code
TEST_ESP_OK(s_ir_builder->build_frame(s_ir_builder, addr, cmd));
TEST_ESP_OK(s_ir_builder->get_result(s_ir_builder, &items, &length));
if (cmd & 0x01) {
TEST_ESP_OK(rmt_write_items(tx_channel, items, length, false)); // no wait
TEST_ESP_OK(rmt_wait_tx_done(tx_channel, portMAX_DELAY));
} else {
TEST_ESP_OK(rmt_write_items(tx_channel, items, length, true)); // wait until done
}
cmd++;
}
// parse NEC codes
while (rb) {
items = (rmt_item32_t *) xRingbufferReceive(rb, &length, 1000);
if (items) {
length /= 4; // one RMT = 4 Bytes
if (s_ir_parser->input(s_ir_parser, items, length) == ESP_OK) {
if (s_ir_parser->get_scan_code(s_ir_parser, &addr, &cmd, &repeat) == ESP_OK) {
ESP_LOGI(TAG, "Scan Code %s --- addr: 0x%04"PRIx32" cmd: 0x%04"PRIx32, repeat ? "(repeat)" : "", addr, cmd);
}
}
vRingbufferReturnItem(rb, (void *) items);
} else {
ESP_LOGI(TAG, "done");
break;
}
}
TEST_ASSERT_EQUAL(0x30, cmd);
rmt_clean_testbench(tx_channel, rx_channel);
}
// basic nec tx and rx test, using APB source clock, no modulation
TEST_CASE("RMT NEC TX and RX (APB)", "[rmt]")
{
do_nec_tx_rx(0);
}
// test with RMT_TESTBENCH_FLAGS_ALWAYS_ON will take a long time (REF_TICK is much slower than APB CLOCK)
TEST_CASE("RMT NEC TX and RX (always on)", "[rmt][timeout=240]")
{
do_nec_tx_rx(RMT_TESTBENCH_FLAGS_ALWAYS_ON);
}
#if SOC_RMT_SUPPORT_RX_DEMODULATION
// basic nec tx and rx test, using APB source clock, with modulation and demodulation on
TEST_CASE("RMT NEC TX and RX (Modulation/Demodulation)", "[rmt]")
{
do_nec_tx_rx(RMT_TESTBENCH_FLAGS_CARRIER_ON);
}
#endif
TEST_CASE("RMT TX (SOC_RMT_MEM_WORDS_PER_CHANNEL-1) symbols", "[rmt][boundary]")
{
int tx_channel = 0;
rmt_setup_testbench(tx_channel, -1, 0);
rmt_item32_t *items = malloc(sizeof(rmt_item32_t) * (SOC_RMT_MEM_WORDS_PER_CHANNEL - 1));
for (int i = 0; i < SOC_RMT_MEM_WORDS_PER_CHANNEL - 1; i++) {
items[i] = (rmt_item32_t) {
{{
200, 1, 200, 0
}
}
};
}
TEST_ESP_OK(rmt_write_items(tx_channel, items, SOC_RMT_MEM_WORDS_PER_CHANNEL - 1, 1));
free(items);
rmt_clean_testbench(tx_channel, -1);
}
TEST_CASE("RMT TX stop", "[rmt]")
{
RingbufHandle_t rb = NULL;
rmt_item32_t *frames = NULL;
size_t length = 0;
uint32_t count = 10;
uint32_t addr = 0x10;
uint32_t cmd = 0x20;
bool repeat = false;
int tx_channel = 0;
int rx_channel = RMT_RX_CHANNEL_ENCODING_START + 1;
rmt_setup_testbench(tx_channel, rx_channel, 0);
// re-install ir_builder, to enlarge internal buffer size
TEST_ESP_OK(s_ir_builder->del(s_ir_builder));
ir_builder_config_t ir_builder_config = IR_BUILDER_DEFAULT_CONFIG((ir_dev_t)tx_channel);
ir_builder_config.buffer_size *= count;
ir_builder_config.flags = IR_TOOLS_FLAGS_PROTO_EXT;
s_ir_builder = ir_builder_rmt_new_nec(&ir_builder_config);
TEST_ASSERT_NOT_NULL(s_ir_builder);
// get ready to receive
TEST_ESP_OK(rmt_get_ringbuf_handle(rx_channel, &rb));
TEST_ASSERT_NOT_NULL(rb);
TEST_ESP_OK(rmt_rx_start(rx_channel, true));
vTaskDelay(pdMS_TO_TICKS(1000));
// build NEC codes
ESP_LOGI(TAG, "Plan to send command 0x%"PRIx32"~0x%"PRIx32" to address 0x%"PRIx32, cmd, cmd + count, addr);
for (int i = 0; i <= count; i++) {
TEST_ESP_OK(s_ir_builder->build_frame(s_ir_builder, addr, cmd));
cmd++;
}
TEST_ESP_OK(s_ir_builder->get_result(s_ir_builder, &frames, &length));
// send for 1 second and then stop
TEST_ESP_OK(rmt_write_items(tx_channel, frames, length, true));
vTaskDelay(pdMS_TO_TICKS(100));
TEST_ESP_OK(rmt_tx_stop(tx_channel));
// parse NEC codes
uint32_t num = 0;
while (rb) {
frames = (rmt_item32_t *) xRingbufferReceive(rb, &length, 1000);
if (frames) {
length /= 4; // one RMT = 4 Bytes
if (s_ir_parser->input(s_ir_parser, frames, length) == ESP_OK) {
if (s_ir_parser->get_scan_code(s_ir_parser, &addr, &cmd, &repeat) == ESP_OK) {
ESP_LOGI(TAG, "Scan Code %s --- addr: 0x%04"PRIx32"cmd: 0x%04"PRIx32, repeat ? "(repeat)" : "", addr, cmd);
num++;
}
}
vRingbufferReturnItem(rb, (void *) frames);
} else {
ESP_LOGI(TAG, "done");
break;
}
}
TEST_ASSERT(num < count);
rmt_clean_testbench(tx_channel, rx_channel);
}
#if SOC_RMT_SUPPORT_RX_PINGPONG
TEST_CASE("RMT Ping-Pong operation", "[rmt]")
{
int tx_channel = 0;
int rx_channel = RMT_RX_CHANNEL_ENCODING_START + 1;
rmt_item32_t frames[SOC_RMT_MEM_WORDS_PER_CHANNEL * 2]; // send two block data using ping-pong
RingbufHandle_t rb = NULL;
uint32_t size = sizeof(frames) / sizeof(frames[0]);
// The design of the following test frame should trigger three rx threshold interrupt and one rx end interrupt
int i = 0;
for (i = 0; i < size - 1; i++) {
frames[i].level0 = 1;
frames[i].duration0 = 100;
frames[i].level1 = 0;
frames[i].duration1 = 100;
}
frames[i].level0 = 1;
frames[i].duration0 = 0;
frames[i].level1 = 0;
frames[i].duration1 = 0;
rmt_setup_testbench(tx_channel, rx_channel, 0);
// get ready to receive
TEST_ESP_OK(rmt_get_ringbuf_handle(rx_channel, &rb));
TEST_ASSERT_NOT_NULL(rb);
TEST_ESP_OK(rmt_rx_start(rx_channel, true));
vTaskDelay(pdMS_TO_TICKS(1000));
for (uint32_t test_count = 0; test_count < 5; test_count++) {
TEST_ESP_OK(rmt_write_items(tx_channel, frames, size, true));
// parse received data
size_t length = 0;
rmt_item32_t *items = (rmt_item32_t *) xRingbufferReceive(rb, &length, 1000);
if (items) {
vRingbufferReturnItem(rb, (void *) items);
}
TEST_ASSERT_EQUAL(4 * (size - 1), length);
}
rmt_clean_testbench(tx_channel, rx_channel);
}
#endif
#if SOC_RMT_SUPPORT_TX_SYNCHRO
static uint32_t tx_end_time0, tx_end_time1;
static void rmt_tx_end_cb(rmt_channel_t channel, void *arg)
{
if (channel == 0) {
tx_end_time0 = esp_cpu_get_cycle_count();
} else {
tx_end_time1 = esp_cpu_get_cycle_count();
}
}
TEST_CASE("RMT TX simultaneously", "[rmt]")
{
rmt_item32_t frames[SOC_RMT_MEM_WORDS_PER_CHANNEL];
uint32_t size = sizeof(frames) / sizeof(frames[0]);
int channel0 = 0;
int channel1 = 1;
int i = 0;
for (i = 0; i < size - 1; i++) {
frames[i].level0 = 1;
frames[i].duration0 = 1000;
frames[i].level1 = 0;
frames[i].duration1 = 1000;
}
frames[i].level0 = 0;
frames[i].duration0 = 0;
frames[i].level1 = 0;
frames[i].duration1 = 0;
rmt_config_t tx_config0 = RMT_DEFAULT_CONFIG_TX(4, channel0);
rmt_config_t tx_config1 = RMT_DEFAULT_CONFIG_TX(5, channel1);
TEST_ESP_OK(rmt_config(&tx_config0));
TEST_ESP_OK(rmt_config(&tx_config1));
TEST_ESP_OK(rmt_driver_install(channel0, 0, 0));
TEST_ESP_OK(rmt_driver_install(channel1, 0, 0));
rmt_register_tx_end_callback(rmt_tx_end_cb, NULL);
TEST_ESP_OK(rmt_add_channel_to_group(channel0));
TEST_ESP_OK(rmt_add_channel_to_group(channel1));
TEST_ESP_OK(rmt_write_items(channel0, frames, size, false));
vTaskDelay(pdMS_TO_TICKS(1000));
TEST_ESP_OK(rmt_write_items(channel1, frames, size, false));
TEST_ESP_OK(rmt_wait_tx_done(channel0, portMAX_DELAY));
TEST_ESP_OK(rmt_wait_tx_done(channel1, portMAX_DELAY));
ESP_LOGI(TAG, "tx_end_time0=%"PRIu32", tx_end_time1=%"PRIu32, tx_end_time0, tx_end_time1);
TEST_ASSERT_LESS_OR_EQUAL_UINT32(2000, tx_end_time1 - tx_end_time0);
TEST_ESP_OK(rmt_remove_channel_from_group(channel0));
TEST_ESP_OK(rmt_remove_channel_from_group(channel1));
rmt_register_tx_end_callback(NULL, NULL);
TEST_ESP_OK(rmt_driver_uninstall(channel0));
TEST_ESP_OK(rmt_driver_uninstall(channel1));
}
#endif
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
static void rmt_tx_loop_end(rmt_channel_t channel, void *arg)
{
rmt_tx_stop(channel);
}
TEST_CASE("RMT TX loop", "[rmt]")
{
RingbufHandle_t rb = NULL;
rmt_item32_t *items = NULL;
size_t length = 0;
uint32_t addr = 0x10;
uint32_t cmd = 0x20;
bool repeat = false;
int tx_channel = 0;
int rx_channel = RMT_RX_CHANNEL_ENCODING_START + 1;
uint32_t count = 0;
rmt_setup_testbench(tx_channel, rx_channel, RMT_TESTBENCH_FLAGS_LOOP_ON);
// get ready to receive
TEST_ESP_OK(rmt_get_ringbuf_handle(rx_channel, &rb));
TEST_ASSERT_NOT_NULL(rb);
TEST_ESP_OK(rmt_rx_start(rx_channel, true));
vTaskDelay(pdMS_TO_TICKS(1000));
// register callback functions, invoked when tx loop count to ceiling
rmt_register_tx_end_callback(rmt_tx_loop_end, NULL);
// build NEC codes
ESP_LOGI(TAG, "Send command 0x%"PRIx32" to address 0x%"PRIx32, cmd, addr);
// Send new key code
TEST_ESP_OK(s_ir_builder->build_frame(s_ir_builder, addr, cmd));
TEST_ESP_OK(s_ir_builder->get_result(s_ir_builder, &items, &length));
TEST_ESP_OK(rmt_write_items(tx_channel, items, length, true)); // wait until done
// parse NEC codes
while (rb) {
items = (rmt_item32_t *) xRingbufferReceive(rb, &length, 1000);
if (items) {
length /= 4; // one RMT = 4 Bytes
if (s_ir_parser->input(s_ir_parser, items, length) == ESP_OK) {
if (s_ir_parser->get_scan_code(s_ir_parser, &addr, &cmd, &repeat) == ESP_OK) {
count++;
ESP_LOGI(TAG, "Scan Code %s --- addr: 0x%04"PRIx32" cmd: 0x%04"PRIx32, repeat ? "(repeat)" : "", addr, cmd);
}
}
vRingbufferReturnItem(rb, (void *) items);
} else {
ESP_LOGI(TAG, "done");
break;
}
}
TEST_ASSERT_EQUAL(10, count);
rmt_register_tx_end_callback(NULL, NULL);
rmt_clean_testbench(tx_channel, rx_channel);
}
#endif
static void IRAM_ATTR test_delay_post_cache_disable(void *args)
{
esp_rom_delay_us(10000);
}
TEST_CASE("RMT Interrupt IRAM Safe", "[rmt]")
{
rmt_config_t tx = {
.channel = RMT_CHANNEL_0,
.gpio_num = 0,
.mem_block_num = 1,
.clk_div = 40,
.rmt_mode = RMT_MODE_TX,
};
TEST_ESP_OK(rmt_config(&tx));
TEST_ESP_OK(rmt_set_source_clk(tx.channel, RMT_BASECLK_DEFAULT));
// install interrupt with IRAM safe
TEST_ESP_OK(rmt_driver_install(tx.channel, 0, ESP_INTR_FLAG_IRAM));
// send a large buffer, ensure the RMT hardware is still in work when we disable the flash cache afterwards
rmt_item32_t items[256] = {};
for (int i = 0; i < 256; i++) {
items[i].level0 = 0;
items[i].duration0 = 1;
items[i].level1 = 1;
items[i].duration1 = 1;
}
rmt_write_items(RMT_CHANNEL_0, items, 256, false);
unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL);
TEST_ESP_OK(rmt_wait_tx_done(RMT_CHANNEL_0, portMAX_DELAY));
TEST_ESP_OK(rmt_driver_uninstall(RMT_CHANNEL_0));
}

View File

@@ -1,22 +0,0 @@
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
[
'release',
],
indirect=True,
)
@idf_parametrize(
'target',
['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'],
indirect=['target'],
)
def test_legacy_rmt(dut: Dut) -> None:
dut.run_all_single_board_cases(timeout=120)

View File

@@ -1,5 +0,0 @@
CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@@ -1,3 +0,0 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT_EN=n
CONFIG_RMT_SUPPRESS_DEPRECATE_WARN=y

View File

@@ -585,133 +585,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->status_ch[channel];
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->status_ch[channel];
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->conf_ch[channel].conf0, div_cnt);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->conf_ch[channel].conf0, div_cnt);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return HAL_FORCE_READ_U32_REG_FIELD(dev->conf_ch[channel].conf0, idle_thres);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf0.mem_size;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf0.mem_size;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.tx_conti_mode;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
if (dev->conf_ch[channel].conf1.ref_always_on) {
return RMT_CLK_SRC_APB;
}
return RMT_CLK_SRC_REF_TICK;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.idle_out_en;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.idle_out_lv;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
// Only conf0 register of channel0 has `mem_pd`
return dev->conf_ch[0].conf0.mem_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.mem_owner;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x01) >> 0) | ((status & 0x08) >> 2) | ((status & 0x40) >> 4) | ((status & 0x200) >> 6) |
((status & 0x1000) >> 8) | ((status & 0x8000) >> 10) | ((status & 0x40000) >> 12) | ((status & 0x200000) >> 14);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x02) >> 1) | ((status & 0x10) >> 3) | ((status & 0x80) >> 5) | ((status & 0x400) >> 7) |
((status & 0x2000) >> 9) | ((status & 0x10000) >> 11) | ((status & 0x80000) >> 13) | ((status & 0x400000) >> 15);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x04) >> 2) | ((status & 0x20) >> 4) | ((status & 0x100) >> 6) | ((status & 0x800) >> 8) |
((status & 0x4000) >> 10) | ((status & 0x20000) >> 12) | ((status & 0x100000) >> 14) | ((status & 0x800000) >> 16);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x04) >> 2) | ((status & 0x20) >> 4) | ((status & 0x100) >> 6) | ((status & 0x800) >> 8) |
((status & 0x4000) >> 10) | ((status & 0x20000) >> 12) | ((status & 0x100000) >> 14) | ((status & 0x800000) >> 16);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return (status & 0xFF000000) >> 24;
}
#ifdef __cplusplus
}
#endif

View File

@@ -763,150 +763,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->tx_status[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->rx_status[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->tx_conf[channel], div_cnt);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->rx_conf[channel].conf0, div_cnt);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->rx_conf[channel].conf0.idle_thres;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->tx_conf[channel].mem_size;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->rx_conf[channel].conf0.mem_size;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->tx_conf[channel].tx_conti_mode;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_APB;
switch (dev->sys_conf.sclk_sel) {
case 1:
clk_src = RMT_CLK_SRC_APB;
break;
case 2:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 3:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->tx_conf[channel].idle_out_en;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->tx_conf[channel].idle_out_lv;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return dev->sys_conf.mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->rx_conf[channel].conf1.mem_owner;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->rx_lim[channel].rx_lim;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 2) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 6) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 10) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x03;
}
#ifdef __cplusplus
}
#endif

View File

@@ -764,150 +764,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_PLL_F80M;
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
case 2:
clk_src = RMT_CLK_SRC_PLL_F80M;
break;
case 1:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 0:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return PCR.rmt_pd_ctrl.rmt_mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 2) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 6) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 10) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x03;
}
#ifdef __cplusplus
}
#endif

View File

@@ -764,150 +764,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_PLL_F80M;
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
case 1:
clk_src = RMT_CLK_SRC_PLL_F80M;
break;
case 2:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 3:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return dev->sys_conf.mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rmt_rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 2) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 6) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 10) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x03;
}
#ifdef __cplusplus
}
#endif

View File

@@ -761,147 +761,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_XTAL;
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
case 1:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 0:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return dev->sys_conf.mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rmt_rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 2) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 6) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 10) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x03;
}
#ifdef __cplusplus
}
#endif

View File

@@ -761,147 +761,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_XTAL;
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
case 1:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 0:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return dev->sys_conf.rmt_mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rmt_rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 2) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 6) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 10) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x03;
}
#ifdef __cplusplus
}
#endif

View File

@@ -764,147 +764,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_XTAL;
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
case 1:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 0:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return PCR.rmt_mem_lp_ctrl.rmt_mem_lp_en;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 2) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 6) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 10) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x03;
}
#ifdef __cplusplus
}
#endif

View File

@@ -817,150 +817,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_PLL_F80M;
switch (HP_SYS_CLKRST.peri_clk_ctrl22.reg_rmt_clk_src_sel) {
case 0:
clk_src = RMT_CLK_SRC_XTAL;
break;
case 1:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 2:
clk_src = RMT_CLK_SRC_PLL_F80M;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return dev->sys_conf.mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 16) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 20) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 24) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x0F;
}
#ifdef __cplusplus
}
#endif

View File

@@ -729,135 +729,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->conf_ch[channel].conf0, div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->conf_ch[channel].conf0, div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return HAL_FORCE_READ_U32_REG_FIELD(dev->conf_ch[channel].conf0, idle_thres_chn);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf0.mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf0.mem_size_chn;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
if (dev->conf_ch[channel].conf1.ref_always_on_chn) {
return RMT_CLK_SRC_APB;
}
return RMT_CLK_SRC_REF_TICK;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return dev->apb_conf.mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->conf_ch[channel].conf1.mem_owner_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x01) >> 0) | ((status & 0x08) >> 2) | ((status & 0x40) >> 4) | ((status & 0x200) >> 6);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x02) >> 1) | ((status & 0x10) >> 3) | ((status & 0x80) >> 5) | ((status & 0x400) >> 7);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x04) >> 2) | ((status & 0x20) >> 4) | ((status & 0x100) >> 6) | ((status & 0x800) >> 8);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x04) >> 2) | ((status & 0x20) >> 4) | ((status & 0x100) >> 6) | ((status & 0x800) >> 8);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return (status & 0xF000) >> 12;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return (status & 0xF0000) >> 16;
}
#ifdef __cplusplus
}
#endif

View File

@@ -801,150 +801,6 @@ static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t c
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_APB;
switch (dev->sys_conf.sclk_sel) {
case 1:
clk_src = RMT_CLK_SRC_APB;
break;
case 2:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 3:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
{
return dev->sys_conf.mem_force_pd;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 16) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 20) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 24) & 0x0F;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x0F;
}
#ifdef __cplusplus
}
#endif

View File

@@ -209,15 +209,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_APB = SOC_MOD_CLK_APB, /*!< RMT source clock is APB CLK */
RMT_BASECLK_REF = SOC_MOD_CLK_REF_TICK, /*!< RMT source clock is REF_TICK */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_APB, /*!< RMT source clock default choice is APB */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -188,15 +188,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_APB = SOC_MOD_CLK_APB, /*!< RMT source clock is APB */
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_APB, /*!< RMT source clock default choice is APB */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////
/**

View File

@@ -210,15 +210,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock is PLL_F80M */
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock default choice is PLL_F80M */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -207,15 +207,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock is PLL_F80M */
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock default choice is PLL_F80M */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -215,14 +215,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< RMT source clock default choice is XTAL */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -204,14 +204,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< RMT source clock default choice is XTAL */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -206,14 +206,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< RMT source clock default choice is XTAL */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -248,15 +248,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock is PLL_F80M */
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock default choice is PLL_F80M */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -205,15 +205,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_APB = SOC_MOD_CLK_APB, /*!< RMT source clock is APB CLK */
RMT_BASECLK_REF = SOC_MOD_CLK_REF_TICK, /*!< RMT source clock is REF_TICK */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_APB, /*!< RMT source clock default choice is APB */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -224,15 +224,6 @@ typedef enum {
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
} soc_periph_rmt_clk_src_t;
/**
* @brief Type of RMT clock source, reserved for the legacy RMT driver
*/
typedef enum {
RMT_BASECLK_APB = SOC_MOD_CLK_APB, /*!< RMT source clock is APB */
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_APB, /*!< RMT source clock default choice is APB */
} soc_periph_rmt_clk_src_legacy_t;
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
/**

View File

@@ -315,12 +315,14 @@ LEDC
.. only:: SOC_RMT_SUPPORTED
RMT Driver
----------
.. _deprecate_rmt_legacy_driver:
Legacy RMT Driver is Deprecated
-------------------------------
RMT driver has been redesigned (see :doc:`RMT transceiver <../../../api-reference/peripherals/rmt>`), which aims to unify and extend the usage of RMT peripheral.
Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/rmt.h``. However, including ``driver/rmt.h`` triggers the build warning below by default. The warning can be suppressed by the Kconfig option :ref:`CONFIG_RMT_SUPPRESS_DEPRECATE_WARN`.
Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/rmt.h``. However, including ``driver/rmt.h`` triggers the build warning below by default. The warning can be suppressed by the Kconfig option ``CONFIG_RMT_SUPPRESS_DEPRECATE_WARN``.
.. code-block:: text

View File

@@ -130,6 +130,13 @@ The legacy timer group driver ``driver/timer.h`` is deprecated since version 5.0
The legacy PCNT driver ``driver/pcnt.h`` is deprecated since version 5.0 (see :ref:`deprecate_pcnt_legacy_driver`). Starting from version 6.0, the legacy driver is completely removed. The new driver is placed in the :component:`esp_driver_pcnt`, and the header file path is ``driver/pulse_cnt.h``.
.. only:: SOC_RMT_SUPPORTED
Legacy RMT Driver is Removed
-------------------------------
The legacy RMT driver ``driver/rmt.h`` is deprecated since version 5.0 (see :ref:`deprecate_rmt_legacy_driver`). Starting from version 6.0, the legacy driver is completely removed. The new driver is placed in the :component:`esp_driver_rmt`, and the header file path is ``driver/rmt_tx.h``, ``driver/rmt_rx.h`` and ``driver/rmt_encoder.h``.
GDMA
----

View File

@@ -315,12 +315,14 @@ LEDC
.. only:: SOC_RMT_SUPPORTED
RMT 驱动
----------------------
.. _deprecate_rmt_legacy_driver:
旧版 RMT 驱动已被弃用
-----------------------------------
为统一和扩展 RMT 外设的使用RMT 驱动已更新,详见 :doc:`RMT transceiver <../../../api-reference/peripherals/rmt>`
尽管我们建议使用新的驱动 API旧版驱动仍然可用保留在头文件引用路径 ``driver/rmt.h``中。但是,引用路径 ``driver/rmt.h`` 会默认触发如下编译警告,可通过配置 Kconfig 选项 :ref:`CONFIG_RMT_SUPPRESS_DEPRECATE_WARN` 来关闭该警告。
尽管我们建议使用新的驱动 API旧版驱动仍然可用保留在头文件引用路径 ``driver/rmt.h``中。但是,引用路径 ``driver/rmt.h`` 会默认触发如下编译警告,可通过配置 Kconfig 选项 ``CONFIG_RMT_SUPPRESS_DEPRECATE_WARN`` 来关闭该警告。
.. code-block:: text

View File

@@ -130,6 +130,13 @@ I2C 从机在 v5.4 上已经被重新设计。在当前版本上,老的 I2C
旧版的 PCNT 驱动 ``driver/pcnt.h`` 在 5.0 的版本中就已经被弃用 (参考 :ref:`deprecate_pcnt_legacy_driver`)。从 6.0 版本开始,旧版驱动被完全移除。新驱动位于 :component:`esp_driver_pcnt` 组件中,头文件引用路径为 ``driver/pulse_cnt.h``
.. only:: SOC_RMT_SUPPORTED
旧版 RMT 驱动被移除
----------------------
旧版的 RMT 驱动 ``driver/rmt.h`` 在 5.0 的版本中就已经被弃用(请参考 :ref:`deprecate_rmt_legacy_driver`)。从 6.0 版本开始,旧版驱动被完全移除。新驱动位于 :component:`esp_driver_rmt` 组件中,头文件引用路径为 ``driver/rmt_tx.h``, ``driver/rmt_rx.h````driver/rmt_encoder.h``
GDMA
----

View File

@@ -539,6 +539,9 @@
-
re_variables: ['driver/sigmadelta.h']
hint_variables: ['legacy Sigma-Delta', 'driver/sdm.h', 'esp_driver_sdm']
-
re_variables: ['driver/rmt.h']
hint_variables: ['legacy RMT', 'driver/rmt_tx.h, driver/rmt_rx.h, driver/rmt_encoder.h', 'esp_driver_rmt']
-
re: undefined reference to `i3c_new_master_bus'