5#include <carrier/carrier.h>
7#include <net/settings.h>
8#include <utils/is_number.h>
10#ifdef ANABRID_BROKEN_EEPROM_WORKAROUND
18FLASHMEM carrier::Carrier::Carrier(std::vector<platform::Cluster> clusters, carrier::Carrier_HAL *hardware)
19 : Entity(
"", hardware), hardware(hardware), clusters(std::move(clusters)) {
20 classifier.class_enum = CLASS_;
23FLASHMEM utils::status carrier::Carrier::better_init() {
24 LOG(ANABRID_DEBUG_INIT, __PRETTY_FUNCTION__);
26 entity_id = net::StartupConfig::get().mac;
28 if (entity_id.empty())
29 return utils::status(
"Cannot determine Carrier MAC");
32 ctrl_block = entities::detect<blocks::CTRLBlock>(bus::address_from_tuple(1, 0));
34 #ifndef ANABRID_BROKEN_EEPROM_WORKAROUND
35 return utils::status(
"Missing CTRL Block");
37 LOG_ALWAYS(
"Error: Cannot detect Control Block. Continuing");
42 for (
auto &cluster : clusters) {
44 return utils::status(
"Cannot initialize cluster");
47 reset(entities::ResetAction::EVERYTHING);
49 return utils::status::success();
52FLASHMEM std::vector<entities::Entity *> carrier::Carrier::get_child_entities() {
53 std::vector<entities::Entity *> children;
54 for (
auto &cluster : clusters) {
55 children.push_back(&cluster);
58 children.push_back(ctrl_block);
62FLASHMEM entities::Entity *carrier::Carrier::get_child_entity(
const std::string &child_id) {
63 if (utils::is_number(child_id.begin(), child_id.end())) {
64 auto cluster_idx = std::stol(child_id);
65 if (cluster_idx < 0 or clusters.size() < cluster_idx)
67 return &clusters[cluster_idx];
69 if (child_id ==
"CTRL")
74FLASHMEM utils::status carrier::Carrier::config_self_from_json(JsonObjectConst cfg) {
76 return utils::status::success();
79FLASHMEM utils::status carrier::Carrier::write_to_hardware() {
81 int cluster_index = 1;
82 for (
auto &cluster : clusters) {
83 if (!cluster.write_to_hardware()) {
84 error.code += cluster_index;
85 error.msg +=
"Cluster write failed.";
89 if (ctrl_block && !ctrl_block->write_to_hardware()) {
91 error.msg +=
"CTRL Block write failed.";
93 if (!hardware->write_adc_bus_mux(adc_channels)) {
95 error.msg +=
"ADC Bus write failed.";
100FLASHMEM
bool carrier::Carrier::calibrate_offset() {
101 for (
auto &cluster : clusters)
102 if (!cluster.calibrate_offsets())
107FLASHMEM
bool carrier::Carrier::calibrate_routes_in_cluster(platform::Cluster &cluster) {
109 auto old_adcbus = ctrl_block->get_adc_bus();
110 ctrl_block->set_adc_bus_to_cluster_gain(cluster.get_cluster_idx());
111 if (!ctrl_block->write_to_hardware())
115 if (!cluster.calibrate_routes())
119 ctrl_block->set_adc_bus(old_adcbus);
120 if (!ctrl_block->write_to_hardware())
126FLASHMEM
bool carrier::Carrier::calibrate_routes() {
127 for (
auto &cluster : clusters) {
128 if (!calibrate_routes_in_cluster(cluster))
134FLASHMEM
bool carrier::Carrier::calibrate_mblock(platform::Cluster &cluster, blocks::MBlock &mblock) {
136 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
145 LOG(ANABRID_DEBUG_CALIBRATION,
"Connecting outputs to ADC...");
146 for (
auto output_idx : blocks::MBlock::SLOT_OUTPUT_IDX_RANGE()) {
147 auto lane_idx = mblock.slot_to_global_io_index(output_idx);
148 if (!set_adc_channel(output_idx, lane_idx))
152 if (!write_to_hardware())
156 LOG(ANABRID_DEBUG_CALIBRATION,
"Passing control to M-block...");
157 success &= mblock.calibrate(&cluster,
this);
159 LOG(ANABRID_DEBUG_CALIBRATION,
"Cleanup ADC connections...");
160 reset_adc_channels();
162 LOG(ANABRID_DEBUG_CALIBRATION,
"Cleaning up calibration signals...");
163 reset(entities::ResetAction::CIRCUIT_RESET);
166 if (!write_to_hardware())
169 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibration done.");
174FLASHMEM
bool carrier::Carrier::calibrate_m_blocks() {
176 for (
auto &cluster : clusters)
177 for (
auto mblock : {cluster.m0block, cluster.m1block}) {
179 if (!calibrate_mblock(cluster, *mblock))
185FLASHMEM
void carrier::Carrier::reset(entities::ResetAction action) {
186 for (
auto &cluster : clusters) {
187 cluster.reset(action);
190 ctrl_block->reset(action);
191 reset_adc_channels();
194FLASHMEM
const std::array<int8_t, 8> &carrier::Carrier::get_adc_channels()
const {
return adc_channels; }
196FLASHMEM
bool carrier::Carrier::set_adc_channels(
const std::array<int8_t, 8> &channels) {
198 for (
auto channel : channels) {
205 for (
auto &channel : channels) {
208 for (
auto &other_channel : channels) {
209 if (std::addressof(channel) == std::addressof(other_channel))
211 if (channel == other_channel)
215 adc_channels = channels;
219FLASHMEM
bool carrier::Carrier::set_adc_channel(uint8_t idx, int8_t adc_channel) {
220 if (idx >= adc_channels.size())
223 adc_channel = ADC_CHANNEL_DISABLED;
227 if (adc_channel != ADC_CHANNEL_DISABLED)
228 for (
auto other_idx = 0u; other_idx < adc_channels.size(); other_idx++)
229 if (idx != other_idx and adc_channels[other_idx] == adc_channel)
232 adc_channels[idx] = adc_channel;
236FLASHMEM
void carrier::Carrier::reset_adc_channels() {
237 std::fill(adc_channels.begin(), adc_channels.end(), ADC_CHANNEL_DISABLED);
240FLASHMEM utils::status carrier::Carrier::user_set_extended_config(JsonObjectConst msg_in,
241 JsonObject &msg_out) {
242#ifdef ANABRID_DEBUG_COMMS
243 Serial.println(__PRETTY_FUNCTION__);
246 bool default_reset_before =
true, default_sh_kludge =
true, default_mul_calib_kludge =
true,
247 default_calibrate_mblock =
false, default_calibrate_offset =
false, default_calibrate_routes =
false;
249 if (msg_in[
"reset_before"] | default_reset_before) {
250 reset(entities::ResetAction::CIRCUIT_RESET | entities::ResetAction::OVERLOAD_RESET |
251 entities::ResetAction::CALIBRATION_RESET);
255 if (msg_in[
"sh_kludge"] | default_sh_kludge) {
256 for (
auto &cluster : clusters) {
257 if (cluster.shblock) {
258 cluster.shblock->set_state(blocks::SHState::TRACK);
260 delayMicroseconds(1000);
261 cluster.shblock->set_state(blocks::SHState::INJECT);
267 if ((msg_in[
"calibrate_mblock"] | default_calibrate_mblock) && !calibrate_m_blocks())
268 return utils::status(10,
"Calibrate MBlocks failed");
270 auto res = user_set_config(msg_in, msg_out);
275 if ((msg_in[
"calibrate_offset"] | default_calibrate_offset) && !calibrate_offset())
276 return utils::status(10,
"Calibrate-offset failed");
278 if ((msg_in[
"calibrate_routes"] | default_calibrate_routes) && !calibrate_routes())
279 return utils::status(10,
"Calibrate-Routes failed");
281 return utils::status::success();
284FLASHMEM utils::status carrier::Carrier::user_get_overload_status(JsonObjectConst msg_in,
285 JsonObject &msg_out) {
286 msg_out[
"global_overload"] = mode::is_global_overload_active();
288 auto flags = msg_out.createNestedObject(
"entity_overload");
289 for (
auto &cluster : clusters) {
290 auto cluster_obj = flags.createNestedObject(
"/" + cluster.get_entity_id());
291 for (
auto &block : cluster.get_blocks()) {
300 return utils::status::success();
static constexpr int success