REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
hybrid_controller.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
13
14#include "protocol/protocol_oob.h"
15#include "redac/calibration.h"
16#include "run/run_manager.h"
17
18#include <Arduino.h>
19
20#include <build/distributor.h>
21#include <daq/daq.h>
22#include <lucidac/front_panel_signaling.h>
23#include <lucidac/lucidac.h>
24#include <mode/mode.h>
25#include <net/auth.h>
26#include <net/settings.h>
27#include <plugin/static.h>
28#include <protocol/handler.h>
29#include <protocol/jsonl_logging.h>
30#include <protocol/jsonl_server.h>
31#include <protocol/protocol.h>
32#include <protocol/registry.h>
33#include <redac/redac.h>
34#include <utils/crash_report.h>
35#include <utils/hashflash.h>
36#include <utils/logging.h>
37
38void setup() {
39 // Initialize serial communication
40 Serial.begin(0);
41 // while (!Serial && millis() < 4000) {
42 // Wait for Serial, but not forever
43 //}
44
45 msg::Log::get().sinks.add_Serial();
46 msg::Log::get().sinks.add(&msg::StartupLog::get());
47
48 bus::init();
49
50 LOG_ALWAYS(dist::ident());
51 LOGV("Flash image (%d bytes) sha256 sum: %s\n", loader::flashimage::len(),
52 loader::flashimage::sha256sum().to_string().c_str());
53
55
56 // Initialize carrier board
57 // TODO, _ERROR_OUT_ shall not be used, see #116
58 LOG(ANABRID_DEBUG_INIT, "Detecting and Initializing carrier board...");
59 auto &carrier_ = carrier::Carrier::get();
60 auto carrier_init_result = carrier_.init();
61 if (!carrier_init_result) {
62 LOG_ERROR("Error initializing carrier board.");
63 LOG_ERROR(carrier_init_result.err_value().c_str());
64 leds::indicate_error();
65 }
66
67 // all LEDs on: Both visual self-test and showing that now ethernet search takes place.
68 leds::set(0xFF);
69
70 LOG(ANABRID_DEBUG_INIT, "Starting up Ethernet...");
71 net::register_settings();
72 auto &netconf = net::StartupConfig::get();
73 int net_error = netconf.begin_ip();
74 if (!net_error && netconf.enable_mdns) {
75 LOG_ALWAYS("Starting MDNS");
76 netconf.begin_mdns();
77 }
78 if (!net_error && netconf.enable_jsonl)
79 msg::ApplicationServer::get().begin();
80 //if (!net_error && netconf.enable_webserver)
81 // web::LucidacWebServer::get().begin();
82
83 // Initialize things related to runs
84 // TODO: I think mode control must be initialized somewhere here?
85 /*
86 if (!mode::FlexIOControl::init(mode::DEFAULT_IC_TIME, mode::DEFAULT_OP_TIME)) {
87 LOG_ERROR("Error initializing FlexIO mode control.");
88 leds::indicate_error();
89 }
90 */
91
92 auto &reg = msg::handlers::Registry::get();
93 reg.init(carrier_); // registers all commonly known messages
94
95 msg::Broker::get(); // init json lines protocol
96
97 // Initialize data acquisition before it's used later
98 daq::init();
99 if (!daq::calibrate(carrier_)) {
100 LOG_ALWAYS("Warning: Error during DAQ calibration. Machine will continue with reduced accuracy.");
101 }
102
103 // Reset overload line
104 carrier_.reset(entities::ResetAction::OVERLOAD_RESET);
105
106 // Set computer into IC mode at startup
107 mode::RealManualControl::to_ic();
108
109 // Run calibration
110 LOG(ANABRID_DEBUG_INIT, "Executing self-calibration, this may take a few moments...");
111 auto mblock_calibrate_result = carrier_.calibrate_m_blocks();
112 if (!mblock_calibrate_result) {
113 // Right now, self-calibration is still not well tested and the error handling
114 // suggest it fails despite it most likely does not. Therefore, do not make
115 // the output so harsh.
116 //
117 // LOG_ERROR("Error during self-calibration. Machine will continue with reduced accuracy.");
118 // leds::indicate_error();
119 //
120 // instead, do this:
121
122 LOG_ALWAYS(mblock_calibrate_result.err_value().c_str());
123 LOG_ALWAYS("Info: Startup self-calibration apparently did not succeed. The calibration scheme is by "
124 "default not used in this build anyway.");
125
126 // For a quick fix, reset machine here because calibration routines exit
127 // early which *do* result in a machine in an unusable state.
128 carrier_.reset(entities::ResetAction::CIRCUIT_RESET | entities::ResetAction::OVERLOAD_RESET);
129 (void)carrier_.write_to_hardware();
130 }
131
132 // Done.
133 LOG(ANABRID_DEBUG_INIT, "Initialization done.");
134
135 static_plugin::setup();
136
137 platform::CalibrationBase::begin();
138
139 // visual effect to show that booting has been done
140 leds::ease_out();
141}
142
143void loop() {
144
145 auto &netconf = net::StartupConfig::get();
146
147 if (netconf.enable_jsonl)
148 msg::ApplicationServer::get().loop();
149
150 if (Serial.available()) {
151 auto input_stream = std::make_shared<transport::DelimitedInputStream<Stream*>>(&Serial);
152 auto output_stream = std::make_shared<transport::DelimitedMessageOutputStream<Stream*>>(&Serial);
153 transport::Transport transport(std::move(input_stream), output_stream, std::move(output_stream));
154 msg::Broker::get().process(transport);
155 }
156
157 run::RunManager::get().try_run_next(carrier::Carrier::get());
158 static_plugin::loop();
159}
void setup()
void loop()
void check_and_log_crash()
Logs out what has been captured by the Teensy CrashReport tooling, cf.