1#include <entity/visitor.h>
2#include <proto/main.pb.h>
4#include <redac/tblock.h>
8TBlock::TBlock(TBlockHAL *hardware) : FunctionBlock(
"T", hardware), hardware(hardware) { classifier.class_enum = CLASS_; }
10ConfigResult TBlock::config(
const pb_Item &item) {
11 if (item.which_kind == pb_Item_switch_config_tag) {
12 auto &switch_config = item.kind.switch_config;
13 return apply_muxes(switch_config.muxes, switch_config.muxes_count);
17 return ConfigResult::ok(
false);
20ConfigResult TBlock::apply_muxes(
const pb_Mux *muxes,
size_t count) {
21 for (
size_t idx = 0; idx < count; ++idx) {
22 auto &mux = muxes[idx];
23 auto mux_value = mux.state;
25 return ConfigResult::err(
"TBlock: Mux must be interval [0, 3]");
26 connections[mux.index] = mux_value;
29 return ConfigResult::ok(
true);
32std::array<uint8_t, TBlockHAL::NUM_SWITCHES> TBlock::get_connections()
const {
return connections; }
34void TBlock::set_connections(
const std::array<uint8_t, TBlockHAL::NUM_SWITCHES> &connections) { this->connections = connections; }
36void TBlock::extract(entities::ExtractVisitor &collector) {
38 if (!collector.include_configuration())
return;
39 auto &item = collector.create(pb_Item_switch_config_tag);
40 auto &switch_config = item.kind.switch_config = pb_SwitchConfig_init_default;
42 auto &idx = switch_config.muxes_count = 0;
43 for (; idx < connections.size(); ++idx) {
44 switch_config.muxes[idx] = {
45 .state = connections[idx],
51inline uint32_t
mux_idx(TBlock::Sector dst_sector, uint8_t lane_idx) {
52 return lane_idx * 4 + dst_sector;
55UnitResult TBlock::connect(Sector src_sector, Sector dst_sector, uint8_t lane_idx) {
57 return UnitResult::err(
"Invalid lane. Remember that TBlock lanes are allways counted from 0 to 23");
59 connections[
mux_idx(dst_sector, lane_idx)] = src_sector;
60 return UnitResult::ok();
63TBlock::Sector TBlock::src_of_signal(Sector dst_sector, uint8_t lane_idx)
const {
67 return static_cast<Sector
>(connections[
mux_idx(dst_sector, lane_idx)]);
70void TBlock::reset(entities::ResetAction action) {
71 Entity::reset(action);
72 if (action.has(entities::ResetAction::CIRCUIT_RESET)) {
75 if (action.has(entities::ResetAction::EVERYTHING))
79void TBlock::reset_connections() {
82 connections = {Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
83 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2,
84 Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
85 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2,
86 Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
87 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2,
88 Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
89 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2,
90 Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
91 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2};
94bool TBlock::write_to_hardware() {
95 TRY_TRUE(Entity::write_to_hardware());
96 if (!hardware->write_muxes(connections))
97 return UnitResult::err(
"Error writing mux settings to hardware.");
99 hardware->reset_mux_disable();
101 hardware->set_mux_disable();
102 return UnitResult::ok();
105bool TBlock::is_enabled()
const {
return enabled; }
107void TBlock::set_enabled(
bool enabled_) { enabled = enabled_; }
109TBlockBackplane::TBlockBackplane(TBlockBackplaneHAL *hardware) : FunctionBlock(
"T_BPL", hardware), hardware(hardware) {
110 classifier.class_enum = CLASS_;
113UnitResult TBlockBackplane::connect(Sector src_sector, Sector dst_sector, uint8_t lane_idx) {
115 return UnitResult::err(
"lane_idx is invalid! Maximum is 7!");
117 if (src_sector == dst_sector)
118 return UnitResult::err(
"src_sector is equal to dst_sector! This connection is impossible!");
121 uint8_t switch_setting = src_sector;
122 if (src_sector == Sector::EXT0)
123 switch_setting = dst_sector;
125 connections[dst_sector + lane_idx * 9] = switch_setting;
127 return UnitResult::ok();
130TBlockBackplane::Sector TBlockBackplane::src_of_signal(Sector dst_sector, uint8_t lane_idx)
const {
134 uint8_t switch_setting = connections[dst_sector + lane_idx * 9];
135 if (switch_setting == dst_sector)
138 return static_cast<Sector
>(switch_setting);
141void TBlockBackplane::reset(entities::ResetAction action) {
142 Entity::reset(action);
143 if (action.has(entities::ResetAction::CIRCUIT_RESET)) {
146 if (action.has(entities::ResetAction::EVERYTHING))
150void TBlockBackplane::reset_connections() {
157bool TBlockBackplane::write_to_hardware() {
158 TRY_TRUE(Entity::write_to_hardware());
159 if (!hardware->write_muxes(connections))
160 return UnitResult::err(
"Error writing mux settings to hardware.");
162 hardware->reset_mux_disable();
164 hardware->set_mux_disable();
165 return UnitResult::ok();
168std::array<uint8_t, TBlockBackplaneHAL::NUM_SWITCHES> TBlockBackplane::get_connections()
const {
return connections; }
170void TBlockBackplane::set_connections(
const std::array<uint8_t, TBlockBackplaneHAL::NUM_SWITCHES> &connections_) { connections = connections_; }
172bool TBlockBackplane::is_enabled()
const {
return enabled; }
174void TBlockBackplane::set_enabled(
bool enabled_) { enabled = enabled_; }
176ConfigResult TBlockBackplane::config(
const pb_Item &item) {
177 if (item.which_kind == pb_Item_bpl_switch_config_tag) {
178 auto &switch_config = item.kind.bpl_switch_config;
179 return apply_muxes(switch_config.muxes, switch_config.muxes_count);
182 return ConfigResult::ok(
false);
185ConfigResult TBlockBackplane::apply_muxes(
const pb_Mux *muxes,
size_t count) {
186 for (
size_t idx = 0; idx < count; idx++) {
187 auto& mux_value = muxes[idx];
188 if (mux_value.state > 7)
189 return ConfigResult::err_fmt(
"TBlockBackplane::apply_muxes: mux value is invalid, must be between [0, 7] but is %d!", mux_value.state);
190 connections[mux_value.index] = mux_value.state;
193 return ConfigResult::ok(
true);
196void TBlockBackplane::extract(entities::ExtractVisitor &collector) {
197 if (!collector.include_configuration())
return;
198 auto &item = collector.create(pb_Item_bpl_switch_config_tag);
199 auto &switch_config = item.kind.bpl_switch_config = pb_BPLSwitchConfig_init_default;
201 auto &idx = switch_config.muxes_count = 0;
202 for (; idx < connections.size(); ++idx) {
203 switch_config.muxes[idx] = {
204 .state = connections[idx],
uint32_t mux_idx(TBlock::Sector dst_sector, uint8_t lane_idx)