From 47400f16c6ca41330ebaca86b2251b289e016bd8 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 14 May 2021 16:42:41 +0300 Subject: [PATCH] GPIO hal prototype (#9) * gpio hal prototype * Example gpio hal usage * Use uint8_t for GPIO enums --- src/hal/gpio.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/hal/pins.h | 4 +-- src/main.cpp | 8 ++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/hal/gpio.h diff --git a/src/hal/gpio.h b/src/hal/gpio.h new file mode 100644 index 0000000..80f3545 --- /dev/null +++ b/src/hal/gpio.h @@ -0,0 +1,76 @@ +#include +#include + +namespace hal { +namespace gpio { + + struct GPIO_TypeDef { + volatile uint8_t PINx; + volatile uint8_t DDRx; + volatile uint8_t PORTx; + }; + + enum class Mode : uint8_t { + input = 0, + output, + }; + + enum class Pull : uint8_t { + none = 0, + up, + down, //not available on the AVR + }; + + enum class Level : uint8_t { + low = 0, + high, + }; + + struct GPIO_InitTypeDef { + Mode mode; + Pull pull; + Level level; + inline GPIO_InitTypeDef() + : mode(Mode::input) + , pull(Pull::none) {}; + inline GPIO_InitTypeDef(Mode mode, Pull pull) + : mode(mode) + , pull(pull) {}; + inline GPIO_InitTypeDef(Mode mode, Level level) + : mode(mode) + , level(level) {}; + }; + + inline void WritePin(GPIO_TypeDef *const port, const uint8_t pin, Level level) { + if (level == Level::high) + port->PORTx |= (1 << pin); + else + port->PORTx &= ~(1 << pin); + } + + inline Level ReadPin(GPIO_TypeDef *const port, const uint8_t pin) { + return (Level)(port->PINx & (1 << pin)); + } + + inline void TogglePin(GPIO_TypeDef *const port, const uint8_t pin) { + port->PINx |= (1 << pin); + } + + inline void Init(GPIO_TypeDef *const port, const uint8_t pin, GPIO_InitTypeDef GPIO_Init) { + if (GPIO_Init.mode == Mode::output) { + WritePin(port, pin, GPIO_Init.level); + port->DDRx |= (1 << pin); + } else { + port->DDRx &= ~(1 << pin); + WritePin(port, pin, (Level)GPIO_Init.pull); + } + } + +} +} + +#define GPIOB ((hal::gpio::GPIO_TypeDef *)&PINB) +#define GPIOC ((hal::gpio::GPIO_TypeDef *)&PINC) +#define GPIOD ((hal::gpio::GPIO_TypeDef *)&PIND) +#define GPIOE ((hal::gpio::GPIO_TypeDef *)&PINE) +#define GPIOF ((hal::gpio::GPIO_TypeDef *)&PINF) diff --git a/src/hal/pins.h b/src/hal/pins.h index 34a30f7..8745ad5 100644 --- a/src/hal/pins.h +++ b/src/hal/pins.h @@ -5,9 +5,7 @@ namespace hal { namespace pins { - /// pin access routines - void WritePin(uint8_t pin, uint8_t value); - uint8_t ReadPin(uint8_t pin); + /// pin definitions } // namespace pins } // namespace hal diff --git a/src/main.cpp b/src/main.cpp index cb84165..f26c6b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,11 @@ #include "logic/mm_control.h" +#include "hal/gpio.h" /// One-time setup of HW and SW components /// Called before entering the loop() function void setup(){ + using namespace hal::gpio; + hal::gpio::Init(GPIOB, 1, GPIO_InitTypeDef(Mode::output, Level::low)); } @@ -27,6 +30,11 @@ void loop(){ int main() { setup(); for(;;){ + using namespace hal::gpio; + WritePin(GPIOB, 5, Level::low); + TogglePin(GPIOB, 6); + if (hal::gpio::ReadPin(GPIOB, 7) == hal::gpio::Level::low) + break; loop(); } return 0;