feat(rmt): specify interrupt priority

This commit is contained in:
Planck (Lu Zeyu)
2023-08-29 17:56:03 +08:00
parent e0f5d3c527
commit 80fa5da9e8
10 changed files with 199 additions and 10 deletions

View File

@@ -210,10 +210,16 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_
#endif
esp_err_t ret = ESP_OK;
rmt_tx_channel_t *tx_channel = NULL;
// Check if priority is valid
if (config->intr_priority) {
ESP_RETURN_ON_FALSE((config->intr_priority) > 0, ESP_ERR_INVALID_ARG, TAG, "invalid interrupt priority:%d", config->intr_priority);
ESP_RETURN_ON_FALSE(1 << (config->intr_priority) & RMT_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, TAG, "invalid interrupt priority:%d", config->intr_priority);
}
ESP_GOTO_ON_FALSE(config && ret_chan && config->resolution_hz && config->trans_queue_depth, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(GPIO_IS_VALID_GPIO(config->gpio_num), ESP_ERR_INVALID_ARG, err, TAG, "invalid GPIO number");
ESP_GOTO_ON_FALSE((config->mem_block_symbols & 0x01) == 0 && config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL,
ESP_ERR_INVALID_ARG, err, TAG, "mem_block_symbols must be even and at least %d", SOC_RMT_MEM_WORDS_PER_CHANNEL);
#if SOC_RMT_SUPPORT_DMA
// we only support 2 nodes ping-pong, if the configured memory block size needs more than two DMA descriptors, should treat it as invalid
ESP_GOTO_ON_FALSE(config->mem_block_symbols <= RMT_DMA_DESC_BUF_MAX_SIZE * RMT_DMA_NODES_PING_PONG / sizeof(rmt_symbol_word_t),
@@ -246,13 +252,19 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_
portENTER_CRITICAL(&group->spinlock);
rmt_hal_tx_channel_reset(&group->hal, channel_id);
portEXIT_CRITICAL(&group->spinlock);
// install interrupt service
// install tx interrupt
// --- install interrupt service
// interrupt is mandatory to run basic RMT transactions, so it's not lazy installed in `rmt_tx_register_event_callbacks()`
int isr_flags = RMT_INTR_ALLOC_FLAG;
// 1-- Set user specified priority to `group->intr_priority`
bool priority_conflict = rmt_set_intr_priority_to_group(group, config->intr_priority);
ESP_GOTO_ON_FALSE(!priority_conflict, ESP_ERR_INVALID_ARG, err, TAG, "intr_priority conflict");
// 2-- Get interrupt allocation flag
int isr_flags = rmt_get_isr_flags(group);
// 3-- Allocate interrupt using isr_flag
ret = esp_intr_alloc_intrstatus(rmt_periph_signals.groups[group_id].irq, isr_flags,
(uint32_t)rmt_ll_get_interrupt_status_reg(hal->regs),
RMT_LL_EVENT_TX_MASK(channel_id), rmt_tx_default_isr, tx_channel, &tx_channel->base.intr);
(uint32_t) rmt_ll_get_interrupt_status_reg(hal->regs),
RMT_LL_EVENT_TX_MASK(channel_id), rmt_tx_default_isr, tx_channel,
&tx_channel->base.intr);
ESP_GOTO_ON_ERROR(ret, err, TAG, "install tx interrupt failed");
// install DMA service
#if SOC_RMT_SUPPORT_DMA