1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_GPTMR_DRV_H
9 #define HPM_GPTMR_DRV_H
10 #include "hpm_common.h"
11 #include "hpm_gptmr_regs.h"
12
13 /**
14 * @brief GPTMR driver APIs
15 * @defgroup gptmr_interface GPTMR driver APIs
16 * @ingroup io_interfaces
17 * @{
18 */
19
20 /**
21 * @brief GPTMR channel IRQ mask
22 */
23 #define GPTMR_CH_CMP_IRQ_MASK(ch, cmp) (1 << (ch * 4 + 2 + cmp))
24 #define GPTMR_CH_CAP_IRQ_MASK(ch) (1 << (ch * 4 + 1))
25 #define GPTMR_CH_RLD_IRQ_MASK(ch) (1 << (ch * 4))
26
27 /**
28 * @brief GPTMR channel status
29 */
30 #define GPTMR_CH_CMP_STAT_MASK(ch, cmp) (1 << (ch * 4 + 2 + cmp))
31 #define GPTMR_CH_CAP_STAT_MASK(ch) (1 << (ch * 4 + 1))
32 #define GPTMR_CH_RLD_STAT_MASK(ch) (1 << (ch * 4))
33
34 /**
35 * @brief GPTMR one channel support output comparator count
36 */
37 #define GPTMR_CH_CMP_COUNT (2U)
38
39 /**
40 * @brief GPTMR synci valid edge
41 */
42 typedef enum gptmr_synci_edge {
43 gptmr_synci_edge_none = 0,
44 gptmr_synci_edge_falling = GPTMR_CHANNEL_CR_SYNCIFEN_MASK,
45 gptmr_synci_edge_rising = GPTMR_CHANNEL_CR_SYNCIREN_MASK,
46 gptmr_synci_edge_both = gptmr_synci_edge_falling | gptmr_synci_edge_rising,
47 } gptmr_synci_edge_t;
48
49 /**
50 * @brief GPTMR work mode
51 */
52 typedef enum gptmr_work_mode {
53 gptmr_work_mode_no_capture = 0,
54 gptmr_work_mode_capture_at_rising_edge = 1,
55 gptmr_work_mode_capture_at_falling_edge = 2,
56 gptmr_work_mode_capture_at_both_edge = 3,
57 gptmr_work_mode_measure_width = 4,
58 } gptmr_work_mode_t;
59
60 /**
61 * @brief GPTMR DMA request event
62 */
63 typedef enum gptmr_dma_request_event {
64 gptmr_dma_request_on_reload = 0,
65 gptmr_dma_request_on_input_signal_toggle = 1,
66 gptmr_dma_request_on_cmp0 = 2,
67 gptmr_dma_request_on_cmp1 = 3,
68 gptmr_dma_request_disabled = 0xFF,
69 } gptmr_dma_request_event_t;
70
71 /**
72 * @brief GPTMR counter type
73 */
74 typedef enum gptmr_counter_type {
75 gptmr_counter_type_rising_edge,
76 gptmr_counter_type_falling_edge,
77 gptmr_counter_type_measured_period,
78 gptmr_counter_type_measured_duty_cycle,
79 gptmr_counter_type_normal,
80 } gptmr_counter_type_t;
81
82 /**
83 * @brief GPTMR channel config
84 */
85 typedef struct gptmr_channel_config {
86 gptmr_work_mode_t mode;
87 gptmr_dma_request_event_t dma_request_event;
88 gptmr_synci_edge_t synci_edge;
89 uint32_t cmp[GPTMR_CH_CMP_COUNT];
90 uint32_t reload;
91 bool cmp_initial_polarity_high;
92 bool enable_cmp_output;
93 bool enable_sync_follow_previous_channel;
94 bool enable_software_sync;
95 bool debug_mode;
96 } gptmr_channel_config_t;
97
98 #ifdef __cplusplus
99 extern "C" {
100 #endif
101
102 /**
103 * @brief gptmr channel enable
104 *
105 * @param [in] ptr GPTMR base address
106 * @param [in] ch_index channel index
107 * @param [in] enable
108 * @arg true: enable
109 * @arg false: disable
110 */
gptmr_channel_enable(GPTMR_Type * ptr,uint8_t ch_index,bool enable)111 static inline void gptmr_channel_enable(GPTMR_Type *ptr, uint8_t ch_index, bool enable)
112 {
113 ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR
114 & ~(GPTMR_CHANNEL_CR_CNTRST_MASK | GPTMR_CHANNEL_CR_CMPEN_MASK))
115 | GPTMR_CHANNEL_CR_CMPEN_SET(enable);
116 }
117
118 /**
119 * @brief gptmr channel reset counter
120 *
121 * @param [in] ptr GPTMR base address
122 * @param [in] ch_index channel index
123 */
gptmr_channel_reset_count(GPTMR_Type * ptr,uint8_t ch_index)124 static inline void gptmr_channel_reset_count(GPTMR_Type *ptr, uint8_t ch_index)
125 {
126 ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_CNTRST_MASK;
127 ptr->CHANNEL[ch_index].CR &= ~GPTMR_CHANNEL_CR_CNTRST_MASK;
128 }
129
130 /**
131 * @brief gptmr channel update counter
132 *
133 * @param [in] ptr GPTMR base address
134 * @param [in] ch_index channel index
135 * @param [in] value updated vaue
136 */
gptmr_channel_update_count(GPTMR_Type * ptr,uint8_t ch_index,uint32_t value)137 static inline void gptmr_channel_update_count(GPTMR_Type *ptr,
138 uint8_t ch_index,
139 uint32_t value)
140 {
141 ptr->CHANNEL[ch_index].CNTUPTVAL = GPTMR_CHANNEL_CNTUPTVAL_CNTUPTVAL_SET(value);
142 ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_CNTUPT_MASK;
143 }
144
145 /**
146 * @brief gptmr channel slect synci valid edge
147 *
148 * @param [in] ptr GPTMR base address
149 * @param [in] ch_index channel index
150 * @param [in] edge gptmr_synci_edge_t
151 */
gptmr_channel_select_synci_valid_edge(GPTMR_Type * ptr,uint8_t ch_index,gptmr_synci_edge_t edge)152 static inline void gptmr_channel_select_synci_valid_edge(GPTMR_Type *ptr,
153 uint8_t ch_index,
154 gptmr_synci_edge_t edge)
155 {
156 ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR
157 & ~(GPTMR_CHANNEL_CR_SYNCIFEN_MASK
158 | GPTMR_CHANNEL_CR_SYNCIREN_MASK)) | edge;
159 }
160
161 /**
162 * @brief gptmr channel enable dma request
163 *
164 * @param [in] ptr GPTMR base address
165 * @param [in] ch_index channel index
166 * @param [in] enable
167 * @arg true: enable
168 * @arg false: disable
169 */
gptmr_channel_enable_dma_request(GPTMR_Type * ptr,uint8_t ch_index,bool enable)170 static inline void gptmr_channel_enable_dma_request(GPTMR_Type *ptr,
171 uint8_t ch_index,
172 bool enable)
173 {
174 ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR
175 & ~(GPTMR_CHANNEL_CR_DMAEN_MASK)) | GPTMR_CHANNEL_CR_DMAEN_SET(enable);
176 }
177
178 /**
179 * @brief gptmr channel get counter value
180 *
181 * @param [in] ptr GPTMR base address
182 * @param [in] ch_index channel index
183 * @param [in] capture gptmr_counter_type_t
184 */
gptmr_channel_get_counter(GPTMR_Type * ptr,uint8_t ch_index,gptmr_counter_type_t capture)185 static inline uint32_t gptmr_channel_get_counter(GPTMR_Type *ptr,
186 uint8_t ch_index,
187 gptmr_counter_type_t capture)
188 {
189 uint32_t value;
190 switch (capture) {
191 case gptmr_counter_type_rising_edge:
192 value = (ptr->CHANNEL[ch_index].CAPPOS & GPTMR_CHANNEL_CAPPOS_CAPPOS_MASK) >> GPTMR_CHANNEL_CAPPOS_CAPPOS_SHIFT;
193 break;
194 case gptmr_counter_type_falling_edge:
195 value = (ptr->CHANNEL[ch_index].CAPNEG & GPTMR_CHANNEL_CAPNEG_CAPNEG_MASK) >> GPTMR_CHANNEL_CAPNEG_CAPNEG_SHIFT;
196 break;
197 case gptmr_counter_type_measured_period:
198 value = (ptr->CHANNEL[ch_index].CAPPRD & GPTMR_CHANNEL_CAPPRD_CAPPRD_MASK) >> GPTMR_CHANNEL_CAPPRD_CAPPRD_SHIFT;
199 break;
200 case gptmr_counter_type_measured_duty_cycle:
201 value = (ptr->CHANNEL[ch_index].CAPDTY & GPTMR_CHANNEL_CAPDTY_MEAS_HIGH_MASK) >> GPTMR_CHANNEL_CAPDTY_MEAS_HIGH_SHIFT;
202 break;
203 default:
204 value = (ptr->CHANNEL[ch_index].CNT & GPTMR_CHANNEL_CNT_COUNTER_MASK) >> GPTMR_CHANNEL_CNT_COUNTER_SHIFT;
205 break;
206 }
207 return value;
208 }
209
210 /**
211 * @brief gptmr trigger channel software sync
212 *
213 * @param [in] ptr GPTMR base address
214 * @param [in] ch_index_mask channel index mask
215 */
gptmr_trigger_channel_software_sync(GPTMR_Type * ptr,uint32_t ch_index_mask)216 static inline void gptmr_trigger_channel_software_sync(GPTMR_Type *ptr, uint32_t ch_index_mask)
217 {
218 ptr->GCR = ch_index_mask;
219 }
220
221 /**
222 * @brief gptmr enable irq
223 *
224 * @param [in] ptr GPTMR base address
225 * @param [in] irq_mask irq mask
226 */
gptmr_enable_irq(GPTMR_Type * ptr,uint32_t irq_mask)227 static inline void gptmr_enable_irq(GPTMR_Type *ptr, uint32_t irq_mask)
228 {
229 ptr->IRQEN |= irq_mask;
230 }
231
232 /**
233 * @brief gptmr disable irq
234 *
235 * @param [in] ptr GPTMR base address
236 * @param [in] irq_mask irq mask
237 */
gptmr_disable_irq(GPTMR_Type * ptr,uint32_t irq_mask)238 static inline void gptmr_disable_irq(GPTMR_Type *ptr, uint32_t irq_mask)
239 {
240 ptr->IRQEN &= ~irq_mask;
241 }
242
243 /**
244 * @brief gptmr check status
245 *
246 * @param [in] ptr GPTMR base address
247 * @param [in] mask channel flag mask
248 */
gptmr_check_status(GPTMR_Type * ptr,uint32_t mask)249 static inline bool gptmr_check_status(GPTMR_Type *ptr, uint32_t mask)
250 {
251 return (ptr->SR & mask) == mask;
252 }
253
254 /**
255 * @brief gptmr clear status
256 *
257 * @param [in] ptr GPTMR base address
258 * @param [in] mask channel flag mask
259 */
gptmr_clear_status(GPTMR_Type * ptr,uint32_t mask)260 static inline void gptmr_clear_status(GPTMR_Type *ptr, uint32_t mask)
261 {
262 ptr->SR |= mask;
263 }
264
265 /**
266 * @brief gptmr get status
267 *
268 * @param [in] ptr GPTMR base address
269 * @retval SR register value
270 */
gptmr_get_status(GPTMR_Type * ptr)271 static inline uint32_t gptmr_get_status(GPTMR_Type *ptr)
272 {
273 return ptr->SR;
274 }
275
276 /**
277 * @brief gptmr channel start counter
278 *
279 * @param [in] ptr GPTMR base address
280 * @param [in] ch_index channel index
281 */
gptmr_start_counter(GPTMR_Type * ptr,uint8_t ch_index)282 static inline void gptmr_start_counter(GPTMR_Type *ptr, uint8_t ch_index)
283 {
284 ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_CEN_MASK;
285 }
286
287 /**
288 * @brief gptmr channel stop counter
289 *
290 * @param [in] ptr GPTMR base address
291 * @param [in] ch_index channel index
292 */
gptmr_stop_counter(GPTMR_Type * ptr,uint8_t ch_index)293 static inline void gptmr_stop_counter(GPTMR_Type *ptr, uint8_t ch_index)
294 {
295 ptr->CHANNEL[ch_index].CR &= ~GPTMR_CHANNEL_CR_CEN_MASK;
296 }
297
298 /**
299 * @brief gptmr channel update comparator
300 *
301 * @param [in] ptr GPTMR base address
302 * @param [in] ch_index channel index
303 * @param [in] cmp_index comparator index
304 * @param [in] cmp comparator value
305 */
gptmr_update_cmp(GPTMR_Type * ptr,uint8_t ch_index,uint8_t cmp_index,uint32_t cmp)306 static inline void gptmr_update_cmp(GPTMR_Type *ptr, uint8_t ch_index, uint8_t cmp_index, uint32_t cmp)
307 {
308 ptr->CHANNEL[ch_index].CMP[cmp_index] = GPTMR_CMP_CMP_SET(cmp);
309 }
310
311 /**
312 * @brief gptmr channel update reload
313 *
314 * @param [in] ptr GPTMR base address
315 * @param [in] ch_index channel index
316 * @param [in] reload reload value
317 */
gptmr_channel_config_update_reload(GPTMR_Type * ptr,uint8_t ch_index,uint32_t reload)318 static inline void gptmr_channel_config_update_reload(GPTMR_Type *ptr, uint8_t ch_index, uint32_t reload)
319 {
320 ptr->CHANNEL[ch_index].RLD = GPTMR_CHANNEL_RLD_RLD_SET(reload - 1);
321 }
322
323 /**
324 * @brief gptmr channel config
325 *
326 * @param [in] ptr GPTMR base address
327 * @param [in] ch_index channel index
328 * @param [in] config gptmr_channel_config_t
329 * @param [in] enable
330 * @arg true: enable
331 * @arg false: disable
332 *
333 * @retval hpm_stat_t status_invalid_argument or status_success
334 */
335 hpm_stat_t gptmr_channel_config(GPTMR_Type *ptr,
336 uint8_t ch_index,
337 gptmr_channel_config_t *config,
338 bool enable);
339
340 /**
341 * @brief gptmr channel get default config
342 *
343 * @param [in] ptr GPTMR base address
344 * @param [out] config gptmr_channel_config_t
345 */
346 void gptmr_channel_get_default_config(GPTMR_Type *ptr, gptmr_channel_config_t *config);
347
348 /**
349 * @}
350 */
351
352 #ifdef __cplusplus
353 }
354 #endif
355
356 #endif /* HPM_GPTMR_DRV_H */
357