5#include <block/cblock.h>
6#include <utils/logging.h>
8FLASHMEM blocks::CBlock::CBlock(CBlockHAL *hardware) : FunctionBlock(
"C", hardware), hardware(hardware) {}
10FLASHMEM blocks::CBlock::CBlock() : CBlock(new CBlockHALDummy()) {}
12FLASHMEM
float blocks::CBlock::get_factor(uint8_t idx) {
18FLASHMEM
const std::array<float, blocks::CBlock::NUM_COEFF> &blocks::CBlock::get_factors()
const {
22FLASHMEM
bool blocks::CBlock::set_factor(uint8_t idx,
float factor) {
25 if (factor > MAX_FACTOR or factor < MIN_FACTOR)
28 factors_[idx] = factor;
32FLASHMEM
void blocks::CBlock::set_factors(
const std::array<float, NUM_COEFF> &factors) { factors_ = factors; }
34FLASHMEM utils::status blocks::CBlock::write_to_hardware() {
35 if (!write_factors_to_hardware()) {
36 LOG(ANABRID_PEDANTIC, __PRETTY_FUNCTION__);
37 return utils::status::failure();
39 return utils::status::success();
42FLASHMEM
bool blocks::CBlock::write_factors_to_hardware() {
43 for (
size_t i = 0; i < factors_.size(); i++) {
44 if (!hardware->write_factor(i, factors_[i] * gain_corrections_[i]))
50FLASHMEM
void blocks::CBlock::reset(entities::ResetAction action) {
51 FunctionBlock::reset(action);
53 if (action.has(entities::ResetAction::CIRCUIT_RESET))
54 for (
size_t i = 0; i < NUM_COEFF; i++)
55 (
void)set_factor(i, 1.0f);
57 if (action.has(entities::ResetAction::CALIBRATION_RESET))
58 reset_gain_corrections();
61FLASHMEM
float blocks::CBlock::get_gain_correction(uint8_t idx)
const {
64 return gain_corrections_[idx];
67FLASHMEM
const std::array<float, blocks::CBlock::NUM_COEFF> &blocks::CBlock::get_gain_corrections()
const {
68 return gain_corrections_;
71FLASHMEM
void blocks::CBlock::reset_gain_corrections() {
72 std::fill(gain_corrections_.begin(), gain_corrections_.end(), 1.0f);
75FLASHMEM
void blocks::CBlock::set_gain_corrections(
const std::array<float, NUM_COEFF> &corrections) {
76 gain_corrections_ = corrections;
79FLASHMEM
bool blocks::CBlock::set_gain_correction(
const uint8_t coeff_idx,
const float correction) {
80 if (coeff_idx > NUM_COEFF)
83 if (fabs(1.0f - correction) > MAX_GAIN_CORRECTION_ABS)
85 gain_corrections_[coeff_idx] = correction;
89FLASHMEM utils::status blocks::CBlock::config_self_from_json(JsonObjectConst cfg) {
90#ifdef ANABRID_DEBUG_ENTITY_CONFIG
91 Serial.println(__PRETTY_FUNCTION__);
93 for (
auto cfgItr = cfg.begin(); cfgItr != cfg.end(); ++cfgItr) {
94 if (cfgItr->key() ==
"elements") {
95 auto res = _config_elements_form_json(cfgItr->value());
99 return utils::status(
"CBlock: Unknown configuration key");
102 return utils::status::success();
105FLASHMEM utils::status blocks::CBlock::_config_elements_form_json(
const JsonVariantConst &cfg) {
107 if (cfg.is<JsonArrayConst>()) {
108 auto factors = cfg.as<JsonArrayConst>();
109 if (factors.size() != NUM_COEFF)
110 return utils::status(
"Expecting %d elements in CBlock", NUM_COEFF);
112 for (JsonVariantConst factor : factors) {
113 if (!factor.is<
float>())
114 return utils::status(
"CBlock: Cannot convert '%s' to float", factor.as<
const char *>());
115 if (!set_factor(idx++, factor.as<
float>()))
116 return utils::status(
"CBlock factor %f is out of valid bounds", factor.as<
float>());
118 return utils::status::success();
121 else if (cfg.is<JsonObjectConst>()) {
122 serializeJson(cfg, Serial);
123 for (JsonPairConst keyval : cfg.as<JsonObjectConst>()) {
126 auto idx = std::stoul(keyval.key().c_str());
128 if (keyval.value().is<JsonObjectConst>() and
129 keyval.value().as<JsonObjectConst>().containsKey(
"factor")) {
130 if (!set_factor(idx, keyval.value().as<JsonObjectConst>()[
"factor"].as<
float>()))
131 return utils::status(
"CBlock factor value is not a float or not within range");
132 }
else if (keyval.value().is<
float>()) {
133 if (!set_factor(idx, keyval.value().as<
float>()))
134 return utils::status(
"CBlock factor value is not within range");
136 return utils::status(
"CBlock factor value is not a float");
139 return utils::status::success();
141 return utils::status(
"CBlock configuration must be an object or array.");
144FLASHMEM
void blocks::CBlock::config_self_to_json(JsonObject &cfg) {
145 Entity::config_self_to_json(cfg);
146 auto factors_cfg = cfg.createNestedArray(
"elements");
147 for (
auto idx = 0u; idx < factors_.size(); idx++) {
148 factors_cfg.add(get_factor(idx));