1 /*
2  * Copyright (c) 2019 Winner Microelectronics Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-11-19     fanwenl      1st version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "wm_type_def.h"
14 #include "wm_timer.h"
15 #include "drv_hw_timer.h"
16 
17 #ifdef BSP_USING_HWTIMER
18 
19 struct wm_timer_Type
20 {
21     enum tls_timer_unit unit;
22     enum tls_timer_id id;
23 };
24 
wm_timer_init(rt_hwtimer_t * timer,rt_uint32_t state)25 static void wm_timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
26 {
27     struct tls_timer_cfg timer_cfg;
28     struct wm_timer_Type *wm_timer = (struct wm_timer_Type *)timer->parent.user_data;
29 
30     timer_cfg.unit = wm_timer->unit;
31     timer_cfg.timeout = 0xFFFFFFFF;
32     timer_cfg.is_repeat = 0;
33     timer_cfg.callback = NULL;
34     timer_cfg.arg = NULL;
35 
36     if (state == 1)
37     {
38         tls_timer_create(&timer_cfg, wm_timer->id);
39     }
40     else if (state == 0)
41     {
42         tls_timer_destroy(wm_timer->id);
43     }
44 }
45 
wm_timer_start(rt_hwtimer_t * timer,rt_uint32_t t,rt_hwtimer_mode_t opmode)46 static rt_err_t wm_timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
47 {
48     struct wm_timer_Type *wm_timer = (struct wm_timer_Type *)timer->parent.user_data;
49     uint8_t m;
50 
51     tls_timer_change(wm_timer->id, t);
52     m = (opmode == HWTIMER_MODE_ONESHOT) ? 0 : 1;
53     tls_timer_set_mode(wm_timer->id, m);
54     tls_timer_start(wm_timer->id);
55 
56     return RT_EOK;
57 }
58 
wm_timer_stop(rt_hwtimer_t * timer)59 static void wm_timer_stop(rt_hwtimer_t *timer)
60 {
61     struct wm_timer_Type *wm_timer = (struct wm_timer_Type *)timer->parent.user_data;
62 
63     tls_timer_stop(wm_timer->id);
64 }
65 
wm_timer_get(rt_hwtimer_t * timer)66 static rt_uint32_t wm_timer_get(rt_hwtimer_t *timer)
67 {
68     return 0;
69 }
70 
wm_timer_ctrl(rt_hwtimer_t * timer,rt_uint32_t cmd,void * arg)71 static rt_err_t wm_timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
72 {
73     /* The frequency value is an immutable value. */
74     if (cmd != HWTIMER_CTRL_FREQ_SET)
75     {
76         return -RT_ENOSYS;
77     }
78     if ( *(rt_uint32_t*)arg == 1000000)
79     {
80         return RT_EOK;
81     }
82     else
83     {
84         return -RT_ENOSYS;
85     }
86 }
87 
88 static const struct rt_hwtimer_info _info =
89 {
90     1000000,            /* the maximum count frequency can be set */
91     1000000,            /* the minimum count frequency can be set */
92     0xFFFFFFFF,         /* the maximum counter value */
93     HWTIMER_CNTMODE_DW, /* Increment or Decreasing count mode */
94 };
95 
96 static const struct rt_hwtimer_ops _ops =
97 {
98     wm_timer_init,
99     wm_timer_start,
100     wm_timer_stop,
101     wm_timer_get,
102     wm_timer_ctrl,
103 };
104 
105 #ifdef USING_HW_TIMER1
106 static rt_hwtimer_t _timer1;
107 static struct wm_timer_Type wm_timer1;
108 #endif
109 #ifdef USING_HW_TIMER2
110 static rt_hwtimer_t _timer2;
111 static struct wm_timer_Type wm_timer2;
112 #endif
113 #ifdef USING_HW_TIMER3
114 static rt_hwtimer_t _timer3;
115 static struct wm_timer_Type wm_timer3;
116 #endif
117 #ifdef USING_HW_TIMER4
118 static rt_hwtimer_t _timer4;
119 static struct wm_timer_Type wm_timer4;
120 #endif
121 #ifdef USING_HW_TIMER5
122 static rt_hwtimer_t _timer5;
123 static struct wm_timer_Type wm_timer5;
124 #endif
125 
wm_hw_timer_init(void)126 int wm_hw_timer_init(void)
127 {
128 #ifdef USING_HW_TIMER1
129     wm_timer1.id = TLS_TIMER_ID_1;
130     wm_timer1.unit = TLS_TIMER_UNIT_US;
131 
132     _timer1.info = &_info;
133     _timer1.ops = &_ops;
134 
135     rt_device_hwtimer_register(&_timer1, "timer1", &wm_timer1);
136 #endif
137 #ifdef USING_HW_TIMER2
138     wm_timer2.id = TLS_TIMER_ID_2;
139     wm_timer2.unit = TLS_TIMER_UNIT_US;
140 
141     _timer2.info = &_info;
142     _timer2.ops = &_ops;
143 
144     rt_device_hwtimer_register(&_timer2, "timer2", &wm_timer2);
145 #endif
146 #ifdef USING_HW_TIMER3
147     wm_timer3.id = TLS_TIMER_ID_3;
148     wm_timer3.unit = TLS_TIMER_UNIT_US;
149 
150     _timer3.info = &_info;
151     _timer3.ops = &_ops;
152 
153     rt_device_hwtimer_register(&_timer3, "timer3", &wm_timer3);
154 #endif
155 #ifdef USING_HW_TIMER4
156     wm_timer4.id = TLS_TIMER_ID_4;
157     wm_timer4.unit = TLS_TIMER_UNIT_US;
158 
159     _timer4.info = &_info;
160     _timer4.ops = &_ops;
161 
162     rt_device_hwtimer_register(&_timer4, "timer4", &wm_timer4);
163 #endif
164 #ifdef USING_HW_TIMER5
165     wm_timer5.id = TLS_TIMER_ID_5;
166     wm_timer5.unit = TLS_TIMER_UNIT_US;
167 
168     _timer5.info = &_info;
169     _timer5.ops = &_ops;
170 
171     rt_device_hwtimer_register(&_timer5, "timer5", &wm_timer5);
172 #endif
173     return 0;
174 }
175 INIT_BOARD_EXPORT(wm_hw_timer_init);
176 
TIM1_IRQHandler(void)177 void TIM1_IRQHandler(void)
178 {
179     timer_clear_irq(1);
180 #ifdef USING_HW_TIMER1
181     rt_device_hwtimer_isr(&_timer1);
182 #endif
183 }
TIM2_IRQHandler(void)184 void TIM2_IRQHandler(void)
185 {
186     timer_clear_irq(2);
187 #ifdef USING_HW_TIMER2
188     rt_device_hwtimer_isr(&_timer2);
189 #endif
190 }
TIM3_IRQHandler(void)191 void TIM3_IRQHandler(void)
192 {
193     timer_clear_irq(3);
194 #ifdef USING_HW_TIMER3
195     rt_device_hwtimer_isr(&_timer3);
196 #endif
197 }
TIM4_IRQHandler(void)198 void TIM4_IRQHandler(void)
199 {
200     timer_clear_irq(4);
201 #ifdef USING_HW_TIMER4
202     rt_device_hwtimer_isr(&_timer4);
203 #endif
204 }
TIM5_IRQHandler(void)205 void TIM5_IRQHandler(void)
206 {
207     timer_clear_irq(5);
208 #ifdef USING_HW_TIMER5
209     rt_device_hwtimer_isr(&_timer5);
210 #endif
211 }
212 #endif /* BSP_USING_HWTIMER */
213