1 /*!
2 \file gd32f3x0_cmp.c
3 \brief CMP driver
4
5 \version 2017-06-06, V1.0.0, firmware for GD32F3x0
6 \version 2019-06-01, V2.0.0, firmware for GD32F3x0
7 \version 2020-09-30, V2.1.0, firmware for GD32F3x0
8 */
9
10 /*
11 Copyright (c) 2020, GigaDevice Semiconductor Inc.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 1. Redistributions of source code must retain the above copyright notice, this
17 list of conditions and the following disclaimer.
18 2. Redistributions in binary form must reproduce the above copyright notice,
19 this list of conditions and the following disclaimer in the documentation
20 and/or other materials provided with the distribution.
21 3. Neither the name of the copyright holder nor the names of its contributors
22 may be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36
37 #include "gd32f3x0_cmp.h"
38
39 /*!
40 \brief deinitialize comparator
41 \param[in] none
42 \param[out] none
43 \retval none
44 */
cmp_deinit(void)45 void cmp_deinit(void)
46 {
47 CMP_CS = ((uint32_t)0x00000000U);
48 }
49
50 /*!
51 \brief initialize comparator mode
52 \param[in] cmp_periph
53 \arg CMP0: comparator 0
54 \arg CMP1: comparator 1
55 \param[in] operating_mode
56 \arg CMP_HIGHSPEED: high speed mode
57 \arg CMP_MIDDLESPEED: medium speed mode
58 \arg CMP_LOWSPEED: low speed mode
59 \arg CMP_VERYLOWSPEED: very-low speed mode
60 \param[in] inverting_input
61 \arg CMP_1_4VREFINT: VREFINT *1/4 input
62 \arg CMP_1_2VREFINT: VREFINT *1/2 input
63 \arg CMP_3_4VREFINT: VREFINT *3/4 input
64 \arg CMP_VREFINT: VREFINT input
65 \arg CMP_DAC: PA4 (DAC) input
66 \arg CMP_PA5: PA5 input
67 \arg CMP_PA_0_2: PA0 or PA2 input
68 \param[in] hysteresis
69 \arg CMP_HYSTERESIS_NO: output no hysteresis
70 \arg CMP_HYSTERESIS_LOW: output low hysteresis
71 \arg CMP_HYSTERESIS_MIDDLE: output middle hysteresis
72 \arg CMP_HYSTERESIS_HIGH: output high hysteresis
73 \param[out] none
74 \retval none
75 */
cmp_mode_init(uint32_t cmp_periph,operating_mode_enum operating_mode,inverting_input_enum inverting_input,cmp_hysteresis_enum output_hysteresis)76 void cmp_mode_init(uint32_t cmp_periph, operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis)
77 {
78 uint32_t CMPx_CS = 0;
79 if(CMP0 == cmp_periph){
80 /* initialize comparator 0 mode */
81 CMPx_CS = CMP_CS;
82 CMPx_CS &= ~(uint32_t)(CMP_CS_CMP0M | CMP_CS_CMP0MSEL | CMP_CS_CMP0HST );
83 CMPx_CS |= CS_CMP0M(operating_mode) | CS_CMP0MSEL(inverting_input) | CS_CMP0HST(output_hysteresis);
84 CMP_CS = CMPx_CS;
85 }else{
86 /* initialize comparator 1 mode */
87 CMPx_CS = CMP_CS;
88 CMPx_CS &= ~(uint32_t)(CMP_CS_CMP1M | CMP_CS_CMP1MSEL | CMP_CS_CMP1HST );
89 CMPx_CS |= CS_CMP1M(operating_mode) | CS_CMP1MSEL(inverting_input) | CS_CMP1HST(output_hysteresis);
90 CMP_CS = CMPx_CS;
91 }
92 }
93
94 /*!
95 \brief initialize comparator output
96 \param[in] cmp_periph
97 \arg CMP0: comparator 0
98 \arg CMP1: comparator 1
99 \param[in] output_slection
100 \arg CMP_OUTPUT_NONE: output no selection
101 \arg CMP_OUTPUT_TIMER0BKIN: TIMER 0 break input
102 \arg CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture
103 \arg CMP_OUTPUT_TIMER0OCPRECLR: TIMER 0 OCPRE_CLR input
104 \arg CMP_OUTPUT_TIMER1IC3: TIMER 1 channel3 input capture
105 \arg CMP_OUTPUT_TIMER1OCPRECLR: TIMER 1 OCPRE_CLR input
106 \arg CMP_OUTPUT_TIMER2IC0: TIMER 2 channel0 input capture
107 \arg CMP_OUTPUT_TIMER2OCPRECLR: TIMER 2 OCPRE_CLR input
108 \param[in] output_polarity
109 \arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted
110 \arg CMP_OUTPUT_POLARITY_NOINVERTED: output is not inverted
111 \param[out] none
112 \retval none
113 */
cmp_output_init(uint32_t cmp_periph,cmp_output_enum output_slection,uint32_t output_polarity)114 void cmp_output_init(uint32_t cmp_periph, cmp_output_enum output_slection, uint32_t output_polarity)
115 {
116 uint32_t CMPx_CS = 0;
117 /* initialize comparator 0 output */
118 if(CMP0 == cmp_periph){
119 CMPx_CS = CMP_CS;
120 CMPx_CS &= ~(uint32_t)CMP_CS_CMP0OSEL;
121 CMPx_CS |= CS_CMP0OSEL(output_slection);
122 /* output polarity */
123 if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){
124 CMPx_CS |= CMP_CS_CMP0PL;
125 }else{
126 CMPx_CS &= ~CMP_CS_CMP0PL;
127 }
128 CMP_CS = CMPx_CS;
129 }else if(CMP1 == cmp_periph){
130 /* initialize comparator 1 output */
131 CMPx_CS = CMP_CS;
132 CMPx_CS &= ~(uint32_t)CMP_CS_CMP1OSEL;
133 CMPx_CS |= CS_CMP1OSEL(output_slection);
134 /* output polarity */
135 if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){
136 CMPx_CS |= CMP_CS_CMP1PL;
137 }else{
138 CMPx_CS &= ~CMP_CS_CMP1PL;
139 }
140 CMP_CS = CMPx_CS;
141 }
142 }
143
144 /*!
145 \brief enable comparator
146 \param[in] cmp_periph
147 \arg CMP0: comparator 0
148 \arg CMP1: comparator 1
149 \param[out] none
150 \retval none
151 */
cmp_enable(uint32_t cmp_periph)152 void cmp_enable(uint32_t cmp_periph)
153 {
154 if(CMP0 == cmp_periph){
155 CMP_CS |= CMP_CS_CMP0EN;
156 }else{
157 CMP_CS |= CMP_CS_CMP1EN;
158 }
159 }
160
161 /*!
162 \brief disable comparator
163 \param[in] cmp_periph
164 \arg CMP0: comparator 0
165 \arg CMP1: comparator 1
166 \param[out] none
167 \retval none
168 */
cmp_disable(uint32_t cmp_periph)169 void cmp_disable(uint32_t cmp_periph)
170 {
171 if(CMP0 == cmp_periph){
172 CMP_CS &= ~CMP_CS_CMP0EN;
173 }else{
174 CMP_CS &= ~CMP_CS_CMP1EN;
175 }
176 }
177
178 /*!
179 \brief enable comparator switch
180 \param[in] none
181 \param[out] none
182 \retval none
183 */
cmp_switch_enable(void)184 void cmp_switch_enable(void)
185 {
186 CMP_CS |= CMP_CS_CMP0SW;
187 }
188
189 /*!
190 \brief disable comparator switch
191 \param[in] none
192 \param[out] none
193 \retval none
194 */
cmp_switch_disable(void)195 void cmp_switch_disable(void)
196 {
197 CMP_CS &= ~CMP_CS_CMP0SW;
198 }
199
200 /*!
201 \brief enable the window mode
202 \param[in] none
203 \param[out] none
204 \retval none
205 */
cmp_window_enable(void)206 void cmp_window_enable(void)
207 {
208 CMP_CS |= CMP_CS_WNDEN;
209 }
210
211 /*!
212 \brief disable the window mode
213 \param[in] none
214 \param[out] none
215 \retval none
216 */
cmp_window_disable(void)217 void cmp_window_disable(void)
218 {
219 CMP_CS &= ~CMP_CS_WNDEN;
220 }
221
222 /*!
223 \brief lock the comparator
224 \param[in] cmp_periph
225 \arg CMP0: comparator 0
226 \arg CMP1: comparator 1
227 \param[out] none
228 \retval none
229 */
cmp_lock_enable(uint32_t cmp_periph)230 void cmp_lock_enable(uint32_t cmp_periph)
231 {
232 if(CMP0 == cmp_periph){
233 /* lock CMP0 */
234 CMP_CS |= CMP_CS_CMP0LK;
235 }else{
236 /* lock CMP1 */
237 CMP_CS |= CMP_CS_CMP1LK;
238 }
239 }
240
241 /*!
242 \brief get output level
243 \param[in] cmp_periph
244 \arg CMP0: comparator 0
245 \arg CMP1: comparator 1
246 \param[out] none
247 \retval the output level
248 */
cmp_output_level_get(uint32_t cmp_periph)249 uint32_t cmp_output_level_get(uint32_t cmp_periph)
250 {
251 if(CMP0 == cmp_periph){
252 /* get output level of CMP0 */
253 if(CMP_CS & CMP_CS_CMP0O){
254 return CMP_OUTPUTLEVEL_HIGH;
255 }else{
256 return CMP_OUTPUTLEVEL_LOW;
257 }
258 }else{
259 /* get output level of CMP1 */
260 if(CMP_CS & CMP_CS_CMP1O){
261 return CMP_OUTPUTLEVEL_HIGH;
262 }else{
263 return CMP_OUTPUTLEVEL_LOW;
264 }
265 }
266 }
267