Subversion Repositories DashDisplay

Rev

Rev 61 | Details | Compare with Previous | Last modification | View Log | RSS feed

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