1 /*!
2     \file    gd32a50x_cmp.c
3     \brief   CMP driver
4 
5     \version 2022-01-30, V1.0.0, firmware for GD32A50x
6 */
7 
8 /*
9     Copyright (c) 2022, GigaDevice Semiconductor Inc.
10 
11     Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13 
14     1. Redistributions of source code must retain the above copyright notice, this
15        list of conditions and the following disclaimer.
16     2. Redistributions in binary form must reproduce the above copyright notice,
17        this list of conditions and the following disclaimer in the documentation
18        and/or other materials provided with the distribution.
19     3. Neither the name of the copyright holder nor the names of its contributors
20        may be used to endorse or promote products derived from this software without
21        specific prior written permission.
22 
23     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34 
35 #include "gd32a50x_cmp.h"
36 
37 /*!
38     \brief      deinitialize comparator
39     \param[in]  none
40     \param[out] none
41     \retval     none
42 */
cmp_deinit(void)43 void cmp_deinit(void)
44 {
45     rcu_periph_reset_enable(RCU_CMPRST);
46     rcu_periph_reset_disable(RCU_CMPRST);
47 }
48 
49 /*!
50     \brief      initialize comparator mode
51     \param[in]  operating_mode
52       \arg        CMP_HIGHSPEED: high speed mode
53       \arg        CMP_MIDDLESPEED: medium speed mode
54       \arg        CMP_LOWSPEED: low speed mode
55     \param[in]  inverting_input
56       \arg        CMP_1_4VREFINT: CMP inverting input VREFINT *1/4
57       \arg        CMP_1_2VREFINT: CMP inverting input VREFINT *1/2
58       \arg        CMP_3_4VREFINT: CMP inverting input VREFINT *3/4
59       \arg        CMP_VREFINT: CMP inverting input VREFINT
60       \arg        CMP_DAC_OUT: CMP inverting input DAC_OUT(PA4��PA5)
61       \arg        CMP_IM_PC11: CMP inverting input PC11
62       \arg        CMP_IM_PC10: CMP inverting input PC10
63       \arg        CMP_IM_PB8: CMP inverting input PB8
64       \arg        CMP_IM_PA0: CMP inverting input PA0
65       \arg        CMP_IM_PA3: CMP inverting input PA3
66       \arg        CMP_IM_PA4: CMP inverting input PA4
67       \arg        CMP_IM_PA5: CMP inverting input PA5
68       \arg        CMP_IM_PA6: CMP inverting input PA6
69     \param[in]  plus_input
70       \arg        CMP_IP_PC11: CMP plus input PC11
71       \arg        CMP_IP_PC10: CMP plus input PC10
72       \arg        CMP_IP_PB8: CMP plus input PB8
73       \arg        CMP_IP_PA0: CMP plus input PA0
74       \arg        CMP_IP_PA3: CMP plus input PA3
75       \arg        CMP_IP_PA4: CMP plus input PA4
76       \arg        CMP_IP_PA5: CMP plus input PA5
77       \arg        CMP_IP_PA6: CMP plus input PA6
78     \param[in]  output_hysteresis
79       \arg        CMP_HYSTERESIS_NO: output no hysteresis
80       \arg        CMP_HYSTERESIS_LOW: output low hysteresis
81       \arg        CMP_HYSTERESIS_MIDDLE: output middle hysteresis
82       \arg        CMP_HYSTERESIS_HIGH: output high hysteresis
83     \param[out] none
84     \retval     none
85 */
cmp_mode_init(operating_mode_enum operating_mode,cmp_inverting_input_enum inverting_input,cmp_plus_input_enum plus_input,cmp_hysteresis_enum output_hysteresis)86 void cmp_mode_init(operating_mode_enum operating_mode, cmp_inverting_input_enum inverting_input, cmp_plus_input_enum plus_input,
87                    cmp_hysteresis_enum output_hysteresis)
88 {
89     uint32_t cmp_cs = 0U;
90     cmp_cs = CMP_CS;
91     /* initialize comparator  mode */
92     cmp_cs &= ~(uint32_t)(CMP_CS_PM | CMP_CS_MESEL | CMP_CS_MISEL | CMP_CS_PSEL | CMP_CS_HST);
93     cmp_cs |= (uint32_t)(CS_CMPPM(operating_mode) | CS_CMPMSEL(inverting_input) | CS_CMPPSEL(plus_input) | CS_CMPHST(output_hysteresis));
94     CMP_CS =  cmp_cs;
95 }
96 
97 /*!
98     \brief      initialize comparator output
99     \param[in]  none
100       \param[in]  output_selection
101       \arg        CMP_OUTPUT_NONE: output no selection
102       \arg        CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture
103       \arg        CMP_OUTPUT_TIMER7IC0: TIMER 7 channel0 input capture
104     \param[in]  output_polarity
105       \arg        CMP_OUTPUT_POLARITY_INVERTED: output is inverted
106       \arg        CMP_OUTPUT_POLARITY_NOINVERTED: output is not inverted
107     \param[out] none
108     \retval     none
109 */
cmp_output_init(cmp_output_enum output_selection,cmp_output_inv_enum output_polarity)110 void cmp_output_init(cmp_output_enum output_selection, cmp_output_inv_enum output_polarity)
111 {
112     uint32_t cmp_cs = 0U;
113     cmp_cs = CMP_CS;
114     /* initialize comparator  output */
115     cmp_cs &= ~(uint32_t)CMP_CS_OSEL;
116     cmp_cs |= (uint32_t)CS_CMPOSEL(output_selection);
117     /* output polarity */
118     if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity) {
119         cmp_cs |= (uint32_t)CMP_CS_PL;
120     } else {
121         cmp_cs &= ~(uint32_t)CMP_CS_PL;
122     }
123     CMP_CS = cmp_cs;
124 }
125 
126 /*!
127     \brief      initialize comparator blanking function
128     \param[in]  none
129     \param[in]  blanking_source_selection
130       \arg        CMP_BLANKING_NONE: output no selection
131       \arg        CMP_BLANKING_TIMER0_OC1: TIMER 0 output channel1
132       \arg        CMP_BLANKING_TIMER7_OC1: TIMER 7 output channel1
133       \arg        CMP_BLANKING_TIMER1_OC1: TIMER 1 output channel1
134     \param[out] none
135     \retval     none
136 */
cmp_outputblank_init(blanking_source_enum blanking_source_selection)137 void cmp_outputblank_init(blanking_source_enum blanking_source_selection)
138 {
139     uint32_t cmp_cs = 0U;
140     cmp_cs = CMP_CS;
141     cmp_cs &= ~(uint32_t)CMP_CS_BLK;
142     cmp_cs |= (uint32_t)CS_CMPBLK(blanking_source_selection);
143     CMP_CS = cmp_cs;
144 }
145 
146 /*!
147     \brief      enable comparator
148     \param[in]  none
149     \param[out] none
150     \retval     none
151 */
cmp_enable(void)152 void cmp_enable(void)
153 {
154     CMP_CS |= (uint32_t)CMP_CS_EN;
155 }
156 
157 /*!
158     \brief      disable comparator
159     \param[in]  none
160     \param[out] none
161     \retval     none
162 */
cmp_disable(void)163 void cmp_disable(void)
164 {
165     CMP_CS &= ~(uint32_t)CMP_CS_EN;
166 }
167 
168 /*!
169     \brief      enable the voltage scaler
170     \param[in]  none
171     \param[out] none
172     \retval     none
173 */
cmp_voltage_scaler_enable(void)174 void cmp_voltage_scaler_enable(void)
175 {
176     CMP_CS |= (uint32_t)CMP_CS_SEN;
177 }
178 
179 /*!
180     \brief      disable the voltage scaler
181     \param[in]  none
182     \param[out] none
183     \retval     none
184 */
cmp_voltage_scaler_disable(void)185 void cmp_voltage_scaler_disable(void)
186 {
187     CMP_CS &= ~(uint32_t)CMP_CS_SEN;
188 }
189 
190 /*!
191     \brief      enable the scaler bridge
192     \param[in]  none
193     \param[out] none
194     \retval     none
195 */
cmp_scaler_bridge_enable(void)196 void cmp_scaler_bridge_enable(void)
197 {
198     CMP_CS |= (uint32_t)CMP_CS_BEN;
199 }
200 
201 /*!
202     \brief      disable the scaler bridge
203     \param[in]  none
204     \param[out] none
205     \retval     none
206 */
cmp_scaler_bridge_disable(void)207 void cmp_scaler_bridge_disable(void)
208 {
209     CMP_CS &= ~(uint32_t)CMP_CS_BEN;
210 }
211 
212 /*!
213     \brief      lock the comparator
214     \param[in]  none
215     \param[out] none
216     \retval     none
217 */
cmp_lock_enable(void)218 void cmp_lock_enable(void)
219 {
220     /* lock CMP */
221     CMP_CS |= (uint32_t)CMP_CS_LK;
222 }
223 
224 /*!
225     \brief      get output level
226     \param[in]  none
227     \param[out] none
228     \retval     the output level
229 */
cmp_output_level_get(void)230 cmp_output_state_enum cmp_output_level_get(void)
231 {
232     /* get output level of CMP */
233     if(CMP_CS & CMP_CS_OT) {
234         return CMP_OUTPUTLEVEL_HIGH;
235     } else {
236         return CMP_OUTPUTLEVEL_LOW;
237     }
238 }
239