1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_common.h"
9 #include "hpm_rdc_drv.h"
10
rdc_output_config(RDC_Type * ptr,rdc_output_cfg_t * cfg)11 void rdc_output_config(RDC_Type *ptr, rdc_output_cfg_t *cfg)
12 {
13 uint32_t rate;
14
15 rate = cfg->excitation_period_cycle >> (cfg->excitation_precision + 2);
16 ptr->EXC_TIMMING = RDC_EXC_TIMMING_SMP_RATE_SET(rate) |
17 RDC_EXC_TIMMING_SMP_NUM_SET(cfg->excitation_precision) |
18 RDC_EXC_TIMMING_PWM_PRD_SET(cfg->pwm_period)|
19 RDC_EXC_TIMMING_SWAP_SET(cfg->output_swap);
20 if (cfg->mode == rdc_output_dac) {
21 ptr->EXC_SCALING = RDC_EXC_SCALING_AMP_MAN_SET(cfg->amp_man) |
22 RDC_EXC_SCALING_AMP_EXP_SET(cfg->amp_exp);
23 ptr->EXC_OFFSET = RDC_EXC_OFFSET_AMP_OFFSET_SET(cfg->amp_offset + 0x800000);
24 ptr->OUT_CTL = RDC_OUT_CTL_CH_I_SEL_SET(cfg->dac_chn_i_sel) |
25 RDC_OUT_CTL_CH_Q_SEL_SET(cfg->dac_chn_q_sel);
26 } else if (cfg->mode == rdc_output_pwm) {
27 ptr->PWM_SCALING = RDC_EXC_SCALING_AMP_MAN_SET(cfg->amp_man) |
28 RDC_EXC_SCALING_AMP_EXP_SET(cfg->amp_exp) |
29 RDC_PWM_SCALING_DITHER_SET(cfg->pwm_dither_enable) |
30 RDC_PWM_SCALING_P_POL_SET(cfg->pwm_exc_p_low_active) |
31 RDC_PWM_SCALING_N_POL_SET(cfg->pwm_exc_n_low_active);
32 ptr->PWM_OFFSET = RDC_PWM_OFFSET_AMP_OFFSET_SET(cfg->amp_offset + (rate >> 1));
33 ptr->PWM_DZ = RDC_PWM_DZ_DZ_N_SET(cfg->pwm_deadzone_n) |
34 RDC_PWM_DZ_DZ_P_SET(cfg->pwm_deadzone_p);
35 }
36 if (cfg->trig_by_hw) {
37 ptr->EXC_SYNC_DLY = RDC_EXC_SYNC_DLY_DELAY_SET(cfg->hw_trig_delay);
38 } else {
39 ptr->EXC_SYNC_DLY = RDC_EXC_SYNC_DLY_DISABLE_MASK;
40 }
41 }
42
43
rdc_input_config(RDC_Type * ptr,rdc_input_cfg_t * cfg)44 void rdc_input_config(RDC_Type *ptr, rdc_input_cfg_t *cfg)
45 {
46 ptr->RDC_CTL = (ptr->RDC_CTL & (~(RDC_RDC_CTL_RECTIFY_SEL_MASK | RDC_RDC_CTL_ACC_LEN_MASK | RDC_RDC_CTL_TS_SEL_MASK)))
47 | RDC_RDC_CTL_RECTIFY_SEL_SET(cfg->rectify_signal_sel)
48 | RDC_RDC_CTL_ACC_LEN_SET(cfg->acc_cycle_len)
49 | RDC_RDC_CTL_TS_SEL_SET(cfg->acc_stamp);
50 ptr->IN_CTL = RDC_IN_CTL_PORT_I_SEL_SET(cfg->acc_input_port_i) |
51 RDC_IN_CTL_CH_I_SEL_SET(cfg->acc_input_chn_i) |
52 RDC_IN_CTL_PORT_Q_SEL_SET(cfg->acc_input_port_q) |
53 RDC_IN_CTL_CH_Q_SEL_SET(cfg->acc_input_chn_q);
54 }
55
rdc_get_acc_avl(RDC_Type * ptr,rdc_input_acc_chn_t chn)56 uint32_t rdc_get_acc_avl(RDC_Type *ptr, rdc_input_acc_chn_t chn)
57 {
58 if (chn == rdc_acc_chn_i) {
59 return RDC_ACC_I_ACC_GET(ptr->ACC_I);
60 } else {
61 return RDC_ACC_Q_ACC_GET(ptr->ACC_Q);
62 }
63 }
64
rdc_output_trig_offset_config(RDC_Type * ptr,rdc_output_trig_chn_t chn,int32_t offset)65 void rdc_output_trig_offset_config(RDC_Type *ptr, rdc_output_trig_chn_t chn, int32_t offset)
66 {
67 if (chn == trigger_out_0) {
68 ptr->TRIG_OUT0_CFG = (ptr->TRIG_OUT0_CFG & (~RDC_TRIG_OUT0_CFG_LEAD_TIM_MASK)) |
69 RDC_TRIG_OUT0_CFG_LEAD_TIM_SET(offset + RDC_TRIG_OUT0_CFG_LEAD_TIM_MASK + 1);
70 } else if (chn == trigger_out_1) {
71 ptr->TRIG_OUT1_CFG = (ptr->TRIG_OUT1_CFG & (~RDC_TRIG_OUT1_CFG_LEAD_TIM_MASK)) |
72 RDC_TRIG_OUT1_CFG_LEAD_TIM_SET(offset + RDC_TRIG_OUT1_CFG_LEAD_TIM_MASK + 1);
73 }
74 }
75
rdc_output_trig_enable(RDC_Type * ptr,rdc_output_trig_chn_t chn)76 void rdc_output_trig_enable(RDC_Type *ptr, rdc_output_trig_chn_t chn)
77 {
78 if (chn == trigger_out_0) {
79 ptr->TRIG_OUT0_CFG |= RDC_TRIG_OUT0_CFG_ENABLE_MASK;
80 } else if (chn == trigger_out_1) {
81 ptr->TRIG_OUT1_CFG |= RDC_TRIG_OUT1_CFG_ENABLE_MASK;
82 }
83 }
84
rdc_output_trig_disable(RDC_Type * ptr,rdc_output_trig_chn_t chn)85 void rdc_output_trig_disable(RDC_Type *ptr, rdc_output_trig_chn_t chn)
86 {
87 if (chn == trigger_out_0) {
88 ptr->TRIG_OUT0_CFG &= ~RDC_TRIG_OUT0_CFG_ENABLE_MASK;
89 } else if (chn == trigger_out_1) {
90 ptr->TRIG_OUT1_CFG &= ~RDC_TRIG_OUT1_CFG_ENABLE_MASK;
91 }
92 }
93
rdc_get_i_maxval(RDC_Type * ptr)94 int32_t rdc_get_i_maxval(RDC_Type *ptr)
95 {
96 uint32_t val;
97
98 val = ptr->MAX_I;
99 if (RDC_MAX_I_VALID_GET(val)) {
100 return RDC_MAX_I_MAX_GET(val);
101 } else {
102 return -1;
103 }
104
105 }
106
rdc_get_i_minval(RDC_Type * ptr)107 int32_t rdc_get_i_minval(RDC_Type *ptr)
108 {
109 uint32_t val;
110
111 val = ptr->MIN_I;
112 if (RDC_MIN_I_VALID_GET(val)) {
113 return RDC_MIN_I_MIN_GET(val);
114 } else {
115 return -1;
116 }
117 }
118
rdc_get_q_maxval(RDC_Type * ptr)119 int32_t rdc_get_q_maxval(RDC_Type *ptr)
120 {
121 uint32_t val;
122
123 val = ptr->MAX_Q;
124 if (RDC_MAX_Q_VALID_GET(val)) {
125 return RDC_MAX_Q_MAX_GET(val);
126 } else {
127 return -1;
128 }
129 }
130
rdc_get_q_minval(RDC_Type * ptr)131 int32_t rdc_get_q_minval(RDC_Type *ptr)
132 {
133 uint32_t val;
134
135 val = ptr->MIN_Q;
136 if (RDC_MIN_Q_VALID_GET(val)) {
137 return RDC_MIN_Q_MIN_GET(val);
138 } else {
139 return -1;
140 }
141 }
142
rdc_set_edge_detection_offset(RDC_Type * ptr,rdc_input_acc_chn_t chn,int32_t offset)143 void rdc_set_edge_detection_offset(RDC_Type *ptr, rdc_input_acc_chn_t chn, int32_t offset)
144 {
145 if (chn == rdc_acc_chn_i) {
146 ptr->THRS_I = RDC_THRS_I_THRS_SET(offset);
147 } else {
148 ptr->THRS_Q = RDC_THRS_Q_THRS_SET(offset);
149 }
150 }
151
rdc_set_acc_config(RDC_Type * ptr,rdc_acc_cfg_t * cfg)152 void rdc_set_acc_config(RDC_Type *ptr, rdc_acc_cfg_t *cfg)
153 {
154 ptr->EDG_DET_CTL = RDC_EDG_DET_CTL_FILTER_SET(cfg->continue_edge_num) |
155 RDC_EDG_DET_CTL_HOLD_SET(cfg->edge_distance);
156 if (cfg->right_shift_without_sign < 9) {
157 ptr->ACC_SCALING = RDC_ACC_SCALING_ACC_SHIFT_SET(8 - cfg->right_shift_without_sign);
158 } else {
159 ptr->ACC_SCALING = RDC_ACC_SCALING_ACC_SHIFT_SET(cfg->right_shift_without_sign);
160 }
161 if (cfg->error_data_remove) {
162 ptr->ACC_SCALING |= RDC_ACC_SCALING_TOXIC_LK_MASK;
163 } else {
164 ptr->ACC_SCALING &= ~RDC_ACC_SCALING_TOXIC_LK_MASK;
165 }
166 ptr->EXC_PERIOD = RDC_EXC_PERIOD_EXC_PERIOD_SET(cfg->exc_carrier_period);
167 ptr->SYNC_DELAY_I = RDC_SYNC_DELAY_I_DELAY_SET(cfg->sync_delay_i);
168 ptr->SYNC_DELAY_Q = RDC_SYNC_DELAY_Q_DELAY_SET(cfg->sync_delay_q);
169 ptr->AMP_MAX = RDC_AMP_MAX_MAX_SET(cfg->amp_max);
170 ptr->AMP_MIN = RDC_AMP_MIN_MIN_SET(cfg->amp_min);
171 }
172
rdc_set_acc_sync_delay(RDC_Type * ptr,rdc_input_acc_chn_t chn,uint32_t delay)173 void rdc_set_acc_sync_delay(RDC_Type *ptr, rdc_input_acc_chn_t chn, uint32_t delay)
174 {
175 if (chn == rdc_acc_chn_i) {
176 ptr->SYNC_DELAY_I = RDC_SYNC_DELAY_I_DELAY_SET(delay);
177 } else {
178 ptr->SYNC_DELAY_Q = RDC_SYNC_DELAY_Q_DELAY_SET(delay);
179 }
180 }
181