• 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_PTPC_DRV_H
9 #define HPM_PTPC_DRV_H
10 
11 #include "hpm_common.h"
12 #include "hpm_ptpc_regs.h"
13 
14 /**
15  * @brief PTPC driver
16  * @defgroup ptpc_interface PTPC driver APIs
17  * @ingroup timer_interfaces Timers
18  * @{
19  */
20 
21 #define PTPC_EVENT_COMPARE0_MASK    PTPC_INT_STS_COMP_INT_STS0_MASK
22 #define PTPC_EVENT_CAPTURE0_MASK    PTPC_INT_STS_CAPTURE_INT_STS0_MASK
23 #define PTPC_EVENT_PPS0_MASK        PTPC_INT_STS_PPS_INT_STS0_MASK
24 #define PTPC_EVENT_COMPARE1_MASK    PTPC_INT_STS_COMP_INT_STS1_MASK
25 #define PTPC_EVENT_CAPTURE1_MASK    PTPC_INT_STS_CAPTURE_INT_STS1_MASK
26 #define PTPC_EVENT_PPS1_MASK        PTPC_INT_STS_PPS_INT_STS1_MASK
27 
28 #define PTPC_MAX_NS_COUNTER (0x3B9ACA00UL)
29 
30 /**
31  * @brief Counter types
32  */
33 typedef enum ptpc_ns_counter_rollover_type {
34     ptpc_ns_counter_rollover_binary = 0, /**< binary mode, resolution ~0.466ns, overflow at 0x7FFFFFFF */
35     ptpc_ns_counter_rollover_digital = 1, /**< digital mode, resolution 1ns, overflow at 0x3B9ACA00 */
36 } ptpc_ns_counter_rollover_type_t;
37 
38 /**
39  * @brief Capture trigger types
40  */
41 typedef enum ptpc_capture_trigger_type {
42     ptpc_capture_trigger_none = 0,
43     ptpc_capture_trigger_on_rising_edge = PTPC_PTPC_CTRL0_CAPT_SNAP_POS_EN_MASK,
44     ptpc_capture_trigger_on_failing_edge = PTPC_PTPC_CTRL0_CAPT_SNAP_NEG_EN_MASK,
45     ptpc_capture_trigger_on_both_edges = PTPC_PTPC_CTRL0_CAPT_SNAP_POS_EN_MASK
46                                         | PTPC_PTPC_CTRL0_CAPT_SNAP_NEG_EN_MASK,
47 } ptpc_capture_trigger_type_t;
48 
49 /**
50  * @brief Capture trigger types
51  */
52 typedef enum ptpc_counting_mode {
53     ptpc_counting_increment = 0,            /**< Increment the counter */
54     ptpc_counting_decrement = 1,            /**< Decrement the counter */
55 } ptpc_counting_mode;
56 
57 /**
58  * @brief Timer config
59  */
60 typedef struct {
61     ptpc_capture_trigger_type_t capture_trigger;        /**< Capture trigger */
62     ptpc_ns_counter_rollover_type_t ns_rollover_mode;   /**< Ns rollover mode */
63     bool coarse_increment;                              /**< Set false to use fine increment */
64     bool capture_keep;                                  /**< Keep captured timer counter */
65     uint32_t src_frequency;                             /**< Source frequency */
66 } ptpc_config_t;
67 
68 #ifdef __cplusplus
69 extern "C" {
70 #endif
71 
72 /**
73  * @brief   Configure ns counter rollover mode
74  *
75  * @param[in] ptr PTPC base address
76  * @param[in] index Index of target counter
77  * @param[in] rollover Rollover type
78  */
ptpc_set_ns_counter_rollover(PTPC_Type * ptr,uint8_t index,ptpc_ns_counter_rollover_type_t rollover)79 static inline void ptpc_set_ns_counter_rollover(PTPC_Type *ptr, uint8_t index,
80                                 ptpc_ns_counter_rollover_type_t rollover)
81 {
82     ptr->PTPC[index].CTRL0 = (ptr->PTPC[index].CTRL0 & ~PTPC_PTPC_CTRL0_SUBSEC_DIGITAL_ROLLOVER_MASK)
83         | PTPC_PTPC_CTRL0_SUBSEC_DIGITAL_ROLLOVER_SET(rollover);
84 }
85 
86 /**
87  * @brief   Enable capture keep
88  *
89  * @param[in] ptr PTPC base address
90  * @param[in] index Target index
91  */
ptpc_enable_capture_keep(PTPC_Type * ptr,uint8_t index)92 static inline void ptpc_enable_capture_keep(PTPC_Type *ptr, uint8_t index)
93 {
94     ptr->PTPC[index].CTRL0 |= PTPC_PTPC_CTRL0_CAPT_SNAP_KEEP_MASK;
95 }
96 
97 /**
98  * @brief   Disable capture keep
99  *
100  * @param[in] ptr PTPC base address
101  * @param[in] index Target index
102  */
ptpc_disable_capture_keep(PTPC_Type * ptr,uint8_t index)103 static inline void ptpc_disable_capture_keep(PTPC_Type *ptr, uint8_t index)
104 {
105     ptr->PTPC[index].CTRL0 &= ~PTPC_PTPC_CTRL0_CAPT_SNAP_KEEP_MASK;
106 }
107 
108 /**
109  * @brief   Update ns counter update type
110  *
111  * @param[in] ptr PTPC base address
112  * @param[in] index Index of target counter
113  * @param[in] coarse_update Counter will be increment by 1 on
114  */
ptpc_set_ns_counter_update_type(PTPC_Type * ptr,uint8_t index,bool coarse_update)115 static inline void ptpc_set_ns_counter_update_type(PTPC_Type *ptr, uint8_t index, bool coarse_update)
116 {
117     ptr->PTPC[index].CTRL0 = (ptr->PTPC[index].CTRL0 & ~PTPC_PTPC_CTRL0_FINE_COARSE_SEL_MASK)
118         | PTPC_PTPC_CTRL0_FINE_COARSE_SEL_SET(coarse_update);
119 }
120 
121 /**
122  * @brief   Set ns counter increment step
123  *
124  * @param[in] ptr PTPC base address
125  * @param[in] index Target index
126  * @param[in] ns_step Increment step
127  */
ptpc_set_ns_counter_step(PTPC_Type * ptr,uint8_t index,uint32_t ns_step)128 static inline void ptpc_set_ns_counter_step(PTPC_Type *ptr, uint8_t index, uint32_t ns_step)
129 {
130     ptr->PTPC[index].CTRL1 = PTPC_PTPC_CTRL1_SS_INCR_SET(ns_step);
131 }
132 
133 /**
134  * @brief   Set Second portion update value
135  *
136  * @param[in] ptr PTPC base address
137  * @param[in] index Target index
138  * @param[in] sec Second value
139  */
ptpc_set_second_update(PTPC_Type * ptr,uint8_t index,uint32_t sec)140 static inline void ptpc_set_second_update(PTPC_Type *ptr, uint8_t index, uint32_t sec)
141 {
142     ptr->PTPC[index].TS_UPDTH = PTPC_PTPC_TS_UPDTH_SEC_UPDATE_SET(sec);
143 }
144 
145 /**
146  * @brief   Set ns portion update value
147  *
148  * @param[in] ptr PTPC base address
149  * @param[in] index Target index
150  * @param[in] ns Ns value (31 bits, 0x3B9ACA00 max)
151  * @param[in] mode Counting mode
152  *
153  * @return status_success if everything is okay
154  */
155 hpm_stat_t ptpc_set_ns_update(PTPC_Type *ptr, uint8_t index, uint32_t ns, ptpc_counting_mode mode);
156 
157 /**
158  * @brief   Get current timestamp Second portion
159  *
160  * @param[in] ptr PTPC base address
161  * @param[in] index Target index
162  *
163  * @return Seconds value
164  */
ptpc_get_timestamp_second(PTPC_Type * ptr,uint8_t index)165 static inline uint32_t ptpc_get_timestamp_second(PTPC_Type *ptr, uint8_t index)
166 {
167     return PTPC_PTPC_TIMEH_TIMESTAMP_HIGH_GET(ptr->PTPC[index].TIMEH);
168 }
169 
170 /**
171  * @brief   Get timestamp ns portion
172  *
173  * @param[in] ptr PTPC base address
174  * @param[in] index Target index
175  *
176  * @return ns value
177  */
ptpc_get_timestamp_ns(PTPC_Type * ptr,uint8_t index)178 static inline uint32_t ptpc_get_timestamp_ns(PTPC_Type *ptr, uint8_t index)
179 {
180     return PTPC_PTPC_TIMEL_TIMESTAMP_LOW_GET(ptr->PTPC[index].TIMEL);
181 }
182 
183 /**
184  * @brief   Config compare
185  *
186  * @param[in] ptr PTPC base address
187  * @param[in] index Target index
188  * @param[in] sec Target second
189  * @param[in] ns Target ns
190  */
ptpc_config_compare(PTPC_Type * ptr,uint8_t index,uint32_t sec,uint32_t ns)191 static inline void ptpc_config_compare(PTPC_Type *ptr, uint8_t index, uint32_t sec, uint32_t ns)
192 {
193     ptr->PTPC[index].TARH = PTPC_PTPC_TARH_TARGET_TIME_HIGH_SET(sec);
194     ptr->PTPC[index].TARL = PTPC_PTPC_TARL_TARGET_TIME_LOW_SET(ns);
195     ptr->PTPC[index].CTRL0 |= PTPC_PTPC_CTRL0_COMP_EN_MASK;
196 }
197 
198 /**
199  * @brief   Update Second portion
200  *
201  * @param[in] ptr PTPC base address
202  * @param[in] index Target index
203  * @param[in] sec Target second
204  */
ptpc_update_timestamp_second(PTPC_Type * ptr,uint8_t index,uint32_t sec)205 static inline void ptpc_update_timestamp_second(PTPC_Type *ptr, uint8_t index, uint32_t sec)
206 {
207     ptr->PTPC[index].TS_UPDTH = PTPC_PTPC_TS_UPDTH_SEC_UPDATE_SET(sec);
208 }
209 
210 /**
211  * @brief   Update Ns portion
212  *
213  * @param[in] ptr PTPC base address
214  * @param[in] index Target index
215  * @param[in] ns Target ns
216  * @param[in] mode Counting mode
217  */
ptpc_update_timestamp_ns(PTPC_Type * ptr,uint8_t index,uint32_t ns,ptpc_counting_mode mode)218 static inline void ptpc_update_timestamp_ns(PTPC_Type *ptr, uint8_t index, uint32_t ns, ptpc_counting_mode mode)
219 {
220     ptr->PTPC[index].TS_UPDTL = PTPC_PTPC_TS_UPDTL_NS_UPDATE_SET(ns) | PTPC_PTPC_TS_UPDTL_ADD_SUB_SET(mode);
221 }
222 
223 /**
224  * @brief   Enable timer
225  *
226  * @param[in] ptr PTPC base address
227  * @param[in] index Target index
228  */
ptpc_enable_timer(PTPC_Type * ptr,uint8_t index)229 static inline void ptpc_enable_timer(PTPC_Type *ptr, uint8_t index)
230 {
231     ptr->PTPC[index].CTRL0 |= PTPC_PTPC_CTRL0_TIMER_ENABLE_MASK;
232 }
233 
234 /**
235  * @brief   Disable timer
236  *
237  * @param[in] ptr PTPC base address
238  * @param[in] index Target index
239  */
ptpc_disable_timer(PTPC_Type * ptr,uint8_t index)240 static inline void ptpc_disable_timer(PTPC_Type *ptr, uint8_t index)
241 {
242     ptr->PTPC[index].CTRL0 &= ~PTPC_PTPC_CTRL0_TIMER_ENABLE_MASK;
243 }
244 
245 /**
246  * @brief   Config capture trigger event
247  *
248  * @param[in] ptr PTPC base address
249  * @param[in] index Target index
250  * @param[in] trigger Capture trigger type
251  */
ptpc_config_capture(PTPC_Type * ptr,uint8_t index,ptpc_capture_trigger_type_t trigger)252 static inline void ptpc_config_capture(PTPC_Type *ptr, uint8_t index,
253                                 ptpc_capture_trigger_type_t trigger)
254 {
255     ptr->PTPC[index].CTRL0 = (ptr->PTPC[index].CTRL0 & ~(PTPC_PTPC_CTRL0_CAPT_SNAP_POS_EN_MASK
256                 | PTPC_PTPC_CTRL0_CAPT_SNAP_NEG_EN_MASK)) | trigger;
257 }
258 
259 /**
260  * @brief   Get snapped ns value
261  *
262  * @param[in] ptr PTPC base address
263  * @param[in] index Target index
264  *
265  * @return ns portion on capture
266  */
ptpc_get_capture_ns(PTPC_Type * ptr,uint8_t index)267 static inline uint32_t ptpc_get_capture_ns(PTPC_Type *ptr, uint8_t index)
268 {
269     return PTPC_PTPC_CAPT_SNAPL_CAPT_SNAP_LOW_GET(ptr->PTPC[index].CAPT_SNAPL);
270 }
271 
272 /**
273  * @brief   Get captured second
274  *
275  * @param[in] ptr PTPC base address
276  * @param[in] index Target index
277  *
278  * @return second portion on capture
279  */
ptpc_get_capture_second(PTPC_Type * ptr,uint8_t index)280 static inline uint32_t ptpc_get_capture_second(PTPC_Type *ptr, uint8_t index)
281 {
282     return PTPC_PTPC_CAPT_SNAPH_CAPT_SNAP_HIGH_GET(ptr->PTPC[index].CAPT_SNAPH);
283 }
284 
285 /**
286  * @brief   Clear interrupt status
287  *
288  * @param[in] ptr PTPC base address
289  * @param[in] mask Mask of interrupts to be cleared
290  */
ptpc_clear_irq_status(PTPC_Type * ptr,uint32_t mask)291 static inline void ptpc_clear_irq_status(PTPC_Type *ptr, uint32_t mask)
292 {
293     ptr->INT_STS = mask;
294 }
295 
296 /**
297  * @brief   Get interrupt status
298  *
299  * @param[in] ptr PTPC base address
300  *
301  * @return interrupt status mask
302  */
ptpc_get_irq_status(PTPC_Type * ptr)303 static inline uint32_t ptpc_get_irq_status(PTPC_Type *ptr)
304 {
305     return ptr->INT_STS;
306 }
307 
308 /**
309  * @brief   Disable interrupt with mask
310  *
311  * @param[in] ptr PTPC base address
312  * @param[in] mask Mask of interrupts to be disabled
313  */
ptpc_irq_disable(PTPC_Type * ptr,uint32_t mask)314 static inline void ptpc_irq_disable(PTPC_Type *ptr, uint32_t mask)
315 {
316     ptr->INT_EN &= ~mask;
317 }
318 
319 /**
320  * @brief   Enable interrupt with mask
321  *
322  * @param[in] ptr PTPC base address
323  * @param[in] mask Mask of interrupts to be enabled
324  */
ptpc_irq_enable(PTPC_Type * ptr,uint32_t mask)325 static inline void ptpc_irq_enable(PTPC_Type *ptr, uint32_t mask)
326 {
327     ptr->INT_EN |= mask;
328 }
329 
330 /**
331  * @brief   Initialize PTPC module
332  *
333  * @param[in] ptr PTPC base address
334  * @param[in] index Target index
335  * @param[in] config Pointer to configuration struct
336  *
337  * @return status_success if everything is okay
338  */
339 hpm_stat_t ptpc_init(PTPC_Type *ptr, uint8_t index, ptpc_config_t *config);
340 
341 /**
342  * @brief   Set PTPC output destination
343  *
344  * @param[in] ptr PTPC base address
345  * @param[in] can_index Target CAN instance
346  * @param[in] use_ptpc1 Use PTPC1 if set to true, otherwise PTPC0
347  *
348  * @return status_success if everything is okay
349  */
350 hpm_stat_t ptpc_set_timer_output(PTPC_Type *ptr, uint8_t can_index, bool use_ptpc1);
351 
352 /**
353  * @brief   Get default config
354  *
355  * @param[in] ptr PTPC base address
356  * @param[out] config Pointer of config struct
357  */
358 void ptpc_get_default_config(PTPC_Type *ptr, ptpc_config_t *config);
359 
360 /**
361  * @brief   Initialize timer to count from 0
362  *
363  * @param[in] ptr PTPC base address
364  * @param[in] index Target index
365  *
366  */
367 void ptpc_init_timer(PTPC_Type *ptr, uint8_t index);
368 
369 /**
370  * @brief   Initialize timer with initial values
371  *
372  * @param[in] ptr PTPC base address
373  * @param[in] index Target index
374  * @param[in] sec Seconds
375  * @param[in] ns Ns
376  * @param[in] mode Counting mode
377  *
378  * @return status_success if everything is okay
379  */
380 hpm_stat_t ptpc_init_timer_with_initial(PTPC_Type *ptr, uint8_t index, uint32_t sec, uint32_t ns, ptpc_counting_mode mode);
381 
382 /**
383  * @brief   Update timestamp counter
384  *
385  * @param[in] ptr PTPC base address
386  * @param[in] index Target index
387  * @param[in] sec Seconds
388  * @param[in] ns Ns
389  * @param[in] mode Counting mode
390  * @return status_success if everything is okay
391  */
392 hpm_stat_t ptpc_update_timer(PTPC_Type *ptr, uint8_t index, uint32_t sec, uint32_t ns, ptpc_counting_mode mode);
393 
394 /**
395  * @brief   Set period of pulse generated per second
396  *
397  * @param[in] ptr PTPC base address
398  * @param[in] index Target index
399  * @param[in] p (2^power Hz, from [0 - 15])
400  *
401  * @return true if requested frequency can be set
402  * @return false if requested frequency can not be set
403  */
404 hpm_stat_t ptpc_set_pps(PTPC_Type *ptr, uint8_t index, uint8_t p);
405 
406 #ifdef __cplusplus
407 }
408 #endif
409 /**
410  * @}
411  */
412 
413 #endif /* HPM_PTPC_DRV_H */
414