mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-03 10:30:58 +02:00
Merge branch 'refactor/remove_legacy_rmt_driver' into 'master'
remove(legacy_rmt)!: remove legacy rmt driver in IDF v6.0 Closes IDF-13175 See merge request espressif/esp-idf!40092
This commit is contained in:
@@ -22,11 +22,6 @@ if(CONFIG_SOC_I2C_SUPPORTED)
|
|||||||
list(APPEND ldfragments "i2c/linker.lf")
|
list(APPEND ldfragments "i2c/linker.lf")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# RMT legacy driver
|
|
||||||
if(CONFIG_SOC_RMT_SUPPORTED)
|
|
||||||
list(APPEND srcs "deprecated/rmt_legacy.c")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Touch Sensor related source files
|
# Touch Sensor related source files
|
||||||
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED)
|
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED)
|
||||||
if(CONFIG_SOC_TOUCH_SENSOR_VERSION LESS 3)
|
if(CONFIG_SOC_TOUCH_SENSOR_VERSION LESS 3)
|
||||||
|
@@ -2,23 +2,6 @@ menu "Legacy Driver Configurations"
|
|||||||
|
|
||||||
orsource "./twai/Kconfig.twai"
|
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"
|
menu "Legacy I2C Driver Configurations"
|
||||||
depends on SOC_I2C_SUPPORTED
|
depends on SOC_I2C_SUPPORTED
|
||||||
config I2C_SKIP_LEGACY_CONFLICT_CHECK
|
config I2C_SKIP_LEGACY_CONFLICT_CHECK
|
||||||
|
@@ -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
|
|
@@ -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
|
|
@@ -8,12 +8,6 @@ components/driver/test_apps/legacy_i2c_driver:
|
|||||||
temporary: false
|
temporary: false
|
||||||
reason: disable target test for legacy i2c driver.
|
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:
|
components/driver/test_apps/legacy_twai:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_TWAI_SUPPORTED != 1 or SOC_TWAI_SUPPORT_FD == 1
|
- if: SOC_TWAI_SUPPORTED != 1 or SOC_TWAI_SUPPORT_FD == 1
|
||||||
|
@@ -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)
|
|
@@ -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 |
|
|
||||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
|
@@ -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")
|
|
@@ -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
|
|
@@ -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
|
|
@@ -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;
|
|
||||||
}
|
|
@@ -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;
|
|
||||||
}
|
|
@@ -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;
|
|
||||||
}
|
|
@@ -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;
|
|
||||||
}
|
|
@@ -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)
|
|
@@ -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();
|
|
||||||
}
|
|
@@ -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));
|
|
||||||
}
|
|
@@ -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)
|
|
@@ -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
|
|
@@ -1,3 +0,0 @@
|
|||||||
CONFIG_FREERTOS_HZ=1000
|
|
||||||
CONFIG_ESP_TASK_WDT_EN=n
|
|
||||||
CONFIG_RMT_SUPPRESS_DEPRECATE_WARN=y
|
|
@@ -73,6 +73,7 @@ static size_t rmt_encode_bs(rmt_encoder_t *encoder, rmt_channel_handle_t channel
|
|||||||
// cross line, means desc0 has prepared with sufficient data buffer
|
// cross line, means desc0 has prepared with sufficient data buffer
|
||||||
if (dma_lli0_index != dma_lli1_index) {
|
if (dma_lli0_index != dma_lli1_index) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli0_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoding_truncated) {
|
if (encoding_truncated) {
|
||||||
@@ -94,6 +95,7 @@ static size_t rmt_encode_bs(rmt_encoder_t *encoder, rmt_channel_handle_t channel
|
|||||||
// reset offset pointer when exceeds maximum range
|
// reset offset pointer when exceeds maximum range
|
||||||
if (tx_chan->mem_off_bytes >= tx_chan->ping_pong_symbols * 2 * sizeof(rmt_symbol_word_t)) {
|
if (tx_chan->mem_off_bytes >= tx_chan->ping_pong_symbols * 2 * sizeof(rmt_symbol_word_t)) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli1_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
tx_chan->mem_off_bytes = 0;
|
tx_chan->mem_off_bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -104,6 +104,7 @@ static size_t rmt_encode_bytes(rmt_encoder_t *encoder, rmt_channel_handle_t chan
|
|||||||
// cross line, means desc0 has prepared with sufficient data buffer
|
// cross line, means desc0 has prepared with sufficient data buffer
|
||||||
if (dma_lli0_index != dma_lli1_index) {
|
if (dma_lli0_index != dma_lli1_index) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli0_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // SOC_RMT_SUPPORT_DMA
|
#endif // SOC_RMT_SUPPORT_DMA
|
||||||
@@ -129,6 +130,7 @@ static size_t rmt_encode_bytes(rmt_encoder_t *encoder, rmt_channel_handle_t chan
|
|||||||
#if SOC_RMT_SUPPORT_DMA
|
#if SOC_RMT_SUPPORT_DMA
|
||||||
if (channel->dma_chan) {
|
if (channel->dma_chan) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli1_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
}
|
}
|
||||||
#endif // SOC_RMT_SUPPORT_DMA
|
#endif // SOC_RMT_SUPPORT_DMA
|
||||||
tx_chan->mem_off_bytes = 0;
|
tx_chan->mem_off_bytes = 0;
|
||||||
|
@@ -78,6 +78,7 @@ static size_t rmt_encode_copy(rmt_encoder_t *encoder, rmt_channel_handle_t chann
|
|||||||
// cross line, means desc0 has prepared with sufficient data buffer
|
// cross line, means desc0 has prepared with sufficient data buffer
|
||||||
if (dma_lli0_index != dma_lli1_index) {
|
if (dma_lli0_index != dma_lli1_index) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli0_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // SOC_RMT_SUPPORT_DMA
|
#endif // SOC_RMT_SUPPORT_DMA
|
||||||
@@ -101,6 +102,7 @@ static size_t rmt_encode_copy(rmt_encoder_t *encoder, rmt_channel_handle_t chann
|
|||||||
#if SOC_RMT_SUPPORT_DMA
|
#if SOC_RMT_SUPPORT_DMA
|
||||||
if (channel->dma_chan) {
|
if (channel->dma_chan) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli1_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
}
|
}
|
||||||
#endif // SOC_RMT_SUPPORT_DMA
|
#endif // SOC_RMT_SUPPORT_DMA
|
||||||
tx_chan->mem_off_bytes = 0;
|
tx_chan->mem_off_bytes = 0;
|
||||||
|
@@ -145,6 +145,7 @@ static size_t rmt_encode_simple(rmt_encoder_t *encoder, rmt_channel_handle_t cha
|
|||||||
// cross line, means desc0 has prepared with sufficient data buffer
|
// cross line, means desc0 has prepared with sufficient data buffer
|
||||||
if (dma_lli0_index != dma_lli1_index) {
|
if (dma_lli0_index != dma_lli1_index) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli0_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli0_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // SOC_RMT_SUPPORT_DMA
|
#endif // SOC_RMT_SUPPORT_DMA
|
||||||
@@ -164,6 +165,7 @@ static size_t rmt_encode_simple(rmt_encoder_t *encoder, rmt_channel_handle_t cha
|
|||||||
#if SOC_RMT_SUPPORT_DMA
|
#if SOC_RMT_SUPPORT_DMA
|
||||||
if (channel->dma_chan) {
|
if (channel->dma_chan) {
|
||||||
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
gdma_link_set_owner(tx_chan->dma_link, dma_lli1_index, GDMA_LLI_OWNER_DMA);
|
||||||
|
gdma_link_set_length(tx_chan->dma_link, dma_lli1_index, tx_chan->ping_pong_symbols * sizeof(rmt_symbol_word_t));
|
||||||
}
|
}
|
||||||
#endif // SOC_RMT_SUPPORT_DMA
|
#endif // SOC_RMT_SUPPORT_DMA
|
||||||
tx_chan->mem_off_bytes = 0;
|
tx_chan->mem_off_bytes = 0;
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -209,15 +209,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -188,15 +188,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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///////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -210,15 +210,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -207,15 +207,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -215,14 +215,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -204,14 +204,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -206,14 +206,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -248,15 +248,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -205,15 +205,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -224,15 +224,6 @@ typedef enum {
|
|||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} 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//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////PCNT//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -315,12 +315,14 @@ LEDC
|
|||||||
|
|
||||||
.. only:: SOC_RMT_SUPPORTED
|
.. 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.
|
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
|
.. code-block:: text
|
||||||
|
|
||||||
|
@@ -132,6 +132,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``.
|
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
|
GDMA
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@@ -315,12 +315,14 @@ LEDC
|
|||||||
|
|
||||||
.. only:: SOC_RMT_SUPPORTED
|
.. only:: SOC_RMT_SUPPORTED
|
||||||
|
|
||||||
RMT 驱动
|
.. _deprecate_rmt_legacy_driver:
|
||||||
----------------------
|
|
||||||
|
旧版 RMT 驱动已被弃用
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
为统一和扩展 RMT 外设的使用,RMT 驱动已更新,详见 :doc:`RMT transceiver <../../../api-reference/peripherals/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
|
.. code-block:: text
|
||||||
|
|
||||||
|
@@ -132,6 +132,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``。
|
旧版的 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
|
GDMA
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@@ -539,6 +539,9 @@
|
|||||||
-
|
-
|
||||||
re_variables: ['driver/sigmadelta.h']
|
re_variables: ['driver/sigmadelta.h']
|
||||||
hint_variables: ['legacy Sigma-Delta', 'driver/sdm.h', 'esp_driver_sdm']
|
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'
|
re: undefined reference to `i3c_new_master_bus'
|
||||||
|
Reference in New Issue
Block a user