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