1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include "objects.h"
6 #include <drv/timer.h>
7 
8 #define GTIMER_MAX  4
9 
csi_gtimer_timeout_handler(uint32_t data)10 static void csi_gtimer_timeout_handler(uint32_t data)
11 {
12 	csi_timer_t *timer = (csi_timer_t *)data;
13 	uint32_t tid = timer->dev.idx;
14 
15 	RTIM_INTClear(TIMx[tid]);
16 
17 	if (timer->callback != NULL) {
18         timer->callback(timer,timer->arg);
19 	}
20 }
21 
csi_timer_init(csi_timer_t * timer,uint32_t idx)22 csi_error_t csi_timer_init(csi_timer_t *timer, uint32_t idx)
23 {
24     if(!timer)
25         return CSI_ERROR;
26 
27     if(idx > GTIMER_MAX)
28         return CSI_ERROR;
29 
30     timer->priv = (RTIM_TimeBaseInitTypeDef *)malloc(sizeof(RTIM_TimeBaseInitTypeDef));
31     RTIM_TimeBaseInitTypeDef *TIM_InitStruct = (RTIM_TimeBaseInitTypeDef *)timer->priv;
32 
33     timer->dev.idx = idx;
34 
35     RTIM_TimeBaseStructInit(TIM_InitStruct);
36 	TIM_InitStruct->TIM_Idx = (uint8_t)idx;
37 
38 	TIM_InitStruct->TIM_UpdateEvent = ENABLE; /* UEV enable */
39 	TIM_InitStruct->TIM_UpdateSource = TIM_UpdateSource_Overflow;
40 	TIM_InitStruct->TIM_ARRProtection = ENABLE;
41 
42 	RTIM_TimeBaseInit(TIMx[idx], TIM_InitStruct, TIMx_irq[idx], (IRQ_FUN)csi_gtimer_timeout_handler, (u32)timer);
43     return CSI_OK;
44 }
45 
csi_timer_uninit(csi_timer_t * timer)46 void csi_timer_uninit(csi_timer_t *timer)
47 {
48     uint32_t tid = timer->dev.idx;
49     RTIM_DeInit(TIMx[tid]);
50 
51     if(timer && timer->priv) {
52         free(timer->priv);
53         timer->priv = NULL;
54     }
55 }
56 
csi_timer_start(csi_timer_t * timer,uint32_t timeout_us)57 csi_error_t csi_timer_start(csi_timer_t *timer, uint32_t timeout_us)
58 {
59     uint32_t tid = timer->dev.idx;
60     uint32_t temp = (uint32_t)((float)timeout_us  / 1000000 * 32768);
61 
62     RTIM_ChangePeriodImmediate(TIMx[tid], temp);
63     RTIM_INTConfig(TIMx[tid], TIM_IT_Update, ENABLE);
64 	RTIM_Cmd(TIMx[tid], ENABLE);
65     return CSI_OK;
66 }
67 
csi_timer_stop(csi_timer_t * timer)68 void csi_timer_stop(csi_timer_t *timer)
69 {
70     uint32_t tid = timer->dev.idx;
71 
72     RTIM_Cmd(TIMx[tid], DISABLE);
73 }
74 
csi_timer_get_remaining_value(csi_timer_t * timer)75 uint32_t csi_timer_get_remaining_value(csi_timer_t *timer)
76 {
77     uint32_t tid = timer->dev.idx;
78     uint32_t tick;
79     uint32_t load;
80     uint32_t time_us;
81 
82     RTIM_TypeDef* TIM = TIMx[tid];
83     tick = RTIM_GetCount(TIM);
84     load = (uint32_t)((float)TIM->ARR * 1000000 / 32768);
85     time_us = load - (uint32_t)((float)tick * 1000000 / 32768);
86     return time_us;
87 }
88 
csi_timer_get_load_value(csi_timer_t * timer)89 uint32_t csi_timer_get_load_value(csi_timer_t *timer)
90 {
91     uint32_t tid = timer->dev.idx;
92     uint32_t time_us;
93 
94     RTIM_TypeDef* TIM = TIMx[tid];
95     time_us = (uint32_t)((float)TIM->ARR * 1000000 / 32768);
96     return time_us;
97 }
98 
csi_timer_is_running(csi_timer_t * timer)99 bool csi_timer_is_running(csi_timer_t *timer)
100 {
101     uint32_t tid = timer->dev.idx;
102     uint32_t time_us;
103 
104     RTIM_TypeDef* TIM = TIMx[tid];
105     if(TIM->EN & TIM_CR_CNT_RUN)
106         return TRUE;
107 
108     return FALSE;
109 }
110 
csi_timer_attach_callback(csi_timer_t * timer,void * callback,void * arg)111 csi_error_t csi_timer_attach_callback(csi_timer_t *timer, void *callback, void *arg)
112 {
113     timer->callback = callback;
114     timer->arg = arg;
115     return CSI_OK;
116 }
117 
csi_timer_detach_callback(csi_timer_t * timer)118 void csi_timer_detach_callback(csi_timer_t *timer)
119 {
120     timer->callback = NULL;
121 }