mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 20:41:14 +00:00
rmt: support rmt user context in translator
Merges https://github.com/espressif/esp-idf/pull/6002
This commit is contained in:
@@ -99,6 +99,8 @@ typedef struct {
|
||||
int rx_item_start_idx;
|
||||
#endif
|
||||
sample_to_rmt_t sample_to_rmt;
|
||||
sample_with_context_to_rmt_t sample_with_context_to_rmt;
|
||||
void* tx_context;
|
||||
size_t sample_size_remain;
|
||||
const uint8_t *sample_cur;
|
||||
} rmt_obj_t;
|
||||
@@ -783,12 +785,21 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
|
||||
if (p_rmt->translator) {
|
||||
if (p_rmt->sample_size_remain > 0) {
|
||||
size_t translated_size = 0;
|
||||
p_rmt->sample_to_rmt((void *)p_rmt->sample_cur,
|
||||
p_rmt->tx_buf,
|
||||
p_rmt->sample_size_remain,
|
||||
p_rmt->tx_sub_len,
|
||||
&translated_size,
|
||||
&p_rmt->tx_len_rem);
|
||||
if (p_rmt->sample_with_context_to_rmt == NULL)
|
||||
p_rmt->sample_to_rmt((void *)p_rmt->sample_cur,
|
||||
p_rmt->tx_buf,
|
||||
p_rmt->sample_size_remain,
|
||||
p_rmt->tx_sub_len,
|
||||
&translated_size,
|
||||
&p_rmt->tx_len_rem);
|
||||
else
|
||||
p_rmt->sample_with_context_to_rmt((void *)p_rmt->sample_cur,
|
||||
p_rmt->tx_buf,
|
||||
p_rmt->sample_size_remain,
|
||||
p_rmt->tx_sub_len,
|
||||
&translated_size,
|
||||
&p_rmt->tx_len_rem,
|
||||
p_rmt->tx_context);
|
||||
p_rmt->sample_size_remain -= translated_size;
|
||||
p_rmt->sample_cur += translated_size;
|
||||
p_rmt->tx_data = p_rmt->tx_buf;
|
||||
@@ -1216,17 +1227,59 @@ esp_err_t rmt_translator_init(rmt_channel_t channel, sample_to_rmt_t fn)
|
||||
}
|
||||
}
|
||||
p_rmt_obj[channel]->sample_to_rmt = fn;
|
||||
p_rmt_obj[channel]->sample_with_context_to_rmt = NULL;
|
||||
p_rmt_obj[channel]->tx_context = NULL;
|
||||
p_rmt_obj[channel]->sample_size_remain = 0;
|
||||
p_rmt_obj[channel]->sample_cur = NULL;
|
||||
ESP_LOGD(RMT_TAG, "RMT translator init done");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t rmt_translator_init_with_context(rmt_channel_t channel, sample_with_context_to_rmt_t fn, void* context)
|
||||
{
|
||||
RMT_CHECK(fn != NULL, RMT_TRANSLATOR_NULL_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
|
||||
const uint32_t block_size = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel) *
|
||||
RMT_MEM_ITEM_NUM * sizeof(rmt_item32_t);
|
||||
if (p_rmt_obj[channel]->tx_buf == NULL) {
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
p_rmt_obj[channel]->tx_buf = (rmt_item32_t *)malloc(block_size);
|
||||
#else
|
||||
if (p_rmt_obj[channel]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) {
|
||||
p_rmt_obj[channel]->tx_buf = (rmt_item32_t *)malloc(block_size);
|
||||
} else {
|
||||
p_rmt_obj[channel]->tx_buf = (rmt_item32_t *)heap_caps_calloc(1, block_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
}
|
||||
#endif
|
||||
if (p_rmt_obj[channel]->tx_buf == NULL) {
|
||||
ESP_LOGE(RMT_TAG, "RMT translator buffer create fail");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
p_rmt_obj[channel]->sample_to_rmt = NULL;
|
||||
p_rmt_obj[channel]->sample_with_context_to_rmt = fn;
|
||||
p_rmt_obj[channel]->tx_context = context;
|
||||
p_rmt_obj[channel]->sample_size_remain = 0;
|
||||
p_rmt_obj[channel]->sample_cur = NULL;
|
||||
ESP_LOGD(RMT_TAG, "RMT translator init done");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t rmt_set_translator_context(rmt_channel_t channel, void* context)
|
||||
{
|
||||
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
|
||||
|
||||
p_rmt_obj[channel]->tx_context = context;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src_size, bool wait_tx_done)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
|
||||
RMT_CHECK(p_rmt_obj[channel]->sample_to_rmt != NULL, RMT_TRANSLATOR_UNINIT_STR, ESP_FAIL);
|
||||
RMT_CHECK(p_rmt_obj[channel]->sample_to_rmt != NULL || p_rmt_obj[channel]->sample_with_context_to_rmt != NULL, RMT_TRANSLATOR_UNINIT_STR, ESP_FAIL);
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
if (p_rmt_obj[channel]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) {
|
||||
if (!esp_ptr_internal(src)) {
|
||||
@@ -1241,7 +1294,10 @@ esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src
|
||||
const uint32_t item_block_len = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel) * RMT_MEM_ITEM_NUM;
|
||||
const uint32_t item_sub_len = item_block_len / 2;
|
||||
xSemaphoreTake(p_rmt->tx_sem, portMAX_DELAY);
|
||||
p_rmt->sample_to_rmt((void *)src, p_rmt->tx_buf, src_size, item_block_len, &translated_size, &item_num);
|
||||
if (p_rmt->sample_with_context_to_rmt == NULL)
|
||||
p_rmt->sample_to_rmt((void *)src, p_rmt->tx_buf, src_size, item_block_len, &translated_size, &item_num);
|
||||
else
|
||||
p_rmt->sample_with_context_to_rmt((void*)src, p_rmt->tx_buf, src_size, item_block_len, &translated_size, &item_num, p_rmt->tx_context);
|
||||
p_rmt->sample_size_remain = src_size - translated_size;
|
||||
p_rmt->sample_cur = src + translated_size;
|
||||
rmt_fill_memory(channel, p_rmt->tx_buf, item_num, 0);
|
||||
|
Reference in New Issue
Block a user