test_timer.c 35 KB

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