1 /*!
2     \file    gd32a50x_bkp.c
3     \brief   BKP 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_bkp.h"
36 
37 #define TAMPER_FLAG_SHIFT          ((uint8_t)0x08U)
38 
39 /*!
40     \brief      reset BKP registers
41     \param[in]  none
42     \param[out] none
43     \retval     none
44 */
bkp_deinit(void)45 void bkp_deinit(void)
46 {
47     /* reset BKP domain register */
48     rcu_bkp_reset_enable();
49     rcu_bkp_reset_disable();
50 }
51 
52 /*!
53     \brief      write BKP data register
54     \param[in]  register_number: refer to bkp_data_register_enum
55                 only one parameter can be selected which is shown as below:
56       \arg        BKP_DATA_x(x = 0..9): BKP data register number x
57     \param[in]  data: the data to be write in BKP data register
58     \param[out] none
59     \retval     none
60 */
bkp_data_write(bkp_data_register_enum register_number,uint16_t data)61 void bkp_data_write(bkp_data_register_enum register_number, uint16_t data)
62 {
63     if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){
64         BKP_DATA0_9(register_number-1U) = data;
65     }else{
66         /* illegal parameters */
67     }
68 }
69 
70 /*!
71     \brief      read BKP data register
72     \param[in]  register_number: refer to bkp_data_register_enum
73                 only one parameter can be selected which is shown as below:
74       \arg        BKP_DATA_x(x = 0..9): BKP data register number x
75     \param[out] none
76     \retval     data of BKP data register
77 */
bkp_data_read(bkp_data_register_enum register_number)78 uint16_t bkp_data_read(bkp_data_register_enum register_number)
79 {
80     uint16_t data = 0U;
81 
82     /* get the data from the BKP data register */
83     if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){
84         data = BKP_DATA0_9(register_number-1U);
85     }else{
86         /* illegal parameters */
87     }
88     return data;
89 }
90 
91 /*!
92     \brief      enable RTC clock calibration output
93     \param[in]  none
94     \param[out] none
95     \retval     none
96 */
bkp_rtc_calibration_output_enable(void)97 void bkp_rtc_calibration_output_enable(void)
98 {
99     BKP_OCTL |= (uint16_t)BKP_OCTL_COEN;
100 }
101 
102 /*!
103     \brief      disable RTC clock calibration output
104     \param[in]  none
105     \param[out] none
106     \retval     none
107 */
bkp_rtc_calibration_output_disable(void)108 void bkp_rtc_calibration_output_disable(void)
109 {
110     BKP_OCTL &= (uint16_t)~BKP_OCTL_COEN;
111 }
112 
113 /*!
114     \brief      enable RTC alarm or second signal output
115     \param[in]  none
116     \param[out] none
117     \retval     none
118 */
bkp_rtc_signal_output_enable(void)119 void bkp_rtc_signal_output_enable(void)
120 {
121     BKP_OCTL |= (uint16_t)BKP_OCTL_ASOEN;
122 }
123 
124 /*!
125     \brief      disable RTC alarm or second signal output
126     \param[in]  none
127     \param[out] none
128     \retval     none
129 */
bkp_rtc_signal_output_disable(void)130 void bkp_rtc_signal_output_disable(void)
131 {
132     BKP_OCTL &= (uint16_t)~BKP_OCTL_ASOEN;
133 }
134 
135 /*!
136     \brief      select RTC output
137     \param[in]  outputsel: RTC output selection
138                 only one parameter can be selected which is shown as below:
139       \arg        RTC_OUTPUT_ALARM_PULSE: RTC alarm pulse is selected as the RTC output
140       \arg        RTC_OUTPUT_SECOND_PULSE: RTC second pulse is selected as the RTC output
141     \param[out] none
142     \retval     none
143 */
bkp_rtc_output_select(uint16_t outputsel)144 void bkp_rtc_output_select(uint16_t outputsel)
145 {
146     uint16_t ctl = 0U;
147 
148     ctl = BKP_OCTL;
149     ctl &= (uint16_t)~BKP_OCTL_ROSEL;
150     ctl |= outputsel;
151     BKP_OCTL = ctl;
152 }
153 
154 /*!
155     \brief      select RTC clock output
156     \param[in]  clocksel: RTC clock output selection
157                 only one parameter can be selected which is shown as below:
158       \arg        RTC_CLOCK_DIV_64: RTC clock div 64
159       \arg        RTC_CLOCK_DIV_1: RTC clock
160     \param[out] none
161     \retval     none
162 */
bkp_rtc_clock_output_select(uint16_t clocksel)163 void bkp_rtc_clock_output_select(uint16_t clocksel)
164 {
165     uint16_t ctl = 0U;
166 
167     ctl = BKP_OCTL;
168     ctl &= (uint16_t)~BKP_OCTL_CCOSEL;
169     ctl |= clocksel;
170     BKP_OCTL = ctl;
171 }
172 
173 /*!
174     \brief      RTC clock calibration direction
175     \param[in]  direction: RTC clock calibration direction
176                 only one parameter can be selected which is shown as below:
177       \arg        RTC_CLOCK_SLOWED_DOWN: RTC clock slow down
178       \arg        RTC_CLOCK_SPEED_UP: RTC clock speed up
179     \param[out] none
180     \retval     none
181 */
bkp_rtc_clock_calibration_direction(uint16_t direction)182 void bkp_rtc_clock_calibration_direction(uint16_t direction)
183 {
184     uint16_t ctl = 0U;
185 
186     ctl = BKP_OCTL;
187     ctl &= (uint16_t)~BKP_OCTL_CALDIR;
188     ctl |= direction;
189     BKP_OCTL = ctl;
190 }
191 
192 /*!
193     \brief      set RTC clock calibration value
194     \param[in]  value: RTC clock calibration value
195                 only one parameter can be selected which is shown as below:
196       \arg        0x00 - 0x7F
197     \param[out] none
198     \retval     none
199 */
bkp_rtc_calibration_value_set(uint8_t value)200 void bkp_rtc_calibration_value_set(uint8_t value)
201 {
202     uint16_t ctl;
203 
204     ctl = BKP_OCTL;
205     ctl &= (uint16_t)~BKP_OCTL_RCCV;
206     ctl |= (uint16_t)OCTL_RCCV(value);
207     BKP_OCTL = ctl;
208 }
209 
210 /*!
211     \brief      select OSC32IN pin
212     \param[in]  inputpin: OSC32IN pin selection
213                 only one parameter can be selected which is shown as below:
214       \arg        OSC32IN_PC13: OSC32IN pin is PC13
215       \arg        OSC32IN_PC14: OSC32IN pin is PC14
216     \param[out] none
217     \retval     none
218 */
bkp_osc32in_pin_select(uint16_t inputpin)219 void bkp_osc32in_pin_select(uint16_t inputpin)
220 {
221     uint16_t ctl = 0U;
222 
223     ctl = BKP_TPCTL;
224     ctl &= (uint16_t)~BKP_TPCTL_PCSEL;
225     ctl |= inputpin;
226     BKP_TPCTL = ctl;
227 }
228 
229 /*!
230     \brief      enable tamper pin detection
231     \param[in]  none
232     \param[out] none
233     \retval     none
234 */
bkp_tamper_detection_enable(void)235 void bkp_tamper_detection_enable(void)
236 {
237     BKP_TPCTL |= (uint16_t)BKP_TPCTL_TPEN;
238 }
239 
240 /*!
241     \brief      disable tamper pin detection
242     \param[in]  none
243     \param[out] none
244     \retval     none
245 */
bkp_tamper_detection_disable(void)246 void bkp_tamper_detection_disable(void)
247 {
248     BKP_TPCTL &= (uint16_t)~BKP_TPCTL_TPEN;
249 }
250 
251 /*!
252     \brief      set tamper pin active level
253     \param[in]  level: tamper active level
254                 only one parameter can be selected which is shown as below:
255       \arg        TAMPER_PIN_ACTIVE_HIGH: the tamper pin is active high
256       \arg        TAMPER_PIN_ACTIVE_LOW: the tamper pin is active low
257     \param[out] none
258     \retval     none
259 */
bkp_tamper_active_level_set(uint16_t level)260 void bkp_tamper_active_level_set(uint16_t level)
261 {
262     uint16_t ctl = 0U;
263 
264     ctl = BKP_TPCTL;
265     ctl &= (uint16_t)~BKP_TPCTL_TPAL;
266     ctl |= level;
267     BKP_TPCTL = ctl;
268 }
269 
270 /*!
271     \brief      enable tamper pin interrupt
272     \param[in]  none
273     \param[out] none
274     \retval     none
275 */
bkp_tamper_interrupt_enable(void)276 void bkp_tamper_interrupt_enable(void)
277 {
278     BKP_TPCS |= (uint16_t)BKP_TPCS_TPIE;
279 }
280 
281 /*!
282     \brief      disable tamper pin interrupt
283     \param[in]  none
284     \param[out] none
285     \retval     none
286 */
bkp_tamper_interrupt_disable(void)287 void bkp_tamper_interrupt_disable(void)
288 {
289     BKP_TPCS &= (uint16_t)~BKP_TPCS_TPIE;
290 }
291 
292 /*!
293     \brief      get bkp flag state
294     \param[in]  flag:
295       \arg        BKP_FLAG_TAMPER: tamper event flag
296     \param[out] none
297     \retval     FlagStatus: SET or RESET
298 */
bkp_flag_get(uint16_t flag)299 FlagStatus bkp_flag_get(uint16_t flag)
300 {
301     if(0U != (BKP_TPCS & flag)){
302         return SET;
303     }else{
304         return RESET;
305     }
306 }
307 
308 /*!
309     \brief      clear BKP flag state
310     \param[in]  flag:
311       \arg        BKP_FLAG_TAMPER: tamper event flag
312     \param[out] none
313     \retval     none
314 */
bkp_flag_clear(uint16_t flag)315 void bkp_flag_clear(uint16_t flag)
316 {
317     BKP_TPCS |= (uint16_t)(flag >> TAMPER_FLAG_SHIFT);
318 }
319 
320 /*!
321     \brief      get BKP interrupt flag state
322     \param[in]  flag
323       \arg        BKP_INT_FLAG_TAMPER: tamper interrupt flag
324     \param[out] none
325     \retval     FlagStatus: SET or RESET
326 */
bkp_interrupt_flag_get(uint16_t flag)327 FlagStatus bkp_interrupt_flag_get(uint16_t flag)
328 {
329     if(0U != (BKP_TPCS & flag)){
330         return SET;
331     }else{
332         return RESET;
333     }
334 }
335 
336 /*!
337     \brief      clear BKP interrupt flag state
338     \param[in]  flag:
339       \arg        BKP_INT_FLAG_TAMPER: tamper interrupt flag
340     \param[out] none
341     \retval     none
342 */
bkp_interrupt_flag_clear(uint16_t flag)343 void bkp_interrupt_flag_clear(uint16_t flag)
344 {
345     BKP_TPCS |= (uint16_t)(flag >> TAMPER_FLAG_SHIFT);
346 }
347