parent
b65fa2f79f
commit
c13fdb52a7
@ -0,0 +1,123 @@
|
||||
// Example program
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Template class for portable Bitfields
|
||||
*
|
||||
* @tparam T type of variable in which the bitfield resides
|
||||
* @tparam START bit index starting from LSB where the bitfield starts
|
||||
* @tparam SIZE number of bits
|
||||
*/
|
||||
template<typename T, uint8_t START, uint8_t SIZE>
|
||||
struct BitField
|
||||
{
|
||||
/**
|
||||
* @brief Construct a new Bit Field object
|
||||
*
|
||||
*/
|
||||
BitField()
|
||||
{
|
||||
static_assert(SIZE != 0, "Bitfield SIZE must be > 0!");
|
||||
static_assert(START < sizeof(T) * 8, "START exceeds number of bits of the chosen typename T!");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief assignment operator
|
||||
*
|
||||
* @param v value to be written in the bitfield
|
||||
* @return BitField&
|
||||
*/
|
||||
BitField& operator =(T v)
|
||||
{
|
||||
|
||||
/*
|
||||
// this step can be optimised for systems that support bitbandalias
|
||||
T mask = ((1ULL << SIZE)-1) << START;
|
||||
_raw &= ~mask;
|
||||
_raw |= ((v & ((1ULL << SIZE)-1)) << START);
|
||||
return *this;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//#ifdef old
|
||||
//TODO: test = problem with |= instead of =
|
||||
// mask creation for v : https://stackoverflow.com/questions/1392059/algorithm-to-generate-bit-mask
|
||||
_raw = ((v & ((1ULL << SIZE)-1)) << START) | (_raw & ~(((1ULL << SIZE)-1) << START));
|
||||
return *this;
|
||||
//#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return the value inside the bitfield
|
||||
*
|
||||
* @return T
|
||||
*/
|
||||
operator T() const
|
||||
{
|
||||
return _raw >> START;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return the raw value
|
||||
*
|
||||
* @return T
|
||||
*/
|
||||
T operator ()() const
|
||||
{
|
||||
return _raw;
|
||||
}
|
||||
|
||||
private:
|
||||
T _raw;
|
||||
};
|
||||
|
||||
union Reg_Control
|
||||
{
|
||||
// bit 4
|
||||
struct POWER_DEV{
|
||||
typedef BitField<uint8_t, 4, 1> Bits;
|
||||
enum{TURN_OFF = 0, TURN_ON = 1};
|
||||
};
|
||||
// bits 2-3
|
||||
struct SPEED{
|
||||
typedef BitField<uint8_t, 2, 2> Bits;
|
||||
enum{STAND_STILL = 0,
|
||||
SLOW = 1,
|
||||
NORMAL = 2,
|
||||
FAST = 3};
|
||||
};
|
||||
struct Bits{
|
||||
Reg_Control::POWER_DEV::Bits POWER_DEV;
|
||||
Reg_Control::SPEED::Bits SPEED;
|
||||
} bits;
|
||||
// raw value. all bitfields will be "unified" here ;)
|
||||
uint8_t raw;
|
||||
// union Ctor with default value set to 0x00
|
||||
Reg_Control(uint8_t v = 0x00) : raw(v) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Reg_Control reg;
|
||||
|
||||
reg.bits.SPEED = Reg_Control::SPEED::FAST;
|
||||
reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_ON;
|
||||
|
||||
|
||||
std::cout << +reg.raw << std::endl;
|
||||
|
||||
reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_OFF;
|
||||
reg.bits.SPEED = Reg_Control::SPEED::SLOW;
|
||||
|
||||
|
||||
std::cout << +reg.raw << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in new issue