mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-18 23:54:39 +00:00
feat(rmt): specify interrupt priority
This commit is contained in:
@@ -53,6 +53,8 @@ rmt_group_t *rmt_acquire_group_handle(int group_id)
|
||||
// enable APB access RMT registers
|
||||
periph_module_enable(rmt_periph_signals.groups[group_id].module);
|
||||
periph_module_reset(rmt_periph_signals.groups[group_id].module);
|
||||
// "uninitialize" group intr_priority, read comments in `rmt_new_tx_channel()` for detail
|
||||
group->intr_priority = RMT_GROUP_INTR_PRIORITY_UNINITALIZED;
|
||||
// hal layer initialize
|
||||
rmt_hal_init(&group->hal);
|
||||
}
|
||||
@@ -204,3 +206,48 @@ esp_err_t rmt_disable(rmt_channel_handle_t channel)
|
||||
ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state");
|
||||
return channel->disable(channel);
|
||||
}
|
||||
|
||||
bool rmt_set_intr_priority_to_group(rmt_group_t *group, int intr_priority)
|
||||
{
|
||||
bool priority_conflict = false;
|
||||
portENTER_CRITICAL(&group->spinlock);
|
||||
if (group->intr_priority == RMT_GROUP_INTR_PRIORITY_UNINITALIZED) {
|
||||
// intr_priority never allocated, accept user's value unconditionally
|
||||
// intr_priority could only be set once here
|
||||
group->intr_priority = intr_priority;
|
||||
} else {
|
||||
// group intr_priority already specified
|
||||
// If interrupt priority specified before, it CANNOT BE CHANGED until `rmt_release_group_handle()` called
|
||||
// So we have to check if the new priority specified conflicts with the old one
|
||||
if (intr_priority) {
|
||||
// User specified intr_priority, check if conflict or not
|
||||
// Even though the `group->intr_priority` is 0, an intr_priority must have been specified automatically too,
|
||||
// although we do not know it exactly now, so specifying the intr_priority again might also cause conflict.
|
||||
// So no matter if `group->intr_priority` is 0 or not, we have to check.
|
||||
// Value `0` of `group->intr_priority` means "unknown", NOT "unspecified"!
|
||||
if (intr_priority != (group->intr_priority)) {
|
||||
// intr_priority conflicts!
|
||||
priority_conflict = true;
|
||||
}
|
||||
}
|
||||
// else do nothing
|
||||
// user did not specify intr_priority, then keep the old priority
|
||||
// We'll use the `RMT_INTR_ALLOC_FLAG | RMT_ALLOW_INTR_PRIORITY_MASK`, which should always success
|
||||
}
|
||||
// The `group->intr_priority` will not change any longer, even though another task tries to modify it.
|
||||
// So we could exit critical here safely.
|
||||
portEXIT_CRITICAL(&group->spinlock);
|
||||
return priority_conflict;
|
||||
}
|
||||
|
||||
int rmt_get_isr_flags(rmt_group_t *group) {
|
||||
int isr_flags = RMT_INTR_ALLOC_FLAG;
|
||||
if (group->intr_priority) {
|
||||
// Use user-specified priority bit
|
||||
isr_flags |= (1 << (group->intr_priority));
|
||||
} else {
|
||||
// Allow all LOWMED priority bits
|
||||
isr_flags |= RMT_ALLOW_INTR_PRIORITY_MASK;
|
||||
}
|
||||
return isr_flags;
|
||||
}
|
||||
|
Reference in New Issue
Block a user