text: #include "steptimer.h"
  
  
  
  #include "esp32-hal-timer.h"
  #include "freertos/FreeRTOS.h"
  #include "freertos/xtensa_api.h"
  #include "freertos/task.h"
  #include "rom/ets_sys.h"
  #include "soc/timer_group_struct.h"
  #include "soc/dport_reg.h"
  #include "esp_attr.h"
  #include "esp_intr.h"
  
  #define HWTIMER_LOCK()      portENTER_CRITICAL(timer->lock)
  #define HWTIMER_UNLOCK()    portEXIT_CRITICAL(timer->lock)
  
  typedef struct {
      union {
          struct {
              uint32_t reserved0:   10;
              uint32_t alarm_en:     1;             /*When set  alarm is enabled*/
              uint32_t level_int_en: 1;             /*When set  level type interrupt will be generated during alarm*/
              uint32_t edge_int_en:  1;             /*When set  edge type interrupt will be generated during alarm*/
              uint32_t divider:     16;             /*Timer clock (T0/1_clk) pre-scale value.*/
              uint32_t autoreload:   1;             /*When set  timer 0/1 auto-reload at alarming is enabled*/
              uint32_t increase:     1;             /*When set  timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
              uint32_t enable:       1;             /*When set  timer 0/1 time-base counter is enabled*/
          };
          uint32_t val;
      } config;
      uint32_t cnt_low;                             /*Register to store timer 0/1 time-base counter current value lower 32 bits.*/
      uint32_t cnt_high;                            /*Register to store timer 0 time-base counter current value higher 32 bits.*/
      uint32_t update;                              /*Write any value will trigger a timer 0 time-base counter value update (timer 0 current value will be stored in registers above)*/
      uint32_t alarm_low;                           /*Timer 0 time-base counter value lower 32 bits that will trigger the alarm*/
      uint32_t alarm_high;                          /*Timer 0 time-base counter value higher 32 bits that will trigger the alarm*/
      uint32_t load_low;                            /*Lower 32 bits of the value that will load into timer 0 time-base counter*/
      uint32_t load_high;                           /*higher 32 bits of the value that will load into timer 0 time-base counter*/
      uint32_t reload;                              /*Write any value will trigger timer 0 time-base counter reload*/
  } hw_timer_reg_t;
  
  typedef struct hw_timer_s {
          hw_timer_reg_t * dev;
          uint8_t num;
          uint8_t group;
          uint8_t timer;
          portMUX_TYPE lock;
  } hw_timer_t;
  
  static hw_timer_t hw_timer[4] = {
          {(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE),0,0,0,portMUX_INITIALIZER_UNLOCKED},
          {(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x0024),1,0,1,portMUX_INITIALIZER_UNLOCKED},
          {(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1000),2,1,0,portMUX_INITIALIZER_UNLOCKED},
          {(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1024),3,1,1,portMUX_INITIALIZER_UNLOCKED}
  };
  
  
  
  void IRAM_ATTR steptimerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
      timer->dev->alarm_high = (uint32_t) (alarm_value >> 32);
      timer->dev->alarm_low = (uint32_t) alarm_value;
      timer->dev->config.autoreload = autoreload;
  }
  