REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
mblock_mul.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
5#include <algorithm>
6#include <bitset>
7
8#include "carrier/carrier.h"
9#include "carrier/cluster.h"
10
11#include "block/mblock.h"
12#include "teensy/mblock_mul.h"
13
14#include "block/mul_calibration.h"
15
16extern int abs_clamp(float in, int min, int max);
17
18blocks::MMulBlock *blocks::MMulBlock::from_entity_classifier(entities::EntityClassifier classifier,
19 const bus::addr_t block_address) {
20 if (!classifier or classifier.class_enum != CLASS_ or classifier.type != static_cast<uint8_t>(TYPE))
21 return nullptr;
22
23 // Currently, there are no different variants
24 if (classifier.variant != entities::EntityClassifier::DEFAULT_)
25 return nullptr;
26
27 SLOT slot = block_address % 8 == 4 ? SLOT::M0 : SLOT::M1;
28 // Return default implementation
29 if (classifier.version < entities::Version(1))
30 return nullptr;
31 if (classifier.version < entities::Version(1, 1)) {
32 auto *new_block = new MMulBlock(slot, new MMulBlockHAL_V_1_0_X(block_address));
33 new_block->classifier = classifier;
34 return new_block;
35 }
36 if (classifier.version <= entities::Version(1, 2)) {
37 auto *new_block = new MMulBlock_FullAutoCalibration(slot, new MMulBlockHAL_V_1_1_X(block_address));
38 new_block->classifier = classifier;
39 return new_block;
40 }
41 if (classifier.version == entities::Version(1, -1)) {
42 auto *new_block = new MMulBlock_FullAutoCalibration(slot, new MMulBlockHAL_V_1_M1_X(block_address));
43 new_block->classifier = classifier;
44 return new_block;
45 }
46 return nullptr;
47}
48
49UnitResult blocks::MMulBlock::calibrate(platform::Cluster *cluster, carrier::Carrier *carrier) {
50 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
51 TRY(calibrate_mul(carrier, cluster, this, calibration));
52 return UnitResult::ok();
53}
54
55// V1.-1.0
59
61 TRY(MMulBlock::write_calibration_to_hardware());
62
63 for (size_t i = 0; i < MMulBlock::NUM_MULTIPLIERS; i++) {
64 if (!hardware->write_calibration_gain(i, calibration[i].gain))
65 return UnitResult::err_fmt("MMulBlock::calibration from json for multiplier %d values gain not accepted", i);
66 }
67 return UnitResult::ok();
68}
69
70// Hardware abstraction layer
72 : MMulBlockHAL_Parent(block_address, 7), f_overload_flags_reset(bus::address_from_tuple(block_address, 3)),
73 f_overload_flags(bus::replace_function_idx(block_address, 2), 7),
74 f_calibration_dac_0(bus::address_from_tuple(block_address, 4), 7, 2.0f),
75 f_calibration_dac_1(bus::address_from_tuple(block_address, 5), 7, 2.0f) {}
76
77UnitResult blocks::MMulBlockHAL::init() { return MBlockHAL::init(); }
78
80 bool error = true;
81 error &= f_calibration_dac_0.init();
82 error &= f_calibration_dac_0.set_external_reference();
83 error &= f_calibration_dac_0.set_double_gain();
84 error &= f_calibration_dac_1.init();
85 error &= f_calibration_dac_1.set_external_reference();
86 error &= f_calibration_dac_1.set_double_gain();
87 error &= MMulBlockHAL::init();
88 if (!error)
89 return UnitResult::err("Failed mmul-blck writing hardware");
90 return UnitResult::ok();
91}
92
94
96 uint16_t offset_y) {
97 return f_calibration_dac_0.set_channel_raw(idx * 2, offset_x) and
98 f_calibration_dac_0.set_channel_raw(idx * 2 + 1, offset_y);
99}
100
102 return f_calibration_dac_1.set_channel_raw(idx, offset_z);
103}
104
106 return f_overload_flags.read8();
107}
108
110 : MMulBlockHAL_V_1_0_X(block_address), f_gain_ch0_1(bus::replace_function_idx(block_address, 6), 7),
111 f_gain_ch2_3(bus::replace_function_idx(block_address, 7), 7) {}
112
114 if (idx < 2)
115 return f_gain_ch0_1.write_channel_raw(idx, gain);
116 else if (idx < 4)
117 return f_gain_ch2_3.write_channel_raw(idx - 2, gain);
118 else
119 return false;
120}
121
123 : MMulBlockHAL_V_1_0_X(block_address), f_gain(bus::replace_function_idx(block_address, 6), 7) {}
124
126 if (idx == 0)
127 return f_gain.write_channel_raw(2, gain);
128 else if (idx == 1)
129 return f_gain.write_channel_raw(0, gain);
130 else if (idx == 2)
131 return f_gain.write_channel_raw(1, gain);
132 if (idx == 3)
133 return f_gain.write_channel_raw(3, gain);
134 return false;
135}
bool write_calibration_output_offset(uint8_t idx, uint16_t offset_z) override
const functions::TriggerFunction f_overload_flags_reset
Definition mblock_mul.h:26
std::bitset< 8 > read_overload_flags() override
UnitResult init() override
void reset_overload_flags() override
const functions::SR74HC16X f_overload_flags
Definition mblock_mul.h:27
MMulBlockHAL_V_1_0_X(bus::addr_t block_address)
const functions::DAC60508 f_calibration_dac_0
Definition mblock_mul.h:28
bool write_calibration_input_offsets(uint8_t idx, uint16_t offset_x, uint16_t offset_y) override
const functions::DAC60508 f_calibration_dac_1
Definition mblock_mul.h:29
MMulBlockHAL_V_1_1_X(bus::addr_t block_address)
bool write_calibration_gain(uint8_t idx, uint8_t gain) override
functions::AD8403 f_gain
Definition mblock_mul.h:89
functions::AD8402 f_gain_ch0_1
Definition mblock_mul.h:64
functions::AD8402 f_gain_ch2_3
Definition mblock_mul.h:65
MMulBlockHAL_V_1_M1_X(bus::addr_t block_address)
bool write_calibration_gain(uint8_t idx, uint8_t gain) override
MMulBlock_FullAutoCalibration(SLOT slot, blocks::MMulBlockHAL_FullAutoCalibration *hardware)
UnitResult write_calibration_to_hardware() override
MMulBlockHAL_FullAutoCalibration * hardware
Definition mblock_mul.h:118
int abs_clamp(float in, int min, int max)
Definition mblock.cpp:20
entities::EntitySharedHardware< MMulBlockHAL > MMulBlockHAL_Parent
Definition mblock_mul.h:17
Definition bus.h:21
Definition daq.h:14