add Chapter13

This commit is contained in:
Amar Mahmutbegovic
2024-11-03 14:41:27 +01:00
parent 4400c3532f
commit 60b08160ba
481 changed files with 650820 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
#pragma once
#include <cstdint>
#include <functional>
namespace hal
{
class gpio
{
public:
gpio(const std::function<void()> & on_press = nullptr);
void execute_interrupt_handler() const;
[[nodiscard]] virtual bool is_interrupt_generated() const = 0;
virtual void clear_interrupt_flag() const = 0;
private:
std::function<void()> on_press_;
};
}; // namespace hal

View File

@@ -0,0 +1,19 @@
#pragma once
#include <array>
#include <cstdint>
#include <gpio.hpp>
namespace hal {
struct gpio_interrupt_manager {
static void register_interrupt_handler(gpio * pin);
static void execute_interrupt_handlers();
static constexpr std::size_t c_gpio_handlers_num = 16;
static inline std::array<gpio*, c_gpio_handlers_num> gpio_handlers{};
static inline std::size_t w_idx = 0;
};
};

View File

@@ -0,0 +1,70 @@
#include <gpio.hpp>
#include <stm32f072xb.h>
namespace hal {
enum class pin : uint16_t {
p_invalid = 0,
p0 = 0x0001U,
p1 = 0x0002U,
p2 = 0x0004U,
p3 = 0x0008U,
p4 = 0x0010U,
p5 = 0x0020U,
p6 = 0x0040U,
p7 = 0x0080U,
p8 = 0x0100U,
p9 = 0x0200U,
p10 = 0x0400U,
p11 = 0x0800U,
p12 = 0x1000U,
p13 = 0x2000U,
p14 = 0x4000U,
p15 = 0x8000U,
all = 0xFFFFU
};
struct port_a {
static constexpr uint8_t c_pin_num = 16;
static inline GPIO_TypeDef * port = reinterpret_cast<GPIO_TypeDef*>(GPIOA);
static void init_clock () {
__HAL_RCC_GPIOA_CLK_ENABLE();
}
};
template<typename Port>
class gpio_stm32 : public gpio {
public:
gpio_stm32(pin the_pin, const std::function<void()> & on_press = nullptr)
: gpio(on_press), the_pin_(the_pin) {
Port::init_clock();
GPIO_InitTypeDef GPIO_InitStruct { static_cast<uint16_t>(the_pin),
GPIO_MODE_IT_RISING,
GPIO_NOPULL,
GPIO_SPEED_FREQ_LOW,
0 };
HAL_GPIO_Init(Port::port, &GPIO_InitStruct);
if(on_press) {
enable_interrupt();
}
}
[[nodiscard]] bool is_interrupt_generated() const override {
return __HAL_GPIO_EXTI_GET_IT(static_cast<uint16_t>(the_pin_));
}
void clear_interrupt_flag() const override {
__HAL_GPIO_EXTI_CLEAR_IT(static_cast<uint16_t>(the_pin_));
}
private:
pin the_pin_ = pin::p_invalid;
void enable_interrupt() {
// TODO: check EXTI line macro according to pin used
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
};
};

View File

@@ -0,0 +1,21 @@
#include <gpio.hpp>
#include <gpio_interrupt_manager.hpp>
namespace hal {
gpio::gpio(const std::function<void()> & on_press) {
on_press_ = on_press;
gpio_interrupt_manager::register_interrupt_handler(this);
}
void gpio::execute_interrupt_handler () const {
if(is_interrupt_generated())
{
clear_interrupt_flag();
if(on_press_) {
on_press_();
}
}
}
};

View File

@@ -0,0 +1,17 @@
#include <gpio_interrupt_manager.hpp>
namespace hal {
void gpio_interrupt_manager::register_interrupt_handler(gpio * pin) {
gpio_handlers.at(w_idx++) = pin;
}
void gpio_interrupt_manager::execute_interrupt_handlers() {
for(std::size_t i = 0; i < w_idx; i++) {
gpio_handlers[i]->execute_interrupt_handler();
}
}
extern "C" void EXTI4_15_IRQHandler(void) {
gpio_interrupt_manager::execute_interrupt_handlers();
}
};