I just started with embeddeded C++ since I only coded in C for the last year and I wanted to do/learn something while I'm in university.
First of the there is the Register manipulation class. I won't include the .cpp
file since stuff done there is trivial.
register.hpp:
class Reg {
public:
Reg(uint32_t *reg, uint32_t reset_value);
Reg();
uint32_t read();
bool bit_set(int n);
void reset();
void set_bit(int n);
void write(uint32_t n);
void clear_bit(int n);
private:
uint32_t *reg;
uint32_t reset_value;
};
gpio_port.hpp:
class gpio_port {
public:
gpio_port(GPIO_TypeDef *port);
gpio_port();
Reg moder;
Reg otyper;
Reg ospeedr;
Reg pupdr;
Reg idr;
Reg odr;
Reg bsrr;
Reg lckr;
Reg afrl;
Reg afrh;
private:
GPIO_TypeDef *port;
};
gpio_port.cpp:
gpio_port::gpio_port(GPIO_TypeDef* port) {
this->port = port;
this->moder = Reg((uint32_t *) &this->port->MODER, 0x0000);
this->otyper = Reg((uint32_t *) &this->port->OTYPER, 0x0000);
this->ospeedr = Reg((uint32_t *) &this->port->OSPEEDR, 0x0000);
this->pupdr = Reg((uint32_t *) &this->port->PUPDR, 0x0000);
this->idr = Reg((uint32_t *) &this->port->IDR, 0x0000);
this->odr = Reg((uint32_t *) &this->port->ODR, 0x0000);
this->bsrr = Reg((uint32_t *) &this->port->BSRR, 0x0000);
this->lckr = Reg((uint32_t *) &this->port->LCKR, 0x0000);
this->afrl = Reg((uint32_t *) &this->port->AFR[0], 0x0000);
this->afrh = Reg((uint32_t *) &this->port->AFR[1], 0x0000);
}
gpio_port::gpio_port() {
this->port = nullptr;
}
cosmic.hpp
namespace csmc {
namespace peripherals {
static gpio_port gpioa = gpio_port(GPIOA);
static gpio_port gpiob = gpio_port(GPIOB);
static gpio_port gpioc = gpio_port(GPIOC);
static gpio_port gpiod = gpio_port(GPIOD);
static gpio_port gpioe = gpio_port(GPIOE);
static gpio_port gpioh = gpio_port(GPIOH);
}
};
So here you see the Reg
class is the abstraction for each Register. It can be applied to any u32
value.
gpio_port
was a simple struct
first. But initializing it in the cosmic.hpp
for each GPIO port looked really messy so I moved it into a class.
The namespaces are the actual libray I want to write.
Here is some example usage:
#include "cosmic/cosmic.hpp"
using namespace csmc;
int main() {
gpio_port gpioa = peripherals::gpioa;
gpio_port gpiob = peripherals::gpiob;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
gpioa.moder.set_bit(16);
gpiob.moder.set_bit(16);
while (1) {
gpioa.odr.set_bit(8);
gpiob.odr.set_bit(8);
delay();
gpioa.odr.clear_bit(8);
gpiob.odr.clear_bit(8);
delay();
}
}
My naming conventions are not that standard for embeddeded Development as far as I know. I'm open for all suggestions and better code structure. :D