REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
cluster.cpp
Go to the documentation of this file.
1// Copyright (c) 2024 anabrid GmbH
2// Contact: https://www.anabrid.com/licensing/
3// SPDX-License-Identifier: MIT OR GPL-2.0-or-later
4
5#include "carrier/cluster.h"
6#include "utils/logging.h"
7
8#include "block/cblock.h"
9#include "block/iblock.h"
10#include "block/mblock.h"
11#include "block/ublock.h"
12
13std::array<blocks::FunctionBlock *, 6> platform::Cluster::get_blocks() const { return {m0block, m1block, ublock, cblock, iblock, shblock}; }
14
15bool platform::Cluster::init() {
16 LOG(ANABRID_DEBUG_INIT, __PRETTY_FUNCTION__);
17
18 // Dynamically detect installed blocks
19 // Check if a block is already set, which may happen with a special constructor in the future
20 LOG(ANABRID_DEBUG_INIT, "Detecting installed blocks...");
21 if (!m0block) {
22 m0block = entities::detect<blocks::MBlock>(bus::idx_to_addr(cluster_idx, bus::M0_BLOCK_IDX, 0));
23 if (!m0block)
24 LOG_ERROR("Warning: M0-block is missing or unknown.");
25 }
26 if (!m1block) {
27 m1block = entities::detect<blocks::MBlock>(bus::idx_to_addr(cluster_idx, bus::M1_BLOCK_IDX, 0));
28 if (!m1block)
29 LOG_ERROR("Warning: M1-block is missing or unknown.");
30 }
31
32 if (!ublock) {
33 ublock = entities::detect<blocks::UBlock>(bus::idx_to_addr(cluster_idx, bus::U_BLOCK_IDX, 0));
34 if (!ublock)
35 LOG_ERROR("Error: U-block is missing or unknown.");
36 }
37 if (!cblock) {
38 cblock = entities::detect<blocks::CBlock>(bus::idx_to_addr(cluster_idx, bus::C_BLOCK_IDX, 0));
39 if (!cblock)
40 LOG_ERROR("Error: C-block is missing or unknown.");
41 }
42 if (!iblock) {
43 iblock = entities::detect<blocks::IBlock>(bus::idx_to_addr(cluster_idx, bus::I_BLOCK_IDX, 0));
44 if (!iblock)
45 LOG_ERROR("Error: I-block is missing or unknown.");
46 }
47 if (!shblock) {
48 shblock = entities::detect<blocks::SHBlock>(bus::idx_to_addr(cluster_idx, bus::SH_BLOCK_IDX, 0));
49 if (!shblock)
50 LOG_ERROR("Error: SH-block is missing or unknown.");
51 }
52
53 LOG(ANABRID_DEBUG_INIT, "Initialising detected blocks...");
54 for (auto block : get_blocks()) {
55 if (block && !block->init())
56 return false;
57 }
58 LOG(ANABRID_DEBUG_INIT, "Cluster initialized.");
59 reset(entities::ResetAction::EVERYTHING);
60 return true;
61}
62
63platform::Cluster::Cluster(uint8_t cluster_idx) : entities::Entity(std::to_string(cluster_idx)), cluster_idx(cluster_idx) {
64 classifier.class_enum = CLASS_;
65}
66
67status platform::Cluster::calibrate_offsets() {
68 LOG(ANABRID_DEBUG_INIT, __PRETTY_FUNCTION__);
69
71
72 LOG_ANABRID_DEBUG_CALIBRATION("Calibrating offsets");
73 if (!ublock or !shblock)
74 success.attach("Writing to u-block failed");
75
76 auto old_transmission_modes = ublock->get_all_transmission_modes();
77
78 ublock->change_all_transmission_modes(blocks::UBlock::Transmission_Mode::GROUND);
79 if (!ublock->write_to_hardware())
80 success.attach("Writing to u-block failed");
81
82 delay(10);
83 shblock->compensate_hardware_offsets();
84
85 ublock->change_all_transmission_modes(old_transmission_modes);
86 if (!ublock->write_to_hardware())
87 success.attach("Writing to u-block failed");
88
89 delay(10);
90
91 LOG(ANABRID_DEBUG_INIT, __PRETTY_FUNCTION__);
92 return success;
93}
94
95status platform::Cluster::write_to_hardware() {
97 for (auto block : get_blocks())
98 if (block)
99 success.attach(block->write_to_hardware());
100
101 return success;
102}
103
104status platform::Cluster::route(uint8_t u_in, uint8_t u_out, float c_factor, uint8_t i_out) {
105 if (fabs(c_factor) > 1.0f) {
106 c_factor = c_factor / 8.0f;
107 iblock->set_upscaling(u_out, true);
108 } else
109 iblock->set_upscaling(u_out, false);
110
111 if (!ublock->connect(u_in, u_out))
112 return status("U block connection not possible");
113 if (!cblock->set_factor(u_out, c_factor))
114 return status("C block configuration not possible");
115 if (!iblock->connect(u_out, i_out))
116 return status("I block connection not possible");
117 return status::success();
118}
119
120status platform::Cluster::add_constant(blocks::UBlock::Transmission_Mode signal_type, uint8_t u_out, float c_factor, uint8_t i_out) {
121 if (fabs(c_factor) > 1.0f) {
122 c_factor = c_factor / 8.0f;
123 iblock->set_upscaling(u_out, true);
124 } else
125 iblock->set_upscaling(u_out, false);
126
127 if (!ublock->connect_alternative(signal_type, u_out))
128 return status("U block connection not possible");
129 if (!cblock->set_factor(u_out, c_factor))
130 return status("C block configuration not possible");
131 if (!iblock->connect(u_out, i_out))
132 return status("I block connection not possible");
133 return status::success();
134}
135
136void platform::Cluster::reset(entities::ResetAction action) {
137 for (auto block : get_blocks()) {
138 if (block)
139 block->reset(action);
140 }
141}
142
143entities::Entity *platform::Cluster::get_child_entity(std::string_view child_id) {
144 if (child_id == "M0")
145 return m0block;
146 else if (child_id == "M1")
147 return m1block;
148 else if (child_id == "U")
149 return ublock;
150 else if (child_id == "C")
151 return cblock;
152 else if (child_id == "I")
153 return iblock;
154 else if (child_id == "SH")
155 return shblock;
156 return nullptr;
157}
158
159ConfigResult platform::Cluster::config(const pb_Config &cfg) {
160#ifdef ANABRID_DEBUG_ENTITY_CONFIG
161 Serial.println(__PRETTY_FUNCTION__);
162#endif
163 // Cluster has no own configuration parameters currently
164 return ConfigResult::ok(false);
165}
166
167std::vector<entities::Entity *> platform::Cluster::get_child_entities() {
168#ifdef ANABRID_DEBUG_ENTITY_CONFIG
169 Serial.println(__PRETTY_FUNCTION__);
170#endif
171 return {m0block, m1block, ublock, cblock, iblock, shblock};
172}
173
174uint8_t platform::Cluster::get_cluster_idx() const { return cluster_idx; }
175
176std::pair<uint8_t, uint8_t> platform::Cluster::get_id_connection() const {
177 blocks::MBlock *id_block = nullptr;
178 if (m0block->has_id_lanes())
179 id_block = m0block;
180 if (m1block->has_id_lanes())
181 id_block = m1block;
182
183 if (id_block == nullptr)
184 return {0xff, 0xff};
185
186
187 for (uint8_t out = 0; out < 8; out++) {
188 int8_t in = id_block->ID_OUTPUT_CONNECTIONS()[out];
189 if (in != -1)
190 return {id_block->slot_to_global_io_index(in), id_block->slot_to_global_io_index(out)};
191 }
192 return {0xff, 0xff};
193}
utils::status status
Definition daq.h:21
static constexpr int success
Definition flasher.cpp:275