1 /*!
2 * @file apm32f4xx_gpio.c
3 *
4 * @brief This file provides all the GPIO firmware functions
5 *
6 * @version V1.0.2
7 *
8 * @date 2022-06-23
9 *
10 * @attention
11 *
12 * Copyright (C) 2021-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 usefull 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 #include "apm32f4xx_gpio.h"
27 #include "apm32f4xx_rcm.h"
28
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30 @{
31 */
32
33 /** @defgroup GPIO_Driver
34 * @brief GPIO driver modules
35 @{
36 */
37
38 /** @defgroup GPIO_Functions
39 @{
40 */
41
42 /*!
43 * @brief Reset the GPIOx peripheral registers to their default reset values.
44 *
45 * @param port: Select the GPIO port.
46 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
47 * for APM32F405xx/407xx and APM32F415xx/417xx devices
48 * @retval None
49 *
50 * @note By reset, The GPIO pins are configured in input floating mode (except the JTAG pins).
51 */
GPIO_Reset(GPIO_T * port)52 void GPIO_Reset(GPIO_T *port)
53 {
54 RCM_AHB1_PERIPH_T AHB1Periph;
55
56 if (port == GPIOA)
57 {
58 AHB1Periph = RCM_AHB1_PERIPH_GPIOA;
59 }
60 else if (port == GPIOB)
61 {
62 AHB1Periph = RCM_AHB1_PERIPH_GPIOB;
63 }
64 else if (port == GPIOC)
65 {
66 AHB1Periph = RCM_AHB1_PERIPH_GPIOC;
67 }
68 else if (port == GPIOD)
69 {
70 AHB1Periph = RCM_AHB1_PERIPH_GPIOD;
71 }
72 else if (port == GPIOE)
73 {
74 AHB1Periph = RCM_AHB1_PERIPH_GPIOE;
75 }
76 else if (port == GPIOF)
77 {
78 AHB1Periph = RCM_AHB1_PERIPH_GPIOF;
79 }
80 else if (port == GPIOG)
81 {
82 AHB1Periph = RCM_AHB1_PERIPH_GPIOG;
83 }
84 else if (port == GPIOH)
85 {
86 AHB1Periph = RCM_AHB1_PERIPH_GPIOH;
87 }
88 else if (port == GPIOI)
89 {
90 AHB1Periph = RCM_AHB1_PERIPH_GPIOI;
91 }
92 else if (port == GPIOJ)
93 {
94 AHB1Periph = RCM_AHB1_PERIPH_GPIOJ;
95 }
96 else if (port == GPIOK)
97 {
98 AHB1Periph = RCM_AHB1_PERIPH_GPIOK;
99 }
100
101 RCM_EnableAHB1PeriphReset(AHB1Periph);
102 RCM_DisableAHB1PeriphReset(AHB1Periph);
103 }
104
105 /*!
106 * @brief Config the GPIO peripheral according to the specified parameters in the gpioConfig
107 *
108 * @param port: Select the GPIO port.
109 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
110 * for APM32F405xx/407xx and APM32F415xx/417xx devices
111 *
112 * @param gpioConfig: pointer to a GPIO_Config_T structure
113 *
114 * @retval None
115 */
GPIO_Config(GPIO_T * port,GPIO_Config_T * gpioConfig)116 void GPIO_Config(GPIO_T *port, GPIO_Config_T *gpioConfig)
117 {
118 uint32_t i = 0x00;
119 uint32_t pos = 0x00;
120 uint32_t temp = 0x00;
121
122 for (i = 0; i < 16; i++)
123 {
124 pos = ((uint32_t)0x01) << i;
125 temp = (gpioConfig->pin) & pos;
126
127 if (temp == pos)
128 {
129 port->MODE &= ~(0x03 << (i * 2));
130 port->MODE |= (((uint32_t)gpioConfig->mode) << (i * 2));
131
132 if ((gpioConfig->mode == GPIO_MODE_OUT) || (gpioConfig->mode == GPIO_MODE_AF))
133 {
134 port->OSSEL &= ~(0x03 << (i * 2));
135 port->OSSEL |= ((uint32_t)(gpioConfig->speed) << (i * 2));
136
137 port->OMODE &= ~(0x01 << ((uint16_t)i)) ;
138 port->OMODE |= (uint16_t)(((uint16_t)gpioConfig->otype) << ((uint16_t)i));
139 }
140
141 port->PUPD &= ~(0x03 << ((uint16_t)i * 2));
142 port->PUPD |= (((uint32_t)gpioConfig->pupd) << (i * 2));
143 }
144 }
145 }
146
147 /*!
148 * @brief Fills every gpioConfig member with its default value.
149 *
150 * @param gpioConfig : pointer to a GPIO_Config_T structure which will be initialized.
151 *
152 * @retval None
153 */
GPIO_ConfigStructInit(GPIO_Config_T * gpioConfig)154 void GPIO_ConfigStructInit(GPIO_Config_T *gpioConfig)
155 {
156 gpioConfig->pin = GPIO_PIN_ALL;
157 gpioConfig->mode = GPIO_MODE_IN;
158 gpioConfig->speed = GPIO_SPEED_2MHz;
159 gpioConfig->otype = GPIO_OTYPE_PP;
160 gpioConfig->pupd = GPIO_PUPD_NOPULL;
161 }
162
163 /*!
164 * @brief Lock GPIO Pins config registers.
165 *
166 * @param port: Select the GPIO port.
167 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
168 * for APM32F405xx/407xx and APM32F415xx/417xx devices
169 *
170 * @param pin: specifies the pin bit to be locked.
171 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
172 *
173 * @retval None
174 *
175 * @note Locked registers are GPIOx_MODER, GPIOx_OMODER, GPIOx_OOSSELR,
176 * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH,until the next reset the
177 * configuration of the locked GPIO pins can no longer be config.
178 *
179 */
GPIO_ConfigPinLock(GPIO_T * port,uint16_t pin)180 void GPIO_ConfigPinLock(GPIO_T *port, uint16_t pin)
181 {
182 __IOM uint32_t temp = 0x00010000;
183
184 temp |= pin;
185
186 port->LOCK = temp;
187
188 port->LOCK = pin;
189
190 port->LOCK = temp;
191
192 temp = port->LOCK;
193 }
194
195 /*!
196 * @brief Reads the specified input port pin.
197 *
198 * @param port :Select the GPIO port.
199 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
200 * for APM32F405xx/407xx and APM32F415xx/417xx devices
201 *
202 * @param pin: specifies the port bit to read.
203 * This parameter can be GPIO_Pin_x where x can be (0..15).
204 *
205 * @retval The input port pin value.
206 */
GPIO_ReadInputBit(GPIO_T * port,uint16_t pin)207 uint8_t GPIO_ReadInputBit(GPIO_T *port, uint16_t pin)
208 {
209 uint8_t readBit = 0x00;
210
211 readBit = (port->IDATA & pin) ? BIT_SET : BIT_RESET;
212
213 return readBit;
214 }
215
216 /*!
217 * @brief Reads the specified GPIO input data port.
218 *
219 * @param port :Select the GPIO port.
220 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
221 * for APM32F405xx/407xx and APM32F415xx/417xx devices
222 *
223 * @retval GPIO input data port value.
224 */
GPIO_ReadInputPort(GPIO_T * port)225 uint16_t GPIO_ReadInputPort(GPIO_T *port)
226 {
227 return ((uint16_t)port->IDATA);
228 }
229
230 /*!
231 * @brief Reads the specified output data port bit.
232 *
233 * @param port :Select the GPIO port.
234 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
235 * for APM32F405xx/407xx and APM32F415xx/417xx devices
236 *
237 * @param pin: specifies the port bit to read.
238 * This parameter can be one of GPIO_Pin_x where x can be (0..15).
239 *
240 * @retval The output port pin value.
241 */
GPIO_ReadOutputBit(GPIO_T * port,uint16_t pin)242 uint8_t GPIO_ReadOutputBit(GPIO_T *port, uint16_t pin)
243 {
244 uint8_t readBit = 0x00;
245
246 readBit = (port->ODATA & pin) ? BIT_SET : BIT_RESET;
247
248 return readBit;
249 }
250
251 /*!
252 * @brief Reads the specified GPIO output data port
253 *
254 * @param port: Select the GPIO port.
255 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
256 * for APM32F405xx/407xx and APM32F415xx/417xx devices
257 *
258 * @retval output data port value
259 */
GPIO_ReadOutputPort(GPIO_T * port)260 uint16_t GPIO_ReadOutputPort(GPIO_T *port)
261 {
262 return ((uint16_t)port->ODATA);
263 }
264
265 /*!
266 * @brief Sets the selected data port bits
267 *
268 * @param port: Select the GPIO port.
269 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
270 * for APM32F405xx/407xx and APM32F415xx/417xx devices
271 *
272 * @param pin : specifies pin to be written.
273 * This parameter can be any combination of GPIO_PIN_x( x can be from 0 to 15).
274 *
275 * @retval None
276 */
GPIO_SetBit(GPIO_T * port,uint16_t pin)277 void GPIO_SetBit(GPIO_T *port, uint16_t pin)
278 {
279 port->BSCL = pin;
280 }
281
282 /*!
283 * @brief Clears the selected data port bits
284 *
285 * @param port: Select the GPIO port.
286 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
287 * for APM32F405xx/407xx and APM32F415xx/417xx devices
288 *
289 * @param pin : specifies pin to be cleared.
290 * This parameter can be any combination of GPIO_PIN_x( x can be from 0 to 15).
291 *
292 * @retval None
293 */
GPIO_ResetBit(GPIO_T * port,uint16_t pin)294 void GPIO_ResetBit(GPIO_T *port, uint16_t pin)
295 {
296 port->BSCH = pin;
297 }
298
299 /*!
300 * @brief Writes data to the specified GPIO data port bit
301 *
302 * @param port: Select the GPIO port.
303 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
304 * for APM32F405xx/407xx and APM32F415xx/417xx devices
305 *
306 * @param pin : Select specifies pin.
307 * This parameter can be one of GPIO_PIN_x( x can be from 0 to 15).
308 *
309 * @param bitVal : specifies the value to be written to the port output data register
310 * This parameter can be one of the following values:
311 * @arg BIT_RESET : Reset the port pin
312 * @arg BIT_SET : Set the port pin
313 *
314 * @retval None
315 */
GPIO_WriteBitValue(GPIO_T * port,uint16_t pin,uint8_t bitVal)316 void GPIO_WriteBitValue(GPIO_T *port, uint16_t pin, uint8_t bitVal)
317 {
318 if (bitVal != BIT_RESET)
319 {
320 port->BSCL = pin;
321 }
322 else
323 {
324 port->BSCH = pin ;
325 }
326 }
327
328 /*!
329 * @brief Writes data to the specified GPIO data port
330 *
331 * @param port: Select the GPIO port.
332 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral
333 * for APM32F405xx/407xx and APM32F415xx/417xx devices
334 *
335 * @param portValue : specifies the value to be written to the port output data register.
336 *
337 * @retval None
338 */
GPIO_WriteOutputPort(GPIO_T * port,uint16_t portValue)339 void GPIO_WriteOutputPort(GPIO_T *port, uint16_t portValue)
340 {
341 port->ODATA = (uint16_t)portValue;
342 }
343
344 /*!
345 * @brief Toggles the specified GPIO pins.
346 *
347 * @param port: Select the GPIO port.
348 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral.
349 *
350 * @param pin: Specifies the pins to be toggled.
351 *
352 * @retval None
353 */
GPIO_ToggleBit(GPIO_T * port,uint16_t pin)354 void GPIO_ToggleBit(GPIO_T *port, uint16_t pin)
355 {
356 port->ODATA ^= pin;
357 }
358
359 /*!
360 * @brief Changes the mapping of the specified pin.
361 *
362 * @param port: Select the GPIO port.
363 * This parameter can be one of GPIOx(x=A..K) to select the GPIO peripheral.
364 *
365 * @param gpioPinSource: specifies the pin for the Alternate function.
366 * This parameter can be GPIO_PinSourcex where x can be (0..15).
367 *
368 * @param gpioAf: selects the pin to used as Alternate function.
369 * This parameter can be one of the following values:
370 * @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)
371 * @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)
372 * @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)
373 * @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)
374 * @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)
375 * @arg GPIO_AF_TMR1: Connect TMR1 pins to AF1
376 * @arg GPIO_AF_TMR2: Connect TMR2 pins to AF1
377 * @arg GPIO_AF_TMR3: Connect TMR3 pins to AF2
378 * @arg GPIO_AF_TMR4: Connect TMR4 pins to AF2
379 * @arg GPIO_AF_TMR5: Connect TMR5 pins to AF2
380 * @arg GPIO_AF_TMR8: Connect TMR8 pins to AF3
381 * @arg GPIO_AF_TMR9: Connect TMR9 pins to AF3
382 * @arg GPIO_AF_TMR10: Connect TMR10 pins to AF3
383 * @arg GPIO_AF_TMR11: Connect TMR11 pins to AF3
384 * @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4
385 * @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4
386 * @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4
387 * @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5
388 * @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5
389 * @arg GPIO_AF_SPI4: Connect SPI4 pins to AF5
390 * @arg GPIO_AF_SPI5: Connect SPI5 pins to AF5
391 * @arg GPIO_AF_SPI6: Connect SPI6 pins to AF5
392 * @arg GPIO_AF_SAI1: Connect SAI1 pins to AF6
393 * @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6
394 * @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7
395 * @arg GPIO_AF_USART1: Connect USART1 pins to AF7
396 * @arg GPIO_AF_USART2: Connect USART2 pins to AF7
397 * @arg GPIO_AF_USART3: Connect USART3 pins to AF7
398 * @arg GPIO_AF_UART4: Connect UART4 pins to AF8
399 * @arg GPIO_AF_UART5: Connect UART5 pins to AF8
400 * @arg GPIO_AF_USART6: Connect USART6 pins to AF8
401 * @arg GPIO_AF_UART7: Connect UART7 pins to AF8
402 * @arg GPIO_AF_UART8: Connect UART8 pins to AF8
403 * @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9
404 * @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9
405 * @arg GPIO_AF_TMR12: Connect TMR12 pins to AF9
406 * @arg GPIO_AF_TMR13: Connect TMR13 pins to AF9
407 * @arg GPIO_AF_TMR14: Connect TMR14 pins to AF9
408 * @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10
409 * @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10
410 * @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11
411 * @arg GPIO_AF_FSMC: Connect FSMC pins to AF12
412 * @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12
413 * @arg GPIO_AF_SDIO: Connect SDIO pins to AF12
414 * @arg GPIO_AF_DCMI: Connect DCMI pins to AF13
415 * @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15
416 *
417 * @retval None
418 */
GPIO_ConfigPinAF(GPIO_T * port,GPIO_PIN_SOURCE_T gpioPinSource,GPIO_AF_T gpioAf)419 void GPIO_ConfigPinAF(GPIO_T *port, GPIO_PIN_SOURCE_T gpioPinSource, GPIO_AF_T gpioAf)
420 {
421 uint32_t val = 0x00;
422 uint32_t val_2 = 0x00;
423
424 if (gpioPinSource >> 0x03 == 0)
425 {
426 val = (uint32_t)(gpioAf) << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4);
427 port->ALFL &= ~((uint32_t)0xF << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4)) ;
428 val_2 = port->ALFL | val;
429 port->ALFL = val_2;
430 }
431 else
432 {
433 val = (uint32_t)(gpioAf) << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4);
434 port->ALFH &= ~((uint32_t)0xF << (((uint32_t)gpioPinSource & (uint32_t)0x07) * 4)) ;
435 val_2 = port->ALFH | val;
436 port->ALFH = val_2;
437 }
438 }
439
440 /**@} end of group GPIO_Functions */
441 /**@} end of group GPIO_Driver */
442 /**@} end of group APM32F4xx_StdPeriphDriver */
443