1 // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifdef __cpp_exceptions 16 17 #include "unity.h" 18 #include "unity_cxx.hpp" 19 #include <limits> 20 #include <stdio.h> 21 22 #include <iostream> 23 #include "test_utils.h" // ref clock 24 #include "freertos/FreeRTOS.h" 25 #include "freertos/task.h" 26 #include "freertos/semphr.h" 27 28 #include "esp_timer_cxx.hpp" 29 #include "esp_exception.hpp" 30 31 using namespace std; 32 using namespace idf; 33 using namespace idf::esp_timer; 34 35 struct RefClock { RefClockRefClock36 RefClock() 37 { 38 ref_clock_init(); 39 }; 40 ~RefClockRefClock41 ~RefClock() 42 { 43 ref_clock_deinit(); 44 } 45 }; 46 47 TEST_CASE("ESPTimer produces correct delay", "[ESPTimer]") 48 { 49 int64_t t_end; 50 51 RefClock ref_clock; 52 __anon7588ac300102() 53 function<void()> timer_cb = [&t_end]() { 54 t_end = ref_clock_get(); 55 }; 56 57 ESPTimer timer(timer_cb, "timer1"); 58 59 const int delays_ms[] = {20, 100, 200, 250}; 60 const size_t delays_count = sizeof(delays_ms)/sizeof(delays_ms[0]); 61 62 for (size_t i = 0; i < delays_count; ++i) { 63 t_end = 0; 64 int64_t t_start = ref_clock_get(); 65 66 timer.start(chrono::microseconds(delays_ms[i] * 1000)); 67 68 vTaskDelay(delays_ms[i] * 2 / portTICK_PERIOD_MS); 69 TEST_ASSERT(t_end != 0); 70 int32_t ms_diff = (t_end - t_start) / 1000; 71 printf("%d %d\n", delays_ms[i], ms_diff); 72 73 TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, delays_ms[i], ms_diff); 74 } 75 } 76 77 TEST_CASE("ESPtimer produces correct periodic delays", "[ESPTimer]") 78 { 79 const size_t NUM_INTERVALS = 3u; 80 81 size_t cur_interval = 0; 82 int intervals[NUM_INTERVALS]; 83 int64_t t_start; 84 SemaphoreHandle_t done; 85 86 const int DELAY_MS = 100; __anon7588ac300202() 87 function<void()> timer_cb = [&]() { 88 int64_t t_end = ref_clock_get(); 89 int32_t ms_diff = (t_end - t_start) / 1000; 90 printf("timer #%d %dms\n", cur_interval, ms_diff); 91 if (cur_interval < NUM_INTERVALS) { 92 intervals[cur_interval++] = ms_diff; 93 } 94 // Deliberately make timer handler run longer. 95 // We check that this doesn't affect the result. 96 esp_rom_delay_us(10*1000); 97 if (cur_interval == NUM_INTERVALS) { 98 printf("done\n"); 99 xSemaphoreGive(done); 100 } 101 }; 102 103 ESPTimer timer(timer_cb, "timer1"); 104 RefClock ref_clock; 105 t_start = ref_clock_get(); 106 done = xSemaphoreCreateBinary(); 107 timer.start_periodic(chrono::microseconds(DELAY_MS * 1000)); 108 109 TEST_ASSERT(xSemaphoreTake(done, DELAY_MS * NUM_INTERVALS * 2)); 110 timer.stop(); 111 112 TEST_ASSERT_EQUAL_UINT32(NUM_INTERVALS, cur_interval); 113 for (size_t i = 0; i < NUM_INTERVALS; ++i) { 114 TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, (i + 1) * DELAY_MS, intervals[i]); 115 } 116 TEST_ESP_OK(esp_timer_dump(stdout)); 117 118 vSemaphoreDelete(done); 119 #undef NUM_INTERVALS 120 } 121 122 #endif // __cpp_exceptions 123