5#include "carrier/cluster.h"
7#include "utils/logging.h"
8#include "utils/running_avg.h"
10#include "block/cblock.h"
11#include "block/iblock.h"
12#include "block/mblock.h"
13#include "block/ublock.h"
15FLASHMEM std::array<blocks::FunctionBlock *, 6> platform::Cluster::get_blocks()
const {
16 return {m0block, m1block, ublock, cblock, iblock, shblock};
19FLASHMEM
bool platform::Cluster::init() {
20 LOG(ANABRID_DEBUG_INIT, __PRETTY_FUNCTION__);
24 LOG(ANABRID_DEBUG_INIT,
"Detecting installed blocks...");
26 m0block = entities::detect<blocks::MBlock>(bus::idx_to_addr(cluster_idx, bus::M0_BLOCK_IDX, 0));
28 LOG(ANABRID_DEBUG_INIT,
"Warning: M0-block is missing or unknown.");
31 m1block = entities::detect<blocks::MBlock>(bus::idx_to_addr(cluster_idx, bus::M1_BLOCK_IDX, 0));
33 LOG(ANABRID_DEBUG_INIT,
"Warning: M1-block is missing or unknown.");
35 if (!m0block and !m1block)
36 LOG(ANABRID_DEBUG_INIT,
"Error: Both M0 and M1-blocks are missing or unknown.");
39 ublock = entities::detect<blocks::UBlock>(bus::idx_to_addr(cluster_idx, bus::U_BLOCK_IDX, 0));
41 LOG_ERROR(
"Error: U-block is missing or unknown.");
44 cblock = entities::detect<blocks::CBlock>(bus::idx_to_addr(cluster_idx, bus::C_BLOCK_IDX, 0));
46 LOG_ERROR(
"Error: C-block is missing or unknown.");
49 iblock = entities::detect<blocks::IBlock>(bus::idx_to_addr(cluster_idx, bus::I_BLOCK_IDX, 0));
51 LOG_ERROR(
"Error: I-block is missing or unknown.");
54 shblock = entities::detect<blocks::SHBlock>(bus::idx_to_addr(cluster_idx, bus::SH_BLOCK_IDX, 0));
56 LOG_ERROR(
"Error: SH-block is missing or unknown.");
59 LOG(ANABRID_DEBUG_INIT,
"Initialising detected blocks...");
60 for (
auto block : get_blocks()) {
61 if (block && !block->init())
64 LOG(ANABRID_DEBUG_INIT,
"Cluster initialized.");
65 reset(entities::ResetAction::EVERYTHING);
69FLASHMEM platform::Cluster::Cluster(uint8_t cluster_idx)
70 :
entities::Entity(std::to_string(cluster_idx)), cluster_idx(cluster_idx) {
71 classifier.class_enum = CLASS_;
74FLASHMEM
bool platform::Cluster::calibrate_offsets() {
75 LOG_ANABRID_DEBUG_CALIBRATION(
"Calibrating offsets");
76 if (!ublock or !shblock)
79 auto old_transmission_modes = ublock->get_all_transmission_modes();
81 ublock->change_all_transmission_modes(blocks::UBlock::Transmission_Mode::GROUND);
82 if (!ublock->write_to_hardware())
86 shblock->compensate_hardware_offsets();
88 ublock->change_all_transmission_modes(old_transmission_modes);
89 if (!ublock->write_to_hardware())
95FLASHMEM
bool platform::Cluster::calibrate_routes() {
100 LOG_ANABRID_DEBUG_CALIBRATION(
"Starting calibration");
101 auto old_transmission_modes = ublock->get_all_transmission_modes();
102 auto old_reference_magnitude = ublock->get_reference_magnitude();
105 auto old_c_block_factors = cblock->get_factors();
106 cblock->set_factors({});
109 LOG_ANABRID_DEBUG_CALIBRATION(
"Reset c-block");
110 if (!cblock->write_to_hardware())
113 auto old_i_block_upscaling = iblock->get_upscales();
114 iblock->reset_upscaling();
115 if (!iblock->write_to_hardware())
121 for (
auto i_out_idx : blocks::IBlock::OUTPUT_IDX_RANGE()) {
122 for (
auto i_in_idx : blocks::IBlock::INPUT_IDX_RANGE()) {
124 if (!iblock->is_connected(i_in_idx, i_out_idx))
129 if (!ublock->is_output_connected(i_in_idx))
132 LOG_ANABRID_DEBUG_CALIBRATION(
"Calibrating connection: ");
133 LOG_ANABRID_DEBUG_CALIBRATION(i_in_idx);
134 LOG_ANABRID_DEBUG_CALIBRATION(i_out_idx);
138 bool upscaled_channel = iblock->get_upscaling(i_in_idx);
139 ublock->change_all_transmission_modes(blocks::UBlock::Transmission_Mode::POS_REF);
140 ublock->change_reference_magnitude(upscaled_channel ? blocks::UBlock::Reference_Magnitude::ONE_TENTH
141 : blocks::UBlock::Reference_Magnitude::ONE);
143 if (!ublock->write_to_hardware())
148 (void)cblock->set_factor(i_in_idx, 1.0f);
149 (void)cblock->set_gain_correction(i_in_idx, 1.0f);
151 if (!cblock->write_to_hardware())
155 if (!calibrate_offsets())
160 shblock->set_state(blocks::SHState::GAIN_ZERO_TO_SEVEN);
162 shblock->set_state(blocks::SHState::GAIN_EIGHT_TO_FIFTEEN);
163 if (!shblock->write_to_hardware())
170 auto m_adc = daq::average(daq::sample, 4, 10)[i_out_idx % 8];
171 LOG_ANABRID_DEBUG_CALIBRATION(m_adc);
173 auto gain_correction = 1.0f / m_adc;
174 LOG_ANABRID_DEBUG_CALIBRATION(gain_correction);
176 if (!cblock->set_gain_correction(i_in_idx, gain_correction)) {
177 LOG_ANABRID_DEBUG_CALIBRATION(
"Gain correction could not be set as it is out of range. Resetting this "
178 "channel to default corretion");
179 (void)cblock->set_gain_correction(i_in_idx, 1.0f);
184 (void)cblock->set_factor(i_in_idx, 0.0f);
185 if (!cblock->write_to_hardware())
188 LOG_ANABRID_DEBUG_CALIBRATION(
" ");
193 cblock->set_factors(old_c_block_factors);
194 LOG_ANABRID_DEBUG_CALIBRATION(
"Restoring c-block");
195 if (!cblock->write_to_hardware())
201 ublock->change_all_transmission_modes(old_transmission_modes);
202 ublock->change_reference_magnitude(old_reference_magnitude);
204 LOG_ANABRID_DEBUG_CALIBRATION(
"Restoring u-block");
205 if (!ublock->write_to_hardware())
208 iblock->set_upscaling(old_i_block_upscaling);
209 if (!iblock->write_to_hardware()) {
213 if (!calibrate_offsets())
219FLASHMEM utils::status platform::Cluster::write_to_hardware() {
220 for (
auto block : get_blocks()) {
222 if (!block->write_to_hardware()) {
223 LOG(ANABRID_PEDANTIC, __PRETTY_FUNCTION__);
224 return utils::status::failure();
227 return utils::status::success();
230FLASHMEM
bool platform::Cluster::route(uint8_t u_in, uint8_t u_out,
float c_factor, uint8_t i_out) {
231 if (fabs(c_factor) > 1.0f) {
232 c_factor = c_factor * 0.1f;
233 iblock->set_upscaling(u_out,
true);
235 iblock->set_upscaling(u_out,
false);
237 if (!ublock->connect(u_in, u_out))
239 if (!cblock->set_factor(u_out, c_factor))
241 if (!iblock->connect(u_out, i_out))
246FLASHMEM
bool platform::Cluster::add_constant(blocks::UBlock::Transmission_Mode signal_type, uint8_t u_out,
247 float c_factor, uint8_t i_out) {
248 if (fabs(c_factor) > 1.0f) {
249 c_factor = c_factor * 0.1f;
250 iblock->set_upscaling(u_out,
true);
252 iblock->set_upscaling(u_out,
false);
254 if (!ublock->connect_alternative(signal_type, u_out))
256 if (!cblock->set_factor(u_out, c_factor))
258 if (!iblock->connect(u_out, i_out))
263FLASHMEM
bool platform::Cluster::route_in_external(uint8_t in, uint8_t i_out) {
267 return iblock->connect(in + 24, i_out);
270FLASHMEM
bool platform::Cluster::route_out_external(uint8_t u_in, uint8_t out,
float c_factor) {
274 if (!ublock->connect(u_in, out + 24))
276 return cblock->set_factor(out + 24, c_factor);
279FLASHMEM
void platform::Cluster::reset(entities::ResetAction action) {
280 for (
auto block : get_blocks()) {
282 block->reset(action);
286FLASHMEM entities::Entity *platform::Cluster::get_child_entity(
const std::string &child_id) {
287 if (child_id ==
"M0")
289 else if (child_id ==
"M1")
291 else if (child_id ==
"U")
293 else if (child_id ==
"C")
295 else if (child_id ==
"I")
297 else if (child_id ==
"SH")
302FLASHMEM utils::status platform::Cluster::config_self_from_json(JsonObjectConst cfg) {
303#ifdef ANABRID_DEBUG_ENTITY_CONFIG
304 Serial.println(__PRETTY_FUNCTION__);
308 return utils::status::success();
311FLASHMEM std::vector<entities::Entity *> platform::Cluster::get_child_entities() {
312#ifdef ANABRID_DEBUG_ENTITY_CONFIG
313 Serial.println(__PRETTY_FUNCTION__);
315 return {m0block, m1block, ublock, cblock, iblock, shblock};
318FLASHMEM uint8_t platform::Cluster::get_cluster_idx()
const {
return cluster_idx; }
static constexpr int success