From 148f1f2fdb494b86a8444f31b4011115d24f7425 Mon Sep 17 00:00:00 2001 From: Jeff McBride Date: Fri, 29 Oct 2021 17:21:51 -0700 Subject: [PATCH 1/2] [sam] GPIO setOutput overrides peripheral control Calling setOutput now overrides peripheral control of the pin. This behavior is consistent with the STM32 GPIO implementation, this commit also ensures output value is set before the output drive is enabled to prevent glitch. Co-authored-by: Christopher Durand --- src/modm/platform/gpio/sam/pin.hpp.in | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/modm/platform/gpio/sam/pin.hpp.in b/src/modm/platform/gpio/sam/pin.hpp.in index 2446fe9109..3b1ceb3534 100644 --- a/src/modm/platform/gpio/sam/pin.hpp.in +++ b/src/modm/platform/gpio/sam/pin.hpp.in @@ -183,20 +183,26 @@ public: inline static void setOutput() { + // Enable PIO control of the pin (disables peripheral control) + setPortReg(PIO_PER_OFFSET); + // Enable output driver setPortReg(PIO_OER_OFFSET); } inline static void setOutput(bool status) { - setOutput(); set(status); + setOutput(); } static void setInput() { - setPortReg(PIO_ODR_OFFSET); // Disable output driver + // Enable PIO control of the pin (disables peripheral control) + setPortReg(PIO_PER_OFFSET); + // Disable output driver + setPortReg(PIO_ODR_OFFSET); } static void @@ -336,19 +342,22 @@ public: setOutput() { setPortReg(PORT_DIRSET_OFFSET); + // Disable peripheral multiplexer + PinCfg::set(0); } inline static void setOutput(bool status) { - setOutput(); set(status); + setOutput(); } static void setInput() { setPortReg(PORT_DIRCLR_OFFSET); + PinCfg::set(PORT_PINCFG_INEN); } static void From c868f59fdf1272e327b16e6cffdecd0faad9cc0a Mon Sep 17 00:00:00 2001 From: Christopher Durand Date: Tue, 8 Feb 2022 01:40:43 +0100 Subject: [PATCH 2/2] [sam] Do not reset peripheral mode in configure(InputMode) for SAM D21 --- src/modm/platform/gpio/sam/pin.hpp.in | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/modm/platform/gpio/sam/pin.hpp.in b/src/modm/platform/gpio/sam/pin.hpp.in index 3b1ceb3534..bbd4095f0a 100644 --- a/src/modm/platform/gpio/sam/pin.hpp.in +++ b/src/modm/platform/gpio/sam/pin.hpp.in @@ -278,6 +278,7 @@ template struct PinCfgMixin { inline static void set(uint8_t){}; + inline static void set(uint8_t, uint8_t){}; }; template @@ -292,6 +293,18 @@ struct PinCfgMixin %% endfor PinCfgMixin::set(cfg); } + + inline static void + set(uint8_t setBits, uint8_t clearMask) + { +%% for port in ports + if constexpr (PinConfig::port == PortName::{{ port }}) { + auto& reg = PORT->Group[{{loop.index0}}].PINCFG[PinConfig::pin].reg; + reg = (reg & (~clearMask)) | setBits; + } +%% endfor + PinCfgMixin::set(setBits, clearMask); + } }; template @@ -371,7 +384,7 @@ public: configure(InputType type) { set(type == InputType::PullUp); - PinCfg::set(PORT_PINCFG_INEN | (type != InputType::Floating) << PORT_PINCFG_PULLEN_Pos); + PinCfg::set(PORT_PINCFG_INEN | (type != InputType::Floating) << PORT_PINCFG_PULLEN_Pos, PORT_PINCFG_PULLEN); } static void