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 }