1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author         Notes
8  * 2019-07-29     zdzn           first version
9  */
10 
11 #include "drv_timer.h"
12 #include "interrupt.h"
13 #include "raspi.h"
14 
15 #ifdef BSP_USING_SYSTIMER
16 
raspi_systimer_init(rt_hwtimer_t * hwtimer,rt_uint32_t state)17 static void raspi_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state)
18 {
19     if (state == 0)
20         hwtimer->ops->stop(hwtimer);
21 }
22 
raspi_systimer_start(rt_hwtimer_t * hwtimer,rt_uint32_t cnt,rt_hwtimer_mode_t mode)23 static rt_err_t raspi_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
24 {
25     rt_err_t result = RT_EOK;
26     rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
27     int timer_id = timer->timer_id;
28 
29     if (mode == HWTIMER_MODE_PERIOD)
30         timer->cnt = cnt;
31     else
32         timer->cnt = 0;
33 
34     __sync_synchronize();
35     if (timer_id == 1)
36     {
37         rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
38         STIMER_C1 = STIMER_CLO + cnt;
39     }
40     else if (timer_id == 3)
41     {
42         rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
43         STIMER_C3 = STIMER_CLO + cnt;
44     }
45     else
46         result = -RT_ERROR;
47 
48     __sync_synchronize();
49 
50     return result;
51 }
52 
raspi_systimer_stop(rt_hwtimer_t * hwtimer)53 static void raspi_systimer_stop(rt_hwtimer_t *hwtimer)
54 {
55     rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
56     int timer_id = timer->timer_id;
57     if (timer_id == 1)
58         rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_1);
59     else if (timer_id == 3)
60         rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_3);
61 
62 }
63 
raspi_systimer_ctrl(rt_hwtimer_t * timer,rt_uint32_t cmd,void * arg)64 static rt_err_t raspi_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
65 {
66     /* The frequency value is an immutable value. */
67     if (cmd == HWTIMER_CTRL_FREQ_SET)
68     {
69         return RT_EOK;
70     }
71     else
72     {
73         return -RT_ENOSYS;
74     }
75 }
76 
77 
rt_device_systimer_isr(int vector,void * param)78 void rt_device_systimer_isr(int vector, void *param)
79 {
80 
81     rt_hwtimer_t *hwtimer = (rt_hwtimer_t *) param;
82     rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
83     RT_ASSERT(timer != RT_NULL);
84 
85     int timer_id = timer->timer_id;
86 
87     __sync_synchronize();
88     if (timer_id == 1)
89     {
90         STIMER_CS = 0x2;
91         STIMER_C1 = STIMER_CLO + timer->cnt;
92     }
93     else if (timer_id == 3)
94     {
95         STIMER_CS = 0x8;
96         STIMER_C3 = STIMER_CLO + timer->cnt;
97     }
98     __sync_synchronize();
99 
100     rt_device_hwtimer_isr(hwtimer);
101 }
102 
103 #ifdef RT_USING_SYSTIMER1
104 static struct rt_hwtimer_device _hwtimer1;
105 static rt_systimer_t _systimer1;
106 #endif
107 
108 #ifdef RT_USING_SYSTIMER3
109 static struct rt_hwtimer_device _hwtimer3;
110 static rt_systimer_t _systimer3;
111 #endif
112 
113 const static struct rt_hwtimer_ops systimer_ops =
114 {
115     raspi_systimer_init,
116     raspi_systimer_start,
117     raspi_systimer_stop,
118     RT_NULL,
119     raspi_systimer_ctrl
120 };
121 
122 static const struct rt_hwtimer_info _info =
123 {
124     1000000,            /* the maxinum count frequency can be set */
125     1000000,            /* the maxinum count frequency can be set */
126     0xFFFFFFFF,         /* the maximum counter value */
127     HWTIMER_CNTMODE_UP  /* count mode (inc/dec) */
128 };
129 
130 #endif
131 
rt_hw_systimer_init(void)132 int rt_hw_systimer_init(void)
133 {
134 
135 #ifdef BSP_USING_SYSTIMER
136 
137 #ifdef RT_USING_SYSTIMER1
138     _systimer1.timer_id =1;
139     _hwtimer1.ops = &systimer_ops;
140     _hwtimer1.info = &_info;
141     rt_device_hwtimer_register(&_hwtimer1, "timer1",&_systimer1);
142     rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_1, rt_device_systimer_isr, &_hwtimer1, "systimer1");
143     rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
144 #endif
145 
146 #ifdef RT_USING_SYSTIMER3
147     _systimer3.timer_id =3;
148     _hwtimer3.ops = &systimer_ops;
149     _hwtimer3.info = &_info;
150     rt_device_hwtimer_register(&_hwtimer3, "timer3",&_systimer3);
151     rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_3, rt_device_systimer_isr, &_hwtimer3, "systimer3");
152     rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
153 #endif
154 
155 #endif
156 
157     return 0;
158 }
159 INIT_DEVICE_EXPORT(rt_hw_systimer_init);
160