started knx integration

This commit is contained in:
John
2022-05-01 12:13:13 +02:00
parent ac7654e14d
commit 232164c866
12 changed files with 1335 additions and 0 deletions
+133
View File
@@ -793,6 +793,70 @@ result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolS
return readFromRawValue(value, outputFormat, output);
}
result_t NumberDataType::getFloatFromRawValue(unsigned int value, float* output) const {
int signedValue;
if (!hasFlag(REQ) && value == m_replacement) {
return RESULT_EMPTY;
}
bool negative;
if (hasFlag(SIG)) { // signed value
negative = (value & (1 << (m_bitCount - 1))) != 0;
if (negative) { // negative signed value
if (value < m_minValue) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
}
} else if (value > m_maxValue) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
}
} else if (value < m_minValue || value > m_maxValue) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
} else {
negative = false;
}
if (m_bitCount == 32) {
if (hasFlag(EXP)) { // IEEE 754 binary32
float val = uintToFloat(value);
if (val != val) { // !isnan(val)
return RESULT_EMPTY;
}
if (val != 0.0) {
if (m_divisor < 0) {
val *= static_cast<float>(-m_divisor);
} else if (m_divisor > 1) {
val /= static_cast<float>(m_divisor);
}
}
*output = static_cast<float>(val);
return RESULT_OK;
}
// less than 32 bit
if (!negative) {
if (m_divisor < 0) {
*output = static_cast<float>(value) * static_cast<float>(-m_divisor);
} else if (m_divisor <= 1) {
*output = static_cast<float>(value);
} else {
*output = static_cast<float>(value) / static_cast<float>(m_divisor);
}
return RESULT_OK;
}
signedValue = static_cast<int>(value); // negative signed value
} else if (negative) { // negative signed value
signedValue = static_cast<int>(value) - (1 << m_bitCount);
} else {
signedValue = static_cast<int>(value);
}
if (m_divisor < 0) {
*output = static_cast<float>(signedValue) * static_cast<float>(-m_divisor);
} else if (m_divisor <= 1) {
*output = static_cast<float>(signedValue);
} else {
*output = static_cast<float>(signedValue) / static_cast<float>(m_divisor);
}
return RESULT_OK;
}
result_t NumberDataType::readFromRawValue(unsigned int value,
OutputFormat outputFormat, ostream* output) const {
size_t length = (m_bitCount < 8) ? 1 : (m_bitCount/8);
@@ -932,6 +996,75 @@ result_t NumberDataType::writeRawValue(unsigned int value, size_t offset, size_t
return RESULT_OK;
}
result_t NumberDataType::getRawValueFromFloat(float val, unsigned int* output) const {
unsigned int value;
if (hasFlag(EXP)) { // IEEE 754 binary32
double dvalue = val;
if (m_divisor < 0) {
dvalue /= -m_divisor;
} else if (m_divisor > 1) {
dvalue *= m_divisor;
}
value = floatToUint(static_cast<float>(dvalue));
if (value == 0xffffffff) {
return RESULT_ERR_INVALID_NUM;
}
} else {
if (m_divisor == 1) {
if (hasFlag(SIG)) {
long signedValue = static_cast<long>(val); // TODO static_c?
if (signedValue < 0 && m_bitCount != 32) {
value = (unsigned int)(signedValue + (1 << m_bitCount));
} else {
value = (unsigned int)signedValue;
}
} else if (val < 0) {
return RESULT_ERR_INVALID_NUM; // invalid value
} else {
value = static_cast<unsigned int>(val);
}
} else {
double dvalue = val;
if (m_divisor < 0) {
dvalue = round(dvalue / -m_divisor);
} else {
dvalue = round(dvalue * m_divisor);
}
int length = static_cast<int>(m_bitCount/8);
if (hasFlag(SIG)) {
if (dvalue < -exp2((8 * static_cast<double>(length)) - 1)
|| dvalue >= exp2((8 * static_cast<double>(length)) - 1)) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
}
if (dvalue < 0 && m_bitCount != 32) {
value = static_cast<unsigned int>(dvalue + (1 << m_bitCount));
} else {
value = static_cast<unsigned int>(dvalue);
}
} else {
if (dvalue < 0.0 || dvalue >= exp2(8 * static_cast<double>(length))) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
}
value = (unsigned int)dvalue;
}
}
if (hasFlag(SIG)) { // signed value
if ((value & (1 << (m_bitCount - 1))) != 0) { // negative signed value
if (value < m_minValue) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
}
} else if (value > m_maxValue) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
}
} else if (value < m_minValue || value > m_maxValue) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
}
}
*output = value;
return RESULT_OK;
}
result_t NumberDataType::writeSymbols(size_t offset, size_t length, istringstream* input,
SymbolString* output, size_t* usedLength) const {
unsigned int value;
+16
View File
@@ -539,6 +539,22 @@ class NumberDataType : public DataType {
result_t readSymbols(size_t offset, size_t length, const SymbolString& input,
const OutputFormat outputFormat, ostream* output) const override;
/**
* Convert the numeric raw value to its float representation (including optional divisor).
* @param value the numeric raw value.
* @param output the float variable to write the value to.
* @return @a RESULT_OK on success, or an error code.
*/
result_t getFloatFromRawValue(unsigned int value, float* output) const;
/**
* Convert the float value to the numeric raw value (including optional divisor).
* @param value the float value.
* @param output the variable to write the numeric raw value to.
* @return @a RESULT_OK on success, or an error code.
*/
result_t getRawValueFromFloat(float value, unsigned int* output) const;
/**
* Internal method for interpreting a numeric raw value.
* @param value the numeric raw value.