test_timer.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. #include <stdio.h>
  2. #include "freertos/FreeRTOS.h"
  3. #include "freertos/task.h"
  4. #include "freertos/queue.h"
  5. #include "esp_system.h"
  6. #include "unity.h"
  7. #include "nvs_flash.h"
  8. #include "driver/timer.h"
  9. #include "soc/rtc.h"
  10. #include "soc/soc_caps.h"
  11. #include "esp_rom_sys.h"
  12. #define TIMER_DIVIDER 16
  13. #define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) /*!< used to calculate counter value */
  14. #define TIMER_DELTA 0.001
  15. static bool alarm_flag;
  16. static xQueueHandle timer_queue;
  17. typedef struct {
  18. timer_group_t timer_group;
  19. timer_idx_t timer_idx;
  20. } timer_info_t;
  21. typedef struct {
  22. timer_autoreload_t type; // the type of timer's event
  23. timer_group_t timer_group;
  24. timer_idx_t timer_idx;
  25. uint64_t timer_counter_value;
  26. } timer_event_t;
  27. #define TIMER_INFO_INIT(TG, TID) {.timer_group = (TG), .timer_idx = (TID),}
  28. static timer_info_t timer_info[4] = {
  29. TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0),
  30. TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_1),
  31. TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0),
  32. TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_1),
  33. };
  34. static intr_handle_t timer_isr_handles[SOC_TIMER_GROUP_TOTAL_TIMERS];
  35. #define GET_TIMER_INFO(TG, TID) (&timer_info[(TG)*SOC_TIMER_GROUP_TIMERS_PER_GROUP+(TID)])
  36. // timer group interruption handle callback
  37. static bool test_timer_group_isr_cb(void *arg)
  38. {
  39. bool is_awoken = false;
  40. timer_info_t *info = (timer_info_t *) arg;
  41. const timer_group_t timer_group = info->timer_group;
  42. const timer_idx_t timer_idx = info->timer_idx;
  43. uint64_t timer_val;
  44. double time;
  45. uint64_t alarm_value;
  46. timer_event_t evt;
  47. alarm_flag = true;
  48. if (timer_group_get_auto_reload_in_isr(timer_group, timer_idx)) { // For autoreload mode, the counter value has been cleared
  49. timer_group_clr_intr_status_in_isr(timer_group, timer_idx);
  50. esp_rom_printf("This is TG%d timer[%d] reload-timer alarm!\n", timer_group, timer_idx);
  51. timer_get_counter_value(timer_group, timer_idx, &timer_val);
  52. timer_get_counter_time_sec(timer_group, timer_idx, &time);
  53. evt.type = TIMER_AUTORELOAD_EN;
  54. } else {
  55. timer_group_clr_intr_status_in_isr(timer_group, timer_idx);
  56. esp_rom_printf("This is TG%d timer[%d] count-up-timer alarm!\n", timer_group, timer_idx);
  57. timer_get_counter_value(timer_group, timer_idx, &timer_val);
  58. timer_get_counter_time_sec(timer_group, timer_idx, &time);
  59. timer_get_alarm_value(timer_group, timer_idx, &alarm_value);
  60. timer_set_counter_value(timer_group, timer_idx, 0);
  61. evt.type = TIMER_AUTORELOAD_DIS;
  62. }
  63. evt.timer_group = timer_group;
  64. evt.timer_idx = timer_idx;
  65. evt.timer_counter_value = timer_val;
  66. if (timer_queue != NULL) {
  67. BaseType_t awoken = pdFALSE;
  68. BaseType_t ret = xQueueSendFromISR(timer_queue, &evt, &awoken);
  69. TEST_ASSERT_EQUAL(pdTRUE, ret);
  70. if (awoken) {
  71. is_awoken = true;
  72. }
  73. }
  74. return is_awoken;
  75. }
  76. // timer group interruption handle
  77. static void test_timer_group_isr(void *arg)
  78. {
  79. if (test_timer_group_isr_cb(arg)) {
  80. portYIELD_FROM_ISR();
  81. }
  82. }
  83. // initialize all timer
  84. static void all_timer_init(timer_config_t *config, bool expect_init)
  85. {
  86. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  87. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  88. TEST_ASSERT_EQUAL((expect_init ? ESP_OK : ESP_ERR_INVALID_ARG), timer_init(tg_idx, timer_idx, config));
  89. }
  90. }
  91. if (timer_queue == NULL) {
  92. timer_queue = xQueueCreate(10, sizeof(timer_event_t));
  93. }
  94. }
  95. // deinitialize all timer
  96. static void all_timer_deinit(void)
  97. {
  98. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  99. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  100. TEST_ESP_OK(timer_deinit(tg_idx, timer_idx));
  101. }
  102. }
  103. if (timer_queue != NULL) {
  104. vQueueDelete(timer_queue);
  105. timer_queue = NULL;
  106. }
  107. }
  108. // start all of timer
  109. static void all_timer_start(void)
  110. {
  111. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  112. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  113. TEST_ESP_OK(timer_start(tg_idx, timer_idx));
  114. }
  115. }
  116. }
  117. static void all_timer_set_counter_value(uint64_t set_cnt_val)
  118. {
  119. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  120. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  121. TEST_ESP_OK(timer_set_counter_value(tg_idx, timer_idx, set_cnt_val));
  122. }
  123. }
  124. }
  125. static void all_timer_pause(void)
  126. {
  127. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  128. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  129. TEST_ESP_OK(timer_pause(tg_idx, timer_idx));
  130. }
  131. }
  132. }
  133. static void all_timer_get_counter_value(uint64_t set_cnt_val, bool expect_equal_set_val,
  134. uint64_t *actual_cnt_val)
  135. {
  136. uint64_t current_cnt_val;
  137. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  138. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  139. TEST_ESP_OK(timer_get_counter_value(tg_idx, timer_idx, &current_cnt_val));
  140. if (expect_equal_set_val) {
  141. TEST_ASSERT_EQUAL(set_cnt_val, current_cnt_val);
  142. } else {
  143. TEST_ASSERT_NOT_EQUAL(set_cnt_val, current_cnt_val);
  144. if (actual_cnt_val != NULL) {
  145. actual_cnt_val[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx] = current_cnt_val;
  146. }
  147. }
  148. }
  149. }
  150. }
  151. static void all_timer_get_counter_time_sec(int expect_time)
  152. {
  153. double time;
  154. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  155. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  156. TEST_ESP_OK(timer_get_counter_time_sec(tg_idx, timer_idx, &time));
  157. TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, expect_time, time);
  158. }
  159. }
  160. }
  161. static void all_timer_set_counter_mode(timer_count_dir_t counter_dir)
  162. {
  163. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  164. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  165. TEST_ESP_OK(timer_set_counter_mode(tg_idx, timer_idx, counter_dir));
  166. }
  167. }
  168. }
  169. static void all_timer_set_divider(uint32_t divider)
  170. {
  171. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  172. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  173. TEST_ESP_OK(timer_set_divider(tg_idx, timer_idx, divider));
  174. }
  175. }
  176. }
  177. static void all_timer_set_alarm_value(uint64_t alarm_cnt_val)
  178. {
  179. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  180. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  181. TEST_ESP_OK(timer_set_alarm_value(tg_idx, timer_idx, alarm_cnt_val));
  182. }
  183. }
  184. }
  185. static void all_timer_get_alarm_value(uint64_t *alarm_vals)
  186. {
  187. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  188. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  189. TEST_ESP_OK(timer_get_alarm_value(tg_idx, timer_idx, &alarm_vals[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx]));
  190. }
  191. }
  192. }
  193. static void all_timer_isr_reg(void)
  194. {
  195. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  196. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  197. TEST_ESP_OK(timer_isr_register(tg_idx, timer_idx, test_timer_group_isr,
  198. GET_TIMER_INFO(tg_idx, timer_idx), ESP_INTR_FLAG_LOWMED, &timer_isr_handles[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx]));
  199. }
  200. }
  201. }
  202. static void all_timer_isr_unreg(void)
  203. {
  204. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  205. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  206. TEST_ESP_OK(esp_intr_free(timer_isr_handles[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx]));
  207. }
  208. }
  209. }
  210. // enable interrupt and start timer
  211. static void timer_intr_enable_and_start(int timer_group, int timer_idx, double alarm_time)
  212. {
  213. TEST_ESP_OK(timer_pause(timer_group, timer_idx));
  214. TEST_ESP_OK(timer_set_counter_value(timer_group, timer_idx, 0x0));
  215. TEST_ESP_OK(timer_set_alarm_value(timer_group, timer_idx, alarm_time * TIMER_SCALE));
  216. TEST_ESP_OK(timer_enable_intr(timer_group, timer_idx));
  217. TEST_ESP_OK(timer_start(timer_group, timer_idx));
  218. }
  219. static void timer_isr_check(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t autoreload, uint64_t alarm_cnt_val)
  220. {
  221. timer_event_t evt;
  222. TEST_ASSERT_EQUAL(pdTRUE, xQueueReceive(timer_queue, &evt, 3000 / portTICK_PERIOD_MS));
  223. TEST_ASSERT_EQUAL(autoreload, evt.type);
  224. TEST_ASSERT_EQUAL(group_num, evt.timer_group);
  225. TEST_ASSERT_EQUAL(timer_num, evt.timer_idx);
  226. TEST_ASSERT_EQUAL((uint32_t)(alarm_cnt_val >> 32), (uint32_t)(evt.timer_counter_value >> 32));
  227. TEST_ASSERT_UINT32_WITHIN(1000, (uint32_t)(alarm_cnt_val), (uint32_t)(evt.timer_counter_value));
  228. }
  229. static void timer_intr_enable_disable_test(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_cnt_val)
  230. {
  231. alarm_flag = false;
  232. TEST_ESP_OK(timer_set_counter_value(group_num, timer_num, 0));
  233. TEST_ESP_OK(timer_set_alarm(group_num, timer_num, TIMER_ALARM_EN));
  234. TEST_ESP_OK(timer_enable_intr(group_num, timer_num));
  235. TEST_ESP_OK(timer_start(group_num, timer_num));
  236. timer_isr_check(group_num, timer_num, TIMER_AUTORELOAD_DIS, alarm_cnt_val);
  237. TEST_ASSERT_EQUAL(true, alarm_flag);
  238. // disable interrupt of tg0_timer0
  239. alarm_flag = false;
  240. TEST_ESP_OK(timer_pause(group_num, timer_num));
  241. TEST_ESP_OK(timer_set_counter_value(group_num, timer_num, 0));
  242. TEST_ESP_OK(timer_disable_intr(group_num, timer_num));
  243. TEST_ESP_OK(timer_start(group_num, timer_num));
  244. vTaskDelay(2000 / portTICK_PERIOD_MS);
  245. TEST_ASSERT_EQUAL(false, alarm_flag);
  246. }
  247. TEST_CASE("Timer init", "[hw_timer]")
  248. {
  249. // Test init 1:config parameter
  250. // empty parameter
  251. timer_config_t config0 = { };
  252. all_timer_init(&config0, false);
  253. // only one parameter
  254. timer_config_t config1 = {
  255. .auto_reload = TIMER_AUTORELOAD_EN
  256. };
  257. all_timer_init(&config1, false);
  258. // lack one parameter
  259. timer_config_t config2 = {
  260. .auto_reload = TIMER_AUTORELOAD_EN,
  261. .counter_dir = TIMER_COUNT_UP,
  262. .divider = TIMER_DIVIDER,
  263. .counter_en = TIMER_START,
  264. .intr_type = TIMER_INTR_LEVEL
  265. };
  266. all_timer_init(&config2, true);
  267. config2.counter_en = TIMER_PAUSE;
  268. all_timer_init(&config2, true);
  269. // error config parameter
  270. timer_config_t config3 = {
  271. .alarm_en = 3, //error parameter
  272. .auto_reload = TIMER_AUTORELOAD_EN,
  273. .counter_dir = TIMER_COUNT_UP,
  274. .divider = TIMER_DIVIDER,
  275. .counter_en = TIMER_START,
  276. .intr_type = TIMER_INTR_LEVEL
  277. };
  278. all_timer_init(&config3, true);
  279. timer_config_t get_config;
  280. TEST_ESP_OK(timer_get_config(TIMER_GROUP_1, TIMER_0, &get_config));
  281. printf("Error config alarm_en is %d\n", get_config.alarm_en);
  282. TEST_ASSERT_NOT_EQUAL(config3.alarm_en, get_config.alarm_en);
  283. // Test init 2: init
  284. uint64_t set_timer_val = 0x0;
  285. timer_config_t config = {
  286. .alarm_en = TIMER_ALARM_DIS,
  287. .auto_reload = TIMER_AUTORELOAD_EN,
  288. .counter_dir = TIMER_COUNT_UP,
  289. .divider = TIMER_DIVIDER,
  290. .counter_en = TIMER_START,
  291. .intr_type = TIMER_INTR_LEVEL
  292. };
  293. // judge get config parameters
  294. TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config));
  295. TEST_ESP_OK(timer_get_config(TIMER_GROUP_0, TIMER_0, &get_config));
  296. TEST_ASSERT_EQUAL(config.alarm_en, get_config.alarm_en);
  297. TEST_ASSERT_EQUAL(config.auto_reload, get_config.auto_reload);
  298. TEST_ASSERT_EQUAL(config.counter_dir, get_config.counter_dir);
  299. TEST_ASSERT_EQUAL(config.counter_en, get_config.counter_en);
  300. TEST_ASSERT_EQUAL(config.intr_type, get_config.intr_type);
  301. TEST_ASSERT_EQUAL(config.divider, get_config.divider);
  302. all_timer_init(&config, true);
  303. all_timer_pause();
  304. all_timer_set_counter_value(set_timer_val);
  305. all_timer_start();
  306. all_timer_get_counter_value(set_timer_val, false, NULL);
  307. // Test init 3: wrong parameter
  308. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(-1, TIMER_0, &config));
  309. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_1, 2, &config));
  310. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_1, -1, &config));
  311. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(2, TIMER_0, &config));
  312. all_timer_deinit();
  313. }
  314. /**
  315. * read count case:
  316. * 1. start timer compare value
  317. * 2. pause timer compare value
  318. * 3. delay some time */
  319. TEST_CASE("Timer read counter value", "[hw_timer]")
  320. {
  321. timer_config_t config = {
  322. .alarm_en = TIMER_ALARM_EN,
  323. .auto_reload = TIMER_AUTORELOAD_EN,
  324. .counter_dir = TIMER_COUNT_UP,
  325. .divider = TIMER_DIVIDER,
  326. .counter_en = TIMER_START,
  327. .intr_type = TIMER_INTR_LEVEL
  328. };
  329. uint64_t set_timer_val = 0x0;
  330. all_timer_init(&config, true);
  331. // Test read value 1: start timer get counter value
  332. all_timer_set_counter_value(set_timer_val);
  333. all_timer_start();
  334. all_timer_get_counter_value(set_timer_val, false, NULL);
  335. // Test read value 2: pause timer get counter value
  336. all_timer_pause();
  337. set_timer_val = 0x30405000ULL;
  338. all_timer_set_counter_value(set_timer_val);
  339. all_timer_get_counter_value(set_timer_val, true, NULL);
  340. // Test read value 3:delay 1s get counter value
  341. set_timer_val = 0x0;
  342. all_timer_set_counter_value(set_timer_val);
  343. all_timer_start();
  344. vTaskDelay(1000 / portTICK_PERIOD_MS);
  345. all_timer_get_counter_time_sec(1);
  346. all_timer_deinit();
  347. }
  348. /**
  349. * start timer case:
  350. * 1. normal start
  351. * 2. error start parameter
  352. * */
  353. TEST_CASE("Timer start", "[hw_timer]")
  354. {
  355. timer_config_t config = {
  356. .alarm_en = TIMER_ALARM_EN,
  357. .auto_reload = TIMER_AUTORELOAD_EN,
  358. .counter_dir = TIMER_COUNT_UP,
  359. .divider = TIMER_DIVIDER,
  360. .counter_en = TIMER_START,
  361. .intr_type = TIMER_INTR_LEVEL
  362. };
  363. uint64_t set_timer_val = 0x0;
  364. all_timer_init(&config, true);
  365. //Test start 1: normal start
  366. all_timer_start();
  367. all_timer_set_counter_value(set_timer_val);
  368. all_timer_get_counter_value(set_timer_val, false, NULL);
  369. //Test start 2:wrong parameter
  370. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(2, TIMER_0));
  371. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(-1, TIMER_0));
  372. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_1, 2));
  373. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_1, -1));
  374. all_timer_deinit();
  375. }
  376. /**
  377. * pause timer case:
  378. * 1. normal pause, read value
  379. * 2. error pause error
  380. */
  381. TEST_CASE("Timer pause", "[hw_timer]")
  382. {
  383. timer_config_t config = {
  384. .alarm_en = TIMER_ALARM_EN,
  385. .auto_reload = TIMER_AUTORELOAD_EN,
  386. .counter_dir = TIMER_COUNT_UP,
  387. .divider = TIMER_DIVIDER,
  388. .counter_en = TIMER_START,
  389. .intr_type = TIMER_INTR_LEVEL
  390. };
  391. uint64_t set_timer_val = 0x0;
  392. all_timer_init(&config, true);
  393. //Test pause 1: right parameter
  394. all_timer_pause();
  395. all_timer_set_counter_value(set_timer_val);
  396. all_timer_get_counter_value(set_timer_val, true, NULL);
  397. //Test pause 2: wrong parameter
  398. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(-1, TIMER_0));
  399. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_0, -1));
  400. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(2, TIMER_0));
  401. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_1, 2));
  402. all_timer_deinit();
  403. }
  404. // positive mode and negative mode
  405. TEST_CASE("Timer counter mode (up / down)", "[hw_timer]")
  406. {
  407. timer_config_t config = {
  408. .alarm_en = TIMER_ALARM_EN,
  409. .auto_reload = TIMER_AUTORELOAD_EN,
  410. .counter_dir = TIMER_COUNT_UP,
  411. .divider = TIMER_DIVIDER,
  412. .counter_en = TIMER_START,
  413. .intr_type = TIMER_INTR_LEVEL
  414. };
  415. uint64_t set_timer_val = 0x0;
  416. all_timer_init(&config, true);
  417. all_timer_pause();
  418. // Test counter mode 1: TIMER_COUNT_UP
  419. all_timer_set_counter_mode(TIMER_COUNT_UP);
  420. all_timer_set_counter_value(set_timer_val);
  421. all_timer_start();
  422. vTaskDelay(1000 / portTICK_PERIOD_MS);
  423. all_timer_get_counter_time_sec(1);
  424. // Test counter mode 2: TIMER_COUNT_DOWN
  425. all_timer_pause();
  426. set_timer_val = 0x00E4E1C0ULL; // 3s clock counter value
  427. all_timer_set_counter_mode(TIMER_COUNT_DOWN);
  428. all_timer_set_counter_value(set_timer_val);
  429. all_timer_start();
  430. vTaskDelay(1000 / portTICK_PERIOD_MS);
  431. all_timer_get_counter_time_sec(2);
  432. // Test counter mode 3 : wrong parameter
  433. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, -1));
  434. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, 2));
  435. all_timer_deinit();
  436. }
  437. /**
  438. * divider case:
  439. * 1. different divider, read value
  440. * Note: divide 0 = divide max, divide 1 = divide 2
  441. * 2. error parameter
  442. *
  443. * the frequency(timer counts in one sec):
  444. * 80M/divider = 800*100000
  445. * max divider value is 65536, its frequency is 1220 (nearly about 1KHz)
  446. */
  447. TEST_CASE("Timer divider", "[hw_timer]")
  448. {
  449. int i;
  450. timer_config_t config = {
  451. .alarm_en = TIMER_ALARM_EN,
  452. .auto_reload = TIMER_AUTORELOAD_EN,
  453. .counter_dir = TIMER_COUNT_UP,
  454. .divider = TIMER_DIVIDER,
  455. .counter_en = TIMER_START,
  456. .intr_type = TIMER_INTR_LEVEL
  457. };
  458. uint64_t set_timer_val = 0;
  459. uint64_t time_val[4];
  460. uint64_t comp_time_val[4];
  461. all_timer_init(&config, true);
  462. all_timer_pause();
  463. all_timer_set_counter_value(set_timer_val);
  464. all_timer_start();
  465. vTaskDelay(1000 / portTICK_PERIOD_MS);
  466. all_timer_get_counter_value(set_timer_val, false, time_val);
  467. // compare divider 16 and 8, value should be double
  468. all_timer_pause();
  469. all_timer_set_divider(8);
  470. all_timer_set_counter_value(set_timer_val);
  471. all_timer_start();
  472. vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
  473. all_timer_get_counter_value(set_timer_val, false, comp_time_val);
  474. for (i = 0; i < 4; i++) {
  475. TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
  476. TEST_ASSERT_INT_WITHIN(10000, 10000000, comp_time_val[i]);
  477. }
  478. // divider is 256, value should be 2^4
  479. all_timer_pause();
  480. all_timer_set_divider(256);
  481. all_timer_set_counter_value(set_timer_val);
  482. all_timer_start();
  483. vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
  484. all_timer_get_counter_value(set_timer_val, false, comp_time_val);
  485. for (i = 0; i < 4; i++) {
  486. TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
  487. TEST_ASSERT_INT_WITHIN(3126, 312500, comp_time_val[i]);
  488. }
  489. // extrem value test
  490. all_timer_pause();
  491. all_timer_set_divider(2);
  492. all_timer_set_counter_value(set_timer_val);
  493. all_timer_start();
  494. vTaskDelay(1000 / portTICK_PERIOD_MS);
  495. all_timer_get_counter_value(set_timer_val, false, comp_time_val);
  496. for (i = 0; i < 4; i++) {
  497. TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
  498. TEST_ASSERT_INT_WITHIN(40000, 40000000, comp_time_val[i]);
  499. }
  500. all_timer_pause();
  501. all_timer_set_divider(65536);
  502. all_timer_set_counter_value(set_timer_val);
  503. all_timer_start();
  504. vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
  505. all_timer_get_counter_value(set_timer_val, false, comp_time_val);
  506. for (i = 0; i < 4; i++) {
  507. TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
  508. TEST_ASSERT_INT_WITHIN(2, 1220, comp_time_val[i]);
  509. }
  510. // divider is 1 should be equal with 2
  511. all_timer_pause();
  512. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 1));
  513. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_1, TIMER_0, 1));
  514. all_timer_pause();
  515. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 65537));
  516. TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_1, TIMER_0, 65537));
  517. all_timer_deinit();
  518. }
  519. /**
  520. * enable alarm case:
  521. * 1. enable alarm ,set alarm value and get value
  522. * 2. disable alarm ,set alarm value and get value
  523. */
  524. TEST_CASE("Timer enable alarm", "[hw_timer]")
  525. {
  526. timer_config_t config_test = {
  527. .alarm_en = TIMER_ALARM_DIS,
  528. .auto_reload = TIMER_AUTORELOAD_DIS,
  529. .counter_dir = TIMER_COUNT_UP,
  530. .divider = TIMER_DIVIDER,
  531. .counter_en = TIMER_PAUSE,
  532. .intr_type = TIMER_INTR_LEVEL
  533. };
  534. all_timer_init(&config_test, true);
  535. all_timer_isr_reg();
  536. // enable alarm of tg0_timer1
  537. alarm_flag = false;
  538. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
  539. timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.2);
  540. timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
  541. TEST_ASSERT_EQUAL(true, alarm_flag);
  542. // disable alarm of tg0_timer1
  543. alarm_flag = false;
  544. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_DIS));
  545. timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.2);
  546. vTaskDelay(2000 / portTICK_PERIOD_MS);
  547. TEST_ASSERT_EQUAL(false, alarm_flag);
  548. // enable alarm of tg1_timer0
  549. alarm_flag = false;
  550. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
  551. timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.2);
  552. timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
  553. TEST_ASSERT_EQUAL(true, alarm_flag);
  554. // disable alarm of tg1_timer0
  555. alarm_flag = false;
  556. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_DIS));
  557. timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.2);
  558. vTaskDelay(2000 / portTICK_PERIOD_MS);
  559. TEST_ASSERT_EQUAL(false, alarm_flag);
  560. all_timer_isr_unreg();
  561. all_timer_deinit();
  562. }
  563. /**
  564. * alarm value case:
  565. * 1. set alarm value and get value
  566. * 2. interrupt test time
  567. */
  568. TEST_CASE("Timer set alarm value", "[hw_timer]")
  569. {
  570. uint64_t alarm_val[SOC_TIMER_GROUP_TOTAL_TIMERS];
  571. timer_config_t config = {
  572. .alarm_en = TIMER_ALARM_EN,
  573. .auto_reload = TIMER_AUTORELOAD_DIS,
  574. .counter_dir = TIMER_COUNT_UP,
  575. .divider = TIMER_DIVIDER,
  576. .counter_en = TIMER_PAUSE,
  577. .intr_type = TIMER_INTR_LEVEL
  578. };
  579. all_timer_init(&config, true);
  580. all_timer_isr_reg();
  581. // set and get alarm value
  582. all_timer_set_alarm_value(3 * TIMER_SCALE);
  583. all_timer_get_alarm_value(alarm_val);
  584. for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
  585. TEST_ASSERT_EQUAL_UINT32(3 * TIMER_SCALE, (uint32_t)alarm_val[i]);
  586. }
  587. // set interrupt read alarm value
  588. timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 2.4);
  589. timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 2.4 * TIMER_SCALE);
  590. timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4);
  591. timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.4 * TIMER_SCALE);
  592. all_timer_isr_unreg();
  593. all_timer_deinit();
  594. }
  595. /**
  596. * auto reload case:
  597. * 1. no reload
  598. * 2. auto reload
  599. */
  600. TEST_CASE("Timer auto reload", "[hw_timer]")
  601. {
  602. timer_config_t config = {
  603. .alarm_en = TIMER_ALARM_EN,
  604. .auto_reload = TIMER_AUTORELOAD_DIS,
  605. .counter_dir = TIMER_COUNT_UP,
  606. .divider = TIMER_DIVIDER,
  607. .counter_en = TIMER_PAUSE,
  608. .intr_type = TIMER_INTR_LEVEL
  609. };
  610. all_timer_init(&config, true);
  611. all_timer_isr_reg();
  612. // test disable auto_reload
  613. timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.14);
  614. timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.14 * TIMER_SCALE);
  615. //test enable auto_reload
  616. TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN));
  617. timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4);
  618. timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN, 0);
  619. all_timer_isr_unreg();
  620. all_timer_deinit();
  621. }
  622. /**
  623. * timer_enable_intr case:
  624. * 1. enable timer_intr
  625. * 2. disable timer_intr
  626. */
  627. TEST_CASE("Timer enable timer interrupt", "[hw_timer]")
  628. {
  629. timer_config_t config = {
  630. .alarm_en = TIMER_ALARM_DIS,
  631. .counter_dir = TIMER_COUNT_UP,
  632. .auto_reload = TIMER_AUTORELOAD_DIS,
  633. .divider = TIMER_DIVIDER,
  634. .counter_en = TIMER_PAUSE,
  635. .intr_type = TIMER_INTR_LEVEL
  636. };
  637. all_timer_init(&config, true);
  638. all_timer_pause();
  639. all_timer_set_alarm_value(1.2 * TIMER_SCALE);
  640. all_timer_set_counter_value(0);
  641. all_timer_isr_reg();
  642. timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * TIMER_SCALE);
  643. timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * TIMER_SCALE);
  644. // enable interrupt of tg1_timer0 again
  645. alarm_flag = false;
  646. TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0));
  647. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0));
  648. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
  649. TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_1, TIMER_0));
  650. TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0));
  651. timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
  652. TEST_ASSERT_EQUAL(true, alarm_flag);
  653. all_timer_isr_unreg();
  654. all_timer_deinit();
  655. }
  656. /**
  657. * enable timer group case:
  658. * 1. enable timer group
  659. * 2. disable timer group
  660. */
  661. TEST_CASE("Timer enable timer group interrupt", "[hw_timer][ignore]")
  662. {
  663. intr_handle_t isr_handle = NULL;
  664. alarm_flag = false;
  665. timer_config_t config = {
  666. .alarm_en = TIMER_ALARM_EN,
  667. .auto_reload = TIMER_AUTORELOAD_DIS,
  668. .counter_dir = TIMER_COUNT_UP,
  669. .divider = TIMER_DIVIDER,
  670. .counter_en = TIMER_PAUSE,
  671. .intr_type = TIMER_INTR_LEVEL
  672. };
  673. uint64_t set_timer_val = 0x0;
  674. all_timer_init(&config, true);
  675. all_timer_pause();
  676. all_timer_set_counter_value(set_timer_val);
  677. all_timer_set_alarm_value(1.2 * TIMER_SCALE);
  678. // enable interrupt of tg0_timer0
  679. TEST_ESP_OK(timer_group_intr_enable(TIMER_GROUP_0, TIMER_INTR_T0));
  680. TEST_ESP_OK(timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group_isr,
  681. GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED, &isr_handle));
  682. TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
  683. timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
  684. TEST_ASSERT_EQUAL(true, alarm_flag);
  685. // disable interrupt of tg0_timer0
  686. alarm_flag = false;
  687. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val));
  688. TEST_ESP_OK(timer_group_intr_disable(TIMER_GROUP_0, TIMER_INTR_T0));
  689. TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
  690. vTaskDelay(2000 / portTICK_PERIOD_MS);
  691. TEST_ASSERT_EQUAL(false, alarm_flag);
  692. esp_intr_free(isr_handle);
  693. }
  694. /**
  695. * isr_register case:
  696. * Cycle register 15 times, compare the heap size to ensure no memory leaks
  697. */
  698. TEST_CASE("Timer interrupt register", "[hw_timer]")
  699. {
  700. timer_config_t config = {
  701. .alarm_en = TIMER_ALARM_DIS,
  702. .auto_reload = TIMER_AUTORELOAD_DIS,
  703. .counter_dir = TIMER_COUNT_UP,
  704. .divider = TIMER_DIVIDER,
  705. .counter_en = TIMER_PAUSE,
  706. .intr_type = TIMER_INTR_LEVEL
  707. };
  708. for (int i = 0; i < 15; i++) {
  709. all_timer_init(&config, true);
  710. timer_isr_handle_t timer_isr_handle[TIMER_GROUP_MAX * TIMER_MAX];
  711. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  712. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  713. TEST_ESP_OK(timer_isr_register(tg_idx, timer_idx, test_timer_group_isr,
  714. GET_TIMER_INFO(tg_idx, timer_idx), ESP_INTR_FLAG_LOWMED, &timer_isr_handle[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx]));
  715. }
  716. }
  717. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
  718. timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.54);
  719. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
  720. timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.34);
  721. TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN));
  722. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
  723. timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.4);
  724. TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN));
  725. TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
  726. timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.6);
  727. vTaskDelay(1000 / portTICK_PERIOD_MS);
  728. // ISR hanlde function should be free before next ISR register.
  729. for (uint32_t tg_idx = 0; tg_idx < TIMER_GROUP_MAX; tg_idx++) {
  730. for (uint32_t timer_idx = 0; timer_idx < TIMER_MAX; timer_idx++) {
  731. TEST_ESP_OK(esp_intr_free(timer_isr_handle[tg_idx * SOC_TIMER_GROUP_TIMERS_PER_GROUP + timer_idx]));
  732. }
  733. }
  734. all_timer_deinit();
  735. }
  736. }
  737. #if SOC_TIMER_GROUP_SUPPORT_XTAL
  738. /**
  739. * Timer clock source:
  740. * 1. configure clock source as APB clock, and enable timer interrupt
  741. * 2. configure clock source as XTAL clock, adn enable timer interrupt
  742. */
  743. TEST_CASE("Timer clock source", "[hw_timer]")
  744. {
  745. // configure clock source as APB clock
  746. uint32_t timer_scale = rtc_clk_apb_freq_get() / TIMER_DIVIDER;
  747. timer_config_t config = {
  748. .alarm_en = TIMER_ALARM_DIS,
  749. .auto_reload = TIMER_AUTORELOAD_DIS,
  750. .counter_dir = TIMER_COUNT_UP,
  751. .divider = TIMER_DIVIDER,
  752. .counter_en = TIMER_PAUSE,
  753. .intr_type = TIMER_INTR_LEVEL,
  754. .clk_src = TIMER_SRC_CLK_APB
  755. };
  756. all_timer_init(&config, true);
  757. all_timer_pause();
  758. all_timer_set_alarm_value(1.2 * timer_scale);
  759. all_timer_set_counter_value(0);
  760. all_timer_isr_reg();
  761. timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * timer_scale);
  762. timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * timer_scale );
  763. // configure clock source as XTAL clock
  764. all_timer_pause();
  765. timer_scale = rtc_clk_xtal_freq_get() * 1000000 / TIMER_DIVIDER;
  766. config.clk_src = TIMER_SRC_CLK_XTAL;
  767. all_timer_init(&config, true);
  768. all_timer_set_alarm_value(1.2 * timer_scale);
  769. timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * timer_scale);
  770. timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * timer_scale );
  771. all_timer_isr_unreg();
  772. all_timer_deinit();
  773. }
  774. #endif
  775. /**
  776. * Timer ISR callback test
  777. */
  778. TEST_CASE("Timer ISR callback", "[hw_timer]")
  779. {
  780. alarm_flag = false;
  781. timer_config_t config = {
  782. .alarm_en = TIMER_ALARM_EN,
  783. .auto_reload = TIMER_AUTORELOAD_DIS,
  784. .counter_dir = TIMER_COUNT_UP,
  785. .divider = TIMER_DIVIDER,
  786. .counter_en = TIMER_PAUSE,
  787. .intr_type = TIMER_INTR_LEVEL,
  788. };
  789. uint32_t timer_scale = rtc_clk_apb_freq_get() / TIMER_DIVIDER;
  790. uint64_t alarm_cnt_val = 1.2 * timer_scale;
  791. uint64_t set_timer_val = 0x0;
  792. all_timer_init(&config, true);
  793. all_timer_pause();
  794. all_timer_set_alarm_value(alarm_cnt_val);
  795. all_timer_set_counter_value(set_timer_val);
  796. // add isr callback for tg0_timer0
  797. TEST_ESP_OK(timer_isr_callback_add(TIMER_GROUP_0, TIMER_0, test_timer_group_isr_cb,
  798. GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED));
  799. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val));
  800. TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
  801. timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, alarm_cnt_val);
  802. TEST_ASSERT_EQUAL(true, alarm_flag);
  803. // remove isr callback for tg0_timer0
  804. TEST_ESP_OK(timer_pause(TIMER_GROUP_0, TIMER_0));
  805. TEST_ESP_OK(timer_isr_callback_remove(TIMER_GROUP_0, TIMER_0));
  806. alarm_flag = false;
  807. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val));
  808. TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
  809. vTaskDelay(2000 / portTICK_PERIOD_MS);
  810. TEST_ASSERT_EQUAL(false, alarm_flag);
  811. // add isr callback for tg1_timer0
  812. TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0));
  813. TEST_ESP_OK(timer_isr_callback_add(TIMER_GROUP_1, TIMER_0, test_timer_group_isr_cb,
  814. GET_TIMER_INFO(TIMER_GROUP_1, TIMER_0), ESP_INTR_FLAG_LOWMED));
  815. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_1, TIMER_0, set_timer_val));
  816. TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0));
  817. timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, alarm_cnt_val);
  818. TEST_ASSERT_EQUAL(true, alarm_flag);
  819. // remove isr callback for tg1_timer0
  820. TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0));
  821. TEST_ESP_OK(timer_isr_callback_remove(TIMER_GROUP_1, TIMER_0));
  822. alarm_flag = false;
  823. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_1, TIMER_0, set_timer_val));
  824. TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0));
  825. vTaskDelay(2000 / portTICK_PERIOD_MS);
  826. TEST_ASSERT_EQUAL(false, alarm_flag);
  827. all_timer_deinit();
  828. }
  829. /**
  830. * Timer memory test
  831. */
  832. TEST_CASE("Timer memory test", "[hw_timer]")
  833. {
  834. timer_config_t config = {
  835. .alarm_en = TIMER_ALARM_EN,
  836. .auto_reload = TIMER_AUTORELOAD_EN,
  837. .counter_dir = TIMER_COUNT_UP,
  838. .divider = TIMER_DIVIDER,
  839. .counter_en = TIMER_PAUSE,
  840. .intr_type = TIMER_INTR_LEVEL,
  841. };
  842. for (uint32_t i = 0; i < 100; i++) {
  843. all_timer_init(&config, true);
  844. all_timer_deinit();
  845. }
  846. }
  847. // The following test cases are used to check if the timer_group fix works.
  848. // Some applications use a software reset, at the reset time, timer_group happens to generate an interrupt.
  849. // but software reset does not clear interrupt status, this is not safe for application when enable the interrupt of timer_group.
  850. // This case will check under this fix, whether the interrupt status is cleared after timer_group initialization.
  851. static void timer_group_test_init(void)
  852. {
  853. static const uint32_t time_ms = 100; //Alarm value 100ms.
  854. static const uint16_t timer_div = 10; //Timer prescaler
  855. static const uint32_t ste_val = time_ms * (TIMER_BASE_CLK / timer_div / 1000);
  856. timer_config_t config = {
  857. .divider = timer_div,
  858. .counter_dir = TIMER_COUNT_UP,
  859. .counter_en = TIMER_PAUSE,
  860. .alarm_en = TIMER_ALARM_EN,
  861. .intr_type = TIMER_INTR_LEVEL,
  862. .auto_reload = TIMER_AUTORELOAD_EN,
  863. };
  864. TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config));
  865. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL));
  866. TEST_ESP_OK(timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, ste_val));
  867. //Now the timer is ready.
  868. //We only need to check the interrupt status and don't have to register a interrupt routine.
  869. }
  870. static void timer_group_test_first_stage(void)
  871. {
  872. static uint8_t loop_cnt = 0;
  873. timer_group_test_init();
  874. //Start timer
  875. TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0));
  876. TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
  877. //Waiting for timer_group to generate an interrupt
  878. while ( !(timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0) &&
  879. loop_cnt++ < 100) {
  880. vTaskDelay(200);
  881. }
  882. TEST_ASSERT_EQUAL(TIMER_INTR_T0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0);
  883. esp_restart();
  884. }
  885. static void timer_group_test_second_stage(void)
  886. {
  887. TEST_ASSERT_EQUAL(ESP_RST_SW, esp_reset_reason());
  888. timer_group_test_init();
  889. //After the timer_group is initialized, TIMERG0.int_raw.t0 should be cleared.
  890. TEST_ASSERT_EQUAL(0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0);
  891. }
  892. TEST_CASE_MULTIPLE_STAGES("timer_group software reset test",
  893. "[intr_status][intr_status = 0]",
  894. timer_group_test_first_stage,
  895. timer_group_test_second_stage);