mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'fix/fix_rmt_loop_tx_trigger_done_event_v5.5' into 'release/v5.5'
fix(rmt): clear stale TX done status before new transaction (v5.5) See merge request espressif/esp-idf!51654
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -730,11 +730,13 @@ static void rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t
|
||||
// don't enable threshold interrupt with loop mode on
|
||||
// threshold interrupt will be disabled in `rmt_encode_eof()`
|
||||
rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_THRES(channel_id), t->loop_count == 0);
|
||||
// Threshold interrupt will be generated by accident, clear it before starting new transmission
|
||||
rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_THRES(channel_id));
|
||||
}
|
||||
// don't generate trans done event for loop transmission
|
||||
rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), t->loop_count == 0);
|
||||
// Clear stale TX events before the engine starts.
|
||||
// Some targets can keep TX_DONE pending after a loop transaction.
|
||||
// And Threshold interrupt may be generated by accident
|
||||
rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id));
|
||||
portEXIT_CRITICAL_SAFE(&group->spinlock);
|
||||
|
||||
// at the beginning of a new transaction, encoding memory offset should start from zero.
|
||||
@@ -916,6 +918,8 @@ bool rmt_isr_handle_tx_threshold(rmt_tx_channel_t *tx_chan)
|
||||
{
|
||||
// continue ping-pong transmission
|
||||
rmt_tx_trans_desc_t *t = tx_chan->cur_trans;
|
||||
// sanity check
|
||||
assert(t);
|
||||
size_t encoded_symbols = t->transmitted_symbol_num;
|
||||
// encoding finished, only need to send the EOF symbol
|
||||
if (t->flags.encoding_done) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -388,6 +388,96 @@ TEST_CASE("rmt finite loop transaction", "[rmt]")
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t expected_symbols[3];
|
||||
uint32_t done_count;
|
||||
} test_rmt_sequential_loop_context_t;
|
||||
|
||||
TEST_RMT_CALLBACK_ATTR
|
||||
static bool test_rmt_sequential_loop_done_cb(rmt_channel_handle_t channel, const rmt_tx_done_event_data_t *edata, void *user_data)
|
||||
{
|
||||
test_rmt_sequential_loop_context_t *ctx = (test_rmt_sequential_loop_context_t *)user_data;
|
||||
TEST_ASSERT_LESS_THAN(3, ctx->done_count);
|
||||
esp_rom_printf("test_rmt_sequential_loop_done_cb: done_count = %d, expected_symbols = %d, num_symbols = %d\r\n", ctx->done_count, ctx->expected_symbols[ctx->done_count], edata->num_symbols);
|
||||
TEST_ASSERT_EQUAL(ctx->expected_symbols[ctx->done_count], edata->num_symbols);
|
||||
ctx->done_count++;
|
||||
return false;
|
||||
}
|
||||
|
||||
TEST_CASE("rmt loop transaction followed by ping-pong transaction", "[rmt]")
|
||||
{
|
||||
rmt_tx_channel_config_t tx_channel_cfg = {
|
||||
.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * 2,
|
||||
.clk_src = RMT_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 1000000, // 1MHz, 1 tick = 1us
|
||||
.trans_queue_depth = 4,
|
||||
.gpio_num = TEST_RMT_GPIO_NUM_A,
|
||||
.intr_priority = 2,
|
||||
};
|
||||
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 copy encoder\r\n");
|
||||
rmt_encoder_handle_t copy_encoder = NULL;
|
||||
rmt_copy_encoder_config_t copy_encoder_config = {};
|
||||
TEST_ESP_OK(rmt_new_copy_encoder(©_encoder_config, ©_encoder));
|
||||
|
||||
uint32_t ping_pong_symbol_num = SOC_RMT_MEM_WORDS_PER_CHANNEL * 3 + 5;
|
||||
test_rmt_sequential_loop_context_t cb_ctx = {
|
||||
// +1 for the eof marker
|
||||
.expected_symbols = {
|
||||
ping_pong_symbol_num + 1,
|
||||
2,
|
||||
ping_pong_symbol_num + 1,
|
||||
},
|
||||
};
|
||||
rmt_tx_event_callbacks_t cbs = {
|
||||
.on_trans_done = test_rmt_sequential_loop_done_cb,
|
||||
};
|
||||
TEST_ESP_OK(rmt_tx_register_event_callbacks(tx_channel, &cbs, &cb_ctx));
|
||||
|
||||
printf("enable tx channel\r\n");
|
||||
TEST_ESP_OK(rmt_enable(tx_channel));
|
||||
|
||||
rmt_symbol_word_t ping_pong_symbols[ping_pong_symbol_num];
|
||||
memset(ping_pong_symbols, 0, sizeof(ping_pong_symbols));
|
||||
for (int i = 0; i < ping_pong_symbol_num; i++) {
|
||||
ping_pong_symbols[i] = (rmt_symbol_word_t) {
|
||||
.level0 = 0,
|
||||
.duration0 = 5,
|
||||
.level1 = 1,
|
||||
.duration1 = 5,
|
||||
};
|
||||
}
|
||||
rmt_symbol_word_t loop_symbol = {
|
||||
.level0 = 0,
|
||||
.duration0 = 5,
|
||||
.level1 = 1,
|
||||
.duration1 = 5,
|
||||
};
|
||||
|
||||
printf("queue ping-pong, loop, ping-pong transactions\r\n");
|
||||
rmt_transmit_config_t transmit_config = {
|
||||
.loop_count = 0,
|
||||
};
|
||||
TEST_ESP_OK(rmt_transmit(tx_channel, copy_encoder, ping_pong_symbols, sizeof(ping_pong_symbols), &transmit_config));
|
||||
transmit_config.loop_count = 50;
|
||||
TEST_ESP_OK(rmt_transmit(tx_channel, copy_encoder, &loop_symbol, sizeof(loop_symbol), &transmit_config));
|
||||
transmit_config.loop_count = 0;
|
||||
TEST_ESP_OK(rmt_transmit(tx_channel, copy_encoder, ping_pong_symbols, sizeof(ping_pong_symbols), &transmit_config));
|
||||
|
||||
printf("wait for queued transactions done\r\n");
|
||||
TEST_ESP_OK(rmt_tx_wait_all_done(tx_channel, -1));
|
||||
TEST_ASSERT_EQUAL(3, cb_ctx.done_count);
|
||||
|
||||
printf("disable tx channel\r\n");
|
||||
TEST_ESP_OK(rmt_disable(tx_channel));
|
||||
printf("remove tx channel and copy encoder\r\n");
|
||||
TEST_ESP_OK(rmt_del_channel(tx_channel));
|
||||
TEST_ESP_OK(rmt_del_encoder(copy_encoder));
|
||||
}
|
||||
|
||||
#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
|
||||
|
||||
TEST_CASE("rmt infinite loop transaction", "[rmt]")
|
||||
|
||||
Reference in New Issue
Block a user