1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_gpio.c
4 * @author MCD Application Team
5 * @brief GPIO HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the General Purpose Input/Output (GPIO) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2017 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### GPIO Peripheral features #####
25 ==============================================================================
26 [..]
27 Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each
28 port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software
29 in several modes:
30 (+) Input mode
31 (+) Analog mode
32 (+) Output mode
33 (+) Alternate function mode
34 (+) External interrupt/event lines
35
36 [..]
37 During and just after reset, the alternate functions and external interrupt
38 lines are not active and the I/O ports are configured in input floating mode.
39
40 [..]
41 All GPIO pins have weak internal pull-up and pull-down resistors, which can be
42 activated or not.
43
44 [..]
45 In Output or Alternate mode, each IO can be configured on open-drain or push-pull
46 type and the IO speed can be selected depending on the VDD value.
47
48 [..]
49 All ports have external interrupt/event capability. To use external interrupt
50 lines, the port must be configured in input mode. All available GPIO pins are
51 connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
52
53 [..]
54 The external interrupt/event controller consists of up to 23 edge detectors
55 (16 lines are connected to GPIO) for generating event/interrupt requests (each
56 input line can be independently configured to select the type (interrupt or event)
57 and the corresponding trigger event (rising or falling or both). Each line can
58 also be masked independently.
59
60 ##### How to use this driver #####
61 ==============================================================================
62 [..]
63 (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
64
65 (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
66 (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
67 (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
68 structure.
69 (++) In case of Output or alternate function mode selection: the speed is
70 configured through "Speed" member from GPIO_InitTypeDef structure.
71 (++) In alternate mode is selection, the alternate function connected to the IO
72 is configured through "Alternate" member from GPIO_InitTypeDef structure.
73 (++) Analog mode is required when a pin is to be used as ADC channel
74 or DAC output.
75 (++) In case of external interrupt/event selection the "Mode" member from
76 GPIO_InitTypeDef structure select the type (interrupt or event) and
77 the corresponding trigger event (rising or falling or both).
78
79 (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
80 mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
81 HAL_NVIC_EnableIRQ().
82
83 (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
84
85 (#) To set/reset the level of a pin configured in output mode use
86 HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
87
88 (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
89
90
91 (#) During and just after reset, the alternate functions are not
92 active and the GPIO pins are configured in input floating mode (except JTAG
93 pins).
94
95 (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
96 (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
97 priority over the GPIO function.
98
99 (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
100 general purpose PH0 and PH1, respectively, when the HSE oscillator is off.
101 The HSE has priority over the GPIO function.
102
103 @endverbatim
104 ******************************************************************************
105 */
106
107 /* Includes ------------------------------------------------------------------*/
108 #include "stm32f4xx_hal.h"
109
110 /** @addtogroup STM32F4xx_HAL_Driver
111 * @{
112 */
113
114 /** @defgroup GPIO GPIO
115 * @brief GPIO HAL module driver
116 * @{
117 */
118
119 #ifdef HAL_GPIO_MODULE_ENABLED
120
121 /* Private typedef -----------------------------------------------------------*/
122 /* Private define ------------------------------------------------------------*/
123 /** @addtogroup GPIO_Private_Constants GPIO Private Constants
124 * @{
125 */
126
127 #define GPIO_NUMBER 16U
128 /**
129 * @}
130 */
131 /* Private macro -------------------------------------------------------------*/
132 /* Private variables ---------------------------------------------------------*/
133 /* Private function prototypes -----------------------------------------------*/
134 /* Private functions ---------------------------------------------------------*/
135 /* Exported functions --------------------------------------------------------*/
136 /** @defgroup GPIO_Exported_Functions GPIO Exported Functions
137 * @{
138 */
139
140 /** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
141 * @brief Initialization and Configuration functions
142 *
143 @verbatim
144 ===============================================================================
145 ##### Initialization and de-initialization functions #####
146 ===============================================================================
147 [..]
148 This section provides functions allowing to initialize and de-initialize the GPIOs
149 to be ready for use.
150
151 @endverbatim
152 * @{
153 */
154
155
156 /**
157 * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
158 * @param GPIOx where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
159 * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
160 * @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains
161 * the configuration information for the specified GPIO peripheral.
162 * @retval None
163 */
HAL_GPIO_Init(GPIO_TypeDef * GPIOx,GPIO_InitTypeDef * GPIO_Init)164 void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
165 {
166 uint32_t position;
167 uint32_t ioposition = 0x00U;
168 uint32_t iocurrent = 0x00U;
169 uint32_t temp = 0x00U;
170
171 /* Check the parameters */
172 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
173 assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
174 assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
175
176 /* Configure the port pins */
177 for(position = 0U; position < GPIO_NUMBER; position++)
178 {
179 /* Get the IO position */
180 ioposition = 0x01U << position;
181 /* Get the current IO position */
182 iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
183
184 if(iocurrent == ioposition)
185 {
186 /*--------------------- GPIO Mode Configuration ------------------------*/
187 /* In case of Output or Alternate function mode selection */
188 if(((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || \
189 (GPIO_Init->Mode & GPIO_MODE) == MODE_AF)
190 {
191 /* Check the Speed parameter */
192 assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
193 /* Configure the IO Speed */
194 temp = GPIOx->OSPEEDR;
195 temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2U));
196 temp |= (GPIO_Init->Speed << (position * 2U));
197 GPIOx->OSPEEDR = temp;
198
199 /* Configure the IO Output Type */
200 temp = GPIOx->OTYPER;
201 temp &= ~(GPIO_OTYPER_OT_0 << position) ;
202 temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);
203 GPIOx->OTYPER = temp;
204 }
205
206 if((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG)
207 {
208 /* Check the parameters */
209 assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
210
211 /* Activate the Pull-up or Pull down resistor for the current IO */
212 temp = GPIOx->PUPDR;
213 temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2U));
214 temp |= ((GPIO_Init->Pull) << (position * 2U));
215 GPIOx->PUPDR = temp;
216 }
217
218 /* In case of Alternate function mode selection */
219 if((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)
220 {
221 /* Check the Alternate function parameter */
222 assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
223 /* Configure Alternate function mapped with the current IO */
224 temp = GPIOx->AFR[position >> 3U];
225 temp &= ~(0xFU << ((uint32_t)(position & 0x07U) * 4U)) ;
226 temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & 0x07U) * 4U));
227 GPIOx->AFR[position >> 3U] = temp;
228 }
229
230 /* Configure IO Direction mode (Input, Output, Alternate or Analog) */
231 temp = GPIOx->MODER;
232 temp &= ~(GPIO_MODER_MODER0 << (position * 2U));
233 temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U));
234 GPIOx->MODER = temp;
235
236 /*--------------------- EXTI Mode Configuration ------------------------*/
237 /* Configure the External Interrupt or event for the current IO */
238 if((GPIO_Init->Mode & EXTI_MODE) != 0x00U)
239 {
240 /* Enable SYSCFG Clock */
241 __HAL_RCC_SYSCFG_CLK_ENABLE();
242
243 temp = SYSCFG->EXTICR[position >> 2U];
244 temp &= ~(0x0FU << (4U * (position & 0x03U)));
245 temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U)));
246 SYSCFG->EXTICR[position >> 2U] = temp;
247
248 /* Clear Rising Falling edge configuration */
249 temp = EXTI->RTSR;
250 temp &= ~((uint32_t)iocurrent);
251 if((GPIO_Init->Mode & TRIGGER_RISING) != 0x00U)
252 {
253 temp |= iocurrent;
254 }
255 EXTI->RTSR = temp;
256
257 temp = EXTI->FTSR;
258 temp &= ~((uint32_t)iocurrent);
259 if((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00U)
260 {
261 temp |= iocurrent;
262 }
263 EXTI->FTSR = temp;
264
265 temp = EXTI->EMR;
266 temp &= ~((uint32_t)iocurrent);
267 if((GPIO_Init->Mode & EXTI_EVT) != 0x00U)
268 {
269 temp |= iocurrent;
270 }
271 EXTI->EMR = temp;
272
273 /* Clear EXTI line configuration */
274 temp = EXTI->IMR;
275 temp &= ~((uint32_t)iocurrent);
276 if((GPIO_Init->Mode & EXTI_IT) != 0x00U)
277 {
278 temp |= iocurrent;
279 }
280 EXTI->IMR = temp;
281 }
282 }
283 }
284 }
285
286 /**
287 * @brief De-initializes the GPIOx peripheral registers to their default reset values.
288 * @param GPIOx where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
289 * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
290 * @param GPIO_Pin specifies the port bit to be written.
291 * This parameter can be one of GPIO_PIN_x where x can be (0..15).
292 * @retval None
293 */
HAL_GPIO_DeInit(GPIO_TypeDef * GPIOx,uint32_t GPIO_Pin)294 void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
295 {
296 uint32_t position;
297 uint32_t ioposition = 0x00U;
298 uint32_t iocurrent = 0x00U;
299 uint32_t tmp = 0x00U;
300
301 /* Check the parameters */
302 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
303
304 /* Configure the port pins */
305 for(position = 0U; position < GPIO_NUMBER; position++)
306 {
307 /* Get the IO position */
308 ioposition = 0x01U << position;
309 /* Get the current IO position */
310 iocurrent = (GPIO_Pin) & ioposition;
311
312 if(iocurrent == ioposition)
313 {
314 /*------------------------- EXTI Mode Configuration --------------------*/
315 tmp = SYSCFG->EXTICR[position >> 2U];
316 tmp &= (0x0FU << (4U * (position & 0x03U)));
317 if(tmp == ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U))))
318 {
319 /* Clear EXTI line configuration */
320 EXTI->IMR &= ~((uint32_t)iocurrent);
321 EXTI->EMR &= ~((uint32_t)iocurrent);
322
323 /* Clear Rising Falling edge configuration */
324 EXTI->FTSR &= ~((uint32_t)iocurrent);
325 EXTI->RTSR &= ~((uint32_t)iocurrent);
326
327 /* Configure the External Interrupt or event for the current IO */
328 tmp = 0x0FU << (4U * (position & 0x03U));
329 SYSCFG->EXTICR[position >> 2U] &= ~tmp;
330 }
331
332 /*------------------------- GPIO Mode Configuration --------------------*/
333 /* Configure IO Direction in Input Floating Mode */
334 GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (position * 2U));
335
336 /* Configure the default Alternate Function in current IO */
337 GPIOx->AFR[position >> 3U] &= ~(0xFU << ((uint32_t)(position & 0x07U) * 4U)) ;
338
339 /* Deactivate the Pull-up and Pull-down resistor for the current IO */
340 GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << (position * 2U));
341
342 /* Configure the default value IO Output Type */
343 GPIOx->OTYPER &= ~(GPIO_OTYPER_OT_0 << position) ;
344
345 /* Configure the default value for IO Speed */
346 GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2U));
347 }
348 }
349 }
350
351 /**
352 * @}
353 */
354
355 /** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
356 * @brief GPIO Read and Write
357 *
358 @verbatim
359 ===============================================================================
360 ##### IO operation functions #####
361 ===============================================================================
362
363 @endverbatim
364 * @{
365 */
366
367 /**
368 * @brief Reads the specified input port pin.
369 * @param GPIOx where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
370 * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
371 * @param GPIO_Pin specifies the port bit to read.
372 * This parameter can be GPIO_PIN_x where x can be (0..15).
373 * @retval The input port pin value.
374 */
HAL_GPIO_ReadPin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)375 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
376 {
377 GPIO_PinState bitstatus;
378
379 /* Check the parameters */
380 assert_param(IS_GPIO_PIN(GPIO_Pin));
381
382 if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
383 {
384 bitstatus = GPIO_PIN_SET;
385 }
386 else
387 {
388 bitstatus = GPIO_PIN_RESET;
389 }
390 return bitstatus;
391 }
392
393 /**
394 * @brief Sets or clears the selected data port bit.
395 *
396 * @note This function uses GPIOx_BSRR register to allow atomic read/modify
397 * accesses. In this way, there is no risk of an IRQ occurring between
398 * the read and the modify access.
399 *
400 * @param GPIOx where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
401 * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
402 * @param GPIO_Pin specifies the port bit to be written.
403 * This parameter can be one of GPIO_PIN_x where x can be (0..15).
404 * @param PinState specifies the value to be written to the selected bit.
405 * This parameter can be one of the GPIO_PinState enum values:
406 * @arg GPIO_PIN_RESET: to clear the port pin
407 * @arg GPIO_PIN_SET: to set the port pin
408 * @retval None
409 */
HAL_GPIO_WritePin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin,GPIO_PinState PinState)410 void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
411 {
412 /* Check the parameters */
413 assert_param(IS_GPIO_PIN(GPIO_Pin));
414 assert_param(IS_GPIO_PIN_ACTION(PinState));
415
416 if(PinState != GPIO_PIN_RESET)
417 {
418 GPIOx->BSRR = GPIO_Pin;
419 }
420 else
421 {
422 GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
423 }
424 }
425
426 /**
427 * @brief Toggles the specified GPIO pins.
428 * @param GPIOx Where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
429 * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
430 * @param GPIO_Pin Specifies the pins to be toggled.
431 * @retval None
432 */
HAL_GPIO_TogglePin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)433 void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
434 {
435 uint32_t odr;
436
437 /* Check the parameters */
438 assert_param(IS_GPIO_PIN(GPIO_Pin));
439
440 /* get current Output Data Register value */
441 odr = GPIOx->ODR;
442
443 /* Set selected pins that were at low level, and reset ones that were high */
444 GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
445 }
446
447 /**
448 * @brief Locks GPIO Pins configuration registers.
449 * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
450 * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
451 * @note The configuration of the locked GPIO pins can no longer be modified
452 * until the next reset.
453 * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F4 family
454 * @param GPIO_Pin specifies the port bit to be locked.
455 * This parameter can be any combination of GPIO_PIN_x where x can be (0..15).
456 * @retval None
457 */
HAL_GPIO_LockPin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)458 HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
459 {
460 __IO uint32_t tmp = GPIO_LCKR_LCKK;
461
462 /* Check the parameters */
463 assert_param(IS_GPIO_PIN(GPIO_Pin));
464
465 /* Apply lock key write sequence */
466 tmp |= GPIO_Pin;
467 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
468 GPIOx->LCKR = tmp;
469 /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
470 GPIOx->LCKR = GPIO_Pin;
471 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
472 GPIOx->LCKR = tmp;
473 /* Read LCKR register. This read is mandatory to complete key lock sequence */
474 tmp = GPIOx->LCKR;
475
476 /* Read again in order to confirm lock is active */
477 if((GPIOx->LCKR & GPIO_LCKR_LCKK) != RESET)
478 {
479 return HAL_OK;
480 }
481 else
482 {
483 return HAL_ERROR;
484 }
485 }
486
487 /**
488 * @brief This function handles EXTI interrupt request.
489 * @param GPIO_Pin Specifies the pins connected EXTI line
490 * @retval None
491 */
HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)492 void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
493 {
494 /* EXTI line interrupt detected */
495 if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
496 {
497 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
498 HAL_GPIO_EXTI_Callback(GPIO_Pin);
499 }
500 }
501
502 /**
503 * @brief EXTI line detection callbacks.
504 * @param GPIO_Pin Specifies the pins connected EXTI line
505 * @retval None
506 */
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)507 __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
508 {
509 /* Prevent unused argument(s) compilation warning */
510 UNUSED(GPIO_Pin);
511 /* NOTE: This function Should not be modified, when the callback is needed,
512 the HAL_GPIO_EXTI_Callback could be implemented in the user file
513 */
514 }
515
516 /**
517 * @}
518 */
519
520
521 /**
522 * @}
523 */
524
525 #endif /* HAL_GPIO_MODULE_ENABLED */
526 /**
527 * @}
528 */
529
530 /**
531 * @}
532 */
533
534