1 /*!
2  * @file        apm32f0xx_gpio.c
3  *
4  * @brief       This file contains all the functions for the GPIO peripheral
5  *
6  * @version     V1.0.3
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be useful and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Includes */
27 #include "apm32f0xx_gpio.h"
28 #include "apm32f0xx_rcm.h"
29 
30 /** @addtogroup APM32F0xx_StdPeriphDriver
31   @{
32 */
33 
34 /** @addtogroup GPIO_Driver
35   @{
36 */
37 
38 
39 /** @defgroup GPIO_Macros Macros
40   @{
41   */
42 
43 /**@} end of group GPIO_Macros */
44 
45 /** @defgroup GPIO_Enumerates Enumerates
46   @{
47   */
48 
49 /**@} end of group GPIO_Enumerates */
50 
51 /** @defgroup GPIO_Structures Structures
52   @{
53   */
54 
55 /**@} end of group GPIO_Structures */
56 
57 /** @defgroup GPIO_Variables Variables
58   @{
59   */
60 
61 /**@} end of group GPIO_Variables */
62 
63 /** @defgroup GPIO_Functions Functions
64   @{
65   */
66 
67 /*!
68  * @brief       Reset GPIO peripheral registers to their default reset values
69  *
70  * @param       port:   GPIO peripheral.It can be GPIOA/GPIOB/GPIOC/GPIOD/GPIOE/GPIOF
71  *
72  * @retval      None
73  *
74  * @note        GPIOE is available only for APM32F072 and APM32F091
75  */
GPIO_Reset(GPIO_T * port)76 void GPIO_Reset(GPIO_T* port)
77 {
78     if (port == GPIOA)
79     {
80         RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_GPIOA);
81         RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_GPIOA);
82     }
83     else if (port == GPIOB)
84     {
85         RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_GPIOB);
86         RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_GPIOB);
87     }
88     else if (port == GPIOC)
89     {
90         RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_GPIOC);
91         RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_GPIOC);
92     }
93     else if (port == GPIOD)
94     {
95         RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_GPIOD);
96         RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_GPIOD);
97     }
98     else if (port == GPIOE)
99     {
100         RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_GPIOE);
101         RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_GPIOE);
102     }
103     else if (port == GPIOF)
104     {
105         RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_GPIOF);
106         RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_GPIOF);
107     }
108 }
109 
110 /*!
111  * @brief       Config the GPIO peripheral according to the specified parameters in the gpioConfig
112  *
113  * @param       port:   GPIO peripheral.It can be GPIOA/GPIOB/GPIOC/GPIOD/GPIOE/GPIOF
114  *
115  * @param       gpioConfig:     Pointer to a GPIO_Config_T structure that
116  *                              contains the configuration information for the specified GPIO peripheral
117  *
118  * @retval      None
119  *
120  * @note        GPIOE is available only for APM32F072 and APM32F091
121  */
GPIO_Config(GPIO_T * port,GPIO_Config_T * gpioConfig)122 void GPIO_Config(GPIO_T* port, GPIO_Config_T* gpioConfig)
123 {
124     uint32_t i;
125     uint32_t bit;
126 
127     for (i = 0; i < 16; i++)
128     {
129         bit = (uint32_t)1 << i;
130 
131         if (!(gpioConfig->pin & bit))
132         {
133             continue;
134         }
135 
136         if ((gpioConfig->mode == GPIO_MODE_OUT) || (gpioConfig->mode == GPIO_MODE_AF))
137         {
138             /* speed */
139             port->OSSEL &= ~((0x03) << (i * 2));
140             port->OSSEL |= ((uint32_t)(gpioConfig->speed) << (i * 2));
141 
142             /* Output mode configuration */
143             port->OMODE &= ~(((uint16_t)gpioConfig->outtype) << ((uint16_t)i));
144             port->OMODE |= (uint16_t)(((uint16_t)gpioConfig->outtype) << ((uint16_t)i));
145         }
146 
147         /* input/output mode */
148         port->MODE  &= ~(0x03 << (i * 2));
149         port->MODE |= (((uint32_t)gpioConfig->mode) << (i * 2));
150 
151         /* Pull-up Pull down resistor configuration */
152         port->PUPD &= ~(0x03 << ((uint16_t)i * 2));
153         port->PUPD |= (((uint32_t)gpioConfig->pupd) << (i * 2));
154     }
155 }
156 
157 /*!
158  * @brief       Fills each GPIO_Config_T member with its default value
159  *
160  * @param       gpioConfig: Pointer to a GPIO_Config_T structure which will be initialized
161  *
162  * @retval      None
163  */
GPIO_ConfigStructInit(GPIO_Config_T * gpioConfig)164 void GPIO_ConfigStructInit(GPIO_Config_T* gpioConfig)
165 {
166     gpioConfig->pin     = GPIO_PIN_ALL;
167     gpioConfig->mode    = GPIO_MODE_IN;
168     gpioConfig->outtype = GPIO_OUT_TYPE_PP;
169     gpioConfig->speed   = GPIO_SPEED_10MHz;
170     gpioConfig->pupd    = GPIO_PUPD_NO;
171 }
172 
173 /*!
174  * @brief       Locks GPIO Pins configuration registers
175  *
176  * @param       port:   GPIOA/B peripheral
177  *
178  * @param       pin:    specifies the port bit to be written
179  *
180  * @retval      None
181  */
GPIO_ConfigPinLock(GPIO_T * port,uint16_t pin)182 void GPIO_ConfigPinLock(GPIO_T* port, uint16_t pin)
183 {
184     uint32_t val = 0x00010000;
185 
186     val  |= pin;
187     /* Set LOCK bit */
188     port->LOCK = val ;
189     /* Reset LOCK bit */
190     port->LOCK = pin;
191     /* Set LOCK bit */
192     port->LOCK = val;
193     /* Read LOCK bit*/
194     val = port->LOCK;
195     /* Read LOCK bit*/
196     val = port->LOCK;
197 }
198 
199 /*!
200  * @brief       Reads the specified input port pin
201  *
202  * @param       port:   GPIO peripheral.It can be GPIOA/GPIOB/GPIOC/GPIOD/GPIOE/GPIOF
203  *
204  * @param       pin:    specifies pin to read
205  *
206  * @retval      The input port pin value
207  *
208  * @note        APM32F072 and APM32F091: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF.
209  */
GPIO_ReadInputBit(GPIO_T * port,uint16_t pin)210 uint8_t GPIO_ReadInputBit(GPIO_T* port, uint16_t pin)
211 {
212     uint8_t ret;
213 
214     ret = (port->IDATA & pin) ?  BIT_SET : BIT_RESET;
215 
216     return ret;
217 }
218 
219 /*!
220  * @brief       Reads the specified GPIO input data port
221  *
222  * @param       port:   GPIO peripheral
223  *
224  * @retval      GPIO input data port value
225  *
226  * @note        GPIOE is available only for APM32F072 and APM32F091
227  */
GPIO_ReadInputPort(GPIO_T * port)228 uint16_t GPIO_ReadInputPort(GPIO_T* port)
229 {
230     return ((uint16_t)port->IDATA);
231 }
232 
233 /*!
234  * @brief       Reads the specified output data port bit
235  *
236  * @param       port:   GPIO peripheral
237  *
238  * @param       pin:    specifies pin to read
239  *
240  * @retval      The output port pin value
241  *
242  * @note        GPIOE is available only for APM32F072 and APM32F091
243  */
GPIO_ReadOutputBit(GPIO_T * port,uint16_t pin)244 uint8_t GPIO_ReadOutputBit(GPIO_T* port, uint16_t pin)
245 {
246 
247     uint8_t ret;
248 
249     ret = (port->ODATA & pin) ? BIT_SET : BIT_RESET;
250 
251     return ret;
252 }
253 
254 /*!
255  * @brief       Reads the specified GPIO output data port
256  *
257  * @param       port:   GPIO peripheral
258  *
259  * @retval      output data port value
260  *
261  * @note        GPIOE is available only for APM32F072 and APM32F091
262  */
GPIO_ReadOutputPort(GPIO_T * port)263 uint16_t GPIO_ReadOutputPort(GPIO_T* port)
264 {
265     return ((uint16_t)port->ODATA);
266 }
267 
268 /*!
269  * @brief       Sets the selected data port bits
270  *
271  * @param       port:   GPIO peripheral
272  *
273  * @param       pin:    specifies the port bits to be written
274  *
275  * @retval      None
276  *
277  * @note        APM32F072 and APM32F091: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF.
278  */
GPIO_SetBit(GPIO_T * port,uint16_t pin)279 void GPIO_SetBit(GPIO_T* port, uint16_t pin)
280 {
281     port->BSC = (uint32_t)pin;
282 }
283 
284 /*!
285  * @brief       Clears the selected data port bits
286  *
287  * @param       port:   GPIO peripheral
288  *
289  * @param       pin:    specifies the port bits to be written
290  *
291  * @retval      None
292  *
293  * @note        APM32F072 and APM32F091: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF.
294  */
GPIO_ClearBit(GPIO_T * port,uint16_t pin)295 void GPIO_ClearBit(GPIO_T* port, uint16_t pin)
296 {
297     port->BR = (uint32_t)pin;
298 }
299 
300 /*!
301  * @brief       Sets or clears the selected data port bit
302  *
303  * @param       port:   GPIO peripheral
304  *
305  * @param       pin:    specifies the port bits to be written
306  *
307  * @param       bitVal
308  *
309  * @retval      None
310  *
311  * @note        APM32F072 and APM32F091: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF.
312  */
GPIO_WriteBitValue(GPIO_T * port,uint16_t pin,GPIO_BSRET_T bitVal)313 void GPIO_WriteBitValue(GPIO_T* port, uint16_t pin, GPIO_BSRET_T bitVal)
314 {
315     if (bitVal != Bit_RESET)
316     {
317         port->BSC = pin;
318     }
319     else
320     {
321         port->BR = pin ;
322     }
323 }
324 
325 /*!
326  * @brief       Writes data to the specified GPIO data port
327  *
328  * @param       port:     GPIO peripheral
329  *
330  * @param       portVal:  Write value to the port output data register
331  *
332  * @retval      None
333  *
334  * @note        GPIOE is available only for APM32F072 and APM32F091
335  */
GPIO_WriteOutputPort(GPIO_T * port,uint16_t portValue)336 void GPIO_WriteOutputPort(GPIO_T* port, uint16_t portValue)
337 {
338     port->ODATA = (uint32_t)portValue;
339 }
340 
341 /*!
342  * @brief       Changes the mapping of the specified pin
343  *
344  * @param       port: GPIO peripheral
345  *
346  * @param       pinSource:  Specifies the pin for the Alternate function.
347  *              This parameter can be one of the following values:
348  *              @arg GPIOA,GPIOB,GPIOD,GPIOE for 0..15
349  *              @arg GPIOC for 0..12
350  *              @arg GPIOF for 0, 2..5, 9..10
351  *
352  * @param       afPin: Selects the pin to used as Alternate function.
353  *
354  * @retval      None
355  *
356  * @note        GPIOC, GPIOD, GPIOE and GPIOF  are available only for APM32F072 and APM32F091
357  */
GPIO_ConfigPinAF(GPIO_T * port,GPIO_PIN_SOURCE_T pinSource,GPIO_AF_T afPin)358 void GPIO_ConfigPinAF(GPIO_T* port, GPIO_PIN_SOURCE_T pinSource, GPIO_AF_T afPin)
359 {
360     uint32_t temp  = 0x00;
361     uint32_t temp1 = 0x00;
362 
363     if (pinSource <= 0x07)
364     {
365         temp = (uint8_t)afPin << ((uint32_t)pinSource * 4);
366         port->ALFL &= ~((uint32_t)0xf << ((uint32_t)pinSource * 4));
367         port->ALFL |=  temp;
368     }
369     else
370     {
371         temp1 = (uint8_t)afPin << ((uint32_t)(pinSource & 0x07) * 4);
372         port->ALFH &= ~((uint32_t)0xf << (((uint32_t)pinSource & 0x07) * 4));
373         port->ALFH |=  temp1;
374     }
375 }
376 /**@} end of group GPIO_Functions */
377 /**@} end of group GPIO_Driver */
378 /**@} end of group APM32F0xx_StdPeriphDriver */
379