parent
335be7f8c8
commit
c3104ab657
@ -0,0 +1,24 @@
|
||||
cpp_src = $(wildcard *.cpp)
|
||||
cpp_src += $(wildcard ./utils/*.cpp)
|
||||
cpp_src += $(wildcard ./driver/*.cpp)
|
||||
|
||||
cpp_obj = $(cpp_src:.cpp=.o)
|
||||
c_obj = $(c_src:.c=.o)
|
||||
CC = g++
|
||||
CFLAGS = -Wall -pedantic -li2c
|
||||
LDFLAGS =
|
||||
EXEC = runtest
|
||||
|
||||
|
||||
all : $(EXEC)
|
||||
|
||||
$(EXEC): $(cpp_obj) $(c_obj)
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf $(c_obj) $(cpp_obj) $(EXEC)
|
||||
clear
|
||||
|
||||
cleanall:
|
||||
rm -rf $(c_obj) $(cpp_obj) $(EXEC)
|
||||
clear
|
@ -0,0 +1,69 @@
|
||||
#include "device.hpp"
|
||||
#include <iostream>
|
||||
|
||||
Device::Device() :
|
||||
reg_control(0x00)
|
||||
{
|
||||
|
||||
std::cout << "Device::Device()" << std::endl;
|
||||
std::cout << +reg_control.raw << std::endl;
|
||||
|
||||
reg_control.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_OFF;
|
||||
reg_control.bits.SPEED = Reg_Control::SPEED::STAND_STILL;
|
||||
|
||||
std::cout << "POWER = " << +reg_control.bits.POWER_DEV << std::endl;
|
||||
std::cout << "SPEED = " <<+reg_control.bits.SPEED << std::endl;
|
||||
}
|
||||
|
||||
void Device::doSomething()
|
||||
{
|
||||
std::cout << "Device::doSomething()" << std::endl;
|
||||
|
||||
reg_control.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_ON;
|
||||
reg_control.bits.SPEED = Reg_Control::SPEED::FAST;
|
||||
|
||||
if(reg_control.bits.POWER_DEV == Reg_Control::POWER_DEV::TURN_ON){
|
||||
std::cout << "device turned on!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "POWER = " << +reg_control.bits.POWER_DEV << std::endl;
|
||||
std::cout << "SPEED = " << +reg_control.bits.SPEED << std::endl;
|
||||
|
||||
std::cout << +reg_control << std::endl;
|
||||
|
||||
reg_control = 0;
|
||||
|
||||
std::cout << +reg_control << std::endl;
|
||||
|
||||
std::cout << "POWER = " << +reg_control.bits.POWER_DEV << std::endl;
|
||||
std::cout << "SPEED = " << +reg_control.bits.SPEED << std::endl;
|
||||
|
||||
//reg_control.bits.SPEED = Reg_Control::SPEED::FAST;
|
||||
reg_control.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_ON;
|
||||
|
||||
std::cout << "POWER = " << +reg_control.bits.POWER_DEV << std::endl;
|
||||
std::cout << "SPEED = " << +reg_control.bits.SPEED << std::endl;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Device::status()
|
||||
{
|
||||
// imitating read hardware register (for example reading from device via SPI or i2c)
|
||||
reg_motorStatus = 0xFE;
|
||||
|
||||
if(reg_motorStatus.bits.POWER == Reg_MotorStatus::POWER::ON) {
|
||||
std::cout << "Motor is Powered ON!" << std::endl;
|
||||
} else {
|
||||
std::cout << "Motor is Powered OFF!" << std::endl;
|
||||
}
|
||||
|
||||
// will throw error because this bitfield is set const!
|
||||
//reg_motorStatus.bits.STATUS = Reg_MotorStatus::STATUS::STANDSTILL;
|
||||
|
||||
std::cout << +reg_motorStatus.bits.POWER << std::endl;
|
||||
|
||||
std::cout << "Motor Status : " << +reg_motorStatus.bits.STATUS << std::endl;
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
#ifndef _DEVICE_HPP_
|
||||
#define _DEVICE_HPP_
|
||||
|
||||
#include "../utils/BitField.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
Device();
|
||||
|
||||
void doSomething();
|
||||
|
||||
void status();
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// Register declarations
|
||||
//
|
||||
#ifdef EXAMPLE_CODE_FOR_REFERENCE
|
||||
union Control {
|
||||
struct OPM{
|
||||
typedef Bits<uint16_t, 10, 2> bits;
|
||||
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, 8, 2> bits;
|
||||
};
|
||||
struct CTRL_BR2 : CTRL_BR{
|
||||
typedef Bits<uint16_t, 6, 2> bits;
|
||||
};
|
||||
|
||||
union Bits {
|
||||
Control::OPM::bits OPM;
|
||||
Control::CTRL_BR1::bits CTRL_BR1;
|
||||
Control::CTRL_BR2::bits CTRL_BR2;
|
||||
} bits;
|
||||
uint16_t raw;
|
||||
};
|
||||
#endif
|
||||
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, 2, 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) {}
|
||||
// raw value extraction of register
|
||||
operator uint8_t() {return raw;}
|
||||
// used for updating software immage of hardware register
|
||||
void operator = (uint8_t v) {raw = v;}
|
||||
};
|
||||
|
||||
union Reg_MotorStatus
|
||||
{
|
||||
struct POWER{
|
||||
typedef BitField<uint8_t,0,1> Bits;
|
||||
enum{OFF = 0, ON = 1};
|
||||
};
|
||||
struct STATUS{
|
||||
typedef BitField<uint8_t, 2,3>Bits;
|
||||
enum{STANDSTILL = 0,
|
||||
ACCELERATING_CW = 1,
|
||||
DEACCELERATING_CW = 2,
|
||||
ACCELERATING_CCW = 3,
|
||||
DEACCELERATING_CCW = 4,
|
||||
CONSTANT_SPEED = 5,
|
||||
BLOCKED = 6};
|
||||
};
|
||||
union Bits
|
||||
{
|
||||
// is set const because it only used for status indication
|
||||
const Reg_MotorStatus::POWER::Bits POWER;
|
||||
const Reg_MotorStatus::STATUS::Bits STATUS;
|
||||
}bits;
|
||||
uint8_t raw;
|
||||
|
||||
Reg_MotorStatus(uint8_t v = 0x00) : raw(v) {}
|
||||
operator uint8_t() {return raw;}
|
||||
void operator = (uint8_t v) {raw = v;}
|
||||
};
|
||||
|
||||
Reg_Control reg_control;
|
||||
|
||||
Reg_MotorStatus reg_motorStatus;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _DEVICE_HPP_
|
@ -0,0 +1,64 @@
|
||||
#ifdef __MAX31865_HPP_
|
||||
#define __MAX31865_HPP__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../utils/BitFiled.hpp"
|
||||
|
||||
|
||||
class MAX31865
|
||||
{
|
||||
public:
|
||||
MAX31865();
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// register definitions
|
||||
//
|
||||
|
||||
union CONFIG_REG {
|
||||
struct VBIAS{
|
||||
enum {
|
||||
OFF = 0,
|
||||
ON = 1
|
||||
};
|
||||
typedef BitField<uint8_t,7,1> Bits;
|
||||
};
|
||||
|
||||
struct CONVERSION_MODE{
|
||||
enum {
|
||||
OFF = 0,
|
||||
AUTO = 1
|
||||
};
|
||||
typedef BitField<uint8_t,6,1> Bits;
|
||||
};
|
||||
|
||||
struct ONE_SHOT{
|
||||
enum {
|
||||
IDLE = 0,
|
||||
SET = 1
|
||||
};
|
||||
typedef BitField<uint8_t,5,1> Bits;
|
||||
};
|
||||
|
||||
struct WIRING{
|
||||
enum {
|
||||
TWO_OR_FOUR_WIRE = 0,
|
||||
THREE_WIRE = 1
|
||||
};
|
||||
typedef BitField<uint8_t,4,1> Bits;
|
||||
};
|
||||
|
||||
struct {
|
||||
enum {
|
||||
IDLE = 0,
|
||||
SET = 1
|
||||
};
|
||||
typedef BitField<uint8_t,5,1> Bits;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // __MAX31865_HPP__
|
@ -0,0 +1,57 @@
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "./driver/device.hpp"
|
||||
#include "./utils/BitField.hpp"
|
||||
|
||||
#ifdef SIMPLE_TEST
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "test" << std::endl;
|
||||
|
||||
BitField<uint8_t, 1, 2> bitfield_0;
|
||||
BitField<uint8_t, 5, 2> bitfield_1;
|
||||
|
||||
|
||||
std::cout << "testing bitfield 0" << std::endl;
|
||||
|
||||
for(uint8_t i = 0; i < 10; i++) {
|
||||
|
||||
bitfield_0 = i;
|
||||
std::cout << static_cast<uint32_t>(bitfield_0()) << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "testing bitfield 1" << std::endl;
|
||||
|
||||
for(uint8_t i = 0; i < 10; i++) {
|
||||
|
||||
bitfield_1 = i;
|
||||
std::cout << static_cast<uint32_t>(bitfield_1()) << std::endl;
|
||||
}
|
||||
|
||||
Device dev();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "test" << std::endl;
|
||||
|
||||
//std::cout << std::hex << ((1ULL << 2)-1) << std::endl;
|
||||
std::cout << 1ULL << std::endl;
|
||||
|
||||
Device dev;
|
||||
|
||||
//dev.doSomething();
|
||||
|
||||
dev.status();
|
||||
|
||||
//dev.doSomething();
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
// 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;
|
||||
}
|
Binary file not shown.
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file BitField.h
|
||||
* @author Edwin Koch (eddyed.k@gmail.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2020-12-19
|
||||
*
|
||||
* @copyright Copyright (c) 2020
|
||||
*
|
||||
*/
|
||||
|
||||
// Based on:
|
||||
// https://www.youtube.com/watch?v=TYqbgvHfxjM
|
||||
// https://stackoverflow.com/questions/31726191/is-there-a-portable-alternative-to-c-bitfields
|
||||
// https://stackoverflow.com/questions/1392059/algorithm-to-generate-bit-mask
|
||||
|
||||
#ifndef _BITFIELDS_HPP_
|
||||
#define _BITFIELDS_HPP_
|
||||
|
||||
#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)
|
||||
{
|
||||
// use bit band alias if system permits
|
||||
_raw = ((v & ((1ULL << SIZE)-1)) << START) | (_raw & ~(((1ULL << SIZE)-1) << START));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return the value inside the bitfield
|
||||
*
|
||||
* @return T
|
||||
*/
|
||||
operator T() const
|
||||
{
|
||||
return (_raw >> START) & ((1ULL << SIZE) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return the raw value
|
||||
*
|
||||
* @return T
|
||||
*/
|
||||
T operator ()() const
|
||||
{
|
||||
return (_raw >> START) & ((1ULL << SIZE) - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
T _raw;
|
||||
};
|
||||
|
||||
#endif // _BITFIELDS_HPP_
|
Loading…
Reference in new issue