7#include "carrier/carrier.h"
8#include "carrier/cluster.h"
10#include "block/mblock_mdr.h"
15extern int abs_clamp(
float in,
int min,
int max);
17blocks::MMDRBlock *blocks::MMDRBlock::from_entity_classifier(entities::EntityClassifier classifier,
18 const bus::addr_t block_address) {
19 if (!classifier or classifier.class_enum != CLASS_ or classifier.type !=
static_cast<uint8_t
>(TYPE))
23 if (classifier.variant != entities::EntityClassifier::DEFAULT_)
26 SLOT slot = block_address % 8 == 4 ? SLOT::M0 : SLOT::M1;
28 if (classifier.version < entities::Version(1))
30 if (classifier.version < entities::Version(1, 1)) {
32 new_block->classifier = classifier;
38UnitResult blocks::MMDRBlock::calibrate(platform::Cluster *cluster, carrier::Carrier *
carrier) {
39 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
48 TRY(MBlock::calibrate(cluster,
carrier));
51 cluster->reset(entities::ResetAction::CIRCUIT_RESET);
54 reset(entities::ResetAction::CALIBRATION_RESET);
57 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating output offsets...");
58 for (
auto idx : SLOT_INPUT_IDX_RANGE())
59 TRY(cluster->add_constant(UBlock::Transmission_Mode::GROUND, slot_to_global_io_index(idx), 0.0f,
60 slot_to_global_io_index(idx)));
61 TRY(cluster->write_to_hardware());
64 TRY(
carrier->calibrate_routes());
67 auto read_outputs = daq::average(daq::sample, 4, 10);
69 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
71 if (!hardware->write_calibration_output_offset(idx, calibration[idx].offset_z))
72 return UnitResult::err(
"Writing output offsets failed");
77 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating x input offsets...");
78 cluster->ublock->change_b_side_transmission_mode(UBlock::Transmission_Mode::POS_REF);
79 for (
auto idx = 0u; idx < NUM_CELLS; idx++)
80 TRY(cluster->cblock->set_factor(slot_to_global_io_index(idx * 2), 1.0f));
82 TRY(cluster->cblock->write_to_hardware());
84 TRY(cluster->calibrate_offsets());
88 const float target_precision = 0.0005f;
89 const int max_loops = 100;
91 std::bitset<NUM_CELLS> done_channels;
95 while (!done_channels.all()) {
96 read_outputs = daq::average(daq::sample, 4, 10);
98 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
99 if (fabs(read_outputs[idx]) < target_precision) {
100 done_channels[idx] =
true;
103 done_channels[idx] =
false;
106 calibration[idx].offset_x +=
abs_clamp(read_outputs[idx] * 6000.0f, 1, 50);
108 if (!hardware->write_calibration_input_offsets(idx, calibration[idx].offset_x,
109 calibration[idx].offset_y)) {
112 return UnitResult::err(
"Input X offsets out of range");
118 if (loop_count > max_loops) {
119 return UnitResult::err(
"Calibration timed out!");
123 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating y input offsets...");
124 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
127 TRY(cluster->cblock->set_factor(slot_to_global_io_index(idx * 2), 0.0f));
128 TRY(cluster->cblock->set_factor(slot_to_global_io_index(idx * 2 + 1), 1.0f));
130 TRY(cluster->cblock->write_to_hardware());
132 TRY(cluster->calibrate_offsets());
136 read_outputs = daq::average(daq::sample, 4, 10);
138 done_channels.reset();
142 while (!done_channels.all()) {
143 read_outputs = daq::average(daq::sample, 4, 10);
145 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
146 if (fabs(read_outputs[idx]) < target_precision) {
147 done_channels[idx] =
true;
150 done_channels[idx] =
false;
153 calibration[idx].offset_y +=
abs_clamp(read_outputs[idx] * 6000.0f, 1, 50);
155 if (!hardware->write_calibration_input_offsets(idx, calibration[idx].offset_x,
156 calibration[idx].offset_y)) {
159 return UnitResult::err(
"Input Y offsets out of range");
160 done_channels[idx] =
true;
167 if (loop_count > max_loops) {
168 return UnitResult::err(
"Calibration timed out!");
172 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating output gains...");
175 for (
auto idx = 0u; idx < NUM_CELLS; idx++)
176 TRY(cluster->cblock->set_factor(slot_to_global_io_index(idx * 2), 1.0f));
178 TRY(cluster->cblock->write_to_hardware());
180 TRY(cluster->calibrate_offsets());
185 done_channels.reset();
188 while (!done_channels.all()) {
189 read_outputs = daq::average(daq::sample, 4, 10);
191 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
192 if (fabs(read_outputs[idx] - 1.0f) < target_precision) {
193 done_channels[idx] =
true;
196 done_channels[idx] =
false;
199 int step =
abs_clamp((read_outputs[idx] - 1.0f) * -1000.0f, 1, 70);
201 if (calibration[idx].gain + step > 0xff || calibration[idx].gain + step < 0) {
202 return UnitResult::err(
"Output gain out of range");
203 done_channels[idx] =
true;
207 calibration[idx].gain += step;
209 if (!hardware->write_calibration_gain(idx, calibration[idx].gain)) {
210 return UnitResult::err(
"Writing output gain failed");
211 done_channels[idx] =
true;
218 if (loop_count > max_loops) {
219 return UnitResult::err(
"Calibration timed out!");
223 return UnitResult::ok();
226UnitResult blocks::MMDRBlockHAL::init() {
return MBlockHAL::init(); }
234 f_gain(
bus::replace_function_idx(block_address, 6), 0xff),
243 MMDRBlock::CellMode m3) {
248 uint16_t data = (
static_cast<uint16_t
>(m0) << 12) | (
static_cast<uint16_t
>(m1) << 8) |
249 (
static_cast<uint16_t
>(m2) << 4) | (
static_cast<uint16_t
>(m3) << 0);
269 return f_gain.write_channel_raw(2, gain);
271 return f_gain.write_channel_raw(0, gain);
273 return f_gain.write_channel_raw(1, gain);
275 return f_gain.write_channel_raw(3, gain);
const functions::SR74HC16X f_overload_flags
bool write_calibration_gain(uint8_t idx, uint8_t gain) override
static uint16_t float_to_raw_calibration(float value)
Takes in voltage recieved by multiplier, returns DAC raw value.
std::bitset< 8 > read_overload_flags() override
static constexpr uint16_t RAW_MAX
const functions::SR74HCT595 f_mode_config
const functions::DAC60508 f_calibration_dac_1
void reset_overload_flags() override
const functions::DAC60508 f_calibration_dac_0
bool write_calibration_output_offset(uint8_t idx, uint16_t offset_z) override
static constexpr uint16_t RAW_ZERO
const functions::TriggerFunction f_mode_config_sync
const functions::TriggerFunction f_overload_flags_reset
bool write_calibration_input_offsets(uint8_t idx, uint16_t offset_x, uint16_t offset_y) override
bool write_modes(MMDRBlock::CellMode m0, MMDRBlock::CellMode m1, MMDRBlock::CellMode m2, MMDRBlock::CellMode m3) override
MMDRBlockHAL_V_1_0_X(bus::addr_t block_address)
int abs_clamp(float in, int min, int max)
entities::EntitySharedHardware< MMDRBlockHAL > MMDRBlockHAL_Parent