8#include <entity/visitor.h>
9#include <lucidac/lucidac.h>
12platform::LUCIDAC::LUCIDAC(LUCIDAC_HAL *hardware)
13 : Carrier({Cluster(0)}, hardware), hardware(hardware) {}
15bool platform::LUCIDAC::init() {
16 LOG(ANABRID_DEBUG_INIT, __PRETTY_FUNCTION__);
20 LOG(ANABRID_DEBUG_INIT,
"Detecting front panel...");
22 front_panel = entities::detect<LUCIDACFrontPanel>(bus::address_from_tuple(bus::FRONTPLANE_BADDR, 0));
24 LOG_ALWAYS(
"Warning: Front panel is missing or unknown.");
26 LOG(ANABRID_DEBUG_INIT,
"Initialising detected front panel...");
27 if (!front_panel->init()) {
28 LOG_ALWAYS(
"Error: Could not initialize front panel");
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);
80bool platform::LUCIDAC::write_to_hardware() {
81 if(!Carrier::write_to_hardware())
84 auto result = front_panel->write_to_hardware();
88 if (!hardware->write_acl(acl_select))
89 UnitResult::err(
"Write ACL failed");
93const std::array<platform::LUCIDAC::ACL, 8> &platform::LUCIDAC::get_acl_select()
const {
97void platform::LUCIDAC::set_acl_select(
const std::array<ACL, 8> &acl_select_) {
98 acl_select = acl_select_;
101bool platform::LUCIDAC::set_acl_select(uint8_t idx, LUCIDAC::ACL acl) {
102 if (idx >= acl_select.size())
104 acl_select[idx] = acl;
108void platform::LUCIDAC::reset_acl_select() {
109 std::fill(acl_select.begin(), acl_select.end(), ACL::INTERNAL_);
114UnitResult platform::LUCIDAC::calibrate_routes() {
115 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
119 auto& cluster = clusters[0];
120 auto old_i_block_outputs = cluster.iblock->get_outputs();
123 auto old_acl_selection = get_acl_select();
125 if (!hardware->write_acl(acl_select))
126 return UnitResult::err(
"Writing ACL before calibrate_routes() failed");
128 TRY(Carrier::calibrate_routes());
130 set_acl_select(old_acl_selection);
131 if (!hardware->write_acl(acl_select))
132 return UnitResult::err(
"Writing ACL after calibrate_routes() failed");
135 cluster.iblock->set_outputs(old_i_block_outputs);
136 TRY_TRUE(cluster.iblock->write_to_hardware());
138 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
139 return UnitResult::ok();
142ConfigResult platform::LUCIDAC::config(
const pb_Item &item) {
143 if (item.which_kind == pb_Item_port_config_tag) {
144 auto& port_config = item.kind.port_config;
147 for (
size_t idx = 0; idx < port_config.states_count ; ++idx) {
148 acl_select[idx] = (port_config.states[idx] == pb_PortConfig_AclState_EXTERNAL) ?
149 ACL::EXTERNAL_ : ACL::INTERNAL_;
152 if (!hardware->write_acl(acl_select))
153 return ConfigResult::err(
"cannot write acl select to hardware");
155 return ConfigResult::ok(
true);
158 return Carrier::config(item);
161void platform::LUCIDAC::extract(entities::ExtractVisitor &collector) {
162 Carrier::extract(collector);
164 if (!collector.include_configuration())
return;
165 auto& item = collector.create(pb_Item_port_config_tag);
166 auto& lucidac_config = item.kind.port_config;
168 lucidac_config.states_count = acl_select.size();
169 for (
size_t idx = 0; idx < acl_select.size(); idx++) {
170 lucidac_config.states[idx] =
171 (acl_select[idx] == ACL::EXTERNAL_)
172 ? pb_PortConfig_AclState_EXTERNAL
173 : pb_PortConfig_AclState_INTERNAL;
177UnitResult platform::LUCIDAC::calibrate_offsets() {
178 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
180 auto old_acl_selection = get_acl_select();
182 if (!hardware->write_acl(acl_select))
183 UnitResult::err(
"Writing ACL before calibrate_offsets() failed");
185 TRY(Carrier::calibrate_offsets());
187 set_acl_select(old_acl_selection);
188 if (!hardware->write_acl(acl_select))
189 UnitResult::err(
"Writing ACL after calibrate_offsets() failed");
191 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
193 return UnitResult::ok();
196UnitResult platform::LUCIDAC::calibrate(
const pb_CalibrationConfig &item) {
197 TRY(Carrier::calibrate(item));
199 if (item.gain != pb_CalibrationConfig_Kind_Disabled)
200 TRY(calibrate_routes());
202 return UnitResult::ok();