From dddfb681c737c5623dc270bf6c8e59fd3b13b092 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 27 Feb 2019 11:07:51 -0500 Subject: [PATCH] pins: Add support for pull down resistors Add initial support for selecting pull down resistors (for micro-controllers that support it). Signed-off-by: Kevin O'Connor --- klippy/pins.py | 6 ++++-- src/atsam/gpio.c | 39 ++++++++++++++++++++++++++++----------- src/avr/gpio.c | 4 ++-- src/lpc176x/gpio.c | 6 +++--- src/stm32f1/gpio.c | 3 ++- src/tmcuart.c | 2 +- 6 files changed, 40 insertions(+), 20 deletions(-) diff --git a/klippy/pins.py b/klippy/pins.py index 47bd87b5..90679ad1 100644 --- a/klippy/pins.py +++ b/klippy/pins.py @@ -215,8 +215,10 @@ class PrinterPins: share_type=None): desc = pin_desc.strip() pullup = invert = 0 - if can_pullup and desc.startswith('^'): + if can_pullup and (desc.startswith('^') or desc.startswith('~')): pullup = 1 + if desc.startswith('~'): + pullup = -1 desc = desc[1:].strip() if can_invert and desc.startswith('!'): invert = 1 @@ -227,7 +229,7 @@ class PrinterPins: chip_name, pin = [s.strip() for s in desc.split(':', 1)] if chip_name not in self.chips: raise error("Unknown pin chip name '%s'" % (chip_name,)) - if [c for c in '^!: ' if c in pin]: + if [c for c in '^~!: ' if c in pin]: format = "" if can_pullup: format += "[^] " diff --git a/src/atsam/gpio.c b/src/atsam/gpio.c index 5308e546..768a3949 100644 --- a/src/atsam/gpio.c +++ b/src/atsam/gpio.c @@ -28,6 +28,28 @@ static Pio * const digital_regs[] = { * Pin multiplexing ****************************************************************/ +static void +set_pull_up(Pio *regs, uint32_t bit, int32_t pull_up) +{ +#if CONFIG_MACH_SAM3X + if (pull_up > 0) + regs->PIO_PUER = bit; + else + regs->PIO_PUDR = bit; +#else + if (pull_up > 0) { + regs->PIO_PPDDR = bit; + regs->PIO_PUER = bit; + } else if (pull_up < 0) { + regs->PIO_PUDR = bit; + regs->PIO_PPDER = bit; + } else { + regs->PIO_PUDR = bit; + regs->PIO_PPDDR = bit; + } +#endif +} + void gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up) { @@ -40,11 +62,7 @@ gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up) regs->PIO_ABCDSR[0] = (regs->PIO_ABCDSR[0] & ~bit) | (pt & 0x01 ? bit : 0); regs->PIO_ABCDSR[1] = (regs->PIO_ABCDSR[1] & ~bit) | (pt & 0x02 ? bit : 0); #endif - - if (pull_up > 0) - regs->PIO_PUER = bit; - else - regs->PIO_PUDR = bit; + set_pull_up(regs, bit, pull_up); regs->PIO_PDR = bit; } @@ -78,7 +96,7 @@ gpio_out_reset(struct gpio_out g, uint8_t val) regs->PIO_OER = g.bit; regs->PIO_OWER = g.bit; regs->PIO_PER = g.bit; - regs->PIO_PUDR = g.bit; + set_pull_up(regs, g.bit, 0); irq_restore(flag); } @@ -113,13 +131,15 @@ gpio_in_setup(uint8_t pin, int8_t pull_up) { if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) goto fail; + if (CONFIG_MACH_SAM3X && pull_up < 0) + goto fail; uint32_t port = GPIO2PORT(pin); enable_pclock(ID_PIOA + port); struct gpio_in g = { .regs=digital_regs[port], .bit=GPIO2BIT(pin) }; gpio_in_reset(g, pull_up); return g; fail: - shutdown("Not an input pin"); + shutdown("Not a valid input pin"); } void @@ -127,10 +147,7 @@ gpio_in_reset(struct gpio_in g, int8_t pull_up) { Pio *regs = g.regs; irqstatus_t flag = irq_save(); - if (pull_up) - regs->PIO_PUER = g.bit; - else - regs->PIO_PUDR = g.bit; + set_pull_up(regs, g.bit, pull_up); regs->PIO_ODR = g.bit; regs->PIO_PER = g.bit; irq_restore(flag); diff --git a/src/avr/gpio.c b/src/avr/gpio.c index c7ca1220..6ff21c26 100644 --- a/src/avr/gpio.c +++ b/src/avr/gpio.c @@ -74,7 +74,7 @@ gpio_out_write(struct gpio_out g, uint8_t val) struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up) { - if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) + if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs) || pull_up < 0) goto fail; struct gpio_digital_regs *regs = GPIO2REGS(pin); if (! regs) @@ -83,7 +83,7 @@ gpio_in_setup(uint8_t pin, int8_t pull_up) gpio_in_reset(g, pull_up); return g; fail: - shutdown("Not an input pin"); + shutdown("Not a valid input pin"); } void diff --git a/src/lpc176x/gpio.c b/src/lpc176x/gpio.c index 0b5fb1a9..5c76ec55 100644 --- a/src/lpc176x/gpio.c +++ b/src/lpc176x/gpio.c @@ -23,7 +23,7 @@ static LPC_GPIO_TypeDef * const digital_regs[] = { // Set the mode and extended function of a pin void -gpio_peripheral(uint32_t gpio, int func, int pullup) +gpio_peripheral(uint32_t gpio, int func, int pull_up) { uint32_t bank_pos = GPIO2PORT(gpio) * 2, pin_pos = (gpio % 32) * 2; if (pin_pos >= 32) { @@ -31,12 +31,12 @@ gpio_peripheral(uint32_t gpio, int func, int pullup) bank_pos++; } uint32_t sel_bits = (func & 0x03) << pin_pos, mask = ~(0x03 << pin_pos); - uint32_t mode_bits = (pullup ? 0x00 : 0x02) << pin_pos; + uint32_t mode = (pull_up ? (pull_up > 0 ? 0x00 : 0x03) : 0x02) << pin_pos; volatile uint32_t *pinsel = &LPC_PINCON->PINSEL0; volatile uint32_t *pinmode = &LPC_PINCON->PINMODE0; irqstatus_t flag = irq_save(); pinsel[bank_pos] = (pinsel[bank_pos] & mask) | sel_bits; - pinmode[bank_pos] = (pinmode[bank_pos] & mask) | mode_bits; + pinmode[bank_pos] = (pinmode[bank_pos] & mask) | mode; irq_restore(flag); } diff --git a/src/stm32f1/gpio.c b/src/stm32f1/gpio.c index e6df3888..ed950461 100644 --- a/src/stm32f1/gpio.c +++ b/src/stm32f1/gpio.c @@ -114,7 +114,8 @@ gpio_in_reset(struct gpio_in g, int8_t pull_up) irqstatus_t flag = irq_save(); if (pull_up) { LL_GPIO_SetPinMode(g.regs, g.bit, LL_GPIO_MODE_INPUT); - LL_GPIO_SetPinPull(g.regs, g.bit, LL_GPIO_PULL_UP); + uint32_t p = pull_up > 0 ? LL_GPIO_PULL_UP : LL_GPIO_PULL_DOWN; + LL_GPIO_SetPinPull(g.regs, g.bit, p); } else { LL_GPIO_SetPinMode(g.regs, g.bit, LL_GPIO_MODE_FLOATING); } diff --git a/src/tmcuart.c b/src/tmcuart.c index 82846b88..e4b04cb8 100644 --- a/src/tmcuart.c +++ b/src/tmcuart.c @@ -176,7 +176,7 @@ command_config_tmcuart(uint32_t *args) , sizeof(*t)); uint8_t pull_up = args[2]; uint32_t rx_pin = args[1], tx_pin = args[3]; - t->rx_pin = gpio_in_setup(rx_pin, pull_up); + t->rx_pin = gpio_in_setup(rx_pin, !!pull_up); t->tx_pin = gpio_out_setup(tx_pin, 1); t->cfg_bit_time = args[4]; t->flags = (TU_LINE_HIGH | (pull_up ? TU_PULLUP : 0)