1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-08-20     breo.com     first version
9  */
10 
11 #include <board.h>
12 #include "drv_hwtimer.h"
13 
14 #define DRV_DEBUG
15 #define LOG_TAG             "drv.hwtimer"
16 #include <drv_log.h>
17 
18 #ifdef BSP_USING_HWTIMER
19 enum
20 {
21 #ifdef BSP_USING_HWTIM1
22     TIM1_INDEX,
23 #endif
24 
25 #ifdef BSP_USING_HWTIM2
26     TIM2_INDEX,
27 #endif
28 
29 #ifdef BSP_USING_HWTIM3
30     TIM3_INDEX,
31 #endif
32 
33 #ifdef BSP_USING_HWTIM4
34     TIM4_INDEX,
35 #endif
36 
37 #ifdef BSP_USING_HWTIM5
38     TIM5_INDEX,
39 #endif
40 
41 #ifdef BSP_USING_HWTIM6
42     TIM6_INDEX,
43 #endif
44 
45 #ifdef BSP_USING_HWTIM7
46     TIM7_INDEX,
47 #endif
48 
49 #ifdef BSP_USING_HW_TIM8
50     TIM8_INDEX,
51 #endif
52 };
53 
54 struct n32_hwtimer
55 {
56     rt_hwtimer_t    time_device;
57     TIM_Module     *tim_handle;
58     IRQn_Type       tim_irqn;
59     char            *name;
60 };
61 
62 static struct n32_hwtimer n32_hwtimer_obj[] =
63 {
64 #ifdef BSP_USING_HWTIM1
65     TIM1_CONFIG,
66 #endif
67 
68 #ifdef BSP_USING_HWTIM2
69     TIM2_CONFIG,
70 #endif
71 
72 #ifdef BSP_USING_HWTIM3
73     TIM3_CONFIG,
74 #endif
75 
76 #ifdef BSP_USING_HWTIM4
77     TIM4_CONFIG,
78 #endif
79 
80 #ifdef BSP_USING_HWTIM5
81     TIM5_CONFIG,
82 #endif
83 
84 #ifdef BSP_USING_HWTIM6
85     TIM6_CONFIG,
86 #endif
87 
88 #ifdef BSP_USING_HWTIM7
89     TIM7_CONFIG,
90 #endif
91 
92 #ifdef BSP_USING_HWTIM8
93     TIM8_CONFIG,
94 #endif
95 };
96 
n32_timer_init(struct rt_hwtimer_device * timer,rt_uint32_t state)97 static void n32_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
98 {
99     RCC_ClocksType RCC_ClockStruct;
100     TIM_TimeBaseInitType TIM_TimeBaseStructure;
101     NVIC_InitType NVIC_InitStructure;
102     uint32_t freq = 0;
103     uint32_t input_clock;
104     uint32_t prescaler_value = 0;
105     TIM_Module *tim = RT_NULL;
106     struct n32_hwtimer *tim_device = RT_NULL;
107 
108     RT_ASSERT(timer != RT_NULL);
109     if (state)
110     {
111         tim = (TIM_Module *)timer->parent.user_data;
112         tim_device = (struct n32_hwtimer *)timer;
113 
114         RT_ASSERT((tim == TIM2) || (tim == TIM3) || (tim == TIM4) || (tim == TIM5)
115             || (tim == TIM6) || (tim == TIM7));
116 
117         /* timer clock enable */
118         n32_msp_hwtim_init(tim);
119 
120         freq = timer->freq;
121         RCC_GetClocksFreqValue(&RCC_ClockStruct);
122         if (1 == (RCC_ClockStruct.HclkFreq / RCC_ClockStruct.Pclk1Freq))
123             input_clock = RCC_ClockStruct.Pclk1Freq;
124         else
125             input_clock = RCC_ClockStruct.Pclk1Freq * 2;
126         prescaler_value = (uint32_t)(input_clock / freq) - 1;
127 
128         TIM_TimeBaseStructure.Period = freq - 1;
129         TIM_TimeBaseStructure.Prescaler = prescaler_value;
130         TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1;
131         TIM_TimeBaseStructure.RepetCnt = 0;
132 
133         if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
134         {
135             TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP;
136         }
137         else
138         {
139             TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_DOWN;
140         }
141 
142         TIM_InitTimeBase(tim, &TIM_TimeBaseStructure);
143 
144         /* Enable the TIMx global Interrupt */
145         NVIC_InitStructure.NVIC_IRQChannel = tim_device->tim_irqn;
146         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
147         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
148         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
149         NVIC_Init(&NVIC_InitStructure);
150 
151         TIM_ConfigInt(tim, TIM_INT_UPDATE, ENABLE);
152         TIM_ClrIntPendingBit(tim, TIM_INT_UPDATE);
153 
154         LOG_D("%s init success", tim_device->name);
155     }
156 }
157 
n32_timer_start(rt_hwtimer_t * timer,rt_uint32_t t,rt_hwtimer_mode_t opmode)158 static rt_err_t n32_timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
159 {
160     rt_err_t result = RT_EOK;
161     TIM_Module *tim = RT_NULL;
162 
163     RT_ASSERT(timer != RT_NULL);
164 
165     tim = (TIM_Module *)timer->parent.user_data;
166 
167     /* set tim cnt */
168     TIM_SetCnt(tim, 0);
169     /* set tim arr */
170     TIM_SetAutoReload(tim, t - 1);
171     if (opmode == HWTIMER_MODE_ONESHOT)
172     {
173         /* set timer to single mode */
174         TIM_SelectOnePulseMode(tim, TIM_OPMODE_SINGLE);
175     }
176     else
177     {
178         TIM_SelectOnePulseMode(tim, TIM_OPMODE_REPET);
179     }
180 
181     /* start timer */
182     TIM_Enable(tim, ENABLE);
183 
184     return result;
185 }
186 
n32_timer_stop(rt_hwtimer_t * timer)187 static void n32_timer_stop(rt_hwtimer_t *timer)
188 {
189     TIM_Module *tim = RT_NULL;
190 
191     RT_ASSERT(timer != RT_NULL);
192 
193     tim = (TIM_Module *)timer->parent.user_data;
194 
195     /* stop timer */
196     TIM_Enable(tim, DISABLE);
197     /* set tim cnt */
198     TIM_SetCnt(tim, 0);
199 }
200 
n32_timer_counter_get(rt_hwtimer_t * timer)201 static rt_uint32_t n32_timer_counter_get(rt_hwtimer_t *timer)
202 {
203     TIM_Module *tim = RT_NULL;
204 
205     RT_ASSERT(timer != RT_NULL);
206 
207     tim = (TIM_Module *)timer->parent.user_data;
208 
209     return tim->CNT;
210 }
211 
n32_timer_ctrl(rt_hwtimer_t * timer,rt_uint32_t cmd,void * arg)212 static rt_err_t n32_timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
213 {
214     RCC_ClocksType RCC_ClockStruct;
215     TIM_Module *tim = RT_NULL;
216     rt_err_t result = RT_EOK;
217 
218     RT_ASSERT(timer != RT_NULL);
219     RT_ASSERT(arg != RT_NULL);
220 
221     tim = (TIM_Module *)timer->parent.user_data;
222 
223     switch (cmd)
224     {
225     case HWTIMER_CTRL_FREQ_SET:
226     {
227         rt_uint32_t input_clock;
228         rt_uint32_t freq;
229         rt_uint16_t val;
230 
231         /* set timer frequence */
232         freq = *((rt_uint32_t *)arg);
233 
234         /* time init */
235         RCC_GetClocksFreqValue(&RCC_ClockStruct);
236         if (1 == (RCC_ClockStruct.HclkFreq / RCC_ClockStruct.Pclk1Freq))
237             input_clock = RCC_ClockStruct.Pclk1Freq;
238         else
239             input_clock = RCC_ClockStruct.Pclk1Freq * 2;
240         val = input_clock / freq;
241         TIM_ConfigPrescaler(tim, val - 1, TIM_PSC_RELOAD_MODE_IMMEDIATE);
242     }
243     break;
244     default:
245     {
246         result = -RT_ENOSYS;
247     }
248     break;
249     }
250 
251     return result;
252 }
253 
254 static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
255 static const struct rt_hwtimer_ops _ops =
256 {
257     .init      = n32_timer_init,
258     .start     = n32_timer_start,
259     .stop      = n32_timer_stop,
260     .count_get = n32_timer_counter_get,
261     .control   = n32_timer_ctrl,
262 };
263 
264 #ifdef BSP_USING_HWTIM2
TIM2_IRQHandler(void)265 void TIM2_IRQHandler(void)
266 {
267     /* enter interrupt */
268     rt_interrupt_enter();
269 
270     if (TIM_GetIntStatus(TIM2, TIM_INT_UPDATE) == SET)
271     {
272 
273         rt_device_hwtimer_isr(&n32_hwtimer_obj[TIM2_INDEX].time_device);
274         TIM_ClrIntPendingBit(TIM2, TIM_INT_UPDATE);
275 
276     }
277     /* leave interrupt */
278     rt_interrupt_leave();
279 }
280 #endif
281 
282 #ifdef BSP_USING_HWTIM3
TIM3_IRQHandler(void)283 void TIM3_IRQHandler(void)
284 {
285     /* enter interrupt */
286     rt_interrupt_enter();
287 
288     if (TIM_GetIntStatus(TIM3, TIM_INT_UPDATE) == SET)
289     {
290 
291         rt_device_hwtimer_isr(&n32_hwtimer_obj[TIM3_INDEX].time_device);
292         TIM_ClrIntPendingBit(TIM3, TIM_INT_UPDATE);
293 
294     }
295     /* leave interrupt */
296     rt_interrupt_leave();
297 }
298 #endif
299 
300 #ifdef BSP_USING_HWTIM4
TIM4_IRQHandler(void)301 void TIM4_IRQHandler(void)
302 {
303     /* enter interrupt */
304     rt_interrupt_enter();
305 
306     if (TIM_GetIntStatus(TIM4, TIM_INT_UPDATE) == SET)
307     {
308 
309         rt_device_hwtimer_isr(&n32_hwtimer_obj[TIM4_INDEX].time_device);
310         TIM_ClrIntPendingBit(TIM4, TIM_INT_UPDATE);
311 
312     }
313     /* leave interrupt */
314     rt_interrupt_leave();
315 }
316 #endif
317 
318 #ifdef BSP_USING_HWTIM5
TIM5_IRQHandler(void)319 void TIM5_IRQHandler(void)
320 {
321     /* enter interrupt */
322     rt_interrupt_enter();
323 
324     if (TIM_GetIntStatus(TIM5, TIM_INT_UPDATE) == SET)
325     {
326 
327         rt_device_hwtimer_isr(&n32_hwtimer_obj[TIM5_INDEX].time_device);
328         TIM_ClrIntPendingBit(TIM5, TIM_INT_UPDATE);
329 
330     }
331     /* leave interrupt */
332     rt_interrupt_leave();
333 }
334 #endif
335 
336 #ifdef BSP_USING_HWTIM6
TIM6_IRQHandler(void)337 void TIM6_IRQHandler(void)
338 {
339     /* enter interrupt */
340     rt_interrupt_enter();
341 
342     if (TIM_GetIntStatus(TIM6, TIM_INT_UPDATE) == SET)
343     {
344 
345         rt_device_hwtimer_isr(&n32_hwtimer_obj[TIM6_INDEX].time_device);
346         TIM_ClrIntPendingBit(TIM6, TIM_INT_UPDATE);
347 
348     }
349     /* leave interrupt */
350     rt_interrupt_leave();
351 }
352 #endif
353 
354 #ifdef BSP_USING_HWTIM7
TIM7_IRQHandler(void)355 void TIM7_IRQHandler(void)
356 {
357     /* enter interrupt */
358     rt_interrupt_enter();
359 
360     if (TIM_GetIntStatus(TIM7, TIM_INT_UPDATE) == SET)
361     {
362 
363         rt_device_hwtimer_isr(&n32_hwtimer_obj[TIM7_INDEX].time_device);
364         TIM_ClrIntPendingBit(TIM7, TIM_INT_UPDATE);
365 
366     }
367     /* leave interrupt */
368     rt_interrupt_leave();
369 }
370 #endif
371 
rt_hw_hwtimer_init(void)372 static int rt_hw_hwtimer_init(void)
373 {
374     int i = 0;
375     int result = RT_EOK;
376 
377     for (i = 0; i < sizeof(n32_hwtimer_obj) / sizeof(n32_hwtimer_obj[0]); i++)
378     {
379         n32_hwtimer_obj[i].time_device.info = &_info;
380         n32_hwtimer_obj[i].time_device.ops  = &_ops;
381         if (rt_device_hwtimer_register(&n32_hwtimer_obj[i].time_device, n32_hwtimer_obj[i].name, n32_hwtimer_obj[i].tim_handle) == RT_EOK)
382         {
383             LOG_D("%s register success", n32_hwtimer_obj[i].name);
384         }
385         else
386         {
387             LOG_E("%s register failed", n32_hwtimer_obj[i].name);
388             result = -RT_ERROR;
389         }
390     }
391 
392     return result;
393 }
394 INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
395 
396 #endif /* BSP_USING_HWTIMER */
397 
398 
399 
400 
401 
402 
403 
404