From 73d2862863b5261457ffeaf6bd6438c39bbd2a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 31 Mar 2023 14:15:11 +0200 Subject: [PATCH] TIMER refactoring (#7904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor using GPtimer * Updated timer HW test * fix examples * Add v2.0.7 in issue template (#7871) * refactor using GPtimer * Updated timer HW test * fix examples * Revert "Add v2.0.7 in issue template (#7871)" This reverts commit fcc3b17d62ff57861f8913ca1f142fd5163b7457. * Update upload-artifact to v3 in HW CI * Revert "Update upload-artifact to v3 in HW CI" This reverts commit 1ba228071718ba37c4e26d98db22f77b2a7364a6. * replace resolution with frequency * remove count_down option * countup removed from examples + header * Refactored timer object * code cleanup + examples and tests fixes * TimerAlarm fix --------- Co-authored-by: Vojtěch Bartoška <76958047+VojtechBartoska@users.noreply.github.com> --- cores/esp32/esp32-hal-timer.c | 326 +++++++----------- cores/esp32/esp32-hal-timer.h | 57 +-- .../Timer/RepeatTimer/RepeatTimer.ino | 15 +- .../Timer/WatchdogTimer/WatchdogTimer.ino | 11 +- tests/timer/timer.ino | 56 ++- 5 files changed, 192 insertions(+), 273 deletions(-) diff --git a/cores/esp32/esp32-hal-timer.c b/cores/esp32/esp32-hal-timer.c index 87f48e5409c..889a3bfa27e 100644 --- a/cores/esp32/esp32-hal-timer.c +++ b/cores/esp32/esp32-hal-timer.c @@ -13,261 +13,181 @@ // limitations under the License. #include "esp32-hal-timer.h" -#include "driver/timer.h" +#include "driver/gptimer.h" #include "soc/soc_caps.h" +#include "clk_tree.h" -typedef 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; -} timer_cfg_t; - -#define NUM_OF_TIMERS SOC_TIMER_GROUP_TOTAL_TIMERS +typedef void (*voidFuncPtr)(void); +typedef void (*voidFuncPtrArg)(void*); -typedef struct hw_timer_s -{ - uint8_t group; - uint8_t num; -} hw_timer_t; +typedef struct { + voidFuncPtr fn; + void* arg; +} interrupt_config_t; -// Works for all chips -static hw_timer_t timer_dev[4] = { - {0,0}, {1,0}, {0,1}, {1,1} +struct timer_struct_t { + gptimer_handle_t timer_handle; + interrupt_config_t interrupt_handle; }; -// NOTE: (in IDF 5.0 there wont be need to know groups/numbers -// timer_init() will list thru all timers and return free timer handle) - - -inline uint64_t timerRead(hw_timer_t *timer){ - - uint64_t value; - timer_get_counter_value(timer->group, timer->num,&value); - return value; -} +inline uint64_t timerRead(hw_timer_t * timer){ -uint64_t timerAlarmRead(hw_timer_t *timer){ uint64_t value; - timer_get_alarm_value(timer->group, timer->num, &value); + gptimer_get_raw_count(timer->timer_handle, &value); return value; } -void timerWrite(hw_timer_t *timer, uint64_t val){ - timer_set_counter_value(timer->group, timer->num, val); -} - -void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){ - timer_set_alarm_value(timer->group, timer->num, alarm_value); - timerSetAutoReload(timer,autoreload); -} - -void timerSetConfig(hw_timer_t *timer, uint32_t config){ - timer_cfg_t cfg; - cfg.val = config; - timer_set_alarm(timer->group, timer->num, cfg.alarm_en); - timerSetDivider(timer,cfg.divider); - timerSetAutoReload(timer,cfg.autoreload); - timerSetCountUp(timer, cfg.increase); - - if (cfg.enable) { - timerStart(timer); - } - else{ - timerStop(timer); - } - return; -} - -uint32_t timerGetConfig(hw_timer_t *timer){ - timer_config_t timer_cfg; - timer_get_config(timer->group, timer->num,&timer_cfg); - - //Translate to default uint32_t - timer_cfg_t cfg; - cfg.alarm_en = timer_cfg.alarm_en; - cfg.autoreload = timer_cfg.auto_reload; - cfg.divider = timer_cfg.divider; - cfg.edge_int_en = timer_cfg.intr_type; - cfg.level_int_en = !timer_cfg.intr_type; - cfg.enable = timer_cfg.counter_en; - cfg.increase = timer_cfg.counter_dir; - - return cfg.val; -} - -void timerSetCountUp(hw_timer_t *timer, bool countUp){ - timer_set_counter_mode(timer->group, timer->num,countUp); +void timerWrite(hw_timer_t * timer, uint64_t val){ + gptimer_set_raw_count(timer->timer_handle, val); } -bool timerGetCountUp(hw_timer_t *timer){ - timer_cfg_t config; - config.val = timerGetConfig(timer); - return config.increase; -} - -void timerSetAutoReload(hw_timer_t *timer, bool autoreload){ - timer_set_auto_reload(timer->group, timer->num,autoreload); -} - -bool timerGetAutoReload(hw_timer_t *timer){ - timer_cfg_t config; - config.val= timerGetConfig(timer); - return config.autoreload; -} - -// Set divider from 2 to 65535 -void timerSetDivider(hw_timer_t *timer, uint16_t divider){ - if(divider < 2) - { - log_e("Timer divider must be set in range of 2 to 65535"); - return; - } - timer_set_divider(timer->group, timer->num,divider); -} - -uint16_t timerGetDivider(hw_timer_t *timer){ - timer_cfg_t config; - config.val = timerGetConfig(timer); - return config.divider; -} - -void timerStart(hw_timer_t *timer){ - timer_start(timer->group, timer->num); -} - -void timerStop(hw_timer_t *timer){ - timer_pause(timer->group, timer->num); +void timerAlarm(hw_timer_t * timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count){ + esp_err_t err = ESP_OK; + gptimer_alarm_config_t alarm_cfg = { + .alarm_count = alarm_value, + .reload_count = reload_count, + .flags.auto_reload_on_alarm = autoreload, + }; + err = gptimer_set_alarm_action(timer->timer_handle, &alarm_cfg); + if (err != ESP_OK){ + log_e("Timer Alarm Write failed, error num=%d", err); + } } -void timerRestart(hw_timer_t *timer){ - timerWrite(timer,0); +uint32_t timerGetFrequency(hw_timer_t * timer){ + uint32_t frequency; + gptimer_get_resolution(timer->timer_handle, &frequency); + return frequency; } -bool timerStarted(hw_timer_t *timer){ - timer_cfg_t config; - config.val = timerGetConfig(timer); - return config.enable; +void timerStart(hw_timer_t * timer){ + gptimer_start(timer->timer_handle); } -void timerAlarmEnable(hw_timer_t *timer){ - timer_set_alarm(timer->group, timer->num,true); +void timerStop(hw_timer_t * timer){ + gptimer_stop(timer->timer_handle); } -void timerAlarmDisable(hw_timer_t *timer){ - timer_set_alarm(timer->group, timer->num,false); +void timerRestart(hw_timer_t * timer){ + gptimer_set_raw_count(timer->timer_handle,0); } -bool timerAlarmEnabled(hw_timer_t *timer){ - timer_cfg_t config; - config.val = timerGetConfig(timer); - return config.alarm_en; -} +hw_timer_t * timerBegin(uint32_t frequency){ + esp_err_t err = ESP_OK; + uint32_t counter_src_hz = 0; + uint32_t divider = 0; + soc_periph_gptimer_clk_src_t clk; -static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){ - hw_timer_t * timer = (hw_timer_t *)arg; - if(ev_type == APB_BEFORE_CHANGE){ - timerStop(timer); - } else { - old_apb /= 1000000; - new_apb /= 1000000; - uint16_t divider = (new_apb * timerGetDivider(timer)) / old_apb; - timerSetDivider(timer,divider); - timerStart(timer); + soc_periph_gptimer_clk_src_t gptimer_clks[] = SOC_GPTIMER_CLKS; + for (size_t i = 0; i < sizeof(gptimer_clks) / sizeof(gptimer_clks[0]); i++){ + clk = gptimer_clks[i]; + clk_tree_src_get_freq_hz(clk, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz); + divider = counter_src_hz / frequency; + if((divider >= 2) && (divider <= 65536)){ + break; + } + else divider = 0; } -} -hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){ - if(num >= NUM_OF_TIMERS) - { - log_e("Timer number %u exceeds available number of Timers.", num); + if(divider == 0){ + log_e("Resolution cannot be reached with any clock source, aborting!"); return NULL; } - hw_timer_t * timer = &timer_dev[num]; //Get Timer group/num from 0-3 number - - timer_config_t config = { - .divider = divider, - .counter_dir = countUp, - .counter_en = TIMER_PAUSE, - .alarm_en = TIMER_ALARM_DIS, - .auto_reload = false, + gptimer_config_t config = { + .clk_src = clk, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = frequency, + .flags.intr_shared = true, }; - timer_init(timer->group, timer->num, &config); - timer_set_counter_value(timer->group, timer->num, 0); - timerStart(timer); - addApbChangeCallback(timer, _on_apb_change); + hw_timer_t *timer = malloc(sizeof(hw_timer_t)); + + err = gptimer_new_timer(&config, &timer->timer_handle); + if (err != ESP_OK){ + log_e("Failed to create a new GPTimer, error num=%d", err); + free(timer); + return NULL; + } + gptimer_enable(timer->timer_handle); + gptimer_start(timer->timer_handle); return timer; } -void timerEnd(hw_timer_t *timer){ - removeApbChangeCallback(timer, _on_apb_change); - timer_deinit(timer->group, timer->num); +void timerEnd(hw_timer_t * timer){ + esp_err_t err = ESP_OK; + gptimer_disable(timer->timer_handle); + err = gptimer_del_timer(timer->timer_handle); + if (err != ESP_OK){ + log_e("Failed to destroy GPTimer, error num=%d", err); + return; + } + free(timer); } -bool IRAM_ATTR timerFnWrapper(void *arg){ - void (*fn)(void) = arg; - fn(); - +bool IRAM_ATTR timerFnWrapper(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void * args){ + interrupt_config_t * isr = (interrupt_config_t*)args; + if(isr->fn) { + if(isr->arg){ + ((voidFuncPtrArg)isr->fn)(isr->arg); + } else { + isr->fn(); + } + } // some additional logic or handling may be required here to approriately yield or not return false; } -void timerAttachInterruptFlag(hw_timer_t *timer, void (*fn)(void), bool edge, int intr_alloc_flags){ - if(edge){ - log_w("EDGE timer interrupt is not supported! Setting to LEVEL..."); - } - timer_isr_callback_add(timer->group, timer->num, timerFnWrapper, fn, intr_alloc_flags); -} +void timerAttachInterruptFunctionalArg(hw_timer_t * timer, void (*userFunc)(void*), void * arg){ + esp_err_t err = ESP_OK; + gptimer_event_callbacks_t cbs = { + .on_alarm = timerFnWrapper, + }; -void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){ - timerAttachInterruptFlag(timer, fn, edge, 0); -} + timer->interrupt_handle.fn = (voidFuncPtr)userFunc; + timer->interrupt_handle.arg = arg; -void timerDetachInterrupt(hw_timer_t *timer){ - timer_isr_callback_remove(timer->group, timer->num); + gptimer_disable(timer->timer_handle); + err = gptimer_register_event_callbacks(timer->timer_handle, &cbs, &timer->interrupt_handle); + if (err != ESP_OK){ + log_e("Timer Attach Interrupt failed, error num=%d", err); + } + gptimer_enable(timer->timer_handle); } -uint64_t timerReadMicros(hw_timer_t *timer){ - uint64_t timer_val = timerRead(timer); - uint16_t div = timerGetDivider(timer); - return timer_val * div / (getApbFrequency() / 1000000); + +void timerAttachInterruptArg(hw_timer_t * timer, void (*userFunc)(void*), void * arg){ + timerAttachInterruptFunctionalArg(timer, userFunc, arg); } -uint64_t timerReadMilis(hw_timer_t *timer){ - uint64_t timer_val = timerRead(timer); - uint16_t div = timerGetDivider(timer); - return timer_val * div / (getApbFrequency() / 1000); +void timerAttachInterrupt(hw_timer_t * timer, voidFuncPtr userFunc){ + timerAttachInterruptFunctionalArg(timer, (voidFuncPtrArg)userFunc, NULL); } -double timerReadSeconds(hw_timer_t *timer){ - uint64_t timer_val = timerRead(timer); - uint16_t div = timerGetDivider(timer); - return (double)timer_val * div / getApbFrequency(); +void timerDetachInterrupt(hw_timer_t * timer){ + esp_err_t err = ESP_OK; + err = gptimer_set_alarm_action(timer->timer_handle, NULL); + timer->interrupt_handle.fn = NULL; + timer->interrupt_handle.arg = NULL; + if (err != ESP_OK){ + log_e("Timer Detach Interrupt failed, error num=%d", err); + } } -uint64_t timerAlarmReadMicros(hw_timer_t *timer){ - uint64_t timer_val = timerAlarmRead(timer); - uint16_t div = timerGetDivider(timer); - return timer_val * div / (getApbFrequency() / 1000000); +uint64_t timerReadMicros(hw_timer_t * timer){ + uint64_t timer_val = timerRead(timer); + uint32_t frequency = timerGetFrequency(timer); + return timer_val * 1000000 / frequency; } -uint64_t timerAlarmReadMilis(hw_timer_t *timer){ - uint64_t timer_val = timerAlarmRead(timer); - uint16_t div = timerGetDivider(timer); - return timer_val * div / (getApbFrequency() / 1000); +uint64_t timerReadMilis(hw_timer_t * timer){ + uint64_t timer_val = timerRead(timer); + uint32_t frequency = timerGetFrequency(timer); + return timer_val * 1000 / frequency; } -double timerAlarmReadSeconds(hw_timer_t *timer){ - uint64_t timer_val = timerAlarmRead(timer); - uint16_t div = timerGetDivider(timer); - return (double)timer_val * div / getApbFrequency(); +double timerReadSeconds(hw_timer_t * timer){ + uint64_t timer_val = timerRead(timer); + uint32_t frequency = timerGetFrequency(timer); + return (double)timer_val / frequency; } diff --git a/cores/esp32/esp32-hal-timer.h b/cores/esp32/esp32-hal-timer.h index 5f0413b7445..61de2ea813c 100644 --- a/cores/esp32/esp32-hal-timer.h +++ b/cores/esp32/esp32-hal-timer.h @@ -17,58 +17,39 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef MAIN_ESP32_HAL_TIMER_H_ -#define MAIN_ESP32_HAL_TIMER_H_ +#pragma once #include "esp32-hal.h" -#include "freertos/FreeRTOS.h" +#include "driver/gptimer_types.h" #ifdef __cplusplus extern "C" { #endif -struct hw_timer_s; -typedef struct hw_timer_s hw_timer_t; +struct timer_struct_t; +typedef struct timer_struct_t hw_timer_t; -hw_timer_t * timerBegin(uint8_t timer, uint16_t divider, bool countUp); -void timerEnd(hw_timer_t *timer); +hw_timer_t * timerBegin(uint32_t frequency); +void timerEnd(hw_timer_t * timer); -void timerSetConfig(hw_timer_t *timer, uint32_t config); -uint32_t timerGetConfig(hw_timer_t *timer); +void timerStart(hw_timer_t * timer); +void timerStop(hw_timer_t * timer); +void timerRestart(hw_timer_t * timer); +void timerWrite(hw_timer_t * timer, uint64_t val); -void timerAttachInterruptFlag(hw_timer_t *timer, void (*fn)(void), bool edge, int intr_alloc_flags); -void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge); -void timerDetachInterrupt(hw_timer_t *timer); +uint64_t timerRead(hw_timer_t * timer); +uint64_t timerReadMicros(hw_timer_t * timer); +uint64_t timerReadMilis(hw_timer_t * timer); +double timerReadSeconds(hw_timer_t * timer); -void timerStart(hw_timer_t *timer); -void timerStop(hw_timer_t *timer); -void timerRestart(hw_timer_t *timer); -void timerWrite(hw_timer_t *timer, uint64_t val); -void timerSetDivider(hw_timer_t *timer, uint16_t divider); -void timerSetCountUp(hw_timer_t *timer, bool countUp); -void timerSetAutoReload(hw_timer_t *timer, bool autoreload); +uint32_t timerGetFrequency(hw_timer_t * timer); -bool timerStarted(hw_timer_t *timer); -uint64_t timerRead(hw_timer_t *timer); -uint64_t timerReadMicros(hw_timer_t *timer); -uint64_t timerReadMilis(hw_timer_t *timer); -double timerReadSeconds(hw_timer_t *timer); -uint16_t timerGetDivider(hw_timer_t *timer); -bool timerGetCountUp(hw_timer_t *timer); -bool timerGetAutoReload(hw_timer_t *timer); - -void timerAlarmEnable(hw_timer_t *timer); -void timerAlarmDisable(hw_timer_t *timer); -void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload); - -bool timerAlarmEnabled(hw_timer_t *timer); -uint64_t timerAlarmRead(hw_timer_t *timer); -uint64_t timerAlarmReadMicros(hw_timer_t *timer); -double timerAlarmReadSeconds(hw_timer_t *timer); +void timerAttachInterrupt(hw_timer_t * timer, void (*userFunc)(void)); +void timerAttachInterruptArg(hw_timer_t * timer, void (*userFunc)(void*), void * arg); +void timerDetachInterrupt(hw_timer_t * timer); +void timerAlarm(hw_timer_t * timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count); #ifdef __cplusplus } #endif - -#endif /* MAIN_ESP32_HAL_TIMER_H_ */ diff --git a/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino b/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino index c6282429217..275cd0fac68 100644 --- a/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino +++ b/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino @@ -38,20 +38,15 @@ void setup() { // Create semaphore to inform us when the timer has fired timerSemaphore = xSemaphoreCreateBinary(); - // Use 1st timer of 4 (counted from zero). - // Set 80 divider for prescaler (see ESP32 Technical Reference Manual for more - // info). - timer = timerBegin(0, 80, true); + // Set timer frequency to 1Mhz + timer = timerBegin(1000000); // Attach onTimer function to our timer. - timerAttachInterrupt(timer, &onTimer, true); + timerAttachInterrupt(timer, &onTimer); // Set alarm to call onTimer function every second (value in microseconds). - // Repeat the alarm (third parameter) - timerAlarmWrite(timer, 1000000, true); - - // Start an alarm - timerAlarmEnable(timer); + // Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter). + timerAlarm(timer, 1000000, true, 0); } void loop() { diff --git a/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino b/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino index 25163dafeb2..d1a70f800b1 100644 --- a/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino +++ b/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino @@ -3,7 +3,7 @@ const int button = 0; //gpio to use to trigger delay const int wdtTimeout = 3000; //time in ms to trigger the watchdog -hw_timer_t *timer = NULL; +hw_timer_t * timer = NULL; void ARDUINO_ISR_ATTR resetModule() { ets_printf("reboot\n"); @@ -15,11 +15,10 @@ void setup() { Serial.println(); Serial.println("running setup"); - pinMode(button, INPUT_PULLUP); //init control pin - timer = timerBegin(0, 80, true); //timer 0, div 80 - timerAttachInterrupt(timer, &resetModule, true); //attach callback - timerAlarmWrite(timer, wdtTimeout * 1000, false); //set time in us - timerAlarmEnable(timer); //enable interrupt + pinMode(button, INPUT_PULLUP); //init control pin + timer = timerBegin(1000000); //timer 1Mhz resolution + timerAttachInterrupt(timer, &resetModule); //attach callback + timerAlarm(timer, wdtTimeout * 1000, false, 0); //set time in us } void loop() { diff --git a/tests/timer/timer.ino b/tests/timer/timer.ino index bb9d2e70d0a..777a8a7d756 100644 --- a/tests/timer/timer.ino +++ b/tests/timer/timer.ino @@ -1,21 +1,30 @@ /* HW Timer test */ #include -#define TIMER_DIVIDER 16 -#define TIMER_SCALE (APB_CLK_FREQ / TIMER_DIVIDER) +#define TIMER_FREQUENCY 5000000 +#define TIMER_FREQUENCY_XTAL_CLK 1000 + +/* + * ESP32 - APB clk only (1kHz not possible) + * C3 - APB + XTAL clk + * S2 - APB + XTAL clk + * S3 - APB + XTAL clk + */ hw_timer_t * timer = NULL; +hw_timer_t * timer_XTAL = NULL; static volatile bool alarm_flag; /* These functions are intended to be called before and after each test. */ void setUp(void) { - timer = timerBegin(0, TIMER_DIVIDER, true); + timer = timerBegin(TIMER_FREQUENCY); timerStop(timer); timerRestart(timer); } void tearDown(void){ timerEnd(timer); + timer = NULL; } @@ -28,9 +37,8 @@ void ARDUINO_ISR_ATTR onTimer(){ void timer_interrupt_test(void){ alarm_flag = false; - timerAttachInterrupt(timer, &onTimer, true); - timerAlarmWrite(timer, (1.2 * TIMER_SCALE), true); - timerAlarmEnable(timer); + timerAttachInterrupt(timer, &onTimer); + timerAlarm(timer, (1.2 * TIMER_FREQUENCY), true, 0); timerStart(timer); delay(2000); @@ -40,7 +48,7 @@ void timer_interrupt_test(void){ timerStop(timer); timerRestart(timer); alarm_flag = false; - timerAlarmDisable(timer); + timerDetachInterrupt(timer); timerStart(timer); delay(2000); @@ -58,11 +66,11 @@ void timer_divider_test(void){ time_val = timerRead(timer); // compare divider 16 and 8, value should be double - timerStop(timer); - timerSetDivider(timer,8); - timerRestart(timer); - timerStart(timer); + timerEnd(timer); + timer = NULL; + timer = timerBegin(2 * TIMER_FREQUENCY); + timerRestart(timer); delay(1000); comp_time_val = timerRead(timer); @@ -70,14 +78,16 @@ void timer_divider_test(void){ TEST_ASSERT_INT_WITHIN(10000, 10000000, comp_time_val); // divider is 256, value should be 2^4 - timerStop(timer); - timerSetDivider(timer,256); + timerEnd(timer); + timer = NULL; + + timer = timerBegin(TIMER_FREQUENCY / 16); timerRestart(timer); - timerStart(timer); delay(1000); comp_time_val = timerRead(timer); + TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val); - TEST_ASSERT_INT_WITHIN(3126, 312500, comp_time_val); + TEST_ASSERT_INT_WITHIN(3125, 312500, comp_time_val); } void timer_read_test(void){ @@ -85,12 +95,23 @@ void timer_read_test(void){ uint64_t set_timer_val = 0xFF; uint64_t get_timer_val = 0; - timerWrite(timer,set_timer_val); + timerWrite(timer, set_timer_val); get_timer_val = timerRead(timer); TEST_ASSERT_EQUAL(set_timer_val, get_timer_val); } +void timer_clock_select_test(void){ + // Set timer frequency that can be achieved using XTAL clock source (autoselected) + timer_XTAL = timerBegin(TIMER_FREQUENCY_XTAL_CLK); + + uint32_t resolution = timerGetFrequency(timer_XTAL); + TEST_ASSERT_EQUAL(TIMER_FREQUENCY_XTAL_CLK,resolution); + + timerEnd(timer_XTAL); + timer_XTAL = NULL; +} + void setup(){ // Open serial communications and wait for port to open: @@ -103,6 +124,9 @@ void setup(){ RUN_TEST(timer_read_test); RUN_TEST(timer_interrupt_test); RUN_TEST(timer_divider_test); + #if !CONFIG_IDF_TARGET_ESP32 + RUN_TEST(timer_clock_select_test); + #endif UNITY_END(); }