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;
38status blocks::MMDRBlock::calibrate(platform::Cluster *cluster, carrier::Carrier *
carrier) {
40 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
52 cluster->reset(entities::ResetAction::CIRCUIT_RESET);
55 reset(entities::ResetAction::CALIBRATION_RESET);
58 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating output offsets...");
59 for (
auto idx : SLOT_INPUT_IDX_RANGE())
60 success.attach(cluster->add_constant(UBlock::Transmission_Mode::GROUND, slot_to_global_io_index(idx), 0.0f,
61 slot_to_global_io_index(idx)));
62 success.attach(cluster->write_to_hardware());
68 auto read_outputs = daq::average(daq::sample, 4, 10);
70 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
72 if (!hardware->write_calibration_output_offset(idx, calibration[idx].offset_z))
73 success.attach(
"Writing output offsets failed");
78 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating x input offsets...");
79 cluster->ublock->change_b_side_transmission_mode(UBlock::Transmission_Mode::POS_REF);
80 for (
auto idx = 0u; idx < NUM_CELLS; idx++)
81 (
void)cluster->cblock->set_factor(slot_to_global_io_index(idx * 2), 1.0f);
83 if (!cluster->cblock->write_to_hardware())
84 success.attach(
"Writing to c-block failed");
86 success.attach(cluster->calibrate_offsets());
90 const float target_precision = 0.0005f;
91 const int max_loops = 100;
93 std::bitset<NUM_CELLS> done_channels;
97 while (!done_channels.all()) {
98 read_outputs = daq::average(daq::sample, 4, 10);
100 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
101 if (fabs(read_outputs[idx]) < target_precision) {
102 done_channels[idx] =
true;
105 done_channels[idx] =
false;
108 calibration[idx].offset_x +=
abs_clamp(read_outputs[idx] * 6000.0f, 1, 50);
110 if (!hardware->write_calibration_input_offsets(idx, calibration[idx].offset_x,
111 calibration[idx].offset_y)) {
114 success.attach(
"Input X offsets out of range");
115 done_channels[idx] =
true;
122 if (loop_count > max_loops) {
123 success.attach(
"Calibration timed out!");
128 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating y input offsets...");
129 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
132 (void)cluster->cblock->set_factor(slot_to_global_io_index(idx * 2), 0.0f);
133 (void)cluster->cblock->set_factor(slot_to_global_io_index(idx * 2 + 1), 1.0f);
135 if (!cluster->cblock->write_to_hardware())
136 success.attach(
"Writing to c-block failed");
138 success.attach(cluster->calibrate_offsets());
142 read_outputs = daq::average(daq::sample, 4, 10);
144 done_channels.reset();
148 while (!done_channels.all()) {
149 read_outputs = daq::average(daq::sample, 4, 10);
151 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
152 if (fabs(read_outputs[idx]) < target_precision) {
153 done_channels[idx] =
true;
156 done_channels[idx] =
false;
159 calibration[idx].offset_y +=
abs_clamp(read_outputs[idx] * 6000.0f, 1, 50);
161 if (!hardware->write_calibration_input_offsets(idx, calibration[idx].offset_x,
162 calibration[idx].offset_y)) {
165 success.attach(
"Input Y offsets out of range");
166 done_channels[idx] =
true;
173 if (loop_count > max_loops) {
174 success.attach(
"Calibration timed out!");
179 LOG(ANABRID_DEBUG_CALIBRATION,
"Calibrating output gains...");
182 for (
auto idx = 0u; idx < NUM_CELLS; idx++)
183 (
void)cluster->cblock->set_factor(slot_to_global_io_index(idx * 2), 1.0f);
185 if (!cluster->cblock->write_to_hardware())
186 success.attach(
"Writing to c-block failed");
188 success.attach(cluster->calibrate_offsets());
193 done_channels.reset();
196 while (!done_channels.all()) {
197 read_outputs = daq::average(daq::sample, 4, 10);
199 for (
auto idx = 0u; idx < NUM_CELLS; idx++) {
200 if (fabs(read_outputs[idx] - 1.0f) < target_precision) {
201 done_channels[idx] =
true;
204 done_channels[idx] =
false;
207 int step =
abs_clamp((read_outputs[idx] - 1.0f) * -1000.0f, 1, 70);
209 if (calibration[idx].gain + step > 0xff || calibration[idx].gain + step < 0) {
210 success.attach(
"Output gain out of range");
211 done_channels[idx] =
true;
215 calibration[idx].gain += step;
217 if (!hardware->write_calibration_gain(idx, calibration[idx].gain)) {
218 success.attach(
"Writing output gain failed");
219 done_channels[idx] =
true;
226 if (loop_count > max_loops) {
227 success.attach(
"Calibration timed out!");
235bool blocks::MMDRBlockHAL::init() {
return MBlockHAL::init(); }
243 f_gain(
bus::replace_function_idx(block_address, 6), 0xff),
252 MMDRBlock::CellMode m3) {
257 uint16_t data = (
static_cast<uint16_t
>(m0) << 12) | (
static_cast<uint16_t
>(m1) << 8) |
258 (
static_cast<uint16_t
>(m2) << 4) | (
static_cast<uint16_t
>(m3) << 0);
278 return f_gain.write_channel_raw(2, gain);
280 return f_gain.write_channel_raw(0, gain);
282 return f_gain.write_channel_raw(1, gain);
284 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)
static constexpr int success
entities::EntitySharedHardware< MMDRBlockHAL > MMDRBlockHAL_Parent