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