Skip to content

Commit 1dffebd

Browse files
Rework the sequence of GPIO registers in stm32l0_gpio_pin_configure to avoid suprious edges
1 parent 45b40b9 commit 1dffebd

File tree

4 files changed

+39
-24
lines changed

4 files changed

+39
-24
lines changed
144 Bytes
Binary file not shown.
144 Bytes
Binary file not shown.
144 Bytes
Binary file not shown.

system/STM32L0xx/Source/stm32l0_gpio.c

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014-2018 Thomas Roell. All rights reserved.
2+
* Copyright (c) 2014-2019 Thomas Roell. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to
@@ -103,37 +103,52 @@ void stm32l0_gpio_pin_configure(unsigned int pin, unsigned int mode)
103103
RCC->IOPENR |= (RCC_IOPENR_IOPAEN << group);
104104
RCC->IOPENR;
105105

106-
/* First switch the pin back to analog mode */
107-
GPIO->MODER |= (0x00000003 << (index << 1));
108-
109-
/* Set OPTYPER */
110-
GPIO->OTYPER = (GPIO->OTYPER & ~(0x00000001 << index)) | (((mode & STM32L0_GPIO_OTYPE_MASK) >> STM32L0_GPIO_OTYPE_SHIFT) << index);
111-
112-
/* Set OPSPEEDR */
113-
GPIO->OSPEEDR = (GPIO->OSPEEDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_OSPEED_MASK) >> STM32L0_GPIO_OSPEED_SHIFT) << (index << 1));
114-
115-
/* Set PUPD */
116-
GPIO->PUPDR = (GPIO->PUPDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_PUPD_MASK) >> STM32L0_GPIO_PUPD_SHIFT) << (index << 1));
117-
118-
/* Set AFRL/AFRH */
119-
GPIO->AFR[index >> 3] = (GPIO->AFR[index >> 3] & ~(0x0000000f << ((index & 7) << 2))) | (afsel << ((index & 7) << 2));
120-
121-
GPIO->MODER = (GPIO->MODER & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) << (index << 1));
122-
123-
// if ((((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) == STM32L0_GPIO_MODE_INPUT) || (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) == STM32L0_GPIO_MODE_OUTPUT))
124-
if (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) != STM32L0_GPIO_MODE_ANALOG)
125-
{
126-
stm32l0_gpio_device.enables[port] |= (1 << index);
127-
}
128-
else
106+
/* If the mode is ANALOG, set MODER first */
107+
if (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) == STM32L0_GPIO_MODE_ANALOG)
129108
{
109+
GPIO->MODER |= (0x00000003 << (index << 1));
110+
130111
stm32l0_gpio_device.enables[port] &= ~(1 << index);
131112

132113
if (!stm32l0_gpio_device.enables[port])
133114
{
134115
RCC->IOPENR &= ~(RCC_IOPENR_IOPAEN << group);
135116
}
136117
}
118+
else
119+
{
120+
/* Set AFRL/AFRH */
121+
GPIO->AFR[index >> 3] = (GPIO->AFR[index >> 3] & ~(0x0000000f << ((index & 7) << 2))) | (afsel << ((index & 7) << 2));
122+
123+
/* Set OPSPEEDR */
124+
GPIO->OSPEEDR = (GPIO->OSPEEDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_OSPEED_MASK) >> STM32L0_GPIO_OSPEED_SHIFT) << (index << 1));
125+
126+
/* Set OPTYPER */
127+
GPIO->OTYPER = (GPIO->OTYPER & ~(0x00000001 << index)) | (((mode & STM32L0_GPIO_OTYPE_MASK) >> STM32L0_GPIO_OTYPE_SHIFT) << index);
128+
129+
/* If the mode is OUTPUT, or OUTPUT OPENDRAIN with a ODR of 0. then first switch MODER and then PUPDR
130+
* to avoid spurious edges. N.b. ALTERNATE is assumed to be INPUT before the peripheral drives it.
131+
*/
132+
if (((mode & STM32L0_GPIO_MODE_MASK) == STM32L0_GPIO_MODE_OUTPUT) &&
133+
(((mode & STM32L0_GPIO_OTYPE_MASK) != STM32L0_GPIO_OTYPE_OPENDRAIN) || !(GPIO->ODR & (0x00000001 << index))))
134+
{
135+
/* Set MODE */
136+
GPIO->MODER = (GPIO->MODER & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) << (index << 1));
137+
138+
/* Set PUPD */
139+
GPIO->PUPDR = (GPIO->PUPDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_PUPD_MASK) >> STM32L0_GPIO_PUPD_SHIFT) << (index << 1));
140+
}
141+
else
142+
{
143+
/* Set PUPD */
144+
GPIO->PUPDR = (GPIO->PUPDR & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_PUPD_MASK) >> STM32L0_GPIO_PUPD_SHIFT) << (index << 1));
145+
146+
/* Set MODE */
147+
GPIO->MODER = (GPIO->MODER & ~(0x00000003 << (index << 1))) | (((mode & STM32L0_GPIO_MODE_MASK) >> STM32L0_GPIO_MODE_SHIFT) << (index << 1));
148+
}
149+
150+
stm32l0_gpio_device.enables[port] |= (1 << index);
151+
}
137152

138153
stm32l0_gpio_device.mode[port] &= ~(0x00000003 << (index << 1));
139154
stm32l0_gpio_device.pupd[port] &= ~(0x00000003 << (index << 1));

0 commit comments

Comments
 (0)