test_gptimer.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include "sdkconfig.h"
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "unity.h"
  11. #include "driver/gptimer.h"
  12. #include "soc/soc_caps.h"
  13. #include "esp_attr.h"
  14. #if CONFIG_GPTIMER_ISR_IRAM_SAFE
  15. #define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR
  16. #else
  17. #define TEST_ALARM_CALLBACK_ATTR
  18. #endif // CONFIG_GPTIMER_ISR_IRAM_SAFE
  19. TEST_CASE("gptimer_set_get_raw_count", "[gptimer]")
  20. {
  21. gptimer_config_t config = {
  22. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  23. .direction = GPTIMER_COUNT_UP,
  24. .resolution_hz = 1 * 1000 * 1000,
  25. };
  26. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  27. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  28. TEST_ESP_OK(gptimer_new_timer(&config, &timers[i]));
  29. }
  30. TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, gptimer_new_timer(&config, &timers[0]));
  31. unsigned long long get_value = 0;
  32. printf("check gptimer initial count value\r\n");
  33. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  34. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &get_value));
  35. TEST_ASSERT_EQUAL(0, get_value);
  36. }
  37. unsigned long long set_values[] = {100, 500, 666};
  38. for (size_t j = 0; j < sizeof(set_values) / sizeof(set_values[0]); j++) {
  39. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  40. printf("set raw count to %llu for gptimer %d\r\n", set_values[j], i);
  41. TEST_ESP_OK(gptimer_set_raw_count(timers[i], set_values[j]));
  42. }
  43. vTaskDelay(pdMS_TO_TICKS(10));
  44. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  45. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &get_value));
  46. printf("get raw count of gptimer %d: %llu\r\n", i, get_value);
  47. TEST_ASSERT_EQUAL(set_values[j], get_value);
  48. }
  49. }
  50. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  51. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  52. }
  53. }
  54. TEST_CASE("gptimer_wallclock_with_various_clock_sources", "[gptimer]")
  55. {
  56. gptimer_clock_source_t test_clk_srcs[] = SOC_GPTIMER_CLKS;
  57. // test with various clock sources
  58. for (size_t i = 0; i < sizeof(test_clk_srcs) / sizeof(test_clk_srcs[0]); i++) {
  59. gptimer_config_t timer_config = {
  60. .clk_src = test_clk_srcs[i],
  61. .direction = GPTIMER_COUNT_UP,
  62. .resolution_hz = 1 * 1000 * 1000,
  63. };
  64. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  65. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  66. TEST_ESP_OK(gptimer_new_timer(&timer_config, &timers[i]));
  67. }
  68. // start timer before enable should fail
  69. TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gptimer_start(timers[0]));
  70. printf("enable timers\r\n");
  71. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  72. TEST_ESP_OK(gptimer_enable(timers[i]));
  73. }
  74. printf("start timers\r\n");
  75. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  76. TEST_ESP_OK(gptimer_start(timers[i]));
  77. }
  78. vTaskDelay(pdMS_TO_TICKS(20)); // 20ms = 20_000 ticks
  79. unsigned long long value = 0;
  80. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  81. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &value));
  82. TEST_ASSERT_UINT_WITHIN(1000, 20000, value);
  83. }
  84. printf("stop timers\r\n");
  85. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  86. TEST_ESP_OK(gptimer_stop(timers[i]));
  87. }
  88. printf("check whether timers have stopped\r\n");
  89. vTaskDelay(pdMS_TO_TICKS(20));
  90. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  91. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &value));
  92. printf("get raw count of gptimer %d: %llu\r\n", i, value);
  93. TEST_ASSERT_UINT_WITHIN(1000, 20000, value);
  94. }
  95. printf("restart timers\r\n");
  96. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  97. TEST_ESP_OK(gptimer_start(timers[i]));
  98. }
  99. vTaskDelay(pdMS_TO_TICKS(20));
  100. printf("stop timers again\r\n");
  101. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  102. TEST_ESP_OK(gptimer_stop(timers[i]));
  103. }
  104. printf("check whether timers have stopped\r\n");
  105. vTaskDelay(pdMS_TO_TICKS(20));
  106. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  107. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &value));
  108. printf("get raw count of gptimer %d: %llu\r\n", i, value);
  109. TEST_ASSERT_UINT_WITHIN(2000, 40000, value);
  110. }
  111. printf("disable timers\r\n");
  112. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  113. TEST_ESP_OK(gptimer_disable(timers[i]));
  114. }
  115. printf("delete timers\r\n");
  116. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  117. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  118. }
  119. }
  120. }
  121. TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_stop_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  122. {
  123. TaskHandle_t task_handle = (TaskHandle_t)user_data;
  124. BaseType_t high_task_wakeup;
  125. gptimer_stop(timer);
  126. esp_rom_printf("count=%lld @alarm\n", edata->count_value);
  127. vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup);
  128. return high_task_wakeup == pdTRUE;
  129. }
  130. TEST_CASE("gptimer_stop_on_alarm", "[gptimer]")
  131. {
  132. TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
  133. gptimer_config_t timer_config = {
  134. .resolution_hz = 1 * 1000 * 1000,
  135. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  136. .direction = GPTIMER_COUNT_UP,
  137. };
  138. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  139. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  140. TEST_ESP_OK(gptimer_new_timer(&timer_config, &timers[i]));
  141. }
  142. gptimer_event_callbacks_t cbs = {
  143. .on_alarm = test_gptimer_alarm_stop_callback,
  144. };
  145. gptimer_alarm_config_t alarm_config = {};
  146. printf("start timers\r\n");
  147. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  148. alarm_config.alarm_count = 100000 * (i + 1);
  149. TEST_ESP_OK(gptimer_set_alarm_action(timers[i], &alarm_config));
  150. TEST_ESP_OK(gptimer_register_event_callbacks(timers[i], &cbs, task_handle));
  151. TEST_ESP_OK(gptimer_enable(timers[i]));
  152. TEST_ESP_OK(gptimer_start(timers[i]));
  153. printf("alarm value for gptimer %d: %llu\r\n", i, alarm_config.alarm_count);
  154. }
  155. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  156. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  157. }
  158. printf("check whether the timers have stopped in the ISR\r\n");
  159. vTaskDelay(pdMS_TO_TICKS(20));
  160. unsigned long long value = 0;
  161. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  162. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &value));
  163. printf("get raw count of gptimer %d: %llu\r\n", i, value);
  164. TEST_ASSERT_UINT_WITHIN(40, 100000 * (i + 1), value);
  165. }
  166. printf("restart timers\r\n");
  167. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  168. alarm_config.alarm_count = 100000 * (i + 1);
  169. // reset counter value to zero
  170. TEST_ESP_OK(gptimer_set_raw_count(timers[i], 0));
  171. TEST_ESP_OK(gptimer_start(timers[i]));
  172. }
  173. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  174. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  175. }
  176. printf("check whether the timers have stopped in the ISR\r\n");
  177. vTaskDelay(pdMS_TO_TICKS(20));
  178. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  179. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &value));
  180. printf("get raw count of gptimer %d: %llu\r\n", i, value);
  181. TEST_ASSERT_UINT_WITHIN(40, 100000 * (i + 1), value);
  182. }
  183. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  184. TEST_ESP_OK(gptimer_disable(timers[i]));
  185. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  186. }
  187. }
  188. TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_reload_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  189. {
  190. TaskHandle_t task_handle = (TaskHandle_t)user_data;
  191. BaseType_t high_task_wakeup;
  192. esp_rom_printf("alarm isr count=%llu\r\n", edata->count_value);
  193. // check if the count value has been reloaded
  194. TEST_ASSERT_UINT_WITHIN(20, 100, edata->count_value);
  195. vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup);
  196. return high_task_wakeup == pdTRUE;
  197. }
  198. TEST_CASE("gptimer_auto_reload_on_alarm", "[gptimer]")
  199. {
  200. TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
  201. gptimer_config_t timer_config = {
  202. .resolution_hz = 1 * 1000 * 1000,
  203. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  204. .direction = GPTIMER_COUNT_UP,
  205. };
  206. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  207. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  208. TEST_ESP_OK(gptimer_new_timer(&timer_config, &timers[i]));
  209. }
  210. gptimer_event_callbacks_t cbs = {
  211. .on_alarm = test_gptimer_alarm_reload_callback,
  212. };
  213. gptimer_alarm_config_t alarm_config = {
  214. .reload_count = 100,
  215. .alarm_count = 100000,
  216. .flags.auto_reload_on_alarm = true,
  217. };
  218. printf("start timers\r\n");
  219. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  220. TEST_ESP_OK(gptimer_set_alarm_action(timers[i], &alarm_config));
  221. TEST_ESP_OK(gptimer_register_event_callbacks(timers[i], &cbs, task_handle));
  222. TEST_ESP_OK(gptimer_enable(timers[i]));
  223. TEST_ESP_OK(gptimer_start(timers[i]));
  224. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  225. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  226. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  227. // delete should fail if timer is not disabled
  228. TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gptimer_del_timer(timers[i]));
  229. TEST_ESP_OK(gptimer_stop(timers[i]));
  230. }
  231. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  232. TEST_ESP_OK(gptimer_disable(timers[i]));
  233. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  234. }
  235. }
  236. TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_normal_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  237. {
  238. TaskHandle_t task_handle = (TaskHandle_t)user_data;
  239. BaseType_t high_task_wakeup;
  240. esp_rom_printf("alarm isr count=%llu\r\n", edata->count_value);
  241. // check the count value at alarm event
  242. vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup);
  243. return high_task_wakeup == pdTRUE;
  244. }
  245. TEST_CASE("gptimer_one_shot_alarm", "[gptimer]")
  246. {
  247. TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
  248. gptimer_config_t timer_config = {
  249. .resolution_hz = 1 * 1000 * 1000,
  250. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  251. .direction = GPTIMER_COUNT_UP,
  252. };
  253. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  254. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  255. TEST_ESP_OK(gptimer_new_timer(&timer_config, &timers[i]));
  256. }
  257. gptimer_event_callbacks_t cbs = {
  258. .on_alarm = test_gptimer_alarm_normal_callback,
  259. };
  260. gptimer_alarm_config_t alarm_config = {
  261. .reload_count = 0,
  262. .alarm_count = 100000, // 100ms
  263. };
  264. printf("start timers\r\n");
  265. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  266. TEST_ESP_OK(gptimer_set_alarm_action(timers[i], &alarm_config));
  267. TEST_ESP_OK(gptimer_register_event_callbacks(timers[i], &cbs, task_handle));
  268. TEST_ESP_OK(gptimer_enable(timers[i]));
  269. TEST_ESP_OK(gptimer_start(timers[i]));
  270. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  271. // no alarm event should trigger again, as auto-reload is not enabled and alarm value hasn't changed in the isr
  272. TEST_ASSERT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  273. // the alarm is stopped, but the counter should still work
  274. uint64_t value = 0;
  275. TEST_ESP_OK(gptimer_get_raw_count(timers[i], &value));
  276. TEST_ASSERT_UINT_WITHIN(1000, 1100000, value); // 1100000 = 100ms alarm + 1s delay
  277. TEST_ESP_OK(gptimer_stop(timers[i]));
  278. }
  279. printf("restart timers\r\n");
  280. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  281. TEST_ESP_OK(gptimer_start(timers[i]));
  282. // alarm should be triggered immediately as the counter value has across the target alarm value already
  283. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, 0));
  284. TEST_ESP_OK(gptimer_stop(timers[i]));
  285. }
  286. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  287. TEST_ESP_OK(gptimer_disable(timers[i]));
  288. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  289. }
  290. }
  291. TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_update_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  292. {
  293. TaskHandle_t task_handle = (TaskHandle_t)user_data;
  294. BaseType_t high_task_wakeup;
  295. esp_rom_printf("alarm isr count=%llu\r\n", edata->count_value);
  296. gptimer_alarm_config_t alarm_config = {
  297. .alarm_count = edata->count_value + 100000, // alarm in next 100ms again
  298. };
  299. gptimer_set_alarm_action(timer, &alarm_config);
  300. vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup);
  301. return high_task_wakeup == pdTRUE;
  302. }
  303. TEST_CASE("gptimer_update_alarm_dynamically", "[gptimer]")
  304. {
  305. TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
  306. gptimer_config_t timer_config = {
  307. .resolution_hz = 1 * 1000 * 1000,
  308. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  309. .direction = GPTIMER_COUNT_UP,
  310. };
  311. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  312. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  313. TEST_ESP_OK(gptimer_new_timer(&timer_config, &timers[i]));
  314. }
  315. gptimer_event_callbacks_t cbs = {
  316. .on_alarm = test_gptimer_alarm_update_callback,
  317. };
  318. gptimer_alarm_config_t alarm_config = {
  319. .alarm_count = 100000, // initial alarm count, 100ms
  320. };
  321. printf("start timers\r\n");
  322. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  323. TEST_ESP_OK(gptimer_set_alarm_action(timers[i], &alarm_config));
  324. TEST_ESP_OK(gptimer_register_event_callbacks(timers[i], &cbs, task_handle));
  325. TEST_ESP_OK(gptimer_enable(timers[i]));
  326. TEST_ESP_OK(gptimer_start(timers[i]));
  327. // check the alarm event for multiple times
  328. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  329. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  330. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  331. TEST_ESP_OK(gptimer_stop(timers[i]));
  332. // check there won't be more interrupts triggered than expected
  333. TEST_ASSERT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  334. }
  335. printf("restart timers\r\n");
  336. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  337. TEST_ESP_OK(gptimer_start(timers[i]));
  338. // check the alarm event for multiple times
  339. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  340. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  341. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  342. TEST_ESP_OK(gptimer_stop(timers[i]));
  343. // check there won't be more interrupts triggered than expected
  344. TEST_ASSERT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(500)));
  345. }
  346. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  347. TEST_ESP_OK(gptimer_disable(timers[i]));
  348. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  349. }
  350. }
  351. TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_count_down_reload_alarm_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  352. {
  353. TaskHandle_t task_handle = (TaskHandle_t)user_data;
  354. BaseType_t high_task_wakeup;
  355. esp_rom_printf("alarm isr count=%llu\r\n", edata->count_value);
  356. // check if the count value has been reloaded
  357. TEST_ASSERT_UINT_WITHIN(20, 200000, edata->count_value);
  358. vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup);
  359. return high_task_wakeup == pdTRUE;
  360. }
  361. TEST_CASE("gptimer_count_down_reload", "[gptimer]")
  362. {
  363. TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
  364. gptimer_config_t timer_config = {
  365. .resolution_hz = 1 * 1000 * 1000,
  366. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  367. .direction = GPTIMER_COUNT_DOWN,
  368. };
  369. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  370. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  371. TEST_ESP_OK(gptimer_new_timer(&timer_config, &timers[i]));
  372. TEST_ESP_OK(gptimer_set_raw_count(timers[i], 200000));
  373. }
  374. gptimer_event_callbacks_t cbs = {
  375. .on_alarm = test_gptimer_count_down_reload_alarm_callback,
  376. };
  377. gptimer_alarm_config_t alarm_config = {
  378. .reload_count = 200000, // 200ms
  379. .alarm_count = 0,
  380. .flags.auto_reload_on_alarm = true,
  381. };
  382. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  383. TEST_ESP_OK(gptimer_set_alarm_action(timers[i], &alarm_config));
  384. TEST_ESP_OK(gptimer_register_event_callbacks(timers[i], &cbs, task_handle));
  385. TEST_ESP_OK(gptimer_enable(timers[i]));
  386. TEST_ESP_OK(gptimer_start(timers[i]));
  387. // check twice, as it's a period event
  388. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  389. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  390. TEST_ESP_OK(gptimer_stop(timers[i]));
  391. }
  392. printf("restart gptimer with previous configuration\r\n");
  393. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  394. TEST_ESP_OK(gptimer_start(timers[i]));
  395. // check twice, as it's a period event
  396. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  397. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000)));
  398. TEST_ESP_OK(gptimer_stop(timers[i]));
  399. }
  400. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  401. TEST_ESP_OK(gptimer_disable(timers[i]));
  402. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  403. }
  404. }
  405. TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_overflow_reload_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  406. {
  407. TaskHandle_t task_handle = (TaskHandle_t)user_data;
  408. BaseType_t high_task_wakeup;
  409. // Note: esp_rom_printf can't print value with 64 bit length, so the following print result is meaningless, but as an incidator for test that the alarm has fired
  410. esp_rom_printf("alarm isr count=%llu\r\n", edata->count_value);
  411. vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup);
  412. return high_task_wakeup == pdTRUE;
  413. }
  414. TEST_CASE("gptimer_overflow", "[gptimer]")
  415. {
  416. TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
  417. gptimer_config_t timer_config = {
  418. .resolution_hz = 1 * 1000 * 1000,
  419. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  420. .direction = GPTIMER_COUNT_UP,
  421. };
  422. gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS];
  423. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  424. TEST_ESP_OK(gptimer_new_timer(&timer_config, &timers[i]));
  425. }
  426. #if SOC_TIMER_GROUP_COUNTER_BIT_WIDTH == 64
  427. uint64_t reload_at = UINT64_MAX - 100000;
  428. #else
  429. uint64_t reload_at = (1ULL << SOC_TIMER_GROUP_COUNTER_BIT_WIDTH) - 100000;
  430. #endif
  431. gptimer_event_callbacks_t cbs = {
  432. .on_alarm = test_gptimer_overflow_reload_callback,
  433. };
  434. gptimer_alarm_config_t alarm_config = {
  435. .reload_count = reload_at,
  436. .alarm_count = 100000, // 100ms
  437. .flags.auto_reload_on_alarm = true,
  438. };
  439. // The counter should start from [COUNTER_MAX-100000] and overflows to [0] and continue, then reached to alarm value [100000], reloaded to [COUNTER_MAX-100000] automatically
  440. // thus the period should be 200ms
  441. printf("start timers\r\n");
  442. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  443. TEST_ESP_OK(gptimer_set_alarm_action(timers[i], &alarm_config));
  444. TEST_ESP_OK(gptimer_register_event_callbacks(timers[i], &cbs, task_handle));
  445. // we start from the reload value
  446. TEST_ESP_OK(gptimer_set_raw_count(timers[i], reload_at));
  447. TEST_ESP_OK(gptimer_enable(timers[i]));
  448. TEST_ESP_OK(gptimer_start(timers[i]));
  449. TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(400)));
  450. TEST_ESP_OK(gptimer_stop(timers[i]));
  451. }
  452. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  453. TEST_ESP_OK(gptimer_disable(timers[i]));
  454. TEST_ESP_OK(gptimer_del_timer(timers[i]));
  455. }
  456. }