From cad5bd6501868f9532d5b4a227ca156f9c9d1d8e Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Thu, 16 Sep 2021 11:09:30 +0200 Subject: Added NRF52 support. --- gpio/gpio_stm32.h | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 gpio/gpio_stm32.h (limited to 'gpio/gpio_stm32.h') diff --git a/gpio/gpio_stm32.h b/gpio/gpio_stm32.h new file mode 100644 index 0000000..635bcc9 --- /dev/null +++ b/gpio/gpio_stm32.h @@ -0,0 +1,202 @@ +#ifndef LAKS_GPIO_GPIO_STM32_H +#define LAKS_GPIO_GPIO_STM32_H + +#include + +struct GPIO_reg_t { + #if defined(STM32F1) + volatile uint32_t CRL; + volatile uint32_t CRH; + volatile uint32_t IDR; + volatile uint32_t ODR; + volatile uint32_t BSRR; + volatile uint32_t BRR; + volatile uint32_t LCKR; + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + volatile uint32_t MODER; + volatile uint32_t OTYPER; + volatile uint32_t OSPEEDR; + volatile uint32_t PUPDR; + volatile uint32_t IDR; + volatile uint32_t ODR; + volatile uint32_t BSRR; + volatile uint32_t LCKR; + volatile uint32_t AFRL; + volatile uint32_t AFRH; + #endif +}; + +class GPIO_t { + public: + GPIO_reg_t& reg; + + class Pin { + private: + const GPIO_t& g; + int n; + + public: + constexpr Pin(const GPIO_t& gpio, int pin) : g(gpio), n(pin) {} + + enum Mode { + #if defined(STM32F1) + Input = 0x4, + InputPull = 0x8, + Output = 0x3, + AF = 0xb, + Analog = 0x0, + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + Input, + Output, + AF, + Analog, + #endif + }; + + enum Type { + PushPull, + OpenDrain, + }; + + enum Pull { + PullNone, + PullUp, + PullDown, + }; + + enum Speed { + Low, + Medium, + Fast, + High, + }; + + void set_mode(Mode m) { + #if defined(STM32F1) + if(n < 8) { + g.reg.CRL = (g.reg.CRL & ~(0xf << (n * 4))) | m << (n * 4); + } else { + g.reg.CRH = (g.reg.CRH & ~(0xf << (n * 4 - 32))) | m << (n * 4 - 32); + } + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + g.reg.MODER = (g.reg.MODER & ~(3 << (n * 2))) | m << (n * 2); + #endif + } + + void set_type(Type t) { + #if defined(STM32F1) + // TODO: Unified configure() method? + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + if(t) { + g.reg.OTYPER |= 1 << n; + } else { + g.reg.OTYPER &= ~(1 << n); + } + #endif + } + + void set_pull(Pull p) { + #if defined(STM32F1) + // TODO: Unified configure() method? + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + g.reg.PUPDR = (g.reg.PUPDR & ~(3 << (n * 2))) | p << (n * 2); + #endif + } + + void set_af(int af) { + #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + if(n < 8) { + g.reg.AFRL = (g.reg.AFRL & ~(0xf << (n * 4))) | af << (n * 4); + } else { + g.reg.AFRH = (g.reg.AFRH & ~(0xf << (n * 4 - 32))) | af << (n * 4 - 32); + } + #endif + } + + void set_speed(Speed s) { + #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + g.reg.OSPEEDR = (g.reg.OSPEEDR & ~(3 << (n * 2))) | s << (n * 2); + #endif + } + + void on() { + g.reg.BSRR = 1 << n; + } + + void off() { + g.reg.BSRR = 1 << 16 << n; + } + + void set(bool value) { + if(value) { + on(); + } else { + off(); + } + } + + bool get() { + return g.reg.IDR & (1 << n); + } + + void toggle() { + set(!(g.reg.ODR & (1 << n))); + } + }; + + class PinArray { + private: + const GPIO_t& g; + int f; + int l; + + constexpr uint32_t mask1() { + return ((2 << l) - 1) ^ ((1 << f) - 1); + } + + constexpr uint32_t mask2() { + return ((4 << (l * 2)) - 1) ^ ((1 << (f * 2)) - 1); + } + + public: + constexpr PinArray(const GPIO_t& gpio, int first, int last) : g(gpio), f(first), l(last) {} + + #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) + void set_mode(Pin::Mode m) { + g.reg.MODER = (g.reg.MODER & ~mask2()) | ((0x55555555 * m) & mask2()); + } + + void set_type(Pin::Type t) { + g.reg.OTYPER = (g.reg.OTYPER & ~mask2()) | ((0x55555555 * t) & mask2()); + } + + void set_pull(Pin::Pull p) { + g.reg.PUPDR = (g.reg.PUPDR & ~mask2()) | ((0x55555555 * p) & mask2()); + } + #endif + + void set(uint16_t value) { + value <<= f; + g.reg.BSRR = ((~value & mask1()) << 16) | (value & mask1()); + } + + uint16_t get() { + return (g.reg.IDR & mask1()) >> f; + } + }; + + constexpr GPIO_t(uint32_t reg_addr) : reg(*(GPIO_reg_t*)reg_addr) {} + + constexpr Pin operator[](int pin) { + return Pin(*this, pin); + } + + constexpr PinArray array(int first, int last) { + return PinArray(*this, first, last); + } +}; + +typedef GPIO_t::Pin Pin; +typedef GPIO_t::PinArray PinArray; + +#endif -- cgit v1.2.3