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