1 /**
2   ****************************************************************************************************
3   * @file    fm33lc0xx_fl_gpio.c
4   * @author  FMSH Application Team
5   * @brief   Src file of GPIO FL Module
6   ****************************************************************************************************
7   * @attention
8   *
9   * Copyright (c) [2021] [Fudan Microelectronics]
10   * THIS SOFTWARE is licensed under Mulan PSL v2.
11   * You can use this software according to the terms and conditions of the Mulan PSL v2.
12   * You may obtain a copy of Mulan PSL v2 at:
13   *          http://license.coscl.org.cn/MulanPSL2
14   * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
15   * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
16   * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
17   * See the Mulan PSL v2 for more details.
18   *
19   ****************************************************************************************************
20   */
21 
22 
23 /* Includes ------------------------------------------------------------------*/
24 #include "fm33lc0xx_fl.h"
25 
26 /** @addtogroup FM33LC0XX_FL_Driver
27   * @{
28   */
29 
30 /** @addtogroup GPIO
31   * @{
32   */
33 
34 #ifdef FL_GPIO_DRIVER_ENABLED
35 
36 /* Private macros ------------------------------------------------------------*/
37 /** @addtogroup GPIO_FL_Private_Macros
38   * @{
39   */
40 
41 #define         IS_GPIO_ALL_INSTANCE(INSTANCE)             (((INSTANCE) == GPIOA)||\
42                                                             ((INSTANCE) == GPIOB)||\
43                                                             ((INSTANCE) == GPIOC)||\
44                                                             ((INSTANCE) == GPIOD))
45 
46 #define         IS_FL_GPIO_PIN(__VALUE__)                  ((((uint32_t)0x00000000U) < (__VALUE__)) &&\
47                                                             ((__VALUE__) <= (FL_GPIO_PIN_ALL)))
48 
49 #define         IS_FL_GPIO_MODE(__VALUE__)                  (((__VALUE__) == FL_GPIO_MODE_ANALOG)||\
50                                                              ((__VALUE__) == FL_GPIO_MODE_INPUT)||\
51                                                              ((__VALUE__) == FL_GPIO_MODE_OUTPUT)||\
52                                                              ((__VALUE__) == FL_GPIO_MODE_DIGITAL))
53 
54 #define         IS_FL_GPIO_OPENDRAIN(__VALUE__)             (((__VALUE__) == FL_GPIO_OUTPUT_OPENDRAIN)||\
55                                                              ((__VALUE__) == FL_GPIO_OUTPUT_PUSHPULL))
56 
57 #define         IS_FL_GPIO_PULL_UP(__VALUE__)               (((__VALUE__) == FL_DISABLE)||\
58                                                              ((__VALUE__) == FL_ENABLE))
59 
60 
61 #define         IS_FL_GPIO_WKUP_ENTRY(__VALUE__)            (((__VALUE__) == FL_GPIO_WAKEUP_INT_ENTRY_NMI)||\
62                                                              ((__VALUE__) == FL_GPIO_WAKEUP_INT_ENTRY_38))
63 
64 #define         IS_FL_GPIO_WKUP_EDGE(__VALUE__)             (((__VALUE__) == FL_GPIO_WAKEUP_TRIGGER_RISING)||\
65                                                              ((__VALUE__) == FL_GPIO_WAKEUP_TRIGGER_FALLING))
66 
67 
68 #define         IS_FL_GPIO_WKUP_NUM(__VALUE__)              (((__VALUE__) == FL_GPIO_WAKEUP_0)||\
69                                                              ((__VALUE__) == FL_GPIO_WAKEUP_1)||\
70                                                              ((__VALUE__) == FL_GPIO_WAKEUP_2)||\
71                                                              ((__VALUE__) == FL_GPIO_WAKEUP_3)||\
72                                                              ((__VALUE__) == FL_GPIO_WAKEUP_4)||\
73                                                              ((__VALUE__) == FL_GPIO_WAKEUP_5)||\
74                                                              ((__VALUE__) == FL_GPIO_WAKEUP_6)||\
75                                                              ((__VALUE__) == FL_GPIO_WAKEUP_7))
76 /**
77   * @}
78   */
79 
80 /** @addtogroup GPIO_FL_EF_Init
81   * @{
82   */
83 
84 /**
85   * @brief  复位GPIO外设
86   * @param  GPIOx 外设入口地址
87   * @param  pin 引脚
88   * @retval 错误状态,可能值:
89   *         -FL_PASS 外设寄存器值恢复复位值
90   *         -FL_FAIL 未成功执行
91   */
FL_GPIO_DeInit(GPIO_Type * GPIOx,uint32_t pin)92 FL_ErrorStatus FL_GPIO_DeInit(GPIO_Type *GPIOx, uint32_t pin)
93 {
94     uint32_t pinPos     = 0x00000000U;
95     uint32_t currentPin = 0x00000000U;
96     /* 入口参数检查 */
97     assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
98     assert_param(IS_FL_GPIO_PIN(pin));
99     /* 恢复寄存器值为默认值 */
100     while(((pin) >> pinPos) != 0x00000000U)
101     {
102         /* 获取当前遍历到的Pin脚 */
103         currentPin = (pin) & (0x00000001U << pinPos);
104         if(currentPin)
105         {
106             FL_GPIO_SetPinMode(GPIOx, currentPin, FL_GPIO_MODE_INPUT);
107             FL_GPIO_DisablePinInput(GPIOx, currentPin);
108             FL_GPIO_DisablePinOpenDrain(GPIOx, currentPin);
109             FL_GPIO_DisablePinPullup(GPIOx, currentPin);
110             FL_GPIO_DisablePinAnalogSwitch(GPIOx, currentPin);
111             FL_GPIO_DisablePinRemap(GPIOx, currentPin);
112         }
113         pinPos++;
114     }
115     return FL_PASS;
116 }
117 
118 /**
119   * @brief  根据 GPIO_InitStruct 的配置信息初始化对应外设.
120   * @param  GPIOx GPIO Port
121   * @param  GPIO_InitStruct 指向一个 @ref FL_GPIO_InitTypeDef 结构体
122   *         其中包含了外设的相关配置信息.
123   * @retval 错误状态,可能值:
124   *         -FL_FAIL 配置过程发生错误
125   *         -FL_PASS 配置成功
126   */
FL_GPIO_Init(GPIO_Type * GPIOx,FL_GPIO_InitTypeDef * initStruct)127 FL_ErrorStatus FL_GPIO_Init(GPIO_Type *GPIOx, FL_GPIO_InitTypeDef *initStruct)
128 {
129     uint32_t pinPos     = 0x00000000U;
130     uint32_t currentPin = 0x00000000U;
131     /* 入口参数检查 */
132     assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
133     assert_param(IS_FL_GPIO_PIN(initStruct->pin));
134     assert_param(IS_FL_GPIO_MODE(initStruct->mode));
135     assert_param(IS_FL_GPIO_OPENDRAIN(initStruct->outputType));
136     assert_param(IS_FL_GPIO_PULL_UP(initStruct->pull));
137     /* 使能时钟总线 */
138     FL_RCC_EnableGroup1BusClock(FL_RCC_GROUP1_BUSCLK_PAD);
139     /* 这里考虑到PIN有可能不止一个因此需要遍历 */
140     while(((initStruct->pin) >> pinPos) != 0x00000000U)
141     {
142         /* 获取当前遍历到的Pin脚 */
143         currentPin = (initStruct->pin) & (0x00000001U << pinPos);
144         if(currentPin)
145         {
146             /* Pin脚模拟模式设置 */
147             if(initStruct->mode == FL_GPIO_MODE_ANALOG)
148             {
149                 FL_GPIO_DisablePinInput(GPIOx, currentPin);
150                 FL_GPIO_DisablePinPullup(GPIOx, currentPin);
151                 FL_GPIO_DisablePinOpenDrain(GPIOx, currentPin);
152                 FL_GPIO_EnablePinAnalogSwitch(GPIOx, currentPin);
153             }
154             else
155             {
156                 FL_GPIO_DisablePinAnalogSwitch(GPIOx, currentPin);
157                 /* Pin脚输入使能控制 */
158                 if(initStruct->mode == FL_GPIO_MODE_INPUT)
159                 {
160                     FL_GPIO_EnablePinInput(GPIOx, currentPin);
161                 }
162                 else
163                 {
164                     FL_GPIO_DisablePinInput(GPIOx, currentPin);
165                 }
166                 /* Pin脚输出模式设置 */
167                 if(initStruct->outputType == FL_GPIO_OUTPUT_PUSHPULL)
168                 {
169                     FL_GPIO_DisablePinOpenDrain(GPIOx, currentPin);
170                 }
171                 else
172                 {
173                     FL_GPIO_EnablePinOpenDrain(GPIOx, currentPin);
174                 }
175                 /* Pin脚上拉模式设置 */
176                 if(initStruct->pull)
177                 {
178                     FL_GPIO_EnablePinPullup(GPIOx, currentPin);
179                 }
180                 else
181                 {
182                     FL_GPIO_DisablePinPullup(GPIOx, currentPin);
183                 }
184             }
185             /* 数字模式复用功能选择 */
186             if(initStruct->mode == FL_GPIO_MODE_DIGITAL)
187             {
188                 /*重定向*/
189                 if(initStruct->remapPin == FL_ENABLE)
190                 {
191                     FL_GPIO_EnablePinRemap(GPIOx, currentPin);
192                 }
193                 else
194                 {
195                     FL_GPIO_DisablePinRemap(GPIOx, currentPin);
196                 }
197             }
198             /* Pin脚工作模式设置 */
199             FL_GPIO_SetPinMode(GPIOx, currentPin, initStruct->mode);
200         }
201         pinPos++;
202     }
203     return FL_PASS;
204 }
205 
206 /**
207   * @brief  将 @ref FL_GPIO_InitTypeDef 结构体初始化为默认配置
208   * @param  initStruct 指向 @ref FL_GPIO_InitTypeDef 结构体的指针
209   *
210   * @retval None
211   */
FL_GPIO_StructInit(FL_GPIO_InitTypeDef * initStruct)212 void FL_GPIO_StructInit(FL_GPIO_InitTypeDef *initStruct)
213 {
214     /* 复位配置信息 */
215     initStruct->pin        = FL_GPIO_PIN_ALL;
216     initStruct->mode       = FL_GPIO_MODE_INPUT;
217     initStruct->outputType = FL_GPIO_OUTPUT_OPENDRAIN;
218     initStruct->pull       = FL_DISABLE;
219     initStruct->remapPin   = FL_DISABLE;
220 }
221 
222 /**
223   * @brief  根据 FL_WKUP_InitTypeDef 配置GPIO唤醒对应外设
224   * @param  initStruct 指向一个 @ref FL_WKUP_InitTypeDef 结构体
225   *         其中包含了外设的相关配置信息.
226   * @param  wakeup 唤醒入口
227   *         FL_GPIO_WAKEUP_0
228   *         FL_GPIO_WAKEUP_1
229   *         FL_GPIO_WAKEUP_2
230   *         FL_GPIO_WAKEUP_3
231   *         FL_GPIO_WAKEUP_4
232   *         FL_GPIO_WAKEUP_5
233   *         FL_GPIO_WAKEUP_6
234   *         FL_GPIO_WAKEUP_7
235   * @retval 错误状态,可能值:
236   *         -FL_FAIL 配置过程发生错误
237   *         -FL_PASS 配置成功
238   */
FL_WKUP_Init(FL_WKUP_InitTypeDef * initStruct,uint32_t wakeup)239 FL_ErrorStatus FL_WKUP_Init(FL_WKUP_InitTypeDef *initStruct, uint32_t wakeup)
240 {
241     /* 入口参数检查 */
242     assert_param(IS_FL_GPIO_WKUP_NUM(wakeup));
243     assert_param(IS_FL_GPIO_WKUP_EDGE(initStruct->polarity));
244     FL_GPIO_EnableWakeup(GPIO, wakeup);
245     FL_GPIO_SetWakeupEdge(GPIO, wakeup, initStruct->polarity);
246     return FL_PASS;
247 }
248 
249 /**
250   * @brief  去初始化Wakeup配置
251   * @param  Wkupx 唤醒入口
252   *         FL_GPIO_WKUP_0
253   *         FL_GPIO_WKUP_1
254   *         FL_GPIO_WKUP_2
255   *         FL_GPIO_WKUP_3
256   *         FL_GPIO_WKUP_4
257   *         FL_GPIO_WKUP_5
258   *         FL_GPIO_WKUP_6
259   *         FL_GPIO_WKUP_7
260   * @retval 错误状态,可能值:
261   *         -FL_FAIL 配置过程发生错误
262   *         -FL_PASS 配置成功
263   */
FL_WKUP_DeInit(uint32_t wkupx)264 FL_ErrorStatus FL_WKUP_DeInit(uint32_t wkupx)
265 {
266     /* 入口参数检查 */
267     assert_param(IS_FL_GPIO_WKUP_NUM(wkupx));
268     FL_GPIO_EnableWakeup(GPIO, wkupx);
269     return FL_PASS;
270 }
271 
272 /**
273   * @brief  将 @ref FL_WKUP_InitTypeDef 结构体初始化为默认配置
274   * @param  initStruct_Wakeup 指向需要将值设置为默认配置的结构体 @ref FL_WKUP_InitTypeDef 结构体
275   *
276   * @retval None
277   */
FL_WKUP_StructInit(FL_WKUP_InitTypeDef * initStruct_Wakeup)278 void FL_WKUP_StructInit(FL_WKUP_InitTypeDef *initStruct_Wakeup)
279 {
280     /* 复位配置信息 */
281     initStruct_Wakeup->polarity   =   FL_GPIO_WAKEUP_TRIGGER_FALLING;
282 }
283 
284 /**
285   *@}
286   */
287 
288 /** @addtogroup RNG_FL_EF_Operation
289   * @{
290   */
291 
292 /**
293   * @brief  设置所有GPIO为输入模式、输入使能关闭(高阻态),SWD接口除外。
294   * @note   PD7和PD8为调试接口
295   *
296   * @param  None
297   *
298   * @retval None
299   */
FL_GPIO_ALLPIN_LPM_MODE(void)300 void FL_GPIO_ALLPIN_LPM_MODE(void)
301 {
302     FL_GPIO_DeInit(GPIOA, FL_GPIO_PIN_ALL);
303     FL_GPIO_DeInit(GPIOB, FL_GPIO_PIN_ALL);
304     FL_GPIO_DeInit(GPIOC, FL_GPIO_PIN_ALL);
305     FL_GPIO_DeInit(GPIOD, FL_GPIO_PIN_ALL_EXCEPTSWD);
306 }
307 
308 /**
309   * @}
310   */
311 
312 #endif /* FL_GPIO_DRIVER_ENABLED */
313 
314 /**
315   * @}
316   */
317 
318 /**
319   * @}
320   */
321 
322 /********************** (C) COPYRIGHT Fudan Microelectronics **** END OF FILE ***********************/
323