1 /*
2 * Copyright (c) 2016-2017 ARM Limited
3 * Copyright (c) 2023 Nuvoton Technology Corp.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /**
19 * \file timer_cmsdk.c
20 * \brief Generic driver for CMSDK APB Timers.
21 * The timer is a 32-bit down-counter with the following features:
22 * - optional programmable external clock source
23 * - programmable interrupt source, triggered if counter reaches 0
24 * - automatic reload if counter reaches 0
25 */
26
27 #include "timer_cmsdk.h"
28 #include "NuMicro.h"
29
30 /** Setter bit manipulation macro */
31 #define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX)))
32 /** Clearing bit manipulation macro */
33 #define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX)))
34 /** Getter bit manipulation macro */
35 #define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX))))
36
37 /**
38 * \brief INTSTATUS/INTCLEAR register bit definitions
39 *
40 */
41 enum interrupt_reg_bits_t{
42 INTERRUPT_REG_ENUM_STATUS_AND_CLEAR_INDEX = 0
43 };
44
cmsdk_timer_init(const struct cmsdk_timer_dev_t * dev)45 void cmsdk_timer_init(const struct cmsdk_timer_dev_t* dev)
46 {
47 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
48
49 if (dev->data->is_initialized == 0) {
50
51 NVIC_EnableIRQ(TMR0_IRQn);
52 NVIC_EnableIRQ(TMR2_IRQn);
53
54 TIMER_Open(tmr, TIMER_PERIODIC_MODE, 1000);
55 dev->data->is_initialized = 1;
56 }
57 }
58
cmsdk_timer_is_initialized(const struct cmsdk_timer_dev_t * dev)59 bool cmsdk_timer_is_initialized(const struct cmsdk_timer_dev_t* dev)
60 {
61 return dev->data->is_initialized;
62 }
63
cmsdk_timer_enable_external_input(const struct cmsdk_timer_dev_t * dev)64 void cmsdk_timer_enable_external_input(const struct cmsdk_timer_dev_t* dev)
65 {
66 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
67 TIMER_EnableCapture(tmr, TIMER_CAPTURE_COUNTER_RESET_MODE, TIMER_CAPTURE_EVENT_RISING);
68 }
69
cmsdk_timer_disable_external_input(const struct cmsdk_timer_dev_t * dev)70 void cmsdk_timer_disable_external_input(const struct cmsdk_timer_dev_t* dev)
71 {
72 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
73 TIMER_DisableCapture(tmr);
74 }
75
cmsdk_timer_is_external_input_enabled(const struct cmsdk_timer_dev_t * dev)76 bool cmsdk_timer_is_external_input_enabled(const struct cmsdk_timer_dev_t* dev)
77 {
78 return ((((TIMER_T*)dev->cfg->base)->EXTCTL & TIMER_EXTCTL_CAPEN_Msk) != 0);
79 }
80
cmsdk_timer_set_clock_to_internal(const struct cmsdk_timer_dev_t * dev)81 void cmsdk_timer_set_clock_to_internal(const struct cmsdk_timer_dev_t* dev)
82 {
83 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
84 TIMER_DisableEventCounter(tmr);
85 }
86
cmsdk_timer_set_clock_to_external(const struct cmsdk_timer_dev_t * dev)87 void cmsdk_timer_set_clock_to_external(const struct cmsdk_timer_dev_t* dev)
88 {
89 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
90 TIMER_EnableEventCounter(tmr, TIMER_COUNTER_EVENT_RISING);
91 }
92
cmsdk_timer_is_clock_external(const struct cmsdk_timer_dev_t * dev)93 bool cmsdk_timer_is_clock_external(const struct cmsdk_timer_dev_t* dev)
94 {
95 return ((((TIMER_T *)dev->cfg->base)->CTL & TIMER_CTL_EXTCNTEN_Msk) != 0);
96 }
97
cmsdk_timer_enable(const struct cmsdk_timer_dev_t * dev)98 void cmsdk_timer_enable(const struct cmsdk_timer_dev_t* dev)
99 {
100 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
101 TIMER_Start(tmr);
102 }
103
cmsdk_timer_disable(const struct cmsdk_timer_dev_t * dev)104 void cmsdk_timer_disable(const struct cmsdk_timer_dev_t* dev)
105 {
106 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
107 TIMER_Stop(tmr);
108 }
109
cmsdk_timer_is_enabled(const struct cmsdk_timer_dev_t * dev)110 bool cmsdk_timer_is_enabled(const struct cmsdk_timer_dev_t* dev)
111 {
112 return ((((TIMER_T *)dev->cfg->base)->CTL & TIMER_CTL_CNTEN_Msk) != 0);
113 }
114
cmsdk_timer_enable_interrupt(const struct cmsdk_timer_dev_t * dev)115 void cmsdk_timer_enable_interrupt(const struct cmsdk_timer_dev_t* dev)
116 {
117 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
118 TIMER_EnableInt(tmr);
119 }
120
cmsdk_timer_disable_interrupt(const struct cmsdk_timer_dev_t * dev)121 void cmsdk_timer_disable_interrupt(const struct cmsdk_timer_dev_t* dev)
122 {
123 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
124 TIMER_DisableInt(tmr);
125 }
126
cmsdk_timer_is_interrupt_enabled(const struct cmsdk_timer_dev_t * dev)127 bool cmsdk_timer_is_interrupt_enabled(const struct cmsdk_timer_dev_t* dev)
128 {
129 return ((((TIMER_T *)dev->cfg->base)->CTL & TIMER_CTL_INTEN_Msk) != 0);
130 }
131
cmsdk_timer_is_interrupt_active(const struct cmsdk_timer_dev_t * dev)132 bool cmsdk_timer_is_interrupt_active(const struct cmsdk_timer_dev_t* dev)
133 {
134 return ((((TIMER_T *)dev->cfg->base)->INTSTS & TIMER_INTSTS_TIF_Msk) != 0);
135 }
136
cmsdk_timer_clear_interrupt(const struct cmsdk_timer_dev_t * dev)137 void cmsdk_timer_clear_interrupt(const struct cmsdk_timer_dev_t* dev)
138 {
139 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
140 TIMER_ClearIntFlag(tmr);
141 }
142
cmsdk_timer_get_current_value(const struct cmsdk_timer_dev_t * dev)143 uint32_t cmsdk_timer_get_current_value(const struct cmsdk_timer_dev_t* dev)
144 {
145 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
146 return TIMER_GetCounter(tmr);
147 }
148
cmsdk_timer_set_reload_value(const struct cmsdk_timer_dev_t * dev,uint32_t reload)149 void cmsdk_timer_set_reload_value(const struct cmsdk_timer_dev_t* dev,
150 uint32_t reload)
151 {
152 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
153
154 /* reload value must > 1 */
155 if(reload < 2)
156 {
157 reload = 2;
158 }
159
160 TIMER_SET_CMP_VALUE(tmr, reload);
161 }
162
cmsdk_timer_reset(const struct cmsdk_timer_dev_t * dev)163 void cmsdk_timer_reset(const struct cmsdk_timer_dev_t* dev)
164 {
165 TIMER_T* tmr = (TIMER_T*)dev->cfg->base;
166 TIMER_ResetCounter(tmr);
167 }
168
cmsdk_timer_get_reload_value(const struct cmsdk_timer_dev_t * dev)169 uint32_t cmsdk_timer_get_reload_value(const struct cmsdk_timer_dev_t* dev)
170 {
171 return ((TIMER_T*)dev->cfg->base)->CMP;
172 }
173
cmsdk_timer_get_elapsed_value(const struct cmsdk_timer_dev_t * dev)174 uint32_t cmsdk_timer_get_elapsed_value(const struct cmsdk_timer_dev_t* dev)
175 {
176 TIMER_T *tmr;
177
178 tmr = (TIMER_T*)dev->cfg->base;
179 return tmr->CMP - tmr->CNT;
180 }
181