8#include <entity/visitor.h>
9#include <lucidac/lucidac.h>
12platform::LUCIDAC::LUCIDAC(LUCIDAC_HAL *hardware)
13 : Carrier({Cluster(0)}, hardware), hardware(hardware) {}
15UnitResult platform::LUCIDAC::init() {
16 LOG(ANABRID_DEBUG_INIT, __PRETTY_FUNCTION__);
19 LOG(ANABRID_DEBUG_INIT,
"Detecting front panel...");
21 front_panel = entities::detect<LUCIDACFrontPanel>(bus::address_from_tuple(bus::FRONTPLANE_BADDR, 0));
23 LOG_ALWAYS(
"Warning: Front panel is missing or unknown.");
25 LOG(ANABRID_DEBUG_INIT,
"Initialising detected front panel...");
26 auto front_panel_result = front_panel->init();
27 if (front_panel_result.is_err()) {
28 LOG_ALWAYS(
"Error: Could not initialize front panel");
29 return front_panel_result;
31 LOG(ANABRID_DEBUG_INIT,
"Front panel initialized.");
36 return UnitResult::ok();
39void platform::LUCIDAC::reset(entities::ResetAction action) {
40 Carrier::reset(action);
42 front_panel->reset(action);
44 if (action.has(entities::ResetAction::CIRCUIT_RESET)) {
50UnitResult platform::LUCIDAC::route_in_external(uint8_t in, uint8_t i_out) {
52 return UnitResult::err(
"in must be less or equal to 7");
54 TRY(clusters[0].iblock->connect(in + 24, i_out));
55 return UnitResult::ok();
58UnitResult platform::LUCIDAC::route_out_external(uint8_t u_in, uint8_t out,
float c_factor) {
60 return UnitResult::err_fmt(
"out must be less or equal to 7 but is %d", out);
62 TRY(clusters[0].ublock->connect(u_in, out + 24));
63 TRY(clusters[0].cblock->set_factor(out + 24, c_factor));
64 return UnitResult::ok();
67std::vector<entities::Entity *> platform::LUCIDAC::get_child_entities() {
68 auto entities = this->Carrier::get_child_entities();
74entities::Entity *platform::LUCIDAC::get_child_entity(std::string_view child_id) {
77 return this->carrier::Carrier::get_child_entity(child_id);
80UnitResult platform::LUCIDAC::write_to_hardware() {
81 TRY(Carrier::write_to_hardware());
83 auto result = front_panel->write_to_hardware();
85 return UnitResult::err(result.err_value() +
"Front Panel write failed.");
87 if (!hardware->write_acl(acl_select))
88 UnitResult::err(
"Write ACL failed");
89 return UnitResult::ok();
92const std::array<platform::LUCIDAC::ACL, 8> &platform::LUCIDAC::get_acl_select()
const {
96void platform::LUCIDAC::set_acl_select(
const std::array<ACL, 8> &acl_select_) {
97 acl_select = acl_select_;
100bool platform::LUCIDAC::set_acl_select(uint8_t idx, LUCIDAC::ACL acl) {
101 if (idx >= acl_select.size())
103 acl_select[idx] = acl;
107void platform::LUCIDAC::reset_acl_select() {
108 std::fill(acl_select.begin(), acl_select.end(), ACL::INTERNAL_);
113UnitResult platform::LUCIDAC::calibrate_routes() {
114 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
118 auto& cluster = clusters[0];
119 std::array<std::vector<uint8_t>, blocks::IBlock::NUM_OUTPUTS> old_i_block_connections;
120 for (
auto i_out_idx : blocks::IBlock::OUTPUT_IDX_RANGE())
121 for (
auto i_in_idx : blocks::IBlock::INPUT_IDX_RANGE())
122 if (cluster.iblock->is_connected(i_in_idx, i_out_idx))
123 old_i_block_connections[i_out_idx].emplace_back(i_in_idx);
126 auto old_acl_selection = get_acl_select();
128 if (!hardware->write_acl(acl_select))
129 return UnitResult::err(
"Writing ACL before calibrate_routes() failed");
131 TRY(Carrier::calibrate_routes());
133 set_acl_select(old_acl_selection);
134 if (!hardware->write_acl(acl_select))
135 return UnitResult::err(
"Writing ACL after calibrate_routes() failed");
138 for (
auto i_out_idx : blocks::IBlock::OUTPUT_IDX_RANGE())
139 for (
auto i_in_idx : old_i_block_connections[i_out_idx])
140 TRY (cluster.iblock->connect(i_in_idx, i_out_idx));
142 TRY(cluster.iblock->write_to_hardware());
144 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
146 return UnitResult::ok();
149ConfigResult platform::LUCIDAC::config(
const pb_Item &item) {
150 if (item.which_kind == pb_Item_port_config_tag) {
151 auto& port_config = item.kind.port_config;
154 for (
size_t idx = 0; idx < port_config.states_count ; ++idx) {
155 acl_select[idx] = (port_config.states[idx] == pb_PortConfig_AclState_EXTERNAL) ?
156 ACL::EXTERNAL_ : ACL::INTERNAL_;
159 if (!hardware->write_acl(acl_select))
160 return ConfigResult::err(
"cannot write acl select to hardware");
162 return ConfigResult::ok(
true);
165 return Carrier::config(item);
168void platform::LUCIDAC::extract(entities::ExtractVisitor &collector) {
169 Carrier::extract(collector);
171 if (!collector.include_configuration())
return;
172 auto& item = collector.create(pb_Item_port_config_tag);
173 auto& lucidac_config = item.kind.port_config;
175 lucidac_config.states_count = acl_select.size();
176 for (
size_t idx = 0; idx < acl_select.size(); idx++) {
177 lucidac_config.states[idx] =
178 (acl_select[idx] == ACL::EXTERNAL_)
179 ? pb_PortConfig_AclState_EXTERNAL
180 : pb_PortConfig_AclState_INTERNAL;
184UnitResult platform::LUCIDAC::calibrate_offsets() {
185 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
187 auto old_acl_selection = get_acl_select();
189 if (!hardware->write_acl(acl_select))
190 UnitResult::err(
"Writing ACL before calibrate_offsets() failed");
192 TRY(Carrier::calibrate_offsets());
194 set_acl_select(old_acl_selection);
195 if (!hardware->write_acl(acl_select))
196 UnitResult::err(
"Writing ACL after calibrate_offsets() failed");
198 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
200 return UnitResult::ok();
203UnitResult platform::LUCIDAC::calibrate(
const pb_CalibrationConfig &item) {
204 TRY(Carrier::calibrate(item));
206 if (item.gain != pb_CalibrationConfig_Kind_Disabled)
207 TRY(calibrate_routes());
209 return UnitResult::ok();