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