test_timer.c 29 KB

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