Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit 8f492a2

Browse files
authored
Merge pull request ARMmbed#2920 from LMESTM/fix_pull_overwrite
STM32F4: Fix pull overwrite
2 parents d38d82b + 3f81f5d commit 8f492a2

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

targets/TARGET_STM/TARGET_STM32F4/gpio_irq_api.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ static void gpio_irq6(void)
163163
}
164164

165165
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
166+
extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
166167

167168
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
168169
{
@@ -267,15 +268,14 @@ void gpio_irq_free(gpio_irq_t *obj)
267268
gpio_channel->channel_gpio[gpio_idx] = 0;
268269
gpio_channel->channel_pin[gpio_idx] = 0;
269270

270-
// Disable EXTI line
271-
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
271+
// Disable EXTI line, but don't change pull-up config
272+
pin_function_gpiomode(obj->pin, STM_MODE_INPUT);
272273
obj->event = EDGE_NONE;
273274
}
274275

275276
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
276277
{
277278
uint32_t mode = STM_MODE_IT_EVT_RESET;
278-
uint32_t pull = GPIO_NOPULL;
279279

280280
if (enable) {
281281
if (event == IRQ_RISE) {
@@ -317,7 +317,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
317317
}
318318
}
319319

320-
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
320+
pin_function_gpiomode(obj->pin, mode);
321321
}
322322

323323
void gpio_irq_enable(gpio_irq_t *obj)

targets/TARGET_STM/TARGET_STM32F4/pinmap.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,5 +178,20 @@ void pin_mode(PinName pin, PinMode mode)
178178
}
179179
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
180180
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
181+
}
182+
183+
/* Internal function for setting the gpiomode/function
184+
* without changing Pull mode
185+
*/
186+
void pin_function_gpiomode(PinName pin, uint32_t gpiomode) {
187+
188+
/* Read current pull state from HW to avoid over-write*/
189+
uint32_t port_index = STM_PORT(pin);
190+
uint32_t pin_index = STM_PIN(pin);
191+
GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index);
192+
uint32_t temp = gpio->PUPDR;
193+
uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0;
181194

195+
/* Then re-use global function for updating the mode part*/
196+
pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0));
182197
}

0 commit comments

Comments
 (0)