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