5#include <block/cblock.h>
7#include <entity/visitor.h>
8#include <utils/logging.h>
10blocks::CBlock::CBlock(CBlockHAL *hardware) : FunctionBlock(
"C", hardware), hardware(hardware) {
11 classifier.class_enum = CLASS_;
14blocks::CBlock::CBlock() : CBlock(new CBlockHALDummy()) {}
16float blocks::CBlock::get_factor(uint8_t idx) {
22const std::array<float, blocks::CBlock::NUM_COEFF> &blocks::CBlock::get_factors()
const {
26UnitResult blocks::CBlock::set_factor(uint8_t idx,
float factor) {
28 return UnitResult::err_fmt(
"Error c-block factor idx to high %d", idx);
29 if (factor > MAX_FACTOR or factor < MIN_FACTOR)
30 return UnitResult::err_fmt(
"Error c-block factor outside range %f", factor);
31 factors_[idx] = factor;
32 return UnitResult::ok();
35void blocks::CBlock::set_factors(
const std::array<float, NUM_COEFF> &factors) { factors_ = factors; }
37UnitResult blocks::CBlock::write_to_hardware() {
38 if (!write_factors_to_hardware()) {
39 LOG(ANABRID_PEDANTIC, __PRETTY_FUNCTION__);
40 return UnitResult::err(
"Writing to c-block factors failed");
42 return UnitResult::ok();
45bool blocks::CBlock::write_factors_to_hardware() {
46 for (
size_t i = 0; i < factors_.size(); i++) {
47 auto factor = factors_[i] * gain_corrections_[i];
48 if (!hardware->write_factor(i, factor))
54void blocks::CBlock::reset(entities::ResetAction action) {
55 FunctionBlock::reset(action);
57 if (action.has(entities::ResetAction::CIRCUIT_RESET))
58 for (
size_t i = 0; i < NUM_COEFF; i++)
59 (
void)set_factor(i, 1.0f);
61 if (action.has(entities::ResetAction::CALIBRATION_RESET))
62 reset_gain_corrections();
65float blocks::CBlock::get_gain_correction(uint8_t idx)
const {
68 return gain_corrections_[idx];
71const std::array<float, blocks::CBlock::NUM_COEFF> &blocks::CBlock::get_gain_corrections()
const {
72 return gain_corrections_;
75void blocks::CBlock::reset_gain_corrections() {
76 std::fill(gain_corrections_.begin(), gain_corrections_.end(), 1.0f);
79UnitResult blocks::CBlock::set_gain_corrections(
const std::array<float, NUM_COEFF> &corrections) {
80 for (
size_t idx = 0; idx < NUM_COEFF; idx++) {
81 TRY(set_gain_correction(idx, corrections[idx]));
83 return UnitResult::ok();
86UnitResult blocks::CBlock::set_gain_correction(
const uint8_t coeff_idx,
const float correction) {
87 if (coeff_idx > NUM_COEFF)
88 return UnitResult::err_fmt(
"Error c-block coef idx out of range: %d", coeff_idx);
90 if (correction < 0.0f || correction > MAX_GAIN_CORRECTION_ABS + 1.0f)
91 return UnitResult::err_fmt(
"Error c-block coef gain correction out of range: %d %f", coeff_idx, correction);
93 gain_corrections_[coeff_idx] = correction;
94 return UnitResult::ok();
97ConfigResult blocks::CBlock::config(
const pb_Item &item) {
98#ifdef ANABRID_DEBUG_ENTITY_CONFIG
99 Serial.println(__PRETTY_FUNCTION__);
101 if (item.which_kind != pb_Item_coef_config_tag)
102 return ConfigResult::err(
"expected coef block config");
104 auto& coef_config = item.kind.coef_config;
105 return _apply_elements(coef_config);
108ConfigResult blocks::CBlock::_apply_elements(
const pb_CoefConfig &item) {
110 for (
size_t elem_idx = 0; elem_idx < item.elements_count; ++elem_idx) {
111 auto& element = item.elements[elem_idx];
112 TRY(set_factor(element.idx, element.factor));
113 if (element.has_gain_correction )
114 TRY(set_gain_correction(element.idx, element.gain_correction));
117 return ConfigResult::ok(
true);
120void blocks::CBlock::extract(entities::ExtractVisitor &collector) {
122 if (!collector.include_configuration() && !collector.include_calibration())
return;
123 auto& item = collector.create(pb_Item_coef_config_tag);
124 auto& coef_config = item.kind.coef_config;
125 coef_config.elements_count = NUM_COEFF;
126 auto& idx = coef_config.elements_count = 0;
127 for (;idx < NUM_COEFF; ++idx) {
128 auto& elem = coef_config.elements[idx];
131 if (collector.include_configuration()) {
132 elem.factor = factors_[idx];
135 if (collector.include_calibration()) {
136 elem.has_gain_correction =
true;
137 elem.gain_correction = gain_corrections_[idx];