1 /*!
2     \file    gd32e10x_bkp.c
3     \brief   BKP driver
4 
5     \version 2017-12-26, V1.0.0, firmware for GD32E10x
6     \version 2020-09-30, V1.1.0, firmware for GD32E10x
7     \version 2020-12-31, V1.2.0, firmware for GD32E10x
8     \version 2022-06-30, V1.3.0, firmware for GD32E10x
9 */
10 
11 /*
12     Copyright (c) 2022, GigaDevice Semiconductor Inc.
13 
14     Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 
17     1. Redistributions of source code must retain the above copyright notice, this
18        list of conditions and the following disclaimer.
19     2. Redistributions in binary form must reproduce the above copyright notice,
20        this list of conditions and the following disclaimer in the documentation
21        and/or other materials provided with the distribution.
22     3. Neither the name of the copyright holder nor the names of its contributors
23        may be used to endorse or promote products derived from this software without
24        specific prior written permission.
25 
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36 */
37 
38 #include "gd32e10x_bkp.h"
39 
40 /* BKP register bits offset */
41 #define BKP_TAMPER_BITS_OFFSET          ((uint32_t)8U)
42 
43 /*!
44     \brief      reset BKP registers
45     \param[in]  none
46     \param[out] none
47     \retval     none
48 */
bkp_deinit(void)49 void bkp_deinit(void)
50 {
51     /* reset BKP domain register*/
52     rcu_bkp_reset_enable();
53     rcu_bkp_reset_disable();
54 }
55 
56 /*!
57     \brief      write BKP data register
58     \param[in]  register_number: refer to bkp_data_register_enum
59                 only one parameter can be selected which is shown as below:
60       \arg        BKP_DATA_x(x = 0..41): bkp data register number x
61     \param[in]  data: the data to be write in BKP data register
62     \param[out] none
63     \retval     none
64 */
bkp_data_write(bkp_data_register_enum register_number,uint16_t data)65 void bkp_data_write(bkp_data_register_enum register_number, uint16_t data)
66 {
67     if((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)){
68         BKP_DATA10_41(register_number-1U) = data;
69     }else if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){
70         BKP_DATA0_9(register_number-1U) = data;
71     }else{
72         /* illegal parameters */
73     }
74 }
75 
76 /*!
77     \brief      read BKP data register
78     \param[in]  register_number: refer to bkp_data_register_enum
79                 only one parameter can be selected which is shown as below:
80       \arg        BKP_DATA_x(x = 0..41): bkp data register number x
81     \param[out] none
82     \retval     data of BKP data register
83 */
bkp_data_read(bkp_data_register_enum register_number)84 uint16_t bkp_data_read(bkp_data_register_enum register_number)
85 {
86     uint16_t data = 0U;
87 
88     /* get the data from the BKP data register */
89     if((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)){
90         data = BKP_DATA10_41(register_number-1U);
91     }else if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){
92         data = BKP_DATA0_9(register_number-1U);
93     }else{
94         /* illegal parameters */
95     }
96     return data;
97 }
98 
99 /*!
100     \brief      enable RTC clock calibration output
101     \param[in]  none
102     \param[out] none
103     \retval     none
104 */
bkp_rtc_calibration_output_enable(void)105 void bkp_rtc_calibration_output_enable(void)
106 {
107     BKP_OCTL |= (uint16_t)BKP_OCTL_COEN;
108 }
109 
110 /*!
111     \brief      disable RTC clock calibration output
112     \param[in]  none
113     \param[out] none
114     \retval     none
115 */
bkp_rtc_calibration_output_disable(void)116 void bkp_rtc_calibration_output_disable(void)
117 {
118     BKP_OCTL &= (uint16_t)~BKP_OCTL_COEN;
119 }
120 
121 /*!
122     \brief      enable RTC alarm or second signal output
123     \param[in]  none
124     \param[out] none
125     \retval     none
126 */
bkp_rtc_signal_output_enable(void)127 void bkp_rtc_signal_output_enable(void)
128 {
129     BKP_OCTL |= (uint16_t)BKP_OCTL_ASOEN;
130 }
131 
132 /*!
133     \brief      disable RTC alarm or second signal output
134     \param[in]  none
135     \param[out] none
136     \retval     none
137 */
bkp_rtc_signal_output_disable(void)138 void bkp_rtc_signal_output_disable(void)
139 {
140     BKP_OCTL &= (uint16_t)~BKP_OCTL_ASOEN;
141 }
142 
143 /*!
144     \brief      select RTC output
145     \param[in]  outputsel: RTC output selection
146                 only one parameter can be selected which is shown as below:
147       \arg        RTC_OUTPUT_ALARM_PULSE: RTC alarm pulse is selected as the RTC output
148       \arg        RTC_OUTPUT_SECOND_PULSE: RTC second pulse is selected as the RTC output
149     \param[out] none
150     \retval     none
151 */
bkp_rtc_output_select(uint16_t outputsel)152 void bkp_rtc_output_select(uint16_t outputsel)
153 {
154     uint16_t ctl = 0U;
155 
156     /* configure BKP_OCTL_ROSEL with outputsel */
157     ctl = BKP_OCTL;
158     ctl &= (uint16_t)~BKP_OCTL_ROSEL;
159     ctl |= outputsel;
160     BKP_OCTL = ctl;
161 }
162 
163 /*!
164     \brief      select RTC clock output
165     \param[in]  clocksel: RTC clock output selection
166                 only one parameter can be selected which is shown as below:
167       \arg        RTC_CLOCK_DIV_64: RTC clock div 64
168       \arg        RTC_CLOCK_DIV_1: RTC clock
169     \param[out] none
170     \retval     none
171 */
bkp_rtc_clock_output_select(uint16_t clocksel)172 void bkp_rtc_clock_output_select(uint16_t clocksel)
173 {
174     uint16_t ctl = 0U;
175 
176     /* configure BKP_OCTL_CCOSEL with clocksel */
177     ctl = BKP_OCTL;
178     ctl &= (uint16_t)~BKP_OCTL_CCOSEL;
179     ctl |= clocksel;
180     BKP_OCTL = ctl;
181 }
182 
183 /*!
184     \brief      select RTC clock calibration direction
185     \param[in]  direction: RTC clock calibration direction
186                 only one parameter can be selected which is shown as below:
187       \arg        RTC_CLOCK_SLOW_DOWN: RTC clock slow down
188       \arg        RTC_CLOCK_SPEED_UP: RTC clock speed up
189     \param[out] none
190     \retval     none
191 */
bkp_rtc_clock_calibration_direction_select(uint16_t direction)192 void bkp_rtc_clock_calibration_direction_select(uint16_t direction)
193 {
194     uint16_t ctl = 0U;
195 
196     /* configure BKP_OCTL_CALDIR with direction */
197     ctl = BKP_OCTL;
198     ctl &= (uint16_t)~BKP_OCTL_CALDIR;
199     ctl |= direction;
200     BKP_OCTL = ctl;
201 }
202 
203 /*!
204     \brief      set RTC clock calibration value
205     \param[in]  value: RTC clock calibration value
206       \arg        0x00 - 0x7F
207     \param[out] none
208     \retval     none
209 */
bkp_rtc_calibration_value_set(uint8_t value)210 void bkp_rtc_calibration_value_set(uint8_t value)
211 {
212     uint16_t ctl;
213 
214     /* configure BKP_OCTL_RCCV with value */
215     ctl = BKP_OCTL;
216     ctl &= (uint16_t)~BKP_OCTL_RCCV;
217     ctl |= (uint16_t)OCTL_RCCV(value);
218     BKP_OCTL = ctl;
219 }
220 
221 /*!
222     \brief      enable tamper detection
223     \param[in]  none
224     \param[out] none
225     \retval     none
226 */
bkp_tamper_detection_enable(void)227 void bkp_tamper_detection_enable(void)
228 {
229     BKP_TPCTL |= (uint16_t)BKP_TPCTL_TPEN;
230 }
231 
232 /*!
233     \brief      disable tamper detection
234     \param[in]  none
235     \param[out] none
236     \retval     none
237 */
bkp_tamper_detection_disable(void)238 void bkp_tamper_detection_disable(void)
239 {
240     BKP_TPCTL &= (uint16_t)~BKP_TPCTL_TPEN;
241 }
242 
243 /*!
244     \brief      set tamper pin active level
245     \param[in]  level: tamper active level
246                 only one parameter can be selected which is shown as below:
247       \arg        TAMPER_PIN_ACTIVE_HIGH: the tamper pin is active high
248       \arg        TAMPER_PIN_ACTIVE_LOW: the tamper pin is active low
249     \param[out] none
250     \retval     none
251 */
bkp_tamper_active_level_set(uint16_t level)252 void bkp_tamper_active_level_set(uint16_t level)
253 {
254     uint16_t ctl = 0U;
255 
256     /* configure BKP_TPCTL_TPAL with level */
257     ctl = BKP_TPCTL;
258     ctl &= (uint16_t)~BKP_TPCTL_TPAL;
259     ctl |= level;
260     BKP_TPCTL = ctl;
261 }
262 
263 /*!
264     \brief      enable tamper interrupt
265     \param[in]  none
266     \param[out] none
267     \retval     none
268 */
bkp_interrupt_enable(void)269 void bkp_interrupt_enable(void)
270 {
271     BKP_TPCS |= (uint16_t)BKP_TPCS_TPIE;
272 }
273 
274 /*!
275     \brief      disable tamper interrupt
276     \param[in]  none
277     \param[out] none
278     \retval     none
279 */
bkp_interrupt_disable(void)280 void bkp_interrupt_disable(void)
281 {
282     BKP_TPCS &= (uint16_t)~BKP_TPCS_TPIE;
283 }
284 
285 /*!
286     \brief      get tamper flag state
287     \param[in]  none
288     \param[out] none
289     \retval     FlagStatus: SET or RESET
290 */
bkp_flag_get(void)291 FlagStatus bkp_flag_get(void)
292 {
293     if(RESET != (BKP_TPCS & BKP_FLAG_TAMPER)){
294         return SET;
295     }else{
296         return RESET;
297     }
298 }
299 
300 /*!
301     \brief      clear tamper flag state
302     \param[in]  none
303     \param[out] none
304     \retval     none
305 */
bkp_flag_clear(void)306 void bkp_flag_clear(void)
307 {
308     BKP_TPCS |= (uint16_t)(BKP_FLAG_TAMPER >> BKP_TAMPER_BITS_OFFSET);
309 }
310 
311 /*!
312     \brief      get tamper interrupt flag state
313     \param[in]  none
314     \param[out] none
315     \retval     FlagStatus: SET or RESET
316 */
bkp_interrupt_flag_get(void)317 FlagStatus bkp_interrupt_flag_get(void)
318 {
319     if(RESET != (BKP_TPCS & BKP_INT_FLAG_TAMPER)){
320         return SET;
321     }else{
322         return RESET;
323     }
324 }
325 
326 /*!
327     \brief      clear tamper interrupt flag state
328     \param[in]  none
329     \param[out] none
330     \retval     none
331 */
bkp_interrupt_flag_clear(void)332 void bkp_interrupt_flag_clear(void)
333 {
334     BKP_TPCS |= (uint16_t)(BKP_INT_FLAG_TAMPER >> BKP_TAMPER_BITS_OFFSET);
335 }
336