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