• 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 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