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