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.h | 217 +++++------------------------------------------------- gpio/gpio_nrf.h | 83 +++++++++++++++++++++ gpio/gpio_stm32.h | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 302 insertions(+), 200 deletions(-) create mode 100644 gpio/gpio_nrf.h create mode 100644 gpio/gpio_stm32.h (limited to 'gpio') diff --git a/gpio/gpio.h b/gpio/gpio.h index 392b2f7..bb4201e 100644 --- a/gpio/gpio.h +++ b/gpio/gpio.h @@ -1,218 +1,25 @@ -#ifndef GPIO_H -#define GPIO_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; +#ifndef LAKS_GPIO_GPIO_H +#define LAKS_GPIO_GPIO_H #if defined(STM32F1) +#include "gpio_stm32.h" static GPIO_t GPIOA(0x40010800); static GPIO_t GPIOB(0x40010c00); static GPIO_t GPIOC(0x40011000); static GPIO_t GPIOD(0x40011400); static GPIO_t GPIOE(0x40011800); + #elif defined(STM32F3) +#include "gpio_stm32.h" static GPIO_t GPIOA(0x48000000); static GPIO_t GPIOB(0x48000400); static GPIO_t GPIOC(0x48000800); static GPIO_t GPIOD(0x48000c00); static GPIO_t GPIOE(0x48001000); static GPIO_t GPIOF(0x48001400); + #elif defined(STM32F4) +#include "gpio_stm32.h" static GPIO_t GPIOA(0x40020000); static GPIO_t GPIOB(0x40020400); static GPIO_t GPIOC(0x40020800); @@ -222,19 +29,29 @@ static GPIO_t GPIOF(0x40021400); static GPIO_t GPIOG(0x40021800); static GPIO_t GPIOH(0x40021c00); static GPIO_t GPIOI(0x40022000); + #elif defined(STM32L0) +#include "gpio_stm32.h" static GPIO_t GPIOA(0x50000000); static GPIO_t GPIOB(0x50000400); static GPIO_t GPIOC(0x50000800); static GPIO_t GPIOD(0x50000c00); static GPIO_t GPIOH(0x50001c00); + #elif defined(STM32WB) +#include "gpio_stm32.h" static GPIO_t GPIOA(0x48000000); static GPIO_t GPIOB(0x48000400); static GPIO_t GPIOC(0x48000800); static GPIO_t GPIOD(0x48000c00); static GPIO_t GPIOE(0x48001000); static GPIO_t GPIOH(0x48001c00); + +#elif defined(NRF52840) +#include "gpio_nrf.h" +static GPIO_t P0(0x50000000); +static GPIO_t P1(0x50000300); + #endif #endif diff --git a/gpio/gpio_nrf.h b/gpio/gpio_nrf.h new file mode 100644 index 0000000..44c85f4 --- /dev/null +++ b/gpio/gpio_nrf.h @@ -0,0 +1,83 @@ +#ifndef LAKS_GPIO_GPIO_NRF_H +#define LAKS_GPIO_GPIO_NRF_H + +#include + +struct GPIO_reg_t { + uint32_t _reserved; + volatile uint32_t OUT; + volatile uint32_t OUTSET; + volatile uint32_t OUTCLR; + volatile uint32_t IN; + volatile uint32_t DIR; + volatile uint32_t DIRSET; + volatile uint32_t DIRCLR; + volatile uint32_t LATCH; + volatile uint32_t DETECTMODE; + uint32_t _reserved_1[118]; + volatile uint32_t PIN_CNF[32]; +}; + +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 { + Input, + Output, + }; + + void set_mode(Mode m) { + switch(m) { + case Input: + g.reg.DIRCLR = 1 << n; + break; + case Output: + g.reg.DIRSET = 1 << n; + break; + } + } + + void on() { + g.reg.OUTSET = 1 << n; + } + + void off() { + g.reg.OUTCLR = 1 << n; + } + + void set(bool value) { + if(value) { + on(); + } else { + off(); + } + } + + bool get() { + return g.reg.IN & (1 << n); + } + + void toggle() { + set(!(g.reg.OUT & (1 << n))); + } + }; + + constexpr GPIO_t(uint32_t reg_addr) : reg(*(GPIO_reg_t*)(reg_addr + 0x500)) {} + + constexpr Pin operator[](int pin) { + return Pin(*this, pin); + } +}; + +typedef GPIO_t::Pin Pin; + +#endif 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