/* * TI Voxel Lib component. * * Copyright (c) 2014 Texas Instruments Inc. */ #ifndef VOXEL_PARAMETER_H #define VOXEL_PARAMETER_H #include #include "Common.h" #include "RegisterProgrammer.h" #include "Logger.h" #include namespace Voxel { /** * \defgroup Param Parameter related classes * @{ */ class ParameterDMLParser; class VOXEL_EXPORT Parameter { public: enum IOType { IO_READ_ONLY = 0, IO_READ_WRITE, IO_WRITE_ONLY }; protected: uint32_t _address, _mask; uint8_t _msb, _lsb, _registerLength; // This is to do @_address <- (@_address & _mask) | (_value << _lsb) IOType _ioType; String _name; String _displayName; String _description; Vector _dependencies; // Parameter values on which this parameter depends on RegisterProgrammer &_programmer; void _computeMask(); public: Parameter(RegisterProgrammer &programmer, const String &name, uint32_t address, uint8_t registerLength, uint8_t msb, uint8_t lsb, const String &displayName, const String &description, IOType ioType = IO_READ_WRITE, const Vector &dependencies = {}) : _programmer(programmer), _name(name), _displayName(displayName), _description(description), _address(address), _msb(msb), _registerLength(registerLength), _lsb(lsb), _ioType(ioType), _dependencies(dependencies) { _computeMask(); } inline const String &name() const { return _name; } inline const String &displayName() const { return _displayName; } inline const String &description() const { return _description; } inline uint32_t address() const { return _address; } inline uint8_t msb() const { return _msb; } inline uint32_t mask() const { return _mask; } inline uint8_t lsb() const { return _lsb; } inline IOType ioType() const { return _ioType; } inline void setName(const String &n) { _name = n; } inline void setAddress(uint32_t a) { _address = a; } virtual bool refresh() = 0; virtual ~Parameter() {} friend class ParameterDMLParser; }; typedef Ptr ParameterPtr; // NOTE: _value is initialized to defaultValue and not read from H/W. It needs to be manually done from outside via set() or get(true) template class ParameterTemplate: public Parameter { protected: T _value; virtual uint32_t _toRawValue(T value) const { return (uint32_t)value; } virtual T _fromRawValue(uint32_t value) const { return (T)(value); } public: ParameterTemplate(RegisterProgrammer &programmer, const String &name, uint32_t address, uint8_t registerLength, uint8_t msb, uint8_t lsb, const T &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): Parameter(programmer, name, address, registerLength, msb, lsb, displayName, description, ioType, dependencies), _value(defaultValue) { } static Ptr> typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast>(other); } virtual bool set(const T &value) { if(_ioType == IO_READ_ONLY || !validate(value)) { return false; } if(_programmer.setValue(*this, _toRawValue(value), _ioType == IO_WRITE_ONLY)) { _value = value; return true; } else return false; } virtual bool validate(const T &value) const = 0; virtual bool refresh() { T v; return get(v, true); } virtual bool get(T &value, bool refresh = false) { if(!refresh || _ioType == IO_WRITE_ONLY) { value = _value; return true; } uint32_t v; T val; if(_address == 0 && _registerLength == 0) // dummy register? { value == _value; return true; } else if(!_programmer.getValue(*this, v)) { value = _value; return false; } else { val = _fromRawValue(v); if(validate(val)) { value = val; _value = val; return true; } else { value = _value; return false; } } } virtual ~ParameterTemplate() {} }; typedef ParameterTemplate BoolParameterTemplate; typedef ParameterTemplate IntegerParameterTemplate; typedef ParameterTemplate UnsignedIntegerParameterTemplate; typedef ParameterTemplate FloatParameterTemplate; #ifdef SWIG %template(BoolParameterTemplate) ParameterTemplate; %template(IntegerParameterTemplate) ParameterTemplate; %template(UnsignedIntegerParameterTemplate) ParameterTemplate; %template(FloatParameterTemplate) ParameterTemplate; #endif template class EnumParameterTemplate: public ParameterTemplate { protected: Vector _valueMeaning; Vector _valueDescription; public: EnumParameterTemplate(RegisterProgrammer &programmer, const String &name, uint32_t address, uint8_t registerLength, uint8_t msb, uint8_t lsb, const Vector &valueDescription, const Vector &valueMeaning, const T &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): ParameterTemplate(programmer, name, address, registerLength, msb, lsb, defaultValue, displayName, description, ioType, dependencies), _valueDescription(valueDescription), _valueMeaning(valueMeaning) { } static Ptr> typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast>(other); } inline const Vector &valueDescription() const { return _valueDescription; } inline const Vector &valueMeaning() const { return _valueMeaning; } virtual ~EnumParameterTemplate() {} }; typedef EnumParameterTemplate BoolEnumParameterTemplate; typedef EnumParameterTemplate IntegerEnumParameterTemplate; #ifdef SWIG %template(BoolEnumParameterTemplate) EnumParameterTemplate; %template(IntegerEnumParameterTemplate) EnumParameterTemplate; #endif class VOXEL_EXPORT BoolParameter : public EnumParameterTemplate { virtual bool _fromRawValue(uint32_t value) const { return (value?true:false); } virtual uint32_t _toRawValue(bool value) const { return (uint32_t)value?1:0; } public: BoolParameter(RegisterProgrammer &programmer, const String &name, uint32_t address, uint8_t registerLength, uint8_t lsb, const Vector &valueDescription, const Vector &valueMeaning, const bool &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): EnumParameterTemplate(programmer, name, address, registerLength, lsb, lsb, valueDescription, valueMeaning, defaultValue, displayName, description, ioType, dependencies) { } static Ptr typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast(other); } virtual bool validate(const bool &value) const { return true; } virtual ~BoolParameter() {} }; class VOXEL_EXPORT StrobeBoolParameter : public BoolParameter { public: StrobeBoolParameter(RegisterProgrammer &programmer, const String &name, uint32_t address, uint8_t registerLength, uint8_t lsb, const Vector &valueDescription, const Vector &valueMeaning, const bool &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): BoolParameter(programmer, name, address, registerLength, lsb, valueDescription, valueMeaning, defaultValue, displayName, description, ioType, dependencies) { } static Ptr typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast(other); } virtual bool get(bool &value, bool refresh = true) { return BoolParameter::get(value, true); // ignore the refresh set by user and force it to true } virtual ~StrobeBoolParameter() {} }; class VOXEL_EXPORT EnumParameter : public EnumParameterTemplate { protected: Vector _allowedValues; public: EnumParameter(RegisterProgrammer &programmer, const String &name, uint32_t address, uint8_t registerLength, uint8_t msb, uint8_t lsb, const Vector &allowedValues, const Vector valueDescription, const Vector &valueMeaning, const int &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): EnumParameterTemplate(programmer, name, address, registerLength, msb, lsb, valueDescription, valueMeaning, defaultValue, displayName, description, ioType, dependencies), _allowedValues(allowedValues) { } static Ptr typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast(other); } inline const Vector &allowedValues() const { return _allowedValues; } virtual bool validate(const int &value) const { bool allowed = false; for(auto a : _allowedValues) if(value == a) { allowed = true; break; } return allowed; } virtual ~EnumParameter() {} }; template class RangeParameterTemplate : public ParameterTemplate { protected: T _lowerLimit, _upperLimit; String _unit; public: RangeParameterTemplate(RegisterProgrammer &programmer, const String &name, const String &unit, uint32_t address, uint8_t registerLength, uint8_t msb, uint8_t lsb, const T &lowerLimit, const T &upperLimit, const T &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): ParameterTemplate(programmer, name, address, registerLength, msb, lsb, defaultValue, displayName, description, ioType, dependencies), _lowerLimit(lowerLimit), _upperLimit(upperLimit), _unit(unit) { } static Ptr> typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast>(other); } const String &unit() const { return _unit; } virtual const T lowerLimit() const { return _lowerLimit; } virtual const T upperLimit() const { return _upperLimit; } virtual void setLowerLimit(T lowerLimit) { _lowerLimit = lowerLimit; } virtual void setUpperLimit(T upperLimit) { _upperLimit = upperLimit; } virtual bool validate(const T &value) const { return !(value < _lowerLimit || value > _upperLimit); } virtual ~RangeParameterTemplate() {} }; typedef RangeParameterTemplate IntegerRangeParameterTemplate; typedef RangeParameterTemplate FloatRangeParameterTemplate; #ifdef SWIG %template(IntegerRangeParameterTemplate) RangeParameterTemplate; %template(UnsignedIntegerParameter) RangeParameterTemplate; %template(FloatRangeParameterTemplate) RangeParameterTemplate; #endif class VOXEL_EXPORT IntegerParameter : public RangeParameterTemplate { protected: virtual uint32_t _toRawValue(int value) const { if(value < 0) // negative? { return ((uint32_t)value & ((1 << (_msb - _lsb + 1)) - 1)); // remove sign extension } else return (uint32_t)value; } virtual int _fromRawValue(uint32_t value) const { if(value & (1 << (_msb - _lsb))) // negative? return (value | ((uint32_t)(-1) - ((1 << (_msb - _lsb + 1)) - 1))); // extend sign else return (int)value; } public: IntegerParameter(RegisterProgrammer &programmer, const String &name, const String &unit, uint32_t address, uint8_t registerLength, uint8_t msb, uint8_t lsb, int lowerLimit, int upperLimit, const int &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): RangeParameterTemplate(programmer, name, unit, address, registerLength, msb, lsb, lowerLimit, upperLimit, defaultValue, displayName, description, ioType, dependencies) { } static Ptr typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast(other); } virtual ~IntegerParameter() {} }; typedef RangeParameterTemplate UnsignedIntegerParameter; class VOXEL_EXPORT FloatParameter : public RangeParameterTemplate { protected: virtual float _fromRawValue(uint32_t value) const { float v; v = (float)value/(1 << (msb() - lsb() + 1)); // normalized value if(v > 1.0f) v = 1.0f; if(v < 0.0f) v = 0.0f; return v; } virtual uint32_t _toRawValue(float value) const { uint32_t maxValue = (1 << (msb() - lsb() + 1)); uint32_t v = (uint32_t)value*maxValue; // normalized value if(v > maxValue) v = maxValue; if(v < 0) v = 0; return v; } public: FloatParameter(RegisterProgrammer &programmer, const String &name, const String &unit, uint32_t address, uint8_t registerLength, uint8_t msb, uint8_t lsb, float lowerLimit, float upperLimit, const float &defaultValue, const String &displayName, const String &description, Parameter::IOType ioType = Parameter::IO_READ_WRITE, const Vector &dependencies = {}): RangeParameterTemplate(programmer, name, unit, address, registerLength, msb, lsb, lowerLimit, upperLimit, defaultValue, displayName, description, ioType, dependencies) { } static Ptr typeCast(const ParameterPtr &other) { return std::dynamic_pointer_cast(other); } virtual ~FloatParameter() {} }; /** * @} */ } #endif // PARAMETER_H