// The MIT License (MIT) // // Copyright (c) 2018 Mateusz Pusz // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!! Before you commit any changes to this file please make sure to check if it !!! // !!! renders correctly in the documentation "Examples" section. !!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #include #include #ifdef MP_UNITS_IMPORT_STD import std; #else #include #include #endif #ifdef MP_UNITS_MODULES import mp_units; #else #include #include #endif using namespace mp_units; // real voltage range inline constexpr int min_voltage = -10; inline constexpr int max_voltage = 10; inline constexpr int voltage_range = max_voltage - min_voltage; // hardware encoding of voltage using voltage_hw_t = std::uint16_t; inline constexpr voltage_hw_t voltage_hw_error = std::numeric_limits::max(); inline constexpr voltage_hw_t voltage_hw_min = 0; inline constexpr voltage_hw_t voltage_hw_max = voltage_hw_error - 1; inline constexpr voltage_hw_t voltage_hw_range = voltage_hw_max - voltage_hw_min; inline constexpr voltage_hw_t voltage_hw_zero = voltage_hw_range / 2; // clang-format off inline constexpr struct hw_voltage_origin final : relative_point_origin(min_voltage)> {} hw_voltage_origin; inline constexpr struct hw_voltage_unit final : named_unit<"hwV", mag_ratio * si::volt, hw_voltage_origin> {} hw_voltage_unit; using hw_voltage_quantity_point = quantity_point; // clang-format on // mapped HW register volatile voltage_hw_t hw_voltage_value; std::optional read_hw_voltage() { voltage_hw_t local_copy = hw_voltage_value; if (local_copy == voltage_hw_error) return std::nullopt; return point(local_copy); } void print(QuantityPoint auto qp) { std::cout << MP_UNITS_STD_FMT::format("{:10} ({:5})", qp.quantity_from_zero(), value_cast(qp).quantity_from_zero()); } int main() { // simulate reading of 3 values from the hardware hw_voltage_value = voltage_hw_min; quantity_point qp1 = read_hw_voltage().value(); hw_voltage_value = voltage_hw_zero; quantity_point qp2 = read_hw_voltage().value(); hw_voltage_value = voltage_hw_max; quantity_point qp3 = read_hw_voltage().value(); print(qp1); print(qp2); print(qp3); }