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