1 /*!
2     \file    gd32f3x0_syscfg.c
3     \brief   SYSCFG 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_syscfg.h"
38 
39 /*!
40     \brief      reset the SYSCFG registers
41     \param[in]  none
42     \param[out] none
43     \retval     none
44 */
syscfg_deinit(void)45 void syscfg_deinit(void)
46 {
47     rcu_periph_reset_enable(RCU_CFGCMPRST);
48     rcu_periph_reset_disable(RCU_CFGCMPRST);
49 }
50 
51 /*!
52     \brief      enable the DMA channels remapping
53     \param[in]  syscfg_dma_remap: specify the DMA channels to remap
54                 one or more parameters can be selected which is shown as below:
55       \arg        SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
56       \arg        SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
57       \arg        SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
58       \arg        SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
59       \arg        SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
60     \param[out] none
61     \retval     none
62 */
syscfg_dma_remap_enable(uint32_t syscfg_dma_remap)63 void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap)
64 {
65     SYSCFG_CFG0 |= syscfg_dma_remap;
66 }
67 
68 /*!
69     \brief      disable the DMA channels remapping
70     \param[in]  syscfg_dma_remap: specify the DMA channels to remap
71                 one or more parameters can be selected which is shown as below:
72       \arg        SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
73       \arg        SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
74       \arg        SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
75       \arg        SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
76       \arg        SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
77     \param[out] none
78     \retval     none
79 */
syscfg_dma_remap_disable(uint32_t syscfg_dma_remap)80 void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap)
81 {
82     SYSCFG_CFG0 &= ~syscfg_dma_remap;
83 }
84 
85 /*!
86     \brief      enable PB9 high current capability
87     \param[in]  none
88     \param[out] none
89     \retval     none
90 */
syscfg_high_current_enable(void)91 void syscfg_high_current_enable(void)
92 {
93     SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE;
94 }
95 
96 /*!
97     \brief      disable PB9 high current capability
98     \param[in]  none
99     \param[out] none
100     \retval     none
101 */
syscfg_high_current_disable(void)102 void syscfg_high_current_disable(void)
103 {
104     SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE;
105 }
106 
107 /*!
108     \brief      configure the GPIO pin as EXTI Line
109     \param[in]  exti_port: specify the GPIO port used in EXTI
110                 only one parameter can be selected which is shown as below:
111       \arg        EXTI_SOURCE_GPIOx(x = A,B,C,D,F): EXTI GPIO port
112     \param[in]  exti_pin: specify the EXTI line
113                 only one parameter can be selected which is shown as below:
114       \arg        EXTI_SOURCE_PINx(x = 0..15): EXTI GPIO pin
115     \param[out] none
116     \retval     none
117 */
syscfg_exti_line_config(uint8_t exti_port,uint8_t exti_pin)118 void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin)
119 {
120     uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin)));
121     uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin));
122 
123     switch(exti_pin / EXTI_SS_JSTEP){
124     case EXTISS0:
125         /* clear EXTI source line(0..3) */
126         SYSCFG_EXTISS0 &= clear_exti_mask;
127         /* configure EXTI soure line(0..3) */
128         SYSCFG_EXTISS0 |= config_exti_mask;
129         break;
130     case EXTISS1:
131         /* clear EXTI soure line(4..7) */
132         SYSCFG_EXTISS1 &= clear_exti_mask;
133         /* configure EXTI soure line(4..7) */
134         SYSCFG_EXTISS1 |= config_exti_mask;
135         break;
136     case EXTISS2:
137         /* clear EXTI soure line(8..11) */
138         SYSCFG_EXTISS2 &= clear_exti_mask;
139         /* configure EXTI soure line(8..11) */
140         SYSCFG_EXTISS2 |= config_exti_mask;
141         break;
142     case EXTISS3:
143         /* clear EXTI soure line(12..15) */
144         SYSCFG_EXTISS3 &= clear_exti_mask;
145         /* configure EXTI soure line(12..15) */
146         SYSCFG_EXTISS3 |= config_exti_mask;
147         break;
148     default:
149         break;
150     }
151 }
152 
153 /*!
154     \brief      connect TIMER0/14/15/16 break input to the selected parameter
155     \param[in]  syscfg_lock: Specify the parameter to be connected
156                 one or more parameters can be selected which is shown as below:
157       \arg        SYSCFG_LOCK_LOCKUP: Cortex-M4 lockup output connected to the break input
158       \arg        SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY check error connected to the break input
159       \arg        SYSCFG_LOCK_LVD: LVD interrupt connected to the break input
160     \param[out] none
161     \retval     none
162 */
syscfg_lock_config(uint32_t syscfg_lock)163 void syscfg_lock_config(uint32_t syscfg_lock)
164 {
165     SYSCFG_CFG2 |= syscfg_lock;
166 }
167 
168 /*!
169     \brief      check if the specified flag in SYSCFG_CFG2 is set or not.
170     \param[in]  syscfg_flag: specify the flag in SYSCFG_CFG2 to check.
171       \arg        SYSCFG_SRAM_PCEF: SRAM parity check error flag.
172     \param[out] none
173     \retval     the syscfg_flag state returned (SET or RESET).
174   */
syscfg_flag_get(uint32_t syscfg_flag)175 FlagStatus syscfg_flag_get(uint32_t syscfg_flag)
176 {
177     if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){
178         return SET;
179     }else{
180         return RESET;
181     }
182 }
183 
184 /*!
185     \brief      clear the flag in SYSCFG_CFG2 by writing 1.
186     \param[in]  syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear.
187       \arg        SYSCFG_SRAM_PCEF: SRAM parity check error flag.
188     \param[out] none
189     \retval     none
190 */
syscfg_flag_clear(uint32_t syscfg_flag)191 void syscfg_flag_clear(uint32_t syscfg_flag)
192 {
193     SYSCFG_CFG2 |= (uint32_t) syscfg_flag;
194 }
195 
196 /*!
197     \brief      configure the I/O compensation cell
198     \param[in]  syscfg_compensation: specifies the I/O compensation cell mode
199                 only one parameter can be selected which is shown as below:
200       \arg        SYSCFG_COMPENSATION_ENABLE: I/O compensation cell is enabled
201       \arg        SYSCFG_COMPENSATION_DISABLE: I/O compensation cell is disabled
202     \param[out] none
203     \retval     none
204 */
syscfg_compensation_config(uint32_t syscfg_compensation)205 void syscfg_compensation_config(uint32_t syscfg_compensation)
206 {
207     uint32_t reg;
208 
209     reg = SYSCFG_CPSCTL;
210     /* reset the SYSCFG_CPSCTL_CPS_EN bit and set according to syscfg_compensation */
211     reg &= ~SYSCFG_CPSCTL_CPS_EN;
212     SYSCFG_CPSCTL = (reg | syscfg_compensation);
213 }
214 
215 /*!
216     \brief      check if the I/O compensation cell ready flag is set or not
217     \param[in]  none
218     \param[out] none
219     \retval     FlagStatus: SET or RESET
220   */
syscfg_cps_rdy_flag_get(void)221 FlagStatus syscfg_cps_rdy_flag_get(void)
222 {
223     if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)){
224         return SET;
225     }else{
226         return RESET;
227     }
228 }
229