• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_soc_feature.h"
9 #include "hpm_ptpc_drv.h"
10 
11 #define PTPC_SS_INCR_UINT_AT_BIN_MODE_IN_PS (446U)
12 
ptpc_get_default_config(PTPC_Type * ptr,ptpc_config_t * config)13 void ptpc_get_default_config(PTPC_Type *ptr, ptpc_config_t *config)
14 {
15     (void) ptr;
16     config->capture_trigger = ptpc_capture_trigger_none;
17     config->ns_rollover_mode = ptpc_ns_counter_rollover_digital;
18     config->capture_keep = true;
19     config->coarse_increment = false;
20     config->src_frequency = 0;
21 }
22 
ptpc_init(PTPC_Type * ptr,uint8_t index,ptpc_config_t * config)23 hpm_stat_t ptpc_init(PTPC_Type *ptr, uint8_t index, ptpc_config_t *config)
24 {
25     uint8_t ss_incr;
26     if (!config || (index > PTPC_SOC_TIMER_MAX_COUNT) || !config->src_frequency) {
27         return status_invalid_argument;
28     }
29 
30     if (config->ns_rollover_mode == ptpc_ns_counter_rollover_digital) {
31         ss_incr = 1000000000 / config->src_frequency;
32     } else {
33         ss_incr = 1000000000 / config->src_frequency * 1000 / PTPC_SS_INCR_UINT_AT_BIN_MODE_IN_PS;
34     }
35     if (!ss_incr) {
36         return status_invalid_argument;
37     }
38     ptpc_disable_timer(ptr, index);
39     ptr->PTPC[index].CTRL0 = PTPC_PTPC_CTRL0_SUBSEC_DIGITAL_ROLLOVER_SET(config->ns_rollover_mode)
40                     | PTPC_PTPC_CTRL0_CAPT_SNAP_KEEP_SET(config->capture_keep)
41                     | PTPC_PTPC_CTRL0_FINE_COARSE_SEL_SET(config->coarse_increment)
42                     | (config->capture_trigger &
43                         ((PTPC_PTPC_CTRL0_CAPT_SNAP_POS_EN_MASK
44                           | PTPC_PTPC_CTRL0_CAPT_SNAP_NEG_EN_MASK) >> PTPC_PTPC_CTRL0_CAPT_SNAP_NEG_EN_SHIFT)
45                         << PTPC_PTPC_CTRL0_CAPT_SNAP_NEG_EN_SHIFT);
46     ptpc_set_ns_counter_step(ptr, index, ss_incr);
47     ptpc_enable_timer(ptr, index);
48     return status_success;
49 }
50 
ptpc_set_timer_output(PTPC_Type * ptr,uint8_t can_index,bool use_ptpc1)51 hpm_stat_t ptpc_set_timer_output(PTPC_Type *ptr, uint8_t can_index, bool use_ptpc1)
52 {
53     if (can_index > CAN_SOC_MAX_COUNT) {
54         return status_invalid_argument;
55     }
56     ptr->TIME_SEL = (ptr->TIME_SEL & ~(1 << can_index)) | (use_ptpc1 ? (1 << can_index) : 0);
57     return status_success;
58 }
59 
ptpc_set_ns_update(PTPC_Type * ptr,uint8_t index,uint32_t ns,ptpc_counting_mode mode)60 hpm_stat_t ptpc_set_ns_update(PTPC_Type *ptr, uint8_t index, uint32_t ns, ptpc_counting_mode mode)
61 {
62     if ((PTPC_PTPC_CTRL0_SUBSEC_DIGITAL_ROLLOVER_GET(ptr->PTPC[index].CTRL0) == ptpc_ns_counter_rollover_digital)
63             && (ns > PTPC_MAX_NS_COUNTER)) {
64         return status_invalid_argument;
65     }
66     ptr->PTPC[index].TS_UPDTL = PTPC_PTPC_TS_UPDTL_NS_UPDATE_SET(ns) | PTPC_PTPC_TS_UPDTL_ADD_SUB_SET(mode);
67     return status_success;
68 }
69 
ptpc_update_timer(PTPC_Type * ptr,uint8_t index,uint32_t sec,uint32_t ns,ptpc_counting_mode mode)70 hpm_stat_t ptpc_update_timer(PTPC_Type *ptr, uint8_t index, uint32_t sec, uint32_t ns, ptpc_counting_mode mode)
71 {
72     if (status_success != ptpc_set_ns_update(ptr, index, ns, mode)) {
73         return status_invalid_argument;
74     }
75     ptpc_set_second_update(ptr, index, sec);
76     ptr->PTPC[index].CTRL0 |= PTPC_PTPC_CTRL0_UPDATE_TIMER_MASK;
77     return status_success;
78 }
79 
ptpc_init_timer(PTPC_Type * ptr,uint8_t index)80 void ptpc_init_timer(PTPC_Type *ptr, uint8_t index)
81 {
82     ptpc_set_second_update(ptr, index, 0);
83     ptpc_set_ns_update(ptr, index, 0, ptpc_counting_increment);
84     ptr->PTPC[index].CTRL0 |= PTPC_PTPC_CTRL0_INIT_TIMER_MASK;
85 }
86 
ptpc_init_timer_with_initial(PTPC_Type * ptr,uint8_t index,uint32_t sec,uint32_t ns,ptpc_counting_mode mode)87 hpm_stat_t ptpc_init_timer_with_initial(PTPC_Type *ptr, uint8_t index, uint32_t sec, uint32_t ns, ptpc_counting_mode mode)
88 {
89     if (status_success != ptpc_set_ns_update(ptr, index, ns, mode)) {
90         return status_invalid_argument;
91     }
92     ptpc_set_second_update(ptr, index, sec);
93     ptr->PTPC[index].CTRL0 |= PTPC_PTPC_CTRL0_INIT_TIMER_MASK;
94     return status_success;
95 }
96 
ptpc_set_pps(PTPC_Type * ptr,uint8_t index,uint8_t p)97 hpm_stat_t ptpc_set_pps(PTPC_Type *ptr, uint8_t index, uint8_t p)
98 {
99     if (p > 15) {
100         return status_invalid_argument;
101     } else if (p > 0) {
102         if (PTPC_PTPC_CTRL0_SUBSEC_DIGITAL_ROLLOVER_GET(ptr->PTPC[index].CTRL0) == ptpc_ns_counter_rollover_digital) {
103             if (p == 15) {
104                 /* At digital mode, it can only generate interrupt at 16.384 KHz maximum */
105                 return status_invalid_argument;
106             }
107         } else {
108             if (p == 1) {
109                 /* At binary mode, it can only generate interrupt at 2 Hz minimum, when p > 0 */
110                 return status_invalid_argument;
111             }
112             p--;
113         }
114     }
115     ptr->PTPC[index].PPS_CTRL = PTPC_PTPC_PPS_CTRL_PPS_CTRL_SET(p);
116     return status_success;
117 }
118 
119 
120