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