Last active
January 3, 2021 00:09
-
-
Save xueliu/ba531d950c4d4db5f7cf0512c5018bd5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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