#include "driver/gpio.h"
#include "driver/timer.h"
#include "soc/gpio_reg.h"
#include "soc/timer_group_struct.h"
// write value to register
#define REG_W(_r, _v) ((*(volatile uint32_t*)(_r)) = (_v))
void IRAM_ATTR timer_isr(void* arg)
{
uint32_t timer_group = (uint32_t)arg & 1;
uint32_t timer_idx = ((uint32_t)arg & 2) >> 1;
static uint32_t counter = 0;
if (++counter == 1000000) {
static int level = 0;
counter = 0;
level ^= 1;
// gpio_set_level(2, level);
if (level) {
REG_W(GPIO_OUT_W1TS_REG, BIT2);
TIMERG0.hw_timer[0].alarmlo.tx_alarm_lo = 4UL;
} else {
REG_W(GPIO_OUT_W1TC_REG, BIT2);
TIMERG0.hw_timer[0].alarmlo.tx_alarm_lo = 40UL;
}
}
// timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
TIMERG0.int_clr_timers.t0_int_clr = 1;
// timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0);
TIMERG0.hw_timer[0].config.tx_alarm_en = 1;
}
static void timer__init(timer_group_t group, timer_idx_t idx)
{
/* Select and initialize basic parameters of the timer */
timer_config_t config = {
.divider = 2UL,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = TIMER_AUTORELOAD_EN,
}; // default clock source is APB
timer_init(group, idx, &config);
/* Timer's counter will initially start from value below.
Also, if auto_reload is set, this value will be automatically reload on alarm */
timer_set_counter_value(group, idx, 0ULL);
/* Configure the alarm value and the interrupt on alarm. */
timer_set_alarm_value(group, idx, 4ULL);
timer_enable_intr(group, idx);
timer_isr_register(group, idx, timer_isr, (void*)((idx << 1) | group), ESP_INTR_FLAG_IRAM, NULL);
timer_start(group, idx);
}
/*
In this example, we will test hardware timer0 and timer1 of timer group0.
*/
void app_main(void)
{
gpio_reset_pin(2);
gpio_set_direction(2, GPIO_MODE_OUTPUT);
timer__init(TIMER_GROUP_0, TIMER_0);
}