Skip to content

Instantly share code, notes, and snippets.

@xueliu
Last active January 3, 2021 00:09
Show Gist options
  • Save xueliu/ba531d950c4d4db5f7cf0512c5018bd5 to your computer and use it in GitHub Desktop.
Save xueliu/ba531d950c4d4db5f7cf0512c5018bd5 to your computer and use it in GitHub Desktop.
//
// Created by lx on 27.07.20.
//
#ifndef LEDDRIVER_DEVICE_H
#define LEDDRIVER_DEVICE_H
#include <iostream>
using namespace std;
// template dispatching
template <size_t RegSize>
struct RegisterDispatch;
class Device {
public:
Device() : m_value{0} {};
// generic write function
template<class Reg> inline
bool write(const Reg& r)
{
return RegisterDispatch<Reg::LENGTH>::write(*this, Reg::PAGE, Reg::ADDRESS, r.raw);
}
template<class Reg> inline
bool read(Reg& r)
{
return RegisterDispatch<Reg::LENGTH>::read(*this, Reg::PAGE, Reg::ADDRESS, r.raw);
}
template <size_t RegSize> friend struct RegisterDispatch;
private:
bool write8(uint8_t page, uint8_t addr, uint8_t val) { return true; };
bool read8 (uint8_t page, uint8_t addr, uint8_t& val) { return true; };
bool write16(uint8_t page, uint8_t addr, uint16_t val) { return true; };
bool read16 (uint8_t page, uint8_t addr, uint16_t& val) { return true; };
uint16_t m_value;
};
// one byte version
template<> struct RegisterDispatch<1>
{
static bool write(Device& dev, uint8_t page, uint8_t addr, uint8_t val)
{
return dev.write8(page, addr, val);
}
static bool read(Device& dev, uint8_t page, uint8_t addr, uint8_t& val)
{
return dev.read8(page, addr, val);
}
};
// two bytes version
template<> struct RegisterDispatch<2>
{
static bool write(Device& dev, uint8_t page, uint8_t addr, uint16_t val)
{
return dev.write16(page, addr, val);
}
static bool read(Device& dev, uint8_t page, uint8_t addr, uint16_t& val)
{
return dev.read16(page, addr, val);
}
};
#define OPM_START 10
#define OPM_SIZE 2
#define CTRL_BR1_START 8
#define CTRL_BR1_SIZE 2
#define CTRL_BR2_START 6
#define CTRL_BR2_SIZE 2
template<class T, uint8_t START, uint8_t SIZE>
struct Bits {
public:
Bits() : _raw{ 0 } { };
Bits& operator=(T v) {
_raw = (v & (2U^SIZE - 1) ) << START;
return *this;
}
explicit operator T() const {
return _raw >> START;
}
bool operator == (const T lhs) const {
return lhs == this->_raw >> START;
}
bool operator == (const Bits& lhs) const {
return this->_raw == lhs._raw;
}
T getRaw() { return _raw; };
private:
T _raw;
};
struct Registers {
union Control {
enum { PAGE = 0x16, ADDRESS = 0x17, LENGTH = 2 /* two byes */ };
struct OPM {
typedef Bits<uint16_t, OPM_START, OPM_SIZE> BitsVal; // "Bits" is not allowed ??
enum { NO_CHANGE = 0, AS_STANDBY = 1 };
};
struct CTRL_BR {
enum { NO_CHANGE = 0, BRANCH_NORMAL = 1 };
};
struct CTRL_BR1 : CTRL_BR {
typedef Bits<uint16_t, CTRL_BR1_START, CTRL_BR1_SIZE> BitsVal;
};
struct CTRL_BR2 : CTRL_BR {
typedef Bits<uint16_t, CTRL_BR2_START, CTRL_BR2_SIZE> BitsVal;
};
union Bits {
Control::OPM::BitsVal OPM;
Control::CTRL_BR1::BitsVal CTRL_BR1;
Control::CTRL_BR1::BitsVal CTRL_BR2;
} bits;
uint16_t raw;
explicit Control(uint16_t v = 0x00) : raw(v) {}
};
}; /* struct Registers */
#endif //LEDDRIVER_DEVICE_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment