1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <cmsis_os2.h>
9 
10 #define ONESHOT_TIME_TICKS      100
11 #define PERIOD_TICKS            MAX(50, k_ms_to_ticks_ceil32(10))
12 #define NUM_PERIODS             5
13 
14 uint32_t num_oneshots_executed;
15 uint32_t num_periods_executed;
16 
17 const osTimerAttr_t timer_attr = {
18 	"myTimer",
19 	0,
20 	NULL,
21 	0U
22 };
23 
Timer1_Callback(void * arg)24 void Timer1_Callback(void *arg)
25 {
26 	uint32_t Tmr = *(uint32_t *)arg;
27 
28 	num_oneshots_executed++;
29 	TC_PRINT("oneshot_callback (Timer %d) = %d\n",
30 		 Tmr, num_oneshots_executed);
31 }
32 
Timer2_Callback(void * arg)33 void Timer2_Callback(void *arg)
34 {
35 	uint32_t Tmr = *(uint32_t *)arg;
36 
37 	num_periods_executed++;
38 	TC_PRINT("periodic_callback (Timer %d) = %d\n",
39 		 Tmr, num_periods_executed);
40 }
41 
ZTEST(cmsis_timer,test_timer)42 ZTEST(cmsis_timer, test_timer)
43 {
44 	osTimerId_t id1;
45 	osTimerId_t id2;
46 	uint32_t exec1;
47 	uint32_t exec2;
48 	osStatus_t status;
49 	uint32_t timerDelay;
50 	const char *name;
51 
52 	/* Create one-shot timer */
53 	exec1 = 1U;
54 	id1 = osTimerNew(Timer1_Callback, osTimerOnce, &exec1, &timer_attr);
55 	zassert_true(id1 != NULL, "error creating one-shot timer");
56 
57 	name = osTimerGetName(id1);
58 	zassert_str_equal(timer_attr.name, name, "Error getting Timer name");
59 
60 	/* Stop the timer before start */
61 	status = osTimerStop(id1);
62 	zassert_true(status == osErrorResource,
63 		     "error while stopping non-active timer");
64 
65 	timerDelay = ONESHOT_TIME_TICKS;
66 	status = osTimerStart(id1, timerDelay);
67 	zassert_true(status == osOK, "error starting one-shot timer");
68 
69 	zassert_equal(osTimerIsRunning(id1), 1, "Error: Timer not running");
70 
71 	/* Timer should fire only once if setup in one shot
72 	 * mode. Wait for 3 times the one-shot time to see
73 	 * if it fires more than once.
74 	 */
75 	osDelay(timerDelay * 3U + 10);
76 	zassert_true(num_oneshots_executed == 1U,
77 		     "error setting up one-shot timer");
78 
79 	status = osTimerStop(id1);
80 	zassert_true(status == osOK, "error stopping one-shot timer");
81 
82 	status = osTimerDelete(id1);
83 	zassert_true(status == osOK, "error deleting one-shot timer");
84 
85 	/* Create periodic timer */
86 	exec2 = 2U;
87 	id2 = osTimerNew(Timer2_Callback, osTimerPeriodic, &exec2, NULL);
88 	zassert_true(id2 != NULL, "error creating periodic timer");
89 
90 	zassert_equal(osTimerIsRunning(id2), 0, "Error: Timer is running");
91 
92 	timerDelay = PERIOD_TICKS;
93 	status = osTimerStart(id2, timerDelay);
94 	zassert_true(status == osOK, "error starting periodic timer");
95 
96 	/* Timer should fire periodically if setup in periodic
97 	 * mode. Wait for NUM_PERIODS periods to see if it is
98 	 * fired NUM_PERIODS times.
99 	 */
100 	osDelay(timerDelay * NUM_PERIODS + 10);
101 
102 	zassert_true(num_periods_executed == NUM_PERIODS,
103 		     "error setting up periodic timer");
104 
105 	/* Delete the timer before stop */
106 	status = osTimerDelete(id2);
107 	zassert_true(status == osOK, "error deleting periodic timer");
108 }
109 ZTEST_SUITE(cmsis_timer, NULL, NULL, NULL, NULL, NULL);
110