1 #include "hpm_opamp_drv.h"
2
opamp_init(OPAMP_Type * opamp,opamp_cfg_t * cfg)3 hpm_stat_t opamp_init(OPAMP_Type *opamp, opamp_cfg_t *cfg)
4 {
5 opamp_disable(opamp);
6 opamp->CTRL0 = 0;
7 opamp_inn_pad_select(opamp, cfg->negative_input_pin);
8 opamp_inp_pad_select(opamp, cfg->positive_input_pin);
9 opamp_gain_select(opamp, cfg->gain);
10 opamp_miller_cap_select(opamp, cfg->miller_cap);
11 if (cfg->enable_phase_margin_cap) {
12 opamp_phase_margin_cap_enable(opamp);
13 } else {
14 opamp_phase_margin_cap_disable(opamp);
15 }
16 switch (cfg->mode) {
17 case mode_follow:
18 if ((cfg->positive_input_pin & 0x04) != 0) {
19 return status_invalid_argument;
20 }
21 if ((cfg->negative_input_pin & 0x04) == 0) {
22 return status_invalid_argument;
23 }
24 opamp_disconnect_vssa(opamp);
25 opamp_phase_margin_cap_enable(opamp);
26 opamp_mode_set(opamp, OPAMP_MODE_FOLLOW_KEY);
27 break;
28 case mode_invert_intern_vol:
29 if ((cfg->positive_input_pin & 0x04) == 0) {
30 return status_invalid_argument;
31 }
32 if ((cfg->negative_input_pin & 0x04) != 0) {
33 return status_invalid_argument;
34 }
35 opamp_connect_vssa(opamp);
36 opamp_phase_margin_cap_disable(opamp);
37 opamp_mode_set(opamp, OPAMP_MODE_INVERT_INDEX0_KEY);
38 break;
39 case mode_invert_extern_vol:
40 if ((cfg->positive_input_pin & 0x04) != 0) {
41 return status_invalid_argument;
42 }
43 if ((cfg->negative_input_pin & 0x04) != 0) {
44 return status_invalid_argument;
45 }
46 if (cfg->enable_extern_filter_cap) {
47 opamp_mode_set(opamp, OPAMP_MODE_INVERT_INDEX1_KEY);
48 } else {
49 opamp_mode_set(opamp, OPAMP_MODE_INVERT_INDEX0_KEY);
50 }
51 break;
52 case mode_invert_dac_vol:
53 opamp_inp_pad_select(opamp, 0x02);
54 if ((cfg->negative_input_pin & 0x04) != 0) {
55 return status_invalid_argument;
56 }
57 opamp_connect_vssa(opamp);
58 opamp_mode_set(opamp, OPAMP_MODE_INVERT_INDEX0_KEY);
59 break;
60 case mode_non_invert_gnd_vol:
61 if ((cfg->positive_input_pin & 0x04) != 0) {
62 return status_invalid_argument;
63 }
64 opamp_connect_vssa(opamp);
65 if (!cfg->enable_extern_filter_cap) {
66 if ((cfg->negative_input_pin & 0x04) == 0) {
67 return status_invalid_argument;
68 }
69 opamp_mode_set(opamp, OPAMP_MODE_NON_INVERT_INDEX0_KEY);
70 } else {
71 if ((cfg->negative_input_pin & 0x04) != 0) {
72 return status_invalid_argument;
73 }
74 opamp_mode_set(opamp, OPAMP_MODE_NON_INVERT_INDEX2_KEY);
75 }
76 break;
77 case mode_non_invert_extern_vol:
78 if ((cfg->positive_input_pin & 0x04) != 0) {
79 return status_invalid_argument;
80 }
81 if ((cfg->negative_input_pin & 0x04) != 0) {
82 return status_invalid_argument;
83 }
84 opamp_connect_vssa(opamp);
85 if (!cfg->enable_extern_filter_cap) {
86 opamp_mode_set(opamp, OPAMP_MODE_NON_INVERT_INDEX1_KEY);
87 } else {
88 opamp_mode_set(opamp, OPAMP_MODE_NON_INVERT_INDEX3_KEY);
89 }
90 break;
91 case mode_non_invert_dac_vol:
92 if ((cfg->positive_input_pin & 0x04) != 0) {
93 return status_invalid_argument;
94 }
95 opamp_inn_pad_select(opamp, 0x02);
96 opamp_connect_vssa(opamp);
97 opamp_mode_set(opamp, OPAMP_MODE_NON_INVERT_INDEX4_KEY);
98 break;
99 case mode_user:
100 return status_success;
101 break;
102 default:
103 return status_invalid_argument;
104 break;
105 }
106 return status_success;
107 }
108
109
opamp_set_preset_cfg(OPAMP_Type * opamp,uint8_t preset_chn,opamp_cfg_t * cfg)110 hpm_stat_t opamp_set_preset_cfg(OPAMP_Type *opamp, uint8_t preset_chn, opamp_cfg_t *cfg)
111 {
112 if (preset_chn > OPAMP_SOC_HAS_MAX_PRESET_CHN_NUM) {
113 return status_invalid_argument;
114 }
115 opamp->CFG[preset_chn].CFG0 = 0;
116 opamp->CFG[preset_chn].CFG1 = 0;
117 opamp_preset_inn_pad_select(opamp, preset_chn, cfg->negative_input_pin);
118 opamp_preset_inp_pad_select(opamp, preset_chn, cfg->positive_input_pin);
119 opamp_preset_gain_select(opamp, preset_chn, cfg->gain);
120 opamp_preset_miller_cap_select(opamp, preset_chn, cfg->miller_cap);
121 if (cfg->enable_phase_margin_cap) {
122 opamp_preset_phase_margin_cap_enable(opamp, preset_chn);
123 } else {
124 opamp_preset_phase_margin_cap_disable(opamp, preset_chn);
125 }
126 switch (cfg->mode) {
127 case mode_follow:
128 if ((cfg->positive_input_pin & 0x04) != 0) {
129 return status_invalid_argument;
130 }
131 if ((cfg->negative_input_pin & 0x04) == 0) {
132 return status_invalid_argument;
133 }
134 opamp_preset_disconnect_vssa(opamp, preset_chn);
135 opamp_preset_phase_margin_cap_enable(opamp, preset_chn);
136 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_FOLLOW_KEY);
137 break;
138 case mode_invert_intern_vol:
139 if ((cfg->positive_input_pin & 0x04) == 0) {
140 return status_invalid_argument;
141 }
142 if ((cfg->negative_input_pin & 0x04) != 0) {
143 return status_invalid_argument;
144 }
145 opamp_preset_disconnect_vssa(opamp, preset_chn);
146 opamp_preset_phase_margin_cap_disable(opamp, preset_chn);
147 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_INVERT_INDEX0_KEY);
148 break;
149 case mode_invert_extern_vol:
150 if ((cfg->positive_input_pin & 0x04) != 0) {
151 return status_invalid_argument;
152 }
153 if ((cfg->negative_input_pin & 0x04) != 0) {
154 return status_invalid_argument;
155 }
156 if (cfg->enable_extern_filter_cap) {
157 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_INVERT_INDEX1_KEY);
158 } else {
159 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_INVERT_INDEX0_KEY);
160 }
161 break;
162 case mode_invert_dac_vol:
163 opamp_preset_inp_pad_select(opamp, preset_chn, 0x02);
164 if ((cfg->negative_input_pin & 0x04) != 0) {
165 return status_invalid_argument;
166 }
167 opamp_preset_disconnect_vssa(opamp, preset_chn);
168 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_INVERT_INDEX0_KEY);
169 break;
170 case mode_non_invert_gnd_vol:
171 if ((cfg->positive_input_pin & 0x04) != 0) {
172 return status_invalid_argument;
173 }
174 opamp_preset_disconnect_vssa(opamp, preset_chn);
175 if (!cfg->enable_extern_filter_cap) {
176 if ((cfg->negative_input_pin & 0x04) == 0) {
177 return status_invalid_argument;
178 }
179 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_NON_INVERT_INDEX0_KEY);
180 } else {
181 if ((cfg->negative_input_pin & 0x04) != 0) {
182 return status_invalid_argument;
183 }
184 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_NON_INVERT_INDEX2_KEY);
185 }
186 break;
187 case mode_non_invert_extern_vol:
188 if ((cfg->positive_input_pin & 0x04) != 0) {
189 return status_invalid_argument;
190 }
191 if ((cfg->negative_input_pin & 0x04) != 0) {
192 return status_invalid_argument;
193 }
194 opamp_preset_disconnect_vssa(opamp, preset_chn);
195 if (!cfg->enable_extern_filter_cap) {
196 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_NON_INVERT_INDEX1_KEY);
197 } else {
198 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_NON_INVERT_INDEX3_KEY);
199 }
200 break;
201 case mode_non_invert_dac_vol:
202 if ((cfg->positive_input_pin & 0x04) != 0) {
203 return status_invalid_argument;
204 }
205 opamp_preset_inn_pad_select(opamp, preset_chn, 0x02);
206 opamp_preset_disconnect_vssa(opamp, preset_chn);
207 opamp_preset_mode_set(opamp, preset_chn, OPAMP_MODE_NON_INVERT_INDEX4_KEY);
208 break;
209 case mode_user:
210 return status_success;
211 break;
212 default:
213 return status_invalid_argument;
214 break;
215 }
216 return status_success;
217 }
218
219