• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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