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.
123 lines
2.8 KiB
123 lines
2.8 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)
|
|
{
|
|
|
|
/*
|
|
// 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;
|
|
} |