diff --git a/driver_dev/max31865_dev/Makefile b/driver_dev/max31865_dev/Makefile new file mode 100644 index 0000000..38e5ad5 --- /dev/null +++ b/driver_dev/max31865_dev/Makefile @@ -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 diff --git a/driver_dev/max31865_dev/driver/device.cpp b/driver_dev/max31865_dev/driver/device.cpp new file mode 100644 index 0000000..715bf1e --- /dev/null +++ b/driver_dev/max31865_dev/driver/device.cpp @@ -0,0 +1,69 @@ +#include "device.hpp" +#include + +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; +} \ No newline at end of file diff --git a/driver_dev/max31865_dev/driver/device.hpp b/driver_dev/max31865_dev/driver/device.hpp new file mode 100644 index 0000000..2f9e1ea --- /dev/null +++ b/driver_dev/max31865_dev/driver/device.hpp @@ -0,0 +1,113 @@ +#ifndef _DEVICE_HPP_ +#define _DEVICE_HPP_ + +#include "../utils/BitField.hpp" + +#include +#include + +class Device +{ + public: + Device(); + + void doSomething(); + + void status(); + + private: + + // + // Register declarations + // +#ifdef EXAMPLE_CODE_FOR_REFERENCE + union Control { + struct OPM{ + typedef Bits 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 bits; + }; + struct CTRL_BR2 : CTRL_BR{ + typedef Bits 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 Bits; + enum{TURN_OFF = 0, TURN_ON = 1}; + }; + // bits 2-3 + struct SPEED{ + typedef BitField 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 Bits; + enum{OFF = 0, ON = 1}; + }; + struct STATUS{ + typedef BitFieldBits; + 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_ diff --git a/driver_dev/max31865_dev/driver/max31865.cpp b/driver_dev/max31865_dev/driver/max31865.cpp new file mode 100644 index 0000000..e69de29 diff --git a/driver_dev/max31865_dev/driver/max31865.hpp b/driver_dev/max31865_dev/driver/max31865.hpp new file mode 100644 index 0000000..908dc3f --- /dev/null +++ b/driver_dev/max31865_dev/driver/max31865.hpp @@ -0,0 +1,64 @@ +#ifdef __MAX31865_HPP_ +#define __MAX31865_HPP__ + +#include +#include "../utils/BitFiled.hpp" + + +class MAX31865 +{ + public: + MAX31865(); + + private: + + // + // register definitions + // + + union CONFIG_REG { + struct VBIAS{ + enum { + OFF = 0, + ON = 1 + }; + typedef BitField Bits; + }; + + struct CONVERSION_MODE{ + enum { + OFF = 0, + AUTO = 1 + }; + typedef BitField Bits; + }; + + struct ONE_SHOT{ + enum { + IDLE = 0, + SET = 1 + }; + typedef BitField Bits; + }; + + struct WIRING{ + enum { + TWO_OR_FOUR_WIRE = 0, + THREE_WIRE = 1 + }; + typedef BitField Bits; + }; + + struct { + enum { + IDLE = 0, + SET = 1 + }; + typedef BitField Bits; + }; + + }; +}; + + +#endif // __MAX31865_HPP__ diff --git a/driver_dev/max31865_dev/interfaces/i2c.cpp b/driver_dev/max31865_dev/interfaces/i2c.cpp new file mode 100644 index 0000000..e69de29 diff --git a/driver_dev/max31865_dev/interfaces/i2c.hpp b/driver_dev/max31865_dev/interfaces/i2c.hpp new file mode 100644 index 0000000..e69de29 diff --git a/driver_dev/max31865_dev/main.cpp b/driver_dev/max31865_dev/main.cpp new file mode 100644 index 0000000..ea510f1 --- /dev/null +++ b/driver_dev/max31865_dev/main.cpp @@ -0,0 +1,57 @@ +#include +#include + +#include "./driver/device.hpp" +#include "./utils/BitField.hpp" + +#ifdef SIMPLE_TEST + +int main(void) +{ + std::cout << "test" << std::endl; + + BitField bitfield_0; + BitField bitfield_1; + + + std::cout << "testing bitfield 0" << std::endl; + + for(uint8_t i = 0; i < 10; i++) { + + bitfield_0 = i; + std::cout << static_cast(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(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; +} diff --git a/driver_dev/max31865_dev/problem_test.txt b/driver_dev/max31865_dev/problem_test.txt new file mode 100644 index 0000000..ed7d1ee --- /dev/null +++ b/driver_dev/max31865_dev/problem_test.txt @@ -0,0 +1,126 @@ +// Example program +#include +#include + + +#include + +/** + * @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 +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 Bits; + enum{TURN_OFF = 0, TURN_ON = 1}; + }; + // bits 2-3 + struct SPEED{ + typedef BitField 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; +} \ No newline at end of file diff --git a/driver_dev/max31865_dev/runtest b/driver_dev/max31865_dev/runtest new file mode 100755 index 0000000..5dfe56a Binary files /dev/null and b/driver_dev/max31865_dev/runtest differ diff --git a/driver_dev/max31865_dev/utils/BitField.hpp b/driver_dev/max31865_dev/utils/BitField.hpp new file mode 100644 index 0000000..7b36c16 --- /dev/null +++ b/driver_dev/max31865_dev/utils/BitField.hpp @@ -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 + +/** + * @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 +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_ \ No newline at end of file