mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/test_rmt_bytes_encoder' into 'master'
rmt: explained why encoder may results in more data being transmitted Closes IDFGH-10201 See merge request espressif/esp-idf!23880
This commit is contained in:
commit
bdd0d1ddc8
@ -13,7 +13,7 @@
|
||||
#include "driver/rmt_rx.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
TEST_CASE("rmt_channel_install_uninstall", "[rmt]")
|
||||
TEST_CASE("rmt channel install & uninstall", "[rmt]")
|
||||
{
|
||||
rmt_tx_channel_config_t tx_channel_cfg = {
|
||||
.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -78,17 +78,14 @@ static void test_rmt_tx_iram_safe(size_t mem_block_symbols, bool with_dma)
|
||||
TEST_ESP_OK(rmt_del_encoder(led_strip_encoder));
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_tx_iram_safe_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt tx iram safe", "[rmt]")
|
||||
{
|
||||
test_rmt_tx_iram_safe(SOC_RMT_MEM_WORDS_PER_CHANNEL, false);
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
test_rmt_tx_iram_safe(1024, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_tx_iram_safe_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_tx_iram_safe(1024, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void IRAM_ATTR test_simulate_input_post_cache_disable(void *args)
|
||||
@ -169,14 +166,10 @@ static void test_rmt_rx_iram_safe(size_t mem_block_symbols, bool with_dma, rmt_c
|
||||
TEST_ESP_OK(rmt_del_channel(rx_channel));
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_rx_iram_safe_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt rx iram safe", "[rmt]")
|
||||
{
|
||||
test_rmt_rx_iram_safe(SOC_RMT_MEM_WORDS_PER_CHANNEL, false, RMT_CLK_SRC_DEFAULT);
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_rx_iram_safe_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_rx_iram_safe(128, true, RMT_CLK_SRC_DEFAULT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -185,18 +185,14 @@ static void test_rmt_rx_nec_carrier(size_t mem_block_symbols, bool with_dma, rmt
|
||||
TEST_ESP_OK(rmt_del_encoder(nec_encoder));
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_rx_nec_carrier_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt rx nec with carrier", "[rmt]")
|
||||
{
|
||||
// test width different clock sources
|
||||
rmt_clock_source_t clk_srcs[] = SOC_RMT_CLKS;
|
||||
for (size_t i = 0; i < sizeof(clk_srcs) / sizeof(clk_srcs[0]); i++) {
|
||||
test_rmt_rx_nec_carrier(SOC_RMT_MEM_WORDS_PER_CHANNEL, false, clk_srcs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_rx_nec_carrier_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_rx_nec_carrier(128, true, RMT_CLK_SRC_DEFAULT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -20,6 +20,63 @@
|
||||
#define TEST_RMT_CALLBACK_ATTR
|
||||
#endif
|
||||
|
||||
TEST_CASE("rmt bytes encoder", "[rmt]")
|
||||
{
|
||||
rmt_tx_channel_config_t tx_channel_cfg = {
|
||||
.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL,
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 1000000, // 1MHz, 1 tick = 1us
|
||||
.trans_queue_depth = 4,
|
||||
.gpio_num = 0,
|
||||
};
|
||||
printf("install tx channel\r\n");
|
||||
rmt_channel_handle_t tx_channel = NULL;
|
||||
TEST_ESP_OK(rmt_new_tx_channel(&tx_channel_cfg, &tx_channel));
|
||||
printf("install bytes encoder\r\n");
|
||||
rmt_encoder_handle_t bytes_encoder = NULL;
|
||||
rmt_bytes_encoder_config_t bytes_enc_config = {
|
||||
.bit0 = {
|
||||
.level0 = 1,
|
||||
.duration0 = 3, // 3us
|
||||
.level1 = 0,
|
||||
.duration1 = 9, // 9us
|
||||
},
|
||||
.bit1 = {
|
||||
.level0 = 1,
|
||||
.duration0 = 9, // 9us
|
||||
.level1 = 0,
|
||||
.duration1 = 3, // 3us
|
||||
},
|
||||
};
|
||||
TEST_ESP_OK(rmt_new_bytes_encoder(&bytes_enc_config, &bytes_encoder));
|
||||
printf("enable tx channel\r\n");
|
||||
TEST_ESP_OK(rmt_enable(tx_channel));
|
||||
|
||||
printf("start transaction\r\n");
|
||||
rmt_transmit_config_t transmit_config = {
|
||||
.loop_count = 0, // no loop
|
||||
};
|
||||
TEST_ESP_OK(rmt_transmit(tx_channel, bytes_encoder, (uint8_t[]) {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
|
||||
}, 6, &transmit_config));
|
||||
// adding extra delay here for visualizing
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
TEST_ESP_OK(rmt_transmit(tx_channel, bytes_encoder, (uint8_t[]) {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
|
||||
}, 7, &transmit_config));
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
TEST_ESP_OK(rmt_transmit(tx_channel, bytes_encoder, (uint8_t[]) {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04
|
||||
}, 5, &transmit_config));
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
|
||||
printf("disable tx channel\r\n");
|
||||
TEST_ESP_OK(rmt_disable(tx_channel));
|
||||
printf("remove tx channel and encoder\r\n");
|
||||
TEST_ESP_OK(rmt_del_channel(tx_channel));
|
||||
TEST_ESP_OK(rmt_del_encoder(bytes_encoder));
|
||||
}
|
||||
|
||||
static void test_rmt_channel_single_trans(size_t mem_block_symbols, bool with_dma)
|
||||
{
|
||||
rmt_tx_channel_config_t tx_channel_cfg = {
|
||||
@ -66,17 +123,13 @@ static void test_rmt_channel_single_trans(size_t mem_block_symbols, bool with_dm
|
||||
TEST_ESP_OK(rmt_del_encoder(led_strip_encoder));
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_single_trans_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt single transaction", "[rmt]")
|
||||
{
|
||||
test_rmt_channel_single_trans(SOC_RMT_MEM_WORDS_PER_CHANNEL, false);
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_single_trans_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_channel_single_trans(512, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_rmt_ping_pong_trans(size_t mem_block_symbols, bool with_dma)
|
||||
{
|
||||
@ -147,17 +200,14 @@ static void test_rmt_ping_pong_trans(size_t mem_block_symbols, bool with_dma)
|
||||
#undef TEST_LED_NUM
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_ping_pong_trans_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt ping-pong transaction", "[rmt]")
|
||||
{
|
||||
test_rmt_ping_pong_trans(SOC_RMT_MEM_WORDS_PER_CHANNEL, false);
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
test_rmt_ping_pong_trans(1024, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_ping_pong_trans_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_ping_pong_trans(1024, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_RMT_CALLBACK_ATTR
|
||||
static bool test_rmt_tx_done_cb_check_event_data(rmt_channel_handle_t channel, const rmt_tx_done_event_data_t *edata, void *user_data)
|
||||
@ -222,17 +272,13 @@ static void test_rmt_trans_done_event(size_t mem_block_symbols, bool with_dma)
|
||||
#undef TEST_LED_NUM
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_trans_done_event_callback_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt trans_done event callback", "[rmt]")
|
||||
{
|
||||
test_rmt_trans_done_event(SOC_RMT_MEM_WORDS_PER_CHANNEL, false);
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_trans_done_event_callback_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_trans_done_event(332, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
|
||||
|
||||
@ -294,20 +340,17 @@ static void test_rmt_loop_trans(size_t mem_block_symbols, bool with_dma)
|
||||
#undef TEST_LED_NUM
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_loop_trans_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt finite loop transaction", "[rmt]")
|
||||
{
|
||||
test_rmt_loop_trans(SOC_RMT_MEM_WORDS_PER_CHANNEL * 2, false);
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
test_rmt_loop_trans(128, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_loop_trans_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_loop_trans(128, true);
|
||||
}
|
||||
#endif // SOC_RMT_SUPPORT_DMA
|
||||
#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
|
||||
|
||||
TEST_CASE("rmt_infinite_loop_trans", "[rmt]")
|
||||
TEST_CASE("rmt infinite loop transaction", "[rmt]")
|
||||
{
|
||||
rmt_tx_channel_config_t tx_channel_cfg = {
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
@ -441,17 +484,14 @@ static void test_rmt_tx_nec_carrier(size_t mem_block_symbols, bool with_dma)
|
||||
TEST_ESP_OK(rmt_del_encoder(nec_encoder));
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_tx_nec_carrier_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt tx nec with carrier", "[rmt]")
|
||||
{
|
||||
test_rmt_tx_nec_carrier(SOC_RMT_MEM_WORDS_PER_CHANNEL, false);
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
test_rmt_tx_nec_carrier(128, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_tx_nec_carrier_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_tx_nec_carrier(128, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_RMT_CALLBACK_ATTR
|
||||
static bool test_rmt_tx_done_cb_record_time(rmt_channel_handle_t channel, const rmt_tx_done_event_data_t *edata, void *user_data)
|
||||
@ -596,14 +636,10 @@ static void test_rmt_multi_channels_trans(size_t channel0_mem_block_symbols, siz
|
||||
#undef TEST_RMT_CHANS
|
||||
}
|
||||
|
||||
TEST_CASE("rmt_multi_channels_trans_no_dma", "[rmt]")
|
||||
TEST_CASE("rmt multiple channels transaction", "[rmt]")
|
||||
{
|
||||
test_rmt_multi_channels_trans(SOC_RMT_MEM_WORDS_PER_CHANNEL, SOC_RMT_MEM_WORDS_PER_CHANNEL, false, false);
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_DMA
|
||||
TEST_CASE("rmt_multi_channels_trans_with_dma", "[rmt]")
|
||||
{
|
||||
test_rmt_multi_channels_trans(1024, SOC_RMT_MEM_WORDS_PER_CHANNEL, true, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -520,6 +520,17 @@ Application Examples
|
||||
* RMT infinite loop for driving DShot ESC: :example:`peripherals/rmt/dshot_esc`
|
||||
* RMT simulate 1-wire protocol (take DS18B20 as example): :example:`peripherals/rmt/onewire`
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
* Why the RMT encoder results in more data than expected?
|
||||
|
||||
The RMT encoding takes place in the ISR context. If your RMT encoding session takes a long time (e.g. by logging debug information) or the encoding session is deferred somehow because of interrupt latency, then it's possible the transmitting becomes **faster** than the encoding. Which in result, the encoder can't prepare the next data in time, leading to the transmitter sending the previous data again. There's no way to ask the transmitter to stop and wait. You can mitigate the issue by combining the following ways:
|
||||
|
||||
- increase the :cpp:member:`rmt_tx_channel_config_t::mem_block_symbols`, in steps of {IDF_TARGET_SOC_RMT_MEM_WORDS_PER_CHANNEL}
|
||||
- place the encoding function in the IRAM
|
||||
- Enables the :cpp:member:`rmt_tx_channel_config_t::with_dma` if it's available for your chip
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user