From 116b304541f75a7975e7cdfb0689e673a9782d09 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 14 Jul 2025 14:58:49 -0400 Subject: [PATCH] avr: Switch to input state prior to enabling pullup in gpio_in_reset() If switching a pin from output low to input with pullup, there is an intermediate state of either driven high or high impedance without a pullup. Similarly, when switching from output high to input without a pullup, there is an intermediate state of either driven low or high impedence with a pullup. In both cases it is preferable for the latter transition. Also, calculate the final setting prior to making any changes to reduce the time in that intermediate state. Signed-off-by: Kevin O'Connor --- src/avr/gpio.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/avr/gpio.c b/src/avr/gpio.c index d10fc2a1..f5225177 100644 --- a/src/avr/gpio.c +++ b/src/avr/gpio.c @@ -70,8 +70,10 @@ void gpio_out_reset(struct gpio_out g, uint8_t val) { irqstatus_t flag = irq_save(); - g.regs->out = val ? (g.regs->out | g.bit) : (g.regs->out & ~g.bit); - g.regs->mode |= g.bit; + uint8_t newmode = g.regs->mode | g.bit; + uint8_t newout = val ? (g.regs->out | g.bit) : (g.regs->out & ~g.bit); + g.regs->out = newout; + g.regs->mode = newmode; irq_restore(flag); } @@ -114,8 +116,10 @@ void gpio_in_reset(struct gpio_in g, int8_t pull_up) { irqstatus_t flag = irq_save(); - g.regs->out = pull_up > 0 ? (g.regs->out | g.bit) : (g.regs->out & ~g.bit); - g.regs->mode &= ~g.bit; + uint8_t newout = pull_up>0 ? (g.regs->out | g.bit) : (g.regs->out & ~g.bit); + uint8_t newmode = g.regs->mode & ~g.bit; + g.regs->mode = newmode; + g.regs->out = newout; irq_restore(flag); }