2019-11-22 11:57:17 +00:00
|
|
|
#include <Builders.hpp>
|
2019-11-22 14:22:52 +00:00
|
|
|
#include <iostream>
|
2019-12-02 09:10:29 +00:00
|
|
|
#include <bitset>
|
2019-11-22 14:22:52 +00:00
|
|
|
|
|
|
|
void ZeroPointerBuilder::build(std::stringstream& ss) const{
|
2019-11-22 11:57:17 +00:00
|
|
|
ss << "template <unsigned int zero = 0>\n"
|
2019-12-02 09:10:29 +00:00
|
|
|
"constexpr unsigned int *zeroVal = reinterpret_cast<unsigned int *>(zero);\n\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldDefineBuilder::build(std::stringstream& ss) const{
|
|
|
|
ss << "#define __FIELD(_FieldName, _bitOffset, _bitMask, _address) \\\n"
|
|
|
|
"struct _FieldName \\\n"
|
|
|
|
"{ \\\n"
|
|
|
|
" constexpr static inline unsigned int bitOffset() { return _bitOffset; } \\\n"
|
|
|
|
" constexpr static inline unsigned int bitMask() { return _bitMask; } \\\n"
|
|
|
|
" constexpr static inline unsigned int *address() { return zeroVal<> + _address; } \\\n"
|
|
|
|
"};\n\n";
|
2019-11-22 11:57:17 +00:00
|
|
|
}
|
|
|
|
|
2019-11-22 14:22:52 +00:00
|
|
|
void PeripheralBuilder::build(std::stringstream& ss) const{
|
|
|
|
ss << "namespace " << peripheral.name << "{\n";
|
2019-11-22 11:57:17 +00:00
|
|
|
for(auto& registe : peripheral.registers){
|
2019-11-22 14:22:52 +00:00
|
|
|
RegisterBuilder(registe, peripheral.baseAddress).build(ss);
|
2019-11-22 11:57:17 +00:00
|
|
|
}
|
2019-12-02 09:47:01 +00:00
|
|
|
ss << "}\n\n";
|
2019-11-22 11:57:17 +00:00
|
|
|
}
|
|
|
|
|
2019-11-22 14:22:52 +00:00
|
|
|
void RegisterBuilder::build(std::stringstream& ss) const{
|
2019-11-22 11:57:17 +00:00
|
|
|
ss << " "
|
2019-11-22 14:22:52 +00:00
|
|
|
<< "namespace " << registe.name << "{\n";
|
2019-11-22 11:57:17 +00:00
|
|
|
for(auto& field : registe.fields){
|
2019-11-22 14:22:52 +00:00
|
|
|
FieldBuilder(field, getRegisterAddress()).build(ss);
|
2019-11-22 11:57:17 +00:00
|
|
|
}
|
|
|
|
ss << " " << "}\n";
|
|
|
|
}
|
|
|
|
|
2019-11-22 14:22:52 +00:00
|
|
|
unsigned int RegisterBuilder::getRegisterAddress() const{
|
|
|
|
return baseAddress + registe.addressOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldBuilder::build(std::stringstream& ss) const{
|
2019-12-02 09:10:29 +00:00
|
|
|
ss << " " << "__FIELD(" << field.name << ", "
|
|
|
|
<< field.bitOffset << ", "
|
|
|
|
<< field.bitWidth << ", "
|
|
|
|
<< std::hex << "0x" << getAddress() << std::dec << ")\n";
|
2019-11-22 14:22:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-02 09:10:29 +00:00
|
|
|
unsigned int FieldBuilder::getAddress() const{
|
|
|
|
return registerAddress;
|
2019-11-22 14:22:52 +00:00
|
|
|
}
|
2019-12-02 09:10:29 +00:00
|
|
|
|
|
|
|
void FunctionsBuilder::build(std::stringstream& ss) const{
|
|
|
|
ss << "template<class FIELD>\n"
|
|
|
|
"constexpr inline void set(){\n"
|
|
|
|
" *FIELD::address() |= 1 << FIELD::bitOffset();\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"template<class FIELD, unsigned int VAL>\n"
|
|
|
|
"constexpr inline void set(){\n"
|
|
|
|
" static_assert(VAL & (FIELD::bitMask() >> FIELD::bitOffset()), \"Value is too big\");\n"
|
|
|
|
" *FIELD::address() = *FIELD::address() & ~FIELD::bitMask() | VAL << FIELD::bitOffset();\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"template<class FIELD>\n"
|
|
|
|
"constexpr inline void reset(){\n"
|
|
|
|
" *FIELD::address() &= ~(1 << FIELD::bitOffset());\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"template<class FIELD>\n"
|
|
|
|
"constexpr inline unsigned int read(){\n"
|
|
|
|
" return (*FIELD::address() & FIELD::bitMask()) >> FIELD::bitOffset();\n"
|
|
|
|
"}"
|
|
|
|
"\n\n";
|
|
|
|
}
|