mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
esp_timer: Add ESP_TIMER_ISR dispatch method
Using own spinlock for each list (TASK and ISR disp method) Reduced the dependency of ISR on the TASK dispatch method
This commit is contained in:
@@ -154,29 +154,39 @@ int64_t IRAM_ATTR esp_timer_impl_get_time(void)
|
||||
|
||||
int64_t esp_timer_get_time(void) __attribute__((alias("esp_timer_impl_get_time")));
|
||||
|
||||
void IRAM_ATTR esp_timer_impl_set_alarm_id(uint64_t timestamp, unsigned alarm_id)
|
||||
{
|
||||
static uint64_t timestamp_id[2] = { UINT64_MAX, UINT64_MAX };
|
||||
portENTER_CRITICAL_SAFE(&s_time_update_lock);
|
||||
timestamp_id[alarm_id] = timestamp;
|
||||
timestamp = MIN(timestamp_id[0], timestamp_id[1]);
|
||||
if (timestamp != UINT64_MAX) {
|
||||
int64_t offset = TICKS_PER_US * 2;
|
||||
uint64_t now_time = esp_timer_impl_get_counter_reg();
|
||||
timer_64b_reg_t alarm = { .val = MAX(timestamp * TICKS_PER_US, now_time + offset) };
|
||||
do {
|
||||
REG_CLR_BIT(CONFIG_REG, TIMG_LACT_ALARM_EN);
|
||||
REG_WRITE(ALARM_LO_REG, alarm.lo);
|
||||
REG_WRITE(ALARM_HI_REG, alarm.hi);
|
||||
REG_SET_BIT(CONFIG_REG, TIMG_LACT_ALARM_EN);
|
||||
now_time = esp_timer_impl_get_counter_reg();
|
||||
int64_t delta = (int64_t)alarm.val - (int64_t)now_time;
|
||||
if (delta <= 0 && REG_GET_FIELD(INT_ST_REG, TIMG_LACT_INT_ST) == 0) {
|
||||
// new alarm is less than the counter and the interrupt flag is not set
|
||||
offset += abs((int)delta) + TICKS_PER_US * 2;
|
||||
alarm.val = now_time + offset;
|
||||
} else {
|
||||
// finish if either (alarm > counter) or the interrupt flag is already set.
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
|
||||
{
|
||||
portENTER_CRITICAL_SAFE(&s_time_update_lock);
|
||||
int64_t offset = TICKS_PER_US * 2;
|
||||
uint64_t now_time = esp_timer_impl_get_counter_reg();
|
||||
timer_64b_reg_t alarm = { .val = MAX(timestamp * TICKS_PER_US, now_time + offset) };
|
||||
do {
|
||||
REG_CLR_BIT(CONFIG_REG, TIMG_LACT_ALARM_EN);
|
||||
REG_WRITE(ALARM_LO_REG, alarm.lo);
|
||||
REG_WRITE(ALARM_HI_REG, alarm.hi);
|
||||
REG_SET_BIT(CONFIG_REG, TIMG_LACT_ALARM_EN);
|
||||
now_time = esp_timer_impl_get_counter_reg();
|
||||
int64_t delta = (int64_t)alarm.val - (int64_t)now_time;
|
||||
if (delta <= 0 && REG_GET_FIELD(INT_ST_REG, TIMG_LACT_INT_ST) == 0) {
|
||||
// new alarm is less than the counter and the interrupt flag is not set
|
||||
offset += abs((int)delta) + TICKS_PER_US * 2;
|
||||
alarm.val = now_time + offset;
|
||||
} else {
|
||||
// finish if either (alarm > counter) or the interrupt flag is already set.
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
portEXIT_CRITICAL_SAFE(&s_time_update_lock);
|
||||
esp_timer_impl_set_alarm_id(timestamp, 0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR timer_alarm_isr(void *arg)
|
||||
|
Reference in New Issue
Block a user