1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include "aos_hal_timer.h"
7 #include <sys/types.h>
8 #include <sys/time.h>
9 #include <signal.h>
10 #include <time.h>
11
timer_common_cb(union sigval arg)12 static void timer_common_cb(union sigval arg)
13 {
14 timer_dev_t *amp_timer = (timer_dev_t *)arg.sival_ptr;
15
16 if (amp_timer && amp_timer->config.cb) {
17 amp_timer->config.cb(amp_timer->config.arg);
18 }
19 }
20
aos_hal_timer_init(timer_dev_t * tim)21 int32_t aos_hal_timer_init(timer_dev_t *tim)
22 {
23 struct sigevent ent;
24 timer_t *timer = aos_malloc(sizeof(timer_t));
25
26 memset(&ent, 0x00, sizeof(struct sigevent));
27
28 /* create a timer */
29 ent.sigev_notify = SIGEV_THREAD;
30 ent.sigev_notify_function = (void (*)(union sigval))timer_common_cb;
31 ent.sigev_value.sival_ptr = tim;
32
33 if (timer_create(CLOCK_MONOTONIC, &ent, timer) != 0) {
34 aos_free(timer);
35 return -1;
36 }
37
38 tim->priv = timer;
39 return 0;
40 }
41
aos_hal_timer_start(timer_dev_t * tim)42 int32_t aos_hal_timer_start(timer_dev_t *tim)
43 {
44 struct itimerspec ts;
45
46 /* check parameter */
47 if (tim == NULL) {
48 return -1;
49 }
50
51 if (tim->config.reload_mode == TIMER_RELOAD_AUTO) {
52 /* it_value=0: stop timer */
53 ts.it_interval.tv_sec = tim->config.period / 1000000;
54 ts.it_interval.tv_nsec = (tim->config.period % 1000000) * 1000;
55 } else {
56 /* it_interval=0: timer run only once */
57 ts.it_interval.tv_sec = 0;;
58 ts.it_interval.tv_nsec = 0;
59 }
60
61 /* it_value=0: stop timer */
62 ts.it_value.tv_sec = tim->config.period / 1000000;
63 ts.it_value.tv_nsec = (tim->config.period % 1000000) * 1000;
64
65 return timer_settime(*(timer_t *)tim->priv, 0, &ts, NULL);
66 }
67
aos_hal_timer_stop(timer_dev_t * tim)68 void aos_hal_timer_stop(timer_dev_t *tim)
69 {
70 struct itimerspec ts;
71
72 /* check parameter */
73 if (tim == NULL) {
74 return;
75 }
76
77 /* it_interval=0: timer run only once */
78 ts.it_interval.tv_sec = 0;
79 ts.it_interval.tv_nsec = 0;
80
81 /* it_value=0: stop timer */
82 ts.it_value.tv_sec = 0;
83 ts.it_value.tv_nsec = 0;
84
85 timer_settime(*(timer_t *)tim->priv, 0, &ts, NULL);
86
87 return ;
88 }
89
aos_hal_timer_finalize(timer_dev_t * tim)90 int32_t aos_hal_timer_finalize(timer_dev_t *tim)
91 {
92 int ret = 0;
93
94 /* check parameter */
95 if (tim == NULL) {
96 return -1;
97 }
98
99 ret = timer_delete(*(timer_t *)tim->priv);
100
101 aos_free(tim->priv);
102 return 0;
103 }
104