• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 channel swsynct mask
36  */
37 #define GPTMR_CH_GCR_SWSYNCT_MASK(ch) (1 << ch)
38 
39 /**
40  * @brief GPTMR one channel support output comparator count
41  */
42 #define GPTMR_CH_CMP_COUNT (2U)
43 
44 /**
45  * @brief GPTMR synci valid edge
46  */
47 typedef enum gptmr_synci_edge {
48     gptmr_synci_edge_none = 0,
49     gptmr_synci_edge_falling = GPTMR_CHANNEL_CR_SYNCIFEN_MASK,
50     gptmr_synci_edge_rising = GPTMR_CHANNEL_CR_SYNCIREN_MASK,
51     gptmr_synci_edge_both = gptmr_synci_edge_falling | gptmr_synci_edge_rising,
52 } gptmr_synci_edge_t;
53 
54 /**
55  * @brief GPTMR work mode
56  */
57 typedef enum gptmr_work_mode {
58     gptmr_work_mode_no_capture = 0,
59     gptmr_work_mode_capture_at_rising_edge = 1,
60     gptmr_work_mode_capture_at_falling_edge = 2,
61     gptmr_work_mode_capture_at_both_edge = 3,
62     gptmr_work_mode_measure_width = 4,
63 } gptmr_work_mode_t;
64 
65 /**
66  * @brief GPTMR DMA request event
67  */
68 typedef enum gptmr_dma_request_event {
69     gptmr_dma_request_on_cmp0 = 0,
70     gptmr_dma_request_on_cmp1 = 1,
71     gptmr_dma_request_on_input_signal_toggle = 2,
72     gptmr_dma_request_on_reload = 3,
73     gptmr_dma_request_disabled = 0xFF,
74 } gptmr_dma_request_event_t;
75 
76 /**
77  * @brief GPTMR counter type
78  */
79 typedef enum gptmr_counter_type {
80     gptmr_counter_type_rising_edge,
81     gptmr_counter_type_falling_edge,
82     gptmr_counter_type_measured_period,
83     gptmr_counter_type_measured_duty_cycle,
84     gptmr_counter_type_normal,
85 } gptmr_counter_type_t;
86 
87 /**
88  * @brief GPTMR channel config
89  */
90 typedef struct gptmr_channel_config {
91     gptmr_work_mode_t mode;
92     gptmr_dma_request_event_t dma_request_event;
93     gptmr_synci_edge_t synci_edge;
94     uint32_t cmp[GPTMR_CH_CMP_COUNT];
95     uint32_t reload;
96     bool cmp_initial_polarity_high;
97     bool enable_cmp_output;
98     bool enable_sync_follow_previous_channel;
99     bool enable_software_sync;
100     bool debug_mode;
101 } gptmr_channel_config_t;
102 
103 #ifdef __cplusplus
104 extern "C" {
105 #endif
106 
107 /**
108  * @brief gptmr channel enable
109  *
110  * @param [in] ptr GPTMR base address
111  * @param [in] ch_index channel index
112  * @param [in] enable
113  *  @arg true: enable
114  *  @arg false: disable
115  */
gptmr_channel_enable(GPTMR_Type * ptr,uint8_t ch_index,bool enable)116 static inline void gptmr_channel_enable(GPTMR_Type *ptr, uint8_t ch_index, bool enable)
117 {
118     ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR
119          & ~(GPTMR_CHANNEL_CR_CNTRST_MASK | GPTMR_CHANNEL_CR_CMPEN_MASK))
120         | GPTMR_CHANNEL_CR_CMPEN_SET(enable);
121 }
122 
123 /**
124  * @brief gptmr channel reset counter
125  *
126  * @param [in] ptr GPTMR base address
127  * @param [in] ch_index channel index
128  */
gptmr_channel_reset_count(GPTMR_Type * ptr,uint8_t ch_index)129 static inline void gptmr_channel_reset_count(GPTMR_Type *ptr, uint8_t ch_index)
130 {
131     ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_CNTRST_MASK;
132     ptr->CHANNEL[ch_index].CR &= ~GPTMR_CHANNEL_CR_CNTRST_MASK;
133 }
134 
135 /**
136  * @brief gptmr channel update counter
137  *
138  * @param [in] ptr GPTMR base address
139  * @param [in] ch_index channel index
140  * @param [in] value updated vaue
141  */
gptmr_channel_update_count(GPTMR_Type * ptr,uint8_t ch_index,uint32_t value)142 static inline void gptmr_channel_update_count(GPTMR_Type *ptr,
143                                              uint8_t ch_index,
144                                              uint32_t value)
145 {
146     if (value > 0) {
147         value--;
148     }
149     ptr->CHANNEL[ch_index].CNTUPTVAL = GPTMR_CHANNEL_CNTUPTVAL_CNTUPTVAL_SET(value);
150     ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_CNTUPT_MASK;
151 }
152 
153 /**
154  * @brief gptmr channel slect synci valid edge
155  *
156  * @param [in] ptr GPTMR base address
157  * @param [in] ch_index channel index
158  * @param [in] edge gptmr_synci_edge_t
159  */
gptmr_channel_select_synci_valid_edge(GPTMR_Type * ptr,uint8_t ch_index,gptmr_synci_edge_t edge)160 static inline void gptmr_channel_select_synci_valid_edge(GPTMR_Type *ptr,
161                                                         uint8_t ch_index,
162                                                         gptmr_synci_edge_t edge)
163 {
164     ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR
165             & ~(GPTMR_CHANNEL_CR_SYNCIFEN_MASK
166               | GPTMR_CHANNEL_CR_SYNCIREN_MASK)) | edge;
167 }
168 
169 /**
170  * @brief gptmr channel enable dma request
171  *
172  * @param [in] ptr GPTMR base address
173  * @param [in] ch_index channel index
174  * @param [in] enable
175  *  @arg true: enable
176  *  @arg false: disable
177  */
gptmr_channel_enable_dma_request(GPTMR_Type * ptr,uint8_t ch_index,bool enable)178 static inline void gptmr_channel_enable_dma_request(GPTMR_Type *ptr,
179                                                    uint8_t ch_index,
180                                                    bool enable)
181 {
182     ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR
183             & ~(GPTMR_CHANNEL_CR_DMAEN_MASK)) | GPTMR_CHANNEL_CR_DMAEN_SET(enable);
184 }
185 
186 /**
187  * @brief gptmr channel get counter value
188  *
189  * @param [in] ptr GPTMR base address
190  * @param [in] ch_index channel index
191  * @param [in] capture gptmr_counter_type_t
192  */
gptmr_channel_get_counter(GPTMR_Type * ptr,uint8_t ch_index,gptmr_counter_type_t capture)193 static inline uint32_t gptmr_channel_get_counter(GPTMR_Type *ptr,
194                                                      uint8_t ch_index,
195                                                      gptmr_counter_type_t capture)
196 {
197     uint32_t value;
198     switch (capture) {
199     case gptmr_counter_type_rising_edge:
200         value = (ptr->CHANNEL[ch_index].CAPPOS & GPTMR_CHANNEL_CAPPOS_CAPPOS_MASK) >> GPTMR_CHANNEL_CAPPOS_CAPPOS_SHIFT;
201         break;
202     case gptmr_counter_type_falling_edge:
203         value = (ptr->CHANNEL[ch_index].CAPNEG & GPTMR_CHANNEL_CAPNEG_CAPNEG_MASK) >> GPTMR_CHANNEL_CAPNEG_CAPNEG_SHIFT;
204         break;
205     case gptmr_counter_type_measured_period:
206         value = (ptr->CHANNEL[ch_index].CAPPRD & GPTMR_CHANNEL_CAPPRD_CAPPRD_MASK) >> GPTMR_CHANNEL_CAPPRD_CAPPRD_SHIFT;
207         break;
208     case gptmr_counter_type_measured_duty_cycle:
209         value = (ptr->CHANNEL[ch_index].CAPDTY & GPTMR_CHANNEL_CAPDTY_MEAS_HIGH_MASK) >> GPTMR_CHANNEL_CAPDTY_MEAS_HIGH_SHIFT;
210         break;
211     default:
212         value = (ptr->CHANNEL[ch_index].CNT & GPTMR_CHANNEL_CNT_COUNTER_MASK) >> GPTMR_CHANNEL_CNT_COUNTER_SHIFT;
213         break;
214     }
215     return value;
216 }
217 
218 /**
219  * @brief gptmr trigger channel software sync
220  *
221  * @param [in] ptr GPTMR base address
222  * @param [in] ch_index_mask channel index mask
223  */
gptmr_trigger_channel_software_sync(GPTMR_Type * ptr,uint32_t ch_index_mask)224 static inline void gptmr_trigger_channel_software_sync(GPTMR_Type *ptr, uint32_t ch_index_mask)
225 {
226     ptr->GCR = ch_index_mask;
227 }
228 
229 /**
230  * @brief gptmr enable irq
231  *
232  * @param [in] ptr GPTMR base address
233  * @param [in] irq_mask irq mask
234  */
gptmr_enable_irq(GPTMR_Type * ptr,uint32_t irq_mask)235 static inline void gptmr_enable_irq(GPTMR_Type *ptr, uint32_t irq_mask)
236 {
237     ptr->IRQEN |= irq_mask;
238 }
239 
240 /**
241  * @brief gptmr disable irq
242  *
243  * @param [in] ptr GPTMR base address
244  * @param [in] irq_mask irq mask
245  */
gptmr_disable_irq(GPTMR_Type * ptr,uint32_t irq_mask)246 static inline void gptmr_disable_irq(GPTMR_Type *ptr, uint32_t irq_mask)
247 {
248     ptr->IRQEN &= ~irq_mask;
249 }
250 
251 /**
252  * @brief gptmr check status
253  *
254  * @param [in] ptr GPTMR base address
255  * @param [in] mask channel flag mask
256  */
gptmr_check_status(GPTMR_Type * ptr,uint32_t mask)257 static inline bool gptmr_check_status(GPTMR_Type *ptr, uint32_t mask)
258 {
259     return (ptr->SR & mask) == mask;
260 }
261 
262 /**
263  * @brief gptmr clear status
264  *
265  * @param [in] ptr GPTMR base address
266  * @param [in] mask channel flag mask
267  */
gptmr_clear_status(GPTMR_Type * ptr,uint32_t mask)268 static inline void gptmr_clear_status(GPTMR_Type *ptr, uint32_t mask)
269 {
270     ptr->SR = mask;
271 }
272 
273 /**
274  * @brief gptmr get status
275  *
276  * @param [in] ptr GPTMR base address
277  * @retval SR register value
278  */
gptmr_get_status(GPTMR_Type * ptr)279 static inline uint32_t gptmr_get_status(GPTMR_Type *ptr)
280 {
281     return ptr->SR;
282 }
283 
284 /**
285  * @brief gptmr channel start counter
286  *
287  * @param [in] ptr GPTMR base address
288  * @param [in] ch_index channel index
289  */
gptmr_start_counter(GPTMR_Type * ptr,uint8_t ch_index)290 static inline void gptmr_start_counter(GPTMR_Type *ptr, uint8_t ch_index)
291 {
292     ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_CEN_MASK;
293 }
294 
295 /**
296  * @brief gptmr channel stop counter
297  *
298  * @param [in] ptr GPTMR base address
299  * @param [in] ch_index channel index
300  */
gptmr_stop_counter(GPTMR_Type * ptr,uint8_t ch_index)301 static inline void gptmr_stop_counter(GPTMR_Type *ptr, uint8_t ch_index)
302 {
303     ptr->CHANNEL[ch_index].CR &= ~GPTMR_CHANNEL_CR_CEN_MASK;
304 }
305 
306 /**
307  * @brief gptmr channel enable compare output
308  *
309  * @param [in] ptr GPTMR base address
310  * @param [in] ch_index channel index
311  */
gptmr_enable_cmp_output(GPTMR_Type * ptr,uint8_t ch_index)312 static inline void gptmr_enable_cmp_output(GPTMR_Type *ptr, uint8_t ch_index)
313 {
314     ptr->CHANNEL[ch_index].CR |= GPTMR_CHANNEL_CR_CMPEN_MASK;
315 }
316 
317 /**
318  * @brief gptmr channel disable compare output
319  *
320  * @param [in] ptr GPTMR base address
321  * @param [in] ch_index channel index
322  */
gptmr_disable_cmp_output(GPTMR_Type * ptr,uint8_t ch_index)323 static inline void gptmr_disable_cmp_output(GPTMR_Type *ptr, uint8_t ch_index)
324 {
325     ptr->CHANNEL[ch_index].CR &= ~GPTMR_CHANNEL_CR_CMPEN_MASK;
326 }
327 
328 /**
329  * @brief gptmr channel set capmode
330  *
331  * @param [in] ptr GPTMR base address
332  * @param [in] ch_index channel index
333  */
gptmr_channel_set_capmode(GPTMR_Type * ptr,uint8_t ch_index,gptmr_work_mode_t mode)334 static inline void gptmr_channel_set_capmode(GPTMR_Type *ptr, uint8_t ch_index, gptmr_work_mode_t mode)
335 {
336     ptr->CHANNEL[ch_index].CR = (ptr->CHANNEL[ch_index].CR & ~GPTMR_CHANNEL_CR_CAPMODE_MASK) | GPTMR_CHANNEL_CR_CAPMODE_SET(mode);
337 }
338 
339 /**
340  * @brief gptmr channel get capmode
341  *
342  * @param [in] ptr GPTMR base address
343  * @param [in] ch_index channel index
344  * @retval gptmr_work_mode_t enum gptmr_work_mode_capture_at_rising_edge or gptmr_work_mode_capture_at_falling_edge
345  */
gptmr_channel_get_capmode(GPTMR_Type * ptr,uint8_t ch_index)346 static inline gptmr_work_mode_t gptmr_channel_get_capmode(GPTMR_Type *ptr, uint8_t ch_index)
347 {
348     return GPTMR_CHANNEL_CR_CAPMODE_GET(ptr->CHANNEL[ch_index].CR);
349 }
350 
351 /**
352  * @brief gptmr channel update comparator
353  *
354  * @param [in] ptr GPTMR base address
355  * @param [in] ch_index channel index
356  * @param [in] cmp_index comparator index
357  * @param [in] cmp comparator value
358  */
gptmr_update_cmp(GPTMR_Type * ptr,uint8_t ch_index,uint8_t cmp_index,uint32_t cmp)359 static inline void gptmr_update_cmp(GPTMR_Type *ptr, uint8_t ch_index, uint8_t cmp_index, uint32_t cmp)
360 {
361     if (cmp > 0) {
362         cmp--;
363     }
364     ptr->CHANNEL[ch_index].CMP[cmp_index] = GPTMR_CHANNEL_CMP_CMP_SET(cmp);
365 }
366 
367 /**
368  * @brief gptmr channel get reload
369  *
370  * @param [in] ptr GPTMR base address
371  * @param [in] ch_index channel index
372  * @retval RLD register value
373  */
gptmr_channel_get_reload(GPTMR_Type * ptr,uint8_t ch_index)374 static inline uint32_t gptmr_channel_get_reload(GPTMR_Type *ptr, uint8_t ch_index)
375 {
376     return ptr->CHANNEL[ch_index].RLD;
377 }
378 
379 /**
380  * @brief gptmr channel update reload
381  *
382  * @param [in] ptr GPTMR base address
383  * @param [in] ch_index channel index
384  * @param [in] reload reload value
385  */
gptmr_channel_config_update_reload(GPTMR_Type * ptr,uint8_t ch_index,uint32_t reload)386 static inline void gptmr_channel_config_update_reload(GPTMR_Type *ptr, uint8_t ch_index, uint32_t reload)
387 {
388     if (reload > 0) {
389         reload--;
390     }
391     ptr->CHANNEL[ch_index].RLD = GPTMR_CHANNEL_RLD_RLD_SET(reload);
392 }
393 
394 /**
395  * @brief gptmr channel get dma request event
396  *
397  * @param [in] ptr GPTMR base address
398  * @param [in] ch_index channel index
399  * @retval gptmr_dma_request_event_t gptmr_dma_request_on_cmp0 or gptmr_dma_request_on_reload
400  */
gptmr_channel_get_dma_request_event(GPTMR_Type * ptr,uint8_t ch_index)401 static inline gptmr_dma_request_event_t gptmr_channel_get_dma_request_event(GPTMR_Type *ptr, uint8_t ch_index)
402 {
403     return GPTMR_CHANNEL_CR_DMASEL_GET(ptr->CHANNEL[ch_index].CR);
404 }
405 
406 /**
407  * @brief gptmr channel config
408  *
409  * @param [in] ptr GPTMR base address
410  * @param [in] ch_index channel index
411  * @param [in] config gptmr_channel_config_t
412  * @param [in] enable
413  *  @arg true: enable
414  *  @arg false: disable
415  *
416  * @retval hpm_stat_t status_invalid_argument or status_success
417  */
418 hpm_stat_t gptmr_channel_config(GPTMR_Type *ptr,
419                          uint8_t ch_index,
420                          gptmr_channel_config_t *config,
421                          bool enable);
422 
423 /**
424  * @brief gptmr channel get default config
425  *
426  * @param [in] ptr GPTMR base address
427  * @param [out] config gptmr_channel_config_t
428  */
429 void gptmr_channel_get_default_config(GPTMR_Type *ptr, gptmr_channel_config_t *config);
430 
431 /**
432  * @}
433  */
434 
435 #ifdef __cplusplus
436 }
437 #endif
438 
439 #endif /* HPM_GPTMR_DRV_H */
440