mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'feat/allow_setting_rmt_group_prescale' into 'master'
refactor(rmt): set group clock prescale dynamically Closes IDFGH-13921 See merge request espressif/esp-idf!34640
This commit is contained in:
commit
e3cf10564d
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -158,12 +158,64 @@ void rmt_release_group_handle(rmt_group_t *group)
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t clk_src)
|
||||
#if !SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
static esp_err_t s_rmt_set_group_prescale(rmt_channel_t *chan, uint32_t expect_resolution_hz, uint32_t *ret_channel_prescale)
|
||||
{
|
||||
uint32_t periph_src_clk_hz = 0;
|
||||
rmt_group_t *group = chan->group;
|
||||
int group_id = group->group_id;
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(group->clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz), TAG, "get clock source freq failed");
|
||||
|
||||
uint32_t group_resolution_hz = 0;
|
||||
uint32_t group_prescale = 0;
|
||||
uint32_t channel_prescale = 0;
|
||||
|
||||
if (group->resolution_hz == 0) {
|
||||
while (++group_prescale <= RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE) {
|
||||
group_resolution_hz = periph_src_clk_hz / group_prescale;
|
||||
channel_prescale = (group_resolution_hz + expect_resolution_hz / 2) / expect_resolution_hz;
|
||||
// use the first value found during the search that satisfies the division requirement (highest frequency)
|
||||
if (channel_prescale > 0 && channel_prescale <= RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
group_prescale = periph_src_clk_hz / group->resolution_hz;
|
||||
channel_prescale = (group->resolution_hz + expect_resolution_hz / 2) / expect_resolution_hz;
|
||||
}
|
||||
|
||||
ESP_RETURN_ON_FALSE(group_prescale > 0 && group_prescale <= RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE, ESP_ERR_INVALID_ARG, TAG,
|
||||
"group prescale out of the range");
|
||||
ESP_RETURN_ON_FALSE(channel_prescale > 0 && channel_prescale <= RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE, ESP_ERR_INVALID_ARG, TAG,
|
||||
"channel prescale out of the range");
|
||||
|
||||
// group prescale is shared by all rmt_channel, only set once. use critical section to avoid race condition.
|
||||
bool prescale_conflict = false;
|
||||
group_resolution_hz = periph_src_clk_hz / group_prescale;
|
||||
portENTER_CRITICAL(&group->spinlock);
|
||||
if (group->resolution_hz == 0) {
|
||||
group->resolution_hz = group_resolution_hz;
|
||||
RMT_CLOCK_SRC_ATOMIC() {
|
||||
rmt_ll_set_group_clock_src(group->hal.regs, chan->channel_id, group->clk_src, group_prescale, 1, 0);
|
||||
rmt_ll_enable_group_clock(group->hal.regs, true);
|
||||
}
|
||||
} else {
|
||||
prescale_conflict = (group->resolution_hz != group_resolution_hz);
|
||||
}
|
||||
portEXIT_CRITICAL(&group->spinlock);
|
||||
ESP_RETURN_ON_FALSE(!prescale_conflict, ESP_ERR_INVALID_ARG, TAG,
|
||||
"group resolution conflict, already is %"PRIu32" but attempt to %"PRIu32"", group->resolution_hz, group_resolution_hz);
|
||||
ESP_LOGD(TAG, "group (%d) clock resolution:%"PRIu32"Hz", group_id, group->resolution_hz);
|
||||
*ret_channel_prescale = channel_prescale;
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
|
||||
esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t clk_src, uint32_t expect_channel_resolution)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
rmt_group_t *group = chan->group;
|
||||
int channel_id = chan->channel_id;
|
||||
uint32_t periph_src_clk_hz = 0;
|
||||
bool clock_selection_conflict = false;
|
||||
// check if we need to update the group clock source, group clock source is shared by all channels
|
||||
portENTER_CRITICAL(&group->spinlock);
|
||||
@ -173,7 +225,7 @@ esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t
|
||||
clock_selection_conflict = (group->clk_src != clk_src);
|
||||
}
|
||||
portEXIT_CRITICAL(&group->spinlock);
|
||||
ESP_RETURN_ON_FALSE(!clock_selection_conflict, ESP_ERR_INVALID_STATE, TAG,
|
||||
ESP_RETURN_ON_FALSE(!clock_selection_conflict, ESP_ERR_INVALID_ARG, TAG,
|
||||
"group clock conflict, already is %d but attempt to %d", group->clk_src, clk_src);
|
||||
|
||||
// TODO: [clk_tree] to use a generic clock enable/disable or acquire/release function for all clock source
|
||||
@ -185,10 +237,6 @@ esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t
|
||||
}
|
||||
#endif // SOC_RMT_SUPPORT_RC_FAST
|
||||
|
||||
// get clock source frequency
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz),
|
||||
TAG, "get clock source frequency failed");
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
// if DMA is not used, we're using CPU to push the data to the RMT FIFO
|
||||
// if the CPU frequency goes down, the transfer+encoding scheme could be unstable because CPU can't fill the data in time
|
||||
@ -203,19 +251,40 @@ esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t
|
||||
}
|
||||
#endif // SOC_RMT_SUPPORT_APB
|
||||
|
||||
sprintf(chan->pm_lock_name, "rmt_%d_%d", group->group_id, channel_id); // e.g. rmt_0_0
|
||||
sprintf(chan->pm_lock_name, "rmt_%d_%d", group->group_id, chan->channel_id); // e.g. rmt_0_0
|
||||
ret = esp_pm_lock_create(pm_lock_type, 0, chan->pm_lock_name, &chan->pm_lock);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
// no division for group clock source, to achieve highest resolution
|
||||
uint32_t real_div;
|
||||
#if SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
uint32_t periph_src_clk_hz = 0;
|
||||
// get clock source frequency
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz),
|
||||
TAG, "get clock source frequency failed");
|
||||
RMT_CLOCK_SRC_ATOMIC() {
|
||||
rmt_ll_set_group_clock_src(group->hal.regs, channel_id, clk_src, 1, 1, 0);
|
||||
rmt_ll_set_group_clock_src(group->hal.regs, chan->channel_id, clk_src, 1, 1, 0);
|
||||
rmt_ll_enable_group_clock(group->hal.regs, true);
|
||||
}
|
||||
group->resolution_hz = periph_src_clk_hz;
|
||||
ESP_LOGD(TAG, "group clock resolution:%"PRIu32, group->resolution_hz);
|
||||
real_div = (group->resolution_hz + expect_channel_resolution / 2) / expect_channel_resolution;
|
||||
#else
|
||||
// set division for group clock source, to achieve highest resolution while guaranteeing the channel resolution.
|
||||
ESP_RETURN_ON_ERROR(s_rmt_set_group_prescale(chan, expect_channel_resolution, &real_div), TAG, "set rmt group prescale failed");
|
||||
#endif // SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
|
||||
if (chan->direction == RMT_CHANNEL_DIRECTION_TX) {
|
||||
rmt_ll_tx_set_channel_clock_div(group->hal.regs, chan->channel_id, real_div);
|
||||
} else {
|
||||
rmt_ll_rx_set_channel_clock_div(group->hal.regs, chan->channel_id, real_div);
|
||||
}
|
||||
// resolution lost due to division, calculate the real resolution
|
||||
chan->resolution_hz = group->resolution_hz / real_div;
|
||||
if (chan->resolution_hz != expect_channel_resolution) {
|
||||
ESP_LOGW(TAG, "channel resolution loss, real=%"PRIu32, chan->resolution_hz);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -19,6 +19,7 @@
|
||||
#include "hal/rmt_hal.h"
|
||||
#include "hal/dma_types.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "hal/hal_utils.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_clk_tree.h"
|
||||
@ -113,7 +114,7 @@ struct rmt_group_t {
|
||||
portMUX_TYPE spinlock; // to protect per-group register level concurrent access
|
||||
rmt_hal_context_t hal; // hal layer for each group
|
||||
rmt_clock_source_t clk_src; // record the group clock source, group clock is shared by all channels
|
||||
uint32_t resolution_hz; // resolution of group clock
|
||||
uint32_t resolution_hz; // resolution of group clock. clk_src_hz / prescale = resolution_hz
|
||||
uint32_t occupy_mask; // a set bit in the mask indicates the channel is not available
|
||||
rmt_tx_channel_t *tx_channels[SOC_RMT_TX_CANDIDATES_PER_GROUP]; // array of RMT TX channels
|
||||
rmt_rx_channel_t *rx_channels[SOC_RMT_RX_CANDIDATES_PER_GROUP]; // array of RMT RX channels
|
||||
@ -219,17 +220,18 @@ rmt_group_t *rmt_acquire_group_handle(int group_id);
|
||||
void rmt_release_group_handle(rmt_group_t *group);
|
||||
|
||||
/**
|
||||
* @brief Set clock source for RMT peripheral
|
||||
* @brief Set clock source and resolution for RMT peripheral
|
||||
*
|
||||
* @param chan RMT channel handle
|
||||
* @param clk_src Clock source
|
||||
* @param expect_channel_resolution Expected channel resolution
|
||||
* @return
|
||||
* - ESP_OK: Set clock source successfully
|
||||
* - ESP_ERR_NOT_SUPPORTED: Set clock source failed because the clk_src is not supported
|
||||
* - ESP_ERR_INVALID_STATE: Set clock source failed because the clk_src is different from other RMT channel
|
||||
* - ESP_FAIL: Set clock source failed because of other error
|
||||
*/
|
||||
esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t clk_src);
|
||||
esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t clk_src, uint32_t expect_channel_resolution);
|
||||
|
||||
/**
|
||||
* @brief Set interrupt priority to RMT group
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -276,16 +276,9 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_
|
||||
ESP_GOTO_ON_ERROR(ret, err, TAG, "install rx interrupt failed");
|
||||
}
|
||||
|
||||
// select the clock source
|
||||
ESP_GOTO_ON_ERROR(rmt_select_periph_clock(&rx_channel->base, config->clk_src), err, TAG, "set group clock failed");
|
||||
// set channel clock resolution, find the divider to get the closest resolution
|
||||
uint32_t real_div = (group->resolution_hz + config->resolution_hz / 2) / config->resolution_hz;
|
||||
rmt_ll_rx_set_channel_clock_div(hal->regs, channel_id, real_div);
|
||||
// resolution loss due to division, calculate the real resolution
|
||||
rx_channel->base.resolution_hz = group->resolution_hz / real_div;
|
||||
if (rx_channel->base.resolution_hz != config->resolution_hz) {
|
||||
ESP_LOGW(TAG, "channel resolution loss, real=%"PRIu32, rx_channel->base.resolution_hz);
|
||||
}
|
||||
rx_channel->base.direction = RMT_CHANNEL_DIRECTION_RX;
|
||||
// select the clock source and set clock resolution
|
||||
ESP_GOTO_ON_ERROR(rmt_select_periph_clock(&rx_channel->base, config->clk_src, config->resolution_hz), err, TAG, "set clock resolution failed");
|
||||
|
||||
rx_channel->filter_clock_resolution_hz = group->resolution_hz;
|
||||
// On esp32 and esp32s2, the counting clock used by the RX filter always comes from APB clock
|
||||
@ -323,7 +316,6 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_
|
||||
// initialize other members of rx channel
|
||||
portMUX_INITIALIZE(&rx_channel->base.spinlock);
|
||||
atomic_init(&rx_channel->base.fsm, RMT_FSM_INIT);
|
||||
rx_channel->base.direction = RMT_CHANNEL_DIRECTION_RX;
|
||||
rx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_RX_CHANNEL_OFFSET_IN_GROUP].symbols[0];
|
||||
// polymorphic methods
|
||||
rx_channel->base.del = rmt_del_rx_channel;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -331,16 +331,9 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_
|
||||
ESP_GOTO_ON_ERROR(rmt_tx_init_dma_link(tx_channel, config), err, TAG, "install tx DMA failed");
|
||||
}
|
||||
#endif
|
||||
// select the clock source
|
||||
ESP_GOTO_ON_ERROR(rmt_select_periph_clock(&tx_channel->base, config->clk_src), err, TAG, "set group clock failed");
|
||||
// set channel clock resolution, find the divider to get the closest resolution
|
||||
uint32_t real_div = (group->resolution_hz + config->resolution_hz / 2) / config->resolution_hz;
|
||||
rmt_ll_tx_set_channel_clock_div(hal->regs, channel_id, real_div);
|
||||
// resolution lost due to division, calculate the real resolution
|
||||
tx_channel->base.resolution_hz = group->resolution_hz / real_div;
|
||||
if (tx_channel->base.resolution_hz != config->resolution_hz) {
|
||||
ESP_LOGW(TAG, "channel resolution loss, real=%"PRIu32, tx_channel->base.resolution_hz);
|
||||
}
|
||||
tx_channel->base.direction = RMT_CHANNEL_DIRECTION_TX;
|
||||
// select the clock source and set clock resolution
|
||||
ESP_GOTO_ON_ERROR(rmt_select_periph_clock(&tx_channel->base, config->clk_src, config->resolution_hz), err, TAG, "set clock resolution failed");
|
||||
|
||||
rmt_ll_tx_set_mem_blocks(hal->regs, channel_id, tx_channel->base.mem_block_num);
|
||||
// set limit threshold, after transmit ping_pong_symbols size, an interrupt event would be generated
|
||||
@ -376,7 +369,6 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_
|
||||
|
||||
portMUX_INITIALIZE(&tx_channel->base.spinlock);
|
||||
atomic_init(&tx_channel->base.fsm, RMT_FSM_INIT);
|
||||
tx_channel->base.direction = RMT_CHANNEL_DIRECTION_TX;
|
||||
tx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP].symbols[0];
|
||||
// polymorphic methods
|
||||
tx_channel->base.del = rmt_del_tx_channel;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -155,3 +155,34 @@ TEST_CASE("rmt interrupt priority", "[rmt]")
|
||||
TEST_ESP_OK(rmt_del_channel(rx_channel));
|
||||
TEST_ESP_OK(rmt_del_channel(another_rx_channel));
|
||||
}
|
||||
|
||||
#if !SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
TEST_CASE("rmt multiple channels with different resolution", "[rmt]")
|
||||
{
|
||||
rmt_tx_channel_config_t tx_channel_cfg = {
|
||||
.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL,
|
||||
.gpio_num = TEST_RMT_GPIO_NUM_A,
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 20 * 1000, // 20KHz
|
||||
.trans_queue_depth = 1,
|
||||
};
|
||||
rmt_channel_handle_t tx_channel = NULL;
|
||||
rmt_rx_channel_config_t rx_channel_cfg = {
|
||||
.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL,
|
||||
.gpio_num = TEST_RMT_GPIO_NUM_B,
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 40 * 1000 * 1000, // 40MHz
|
||||
};
|
||||
rmt_channel_handle_t rx_channel = NULL;
|
||||
|
||||
TEST_ESP_OK(rmt_new_tx_channel(&tx_channel_cfg, &tx_channel));
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, rmt_new_rx_channel(&rx_channel_cfg, &rx_channel));
|
||||
rx_channel_cfg.resolution_hz = 1 * 1000 * 1000; // 1MHz
|
||||
|
||||
TEST_ESP_OK(rmt_new_rx_channel(&rx_channel_cfg, &rx_channel));
|
||||
|
||||
TEST_ESP_OK(rmt_del_channel(tx_channel));
|
||||
TEST_ESP_OK(rmt_del_channel(rx_channel));
|
||||
}
|
||||
#endif //SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -37,6 +37,11 @@ extern "C" {
|
||||
#define RMT_LL_MAX_FILTER_VALUE 255
|
||||
#define RMT_LL_MAX_IDLE_VALUE 32767
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_FRACTAL_PRESCALE 64
|
||||
|
||||
typedef enum {
|
||||
RMT_LL_MEM_OWNER_SW = 0,
|
||||
RMT_LL_MEM_OWNER_HW = 1,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -38,6 +38,11 @@ extern "C" {
|
||||
#define RMT_LL_MAX_FILTER_VALUE 255
|
||||
#define RMT_LL_MAX_IDLE_VALUE 32767
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_FRACTAL_PRESCALE 64
|
||||
|
||||
typedef enum {
|
||||
RMT_LL_MEM_OWNER_SW = 0,
|
||||
RMT_LL_MEM_OWNER_HW = 1,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -38,6 +38,11 @@ extern "C" {
|
||||
#define RMT_LL_MAX_FILTER_VALUE 255
|
||||
#define RMT_LL_MAX_IDLE_VALUE 32767
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_FRACTAL_PRESCALE 64
|
||||
|
||||
typedef enum {
|
||||
RMT_LL_MEM_OWNER_SW = 0,
|
||||
RMT_LL_MEM_OWNER_HW = 1,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -38,6 +38,11 @@ extern "C" {
|
||||
#define RMT_LL_MAX_FILTER_VALUE 255
|
||||
#define RMT_LL_MAX_IDLE_VALUE 32767
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_FRACTAL_PRESCALE 64
|
||||
|
||||
typedef enum {
|
||||
RMT_LL_MEM_OWNER_SW = 0,
|
||||
RMT_LL_MEM_OWNER_HW = 1,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -37,6 +37,11 @@ extern "C" {
|
||||
#define RMT_LL_MAX_FILTER_VALUE 255
|
||||
#define RMT_LL_MAX_IDLE_VALUE 32767
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_FRACTAL_PRESCALE 64
|
||||
|
||||
typedef enum {
|
||||
RMT_LL_MEM_OWNER_SW = 0,
|
||||
RMT_LL_MEM_OWNER_HW = 1,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -37,6 +37,11 @@ extern "C" {
|
||||
#define RMT_LL_MAX_FILTER_VALUE 255
|
||||
#define RMT_LL_MAX_IDLE_VALUE 32767
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define RMT_LL_CHANNEL_CLOCK_MAX_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_INTEGER_PRESCALE 256
|
||||
#define RMT_LL_GROUP_CLOCK_MAX_FRACTAL_PRESCALE 64
|
||||
|
||||
typedef enum {
|
||||
RMT_LL_MEM_OWNER_SW = 0,
|
||||
RMT_LL_MEM_OWNER_HW = 1,
|
||||
|
@ -144,7 +144,7 @@ Once the :cpp:type:`rmt_rx_channel_config_t` structure is populated with mandato
|
||||
|
||||
.. note::
|
||||
|
||||
Due to a software limitation in the GPIO driver, when both TX and RX channels are bound to the same GPIO, ensure the RX Channel is initialized before the TX Channel. If the TX Channel was set up first, then during the RX Channel setup, the previous RMT TX Channel signal will be overridden by the GPIO control signal.
|
||||
When multiple RMT channels are allocated at the same time, the group’s prescale is determined based on the resolution of the first channel. The driver then selects the appropriate prescale from low to high. To avoid prescale conflicts when allocating multiple channels, allocate channels in order of their target resolution, either from highest to lowest or lowest to highest.
|
||||
|
||||
Uninstall RMT Channel
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -144,7 +144,7 @@ RMT 接收器可以对输入信号采样,将其转换为 RMT 数据格式,
|
||||
|
||||
.. note::
|
||||
|
||||
由于 GPIO 驱动程序中的软件限制,当 TX 和 RX 通道都绑定到同一 GPIO 时,请确保在 TX 通道之前初始化 RX 通道。如果先设置 TX 通道,那么在 RX 通道设置期间,GPIO 控制信号将覆盖先前的 RMT TX 通道信号。
|
||||
同时分配多个 RMT 通道时,RMT 组的分频系数将以第一个通道的分辨率来计算,驱动会从低到高寻找合适的分频系数。若分配多个通道时出现分频系数冲突,请调整分配通道的顺序,按照目标分辨率的大小按序申请通道(从大到小或者从小到大)。
|
||||
|
||||
卸载 RMT 通道
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
Loading…
x
Reference in New Issue
Block a user