You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
2.7 KiB

// 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)
{
#if 0
_raw = ((v & ((1ULL << SIZE)-1)) << START);
return *this;
#else
//_raw & ~(((1ULL << SIZE)-1) << START);
// use bit band alias if system permits
_raw = ((v & ((1ULL << SIZE)-1)) << START) | (_raw & ~(((1ULL << SIZE)-1) << START));
return *this;
//#endif
#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, 7, 1> Bits;
enum{TURN_OFF = 0, TURN_ON = 1};
};
// bits 2-3
struct SPEED{
typedef BitField<uint8_t, 0, 2> Bits;
enum{STAND_STILL = 0,
SLOW = 1,
NORMAL = 2,
FAST = 3};
};
union 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;
std::cout << +reg.raw << std::endl;
reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_ON;
reg.bits.SPEED = Reg_Control::SPEED::SLOW;
std::cout << +reg.raw << std::endl;
reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_OFF;
reg.bits.SPEED = Reg_Control::SPEED::FAST;
std::cout << +reg.raw << std::endl;
return 0;
}