9#include <utils/logging.h>
11#include <carrier/carrier.h>
12#include <carrier/cluster.h>
20extern int abs_clamp(
float in,
int min,
int max);
22blocks::MIntBlock *blocks::MIntBlock::from_entity_classifier(entities::EntityClassifier classifier,
23 const bus::addr_t block_address) {
24 if (!classifier or classifier.class_enum != CLASS_ or classifier.type !=
static_cast<uint8_t
>(TYPE))
28 if (classifier.variant != entities::EntityClassifier::DEFAULT_)
31 SLOT slot = block_address % 8 == 4 ? SLOT::M0 : SLOT::M1;
32 if (classifier.version < entities::Version(1))
34 if (classifier.version < entities::Version(1, 1)) {
35 auto *new_block =
new MIntBlock(slot,
new MIntBlockHAL_V_1_0_X(block_address));
36 new_block->classifier = classifier;
39 if (classifier.version < entities::Version(1, 2)) {
40 auto *new_block =
new MIntBlock_V_1_1_X(slot,
new MIntBlockHAL_V_1_1_X(block_address));
41 new_block->classifier = classifier;
50 MIntBlock::reset(action);
52 if (action.has(entities::ResetAction::CALIBRATION_RESET)) {
53 for (
auto idx = 0u; idx < MIntBlock::NUM_INTEGRATORS; idx++)
57 if (action.has(entities::ResetAction::CIRCUIT_RESET))
62const std::array<blocks::IntegratorCalibration, blocks::MIntBlock_V_1_1_X::NUM_INTEGRATORS> &
68 if (int_idx >= NUM_INTEGRATORS)
75 for (
decltype(ic_values.size()) i = 0; i < ic_values.size(); i++) {
76 if (!
hardware->write_ic(i, ic_values[i])) {
77 LOG(ANABRID_PEDANTIC, __PRETTY_FUNCTION__);
78 return UnitResult::err(
"Error writing IC values to hardware.");
83 std::bitset<NUM_INTEGRATORS> time_factor_switches{};
84 for (
auto idx = 0u; idx < time_factors.size(); idx++)
85 if (time_factors[idx] != DEFAULT_TIME_FACTOR)
86 time_factor_switches.set(idx);
89 return UnitResult::err(
"Error writing time factors or limiters");
94 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
96 TRY(MBlock::calibrate(cluster,
carrier));
99 cluster->reset(entities::ResetAction::CIRCUIT_RESET);
102 LOG(ANABRID_DEBUG_CALIBRATION,
"Connecting calibration signals!");
105 for (
auto idx : SLOT_INPUT_IDX_RANGE()) {
106 TRY(cluster->add_constant(
107 UBlock::Transmission_Mode::POS_REF,
108 slot_to_global_io_index(idx),
110 slot_to_global_io_index(idx)
114 cluster->ublock->change_reference_magnitude(UBlock::Reference_Magnitude::ONE_TENTH);
116 TRY_TRUE(cluster->write_to_hardware());
119 TRY(
carrier->calibrate_routes());
121 LOG(ANABRID_DEBUG_CALIBRATION,
"Starting ramp integration on fast mode!");
122 set_time_factors(10000);
123 set_ic_values(-1.0f);
127 LOG(ANABRID_DEBUG_CALIBRATION,
"Finished ramp integration on fast mode!");
129 LOG(ANABRID_DEBUG_CALIBRATION,
"Starting ramp integration on slow mode!");
130 set_time_factors(100);
134 LOG(ANABRID_DEBUG_CALIBRATION,
"Finished ramp integration on slow mode!");
136 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
139 return UnitResult::ok();
143 for (
size_t i = 0; i < NUM_INTEGRATORS; i++) {
144 auto gain = time_factors[i] == 10000
147 if (!
hardware->write_time_factor_gain(i, gain))
148 return UnitResult::err_fmt(
"Error mint-block writing time factor gain: %d %f", i, gain);
150 return UnitResult::ok();
154 const float target_precision = 0.01f;
155 const int max_loops = 100;
158 std::bitset<NUM_INTEGRATORS> done_channels;
162 while (!done_channels.all()) {
166 mode::OnOverload::IGNORE, mode::OnExtHalt::IGNORE))
167 LOG(ANABRID_DEBUG_CALIBRATION,
"Timer failed!");
173 auto read_outputs = daq::average(daq::sample, 4, 10);
175 for (
auto idx = 0u; idx < NUM_INTEGRATORS; idx++) {
176 uint8_t *time_factor_gain = use_slow_integration ? &
calibration[idx].time_factor_gain_slow
178 if (fabs(read_outputs[idx] + 1.0f) < target_precision) {
179 done_channels[idx] =
true;
182 done_channels[idx] =
false;
185 int step =
abs_clamp((read_outputs[idx] + 1.0f) * -800.0f, 1, 70);
187 if (*time_factor_gain + step > 0xff || *time_factor_gain + step < 0) {
188 *time_factor_gain = std::clamp(
static_cast<int>(*time_factor_gain) + step, 0, 0xff);
189 done_channels[idx] =
true;
190 return UnitResult::err(
"Time factor / gain out of bounds");
192 *time_factor_gain += step;
195 if (!
hardware->write_time_factor_gain(idx, *time_factor_gain)) {
196 done_channels[idx] =
true;
197 return UnitResult::err(
"Writing of time factor gain failed");
204 if (loop_count > max_loops)
205 return UnitResult::err(
"Calibration timed out!");
208 return UnitResult::ok();
215 if (TRY(MIntBlock::config(
config)))
216 return ConfigResult::ok(
true);
218 if (
config.which_kind == pb_Item_limiter_config_tag) {
219 auto& limiter_config =
config.kind.limiter_config;
220 for (
size_t idx = 0; idx < limiter_config.elements_count; idx++) {
221 auto& elem = limiter_config.elements[idx];
225 return ConfigResult::ok(
true);
228 return ConfigResult::ok(
false);
232 MIntBlock::extract(collector);
234 if (!collector.include_configuration())
return;
236 auto& item = collector.create(pb_Item_limiter_config_tag);
237 auto& limiter_config = item.kind.limiter_config;
239 limiter_config.elements_count = NUM_INTEGRATORS;
240 for (
auto idx = 0; idx < NUM_INTEGRATORS; ++idx) {
241 auto& element = limiter_config.elements[idx];
252 f_ic_dac(
bus::replace_function_idx(block_address, 4), 14, 2.0f),
260 TRY(MIntBlockHAL::init());
262 return UnitResult::err(
"Failed to initialize IC dac");
263 if (!
f_ic_dac.set_external_reference(
true))
264 return UnitResult::err(
"Failed to set external reference");
265 if (!
f_ic_dac.set_double_gain(
true))
266 return UnitResult::err(
"Failed to set double gain");
267 return UnitResult::ok();
271 if (idx >= MIntBlock::NUM_INTEGRATORS)
274 return f_ic_dac.set_channel(idx, ic + 1.0f);
278 if (!
f_time_factor.transfer8(
static_cast<uint8_t
>(switches.to_ulong())))
297 std::bitset<8> limiters) {
300 if (!
f_time_factor.transfer16(
static_cast<uint16_t
>(limiters.to_ulong()) << 8 |
301 static_cast<uint8_t
>(switches.to_ulong())))
308 if (idx >= MIntBlock::NUM_INTEGRATORS)
311 return f_ic_dac.set_channel(idx, 1.0f - ic);
315 if (idx >= MIntBlock::NUM_INTEGRATORS)
MIntBlockHAL_V_1_0_X(bus::addr_t block_address)
const functions::TriggerFunction f_overload_flags_reset
std::bitset< 8 > read_overload_flags() override
UnitResult init() override
const functions::SR74HCT595 f_time_factor
const functions::DAC60508 f_ic_dac
const functions::SR74HC16X f_overload_flags
void reset_overload_flags() override
const functions::TriggerFunction f_time_factor_sync
bool write_time_factor_switches(std::bitset< 8 > switches) override
const functions::TriggerFunction f_time_factor_reset
bool write_ic(uint8_t idx, float ic) override
virtual bool write_time_factor_gain(uint8_t idx, uint8_t gain)
virtual bool write_time_factor_switches_and_limiters_enable(std::bitset< 8 > switches, std::bitset< 8 > limiters)
functions::AD8403 f_time_factor_gain_4_7
functions::AD8403 f_time_factor_gain_0_3
MIntBlockHAL_V_1_1_X(bus::addr_t block_address)
bool write_ic(uint8_t idx, float ic) override
void reset(entities::ResetAction action) override
bool write_to_hardware() override
std::array< IntegratorCalibration, NUM_INTEGRATORS > calibration
ConfigResult config(const pb_Item &item) override
UnitResult write_calibration_to_hardware()
MIntBlockHAL_V_1_1_X * hardware
MIntBlock_V_1_1_X(SLOT slot, MIntBlockHAL_V_1_1_X *hardware)
const std::array< IntegratorCalibration, NUM_INTEGRATORS > & get_calibration() const
UnitResult calibrate(platform::Cluster *cluster, carrier::Carrier *carrier) override
std::bitset< NUM_INTEGRATORS > _limiters_enabled
void extract(entities::ExtractVisitor &collector) override
UnitResult _gain_calibration(bool use_slow_integration)
static void force_start()
static bool init(unsigned long long ic_time_ns, unsigned long long op_time_ns, mode::OnOverload on_overload=mode::OnOverload::HALT, mode::OnExtHalt on_ext_halt=mode::OnExtHalt::IGNORE, SyncConfig sync_config={})
int abs_clamp(float in, int min, int max)
int abs_clamp(float in, int min, int max)
entities::EntitySharedHardware< MIntBlockHAL > MIntBlockHAL_Parent