add Chapter11

This commit is contained in:
Amar Mahmutbegovic
2024-09-22 16:52:43 +02:00
parent 7203d7ab66
commit f10d0ef610
205 changed files with 302793 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
#include <functional>
//#include <gpio_interrupt_handler.hpp>
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();
}
};

View File

@@ -0,0 +1,33 @@
#pragma once
#include <cstdint>
#include <stm32f0xx_hal.h>
namespace hal
{
inline void init()
{
HAL_Init();
}
inline std::uint32_t get_pc()
{
std::uint32_t pc;
__asm volatile ("mov %0, pc" : "=r" (pc) );
return pc;
}
struct time
{
static std::uint32_t get_ms()
{
return HAL_GetTick();
}
static void delay_ms(uint32_t delay)
{
HAL_Delay(delay);
}
};
}; // namespace hal

View File

@@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
#include <span>
namespace hal
{
class uart
{
public:
virtual void init(std::uint32_t baudrate) = 0;
virtual void write_array(const char * ptr, std::size_t len) = 0;
virtual void write(std::span<const char> data)
{
write_array(data.data(), data.size());
}
};
}; // namespace hal

View File

@@ -0,0 +1,29 @@
#pragma once
#include <span>
#include <cstdint>
#include <uart.hpp>
#include <stm32f0xx_hal.h>
#include <stm32f072xb.h>
namespace hal
{
class uart_stm32 : public uart
{
public:
uart_stm32(USART_TypeDef *inst);
void init(std::uint32_t baudrate = c_baudrate_default) override;
void write_array(const char * ptr, std::size_t len) override;
private:
UART_HandleTypeDef huart_;
USART_TypeDef *instance_;
std::uint32_t baudrate_;
static constexpr std::uint32_t c_baudrate_default = 115200;
};
}; // namespace hal

View File

@@ -0,0 +1,31 @@
#include <uart_stm32.hpp>
hal::uart_stm32::uart_stm32(USART_TypeDef *inst)
: instance_(inst)
{
}
void hal::uart_stm32::init(std::uint32_t baudrate)
{
huart_.Instance = instance_;
huart_.Init.BaudRate = baudrate;
huart_.Init.WordLength = UART_WORDLENGTH_8B;
huart_.Init.StopBits = UART_STOPBITS_1;
huart_.Init.Parity = UART_PARITY_NONE;
huart_.Init.Mode = UART_MODE_TX_RX;
huart_.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart_.Init.OverSampling = UART_OVERSAMPLING_16;
huart_.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart_.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
// TODO: add GPIO initialization for real hardware
huart_.MspInitCallback = nullptr;
HAL_UART_Init(&huart_);
}
void hal::uart_stm32::write_array(const char * ptr, std::size_t len)
{
// we must cast away costness due to ST HAL's API
char * data_ptr = const_cast<char *>(ptr);
HAL_UART_Transmit(&huart_, reinterpret_cast<uint8_t *>(data_ptr), len,
HAL_MAX_DELAY);
}