Skip to content

Commit 1481ecb

Browse files
committed
Merge branch 'feat/rmt_encoder_func_attr' into 'master'
feat(rmt): introduce RMT_ENCODER_FUNC_ATTR for encoder functions Closes IDFGH-15156 See merge request espressif/esp-idf!38653
2 parents 692512c + ae5f8e5 commit 1481ecb

File tree

19 files changed

+88
-33
lines changed

19 files changed

+88
-33
lines changed

components/esp_driver_rmt/Kconfig

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
menu "ESP-Driver:RMT Configurations"
22
depends on SOC_RMT_SUPPORTED
33

4+
config RMT_ENCODER_FUNC_IN_IRAM
5+
bool "Place RMT encoder function in IRAM"
6+
default y
7+
help
8+
Place RMT encoder function into IRAM for better performance and fewer cache misses.
9+
410
config RMT_TX_ISR_HANDLER_IN_IRAM
511
bool "Place RMT TX ISR handler in IRAM to reduce latency"
612
default y
713
select RMT_OBJ_CACHE_SAFE
8-
select GDMA_CTRL_FUNC_IN_IRAM if SOC_RMT_SUPPORT_DMA
9-
select BITSCRAMBLER_CTRL_FUNC_IN_IRAM if SOC_BITSCRAMBLER_SUPPORTED && SOC_RMT_SUPPORT_DMA
1014
help
1115
Place RMT TX ISR handler in IRAM to reduce latency caused by cache miss.
1216

@@ -21,24 +25,22 @@ menu "ESP-Driver:RMT Configurations"
2125
bool "Place RMT receive function in IRAM"
2226
default n
2327
select RMT_OBJ_CACHE_SAFE
24-
select GDMA_CTRL_FUNC_IN_IRAM if SOC_RMT_SUPPORT_DMA
2528
help
2629
Place RMT receive function into IRAM for better performance and fewer cache misses.
2730

2831
config RMT_TX_ISR_CACHE_SAFE
29-
bool "Allow RMT TX ISR to execute when cache is disabled"
32+
bool "Allow RMT TX ISR to execute when cache is disabled" if !SPI_FLASH_AUTO_SUSPEND
3033
select RMT_TX_ISR_HANDLER_IN_IRAM
31-
select GDMA_ISR_HANDLER_IN_IRAM if SOC_RMT_SUPPORT_DMA
34+
select RMT_ENCODER_FUNC_IN_IRAM
3235
default n
3336
help
3437
Enable this option to allow the RMT TX Interrupt Service Routine (ISR)
3538
to execute even when the cache is disabled. This can be useful in scenarios where the cache
3639
might be turned off, but the RMT TX functionality is still required to operate correctly.
3740

3841
config RMT_RX_ISR_CACHE_SAFE
39-
bool "Allow RMT RX ISR to execute when cache is disabled"
42+
bool "Allow RMT RX ISR to execute when cache is disabled" if !SPI_FLASH_AUTO_SUSPEND
4043
select RMT_RX_ISR_HANDLER_IN_IRAM
41-
select GDMA_ISR_HANDLER_IN_IRAM if SOC_RMT_SUPPORT_DMA
4244
default n
4345
help
4446
Enable this option to allow the RMT RX Interrupt Service Routine (ISR)
@@ -63,7 +65,7 @@ menu "ESP-Driver:RMT Configurations"
6365
Please enable this option by caution, as it will increase the binary size.
6466

6567
config RMT_ISR_IRAM_SAFE
66-
bool "RMT ISR IRAM-Safe (Deprecated)"
68+
bool "RMT ISR IRAM-Safe (Deprecated)" if !SPI_FLASH_AUTO_SUSPEND
6769
select RMT_TX_ISR_CACHE_SAFE
6870
select RMT_RX_ISR_CACHE_SAFE
6971
default n

components/esp_driver_rmt/include/driver/rmt_encoder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#pragma once
88

99
#include <stdint.h>
10+
#include "sdkconfig.h"
1011
#include "esp_err.h"
12+
#include "esp_attr.h"
1113
#include "hal/rmt_types.h"
1214
#include "driver/rmt_types.h"
1315

@@ -69,6 +71,12 @@ struct rmt_encoder_t {
6971
esp_err_t (*del)(rmt_encoder_t *encoder);
7072
};
7173

74+
#if CONFIG_RMT_ENCODER_FUNC_IN_IRAM
75+
#define RMT_ENCODER_FUNC_ATTR IRAM_ATTR
76+
#else
77+
#define RMT_ENCODER_FUNC_ATTR
78+
#endif
79+
7280
/**
7381
* @brief Callback for simple callback encoder
7482
*

components/esp_driver_rmt/linker.lf

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,15 @@ entries:
88
rmt_tx: rmt_tx_do_transaction (noflash)
99
rmt_tx: rmt_encode_check_result (noflash)
1010
rmt_tx: rmt_tx_mark_eof (noflash)
11-
rmt_encoder: rmt_encoder_reset (noflash)
12-
rmt_encoder_bytes: rmt_encode_bytes (noflash)
13-
rmt_encoder_bytes: rmt_bytes_encoder_reset (noflash)
14-
rmt_encoder_copy: rmt_encode_copy (noflash)
15-
rmt_encoder_copy: rmt_copy_encoder_reset (noflash)
16-
rmt_encoder_simple: rmt_encode_simple (noflash)
17-
rmt_encoder_simple: rmt_simple_encoder_reset (noflash)
1811

1912
if SOC_RMT_SUPPORT_TX_LOOP_COUNT = y:
2013
rmt_tx: rmt_isr_handle_tx_loop_end (noflash)
2114

2215
if SOC_RMT_SUPPORT_DMA = y:
2316
rmt_tx: rmt_dma_tx_eof_cb (noflash)
2417

25-
if SOC_BITSCRAMBLER_SUPPORTED = y:
26-
rmt_encoder_bs: rmt_encode_bs (noflash)
27-
rmt_encoder_bs: rmt_bs_encoder_reset (noflash)
18+
if RMT_ENCODER_FUNC_IN_IRAM = y:
19+
rmt_encoder: rmt_encoder_reset (noflash)
2820

2921
if RMT_RX_ISR_HANDLER_IN_IRAM = y:
3022
rmt_rx: rmt_rx_default_isr (noflash)

components/esp_driver_rmt/src/rmt_encoder_bs.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ typedef struct rmt_bs_encoder_t {
1414
bitscrambler_handle_t bs; // BitScrambler handle
1515
} rmt_bs_encoder_t;
1616

17+
RMT_ENCODER_FUNC_ATTR
1718
static esp_err_t rmt_bs_encoder_reset(rmt_encoder_t *encoder)
1819
{
1920
rmt_bs_encoder_t *bs_encoder = __containerof(encoder, rmt_bs_encoder_t, base);
@@ -23,14 +24,7 @@ static esp_err_t rmt_bs_encoder_reset(rmt_encoder_t *encoder)
2324
return ESP_OK;
2425
}
2526

26-
static esp_err_t rmt_del_bs_encoder(rmt_encoder_t *encoder)
27-
{
28-
rmt_bs_encoder_t *bs_encoder = __containerof(encoder, rmt_bs_encoder_t, base);
29-
bitscrambler_free(bs_encoder->bs);
30-
free(bs_encoder);
31-
return ESP_OK;
32-
}
33-
27+
RMT_ENCODER_FUNC_ATTR
3428
static size_t rmt_encode_bs(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *input_raw,
3529
size_t data_size, rmt_encode_state_t *ret_state)
3630
{
@@ -109,11 +103,24 @@ static size_t rmt_encode_bs(rmt_encoder_t *encoder, rmt_channel_handle_t channel
109103
return copy_len;
110104
}
111105

106+
static esp_err_t rmt_del_bs_encoder(rmt_encoder_t *encoder)
107+
{
108+
rmt_bs_encoder_t *bs_encoder = __containerof(encoder, rmt_bs_encoder_t, base);
109+
bitscrambler_free(bs_encoder->bs);
110+
free(bs_encoder);
111+
return ESP_OK;
112+
}
113+
112114
esp_err_t rmt_new_bitscrambler_encoder(const rmt_bs_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder)
113115
{
114116
esp_err_t ret = ESP_OK;
115117
rmt_bs_encoder_t *encoder = NULL;
116-
ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
118+
ESP_RETURN_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
119+
// bitscrambler function is used under RMT TX ISR context
120+
// if the cache is disabled, all functions called by ISR must be in IRAM
121+
#if CONFIG_RMT_TX_ISR_CACHE_SAFE && !CONFIG_BITSCRAMBLER_CTRL_FUNC_IN_IRAM
122+
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "CONFIG_BITSCRAMBLER_CTRL_FUNC_IN_IRAM must be enabled");
123+
#endif
117124
encoder = rmt_alloc_encoder_mem(sizeof(rmt_bs_encoder_t));
118125
ESP_GOTO_ON_FALSE(encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for bitscrambler encoder");
119126

components/esp_driver_rmt/src/rmt_encoder_bytes.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef struct rmt_bytes_encoder_t {
1818
} flags;
1919
} rmt_bytes_encoder_t;
2020

21+
RMT_ENCODER_FUNC_ATTR
2122
static esp_err_t rmt_bytes_encoder_reset(rmt_encoder_t *encoder)
2223
{
2324
rmt_bytes_encoder_t *bytes_encoder = __containerof(encoder, rmt_bytes_encoder_t, base);
@@ -27,6 +28,7 @@ static esp_err_t rmt_bytes_encoder_reset(rmt_encoder_t *encoder)
2728
return ESP_OK;
2829
}
2930

31+
RMT_ENCODER_FUNC_ATTR
3032
static size_t rmt_encode_bytes(rmt_encoder_t *encoder, rmt_channel_handle_t channel,
3133
const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state)
3234
{

components/esp_driver_rmt/src/rmt_encoder_copy.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ typedef struct rmt_copy_encoder_t {
1212
size_t last_symbol_index; // index of symbol position in the primary stream
1313
} rmt_copy_encoder_t;
1414

15+
RMT_ENCODER_FUNC_ATTR
1516
static esp_err_t rmt_copy_encoder_reset(rmt_encoder_t *encoder)
1617
{
1718
rmt_copy_encoder_t *copy_encoder = __containerof(encoder, rmt_copy_encoder_t, base);
1819
copy_encoder->last_symbol_index = 0;
1920
return ESP_OK;
2021
}
2122

23+
RMT_ENCODER_FUNC_ATTR
2224
static size_t rmt_encode_copy(rmt_encoder_t *encoder, rmt_channel_handle_t channel,
2325
const void *input_symbols, size_t data_size, rmt_encode_state_t *ret_state)
2426
{

components/esp_driver_rmt/src/rmt_encoder_simple.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef struct rmt_simple_encoder_t {
1919
bool callback_done; //true if we can't call the callback for more data anymore.
2020
} rmt_simple_encoder_t;
2121

22+
RMT_ENCODER_FUNC_ATTR
2223
static esp_err_t rmt_simple_encoder_reset(rmt_encoder_t *encoder)
2324
{
2425
rmt_simple_encoder_t *simple_encoder = __containerof(encoder, rmt_simple_encoder_t, base);
@@ -29,6 +30,7 @@ static esp_err_t rmt_simple_encoder_reset(rmt_encoder_t *encoder)
2930
return ESP_OK;
3031
}
3132

33+
RMT_ENCODER_FUNC_ATTR
3234
static size_t rmt_encode_simple(rmt_encoder_t *encoder, rmt_channel_handle_t channel,
3335
const void *data, size_t data_size, rmt_encode_state_t *ret_state)
3436
{

components/esp_driver_rmt/src/rmt_rx.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,13 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_
180180
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(config->gpio_num), ESP_ERR_INVALID_ARG, TAG, "invalid GPIO number %d", config->gpio_num);
181181
ESP_RETURN_ON_FALSE((config->mem_block_symbols & 0x01) == 0 && config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL,
182182
ESP_ERR_INVALID_ARG, TAG, "mem_block_symbols must be even and at least %d", SOC_RMT_MEM_WORDS_PER_CHANNEL);
183-
#if !SOC_RMT_SUPPORT_DMA
183+
#if SOC_RMT_SUPPORT_DMA
184+
if (config->flags.with_dma) {
185+
#if CONFIG_RMT_RX_ISR_CACHE_SAFE && (!CONFIG_GDMA_ISR_HANDLER_IN_IRAM || !CONFIG_GDMA_CTRL_FUNC_IN_IRAM)
186+
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "CONFIG_GDMA_ISR_HANDLER_IN_IRAM and CONFIG_GDMA_CTRL_FUNC_IN_IRAM must be enabled");
187+
#endif
188+
}
189+
#else
184190
ESP_RETURN_ON_FALSE(config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA not supported");
185191
#endif // SOC_RMT_SUPPORT_DMA
186192

components/esp_driver_rmt/src/rmt_tx.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,13 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_
243243
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(config->gpio_num), ESP_ERR_INVALID_ARG, TAG, "invalid GPIO number %d", config->gpio_num);
244244
ESP_RETURN_ON_FALSE((config->mem_block_symbols & 0x01) == 0 && config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL,
245245
ESP_ERR_INVALID_ARG, TAG, "mem_block_symbols must be even and at least %d", SOC_RMT_MEM_WORDS_PER_CHANNEL);
246-
#if !SOC_RMT_SUPPORT_DMA
246+
#if SOC_RMT_SUPPORT_DMA
247+
if (config->flags.with_dma) {
248+
#if CONFIG_RMT_TX_ISR_CACHE_SAFE && (!CONFIG_GDMA_ISR_HANDLER_IN_IRAM || !CONFIG_GDMA_CTRL_FUNC_IN_IRAM)
249+
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "CONFIG_GDMA_ISR_HANDLER_IN_IRAM and CONFIG_GDMA_CTRL_FUNC_IN_IRAM must be enabled");
250+
#endif
251+
}
252+
#else
247253
ESP_RETURN_ON_FALSE(config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA not supported");
248254
#endif
249255

components/esp_driver_rmt/test_apps/rmt/main/test_rmt_bitscrambler.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ TEST_CASE("rmt TX with bitscrambler", "[rmt]")
9797
}, 5, &transmit_config));
9898
TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
9999

100+
TEST_ESP_OK(rmt_receive(rx_channel, symbols, sizeof(symbols), &receive_config));
101+
printf("transmit again!\r\n");
102+
TEST_ESP_OK(rmt_transmit(tx_channel, bs_encoder, (uint8_t[]) {
103+
0x12, 0x34, 0x56, 0x78, 0x9a, // dummy test values, will be further processed by bitscrambler program
104+
}, 5, &transmit_config));
105+
TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
106+
100107
printf("disable tx+rx channel\r\n");
101108
TEST_ESP_OK(rmt_disable(tx_channel));
102109
TEST_ESP_OK(rmt_disable(rx_channel));

0 commit comments

Comments
 (0)