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);
17 return ConfigResult::ok(
false);
20ConfigResult TBlock::apply_muxes(
const pb_Mux (&muxes)[TBlockHAL::NUM_SWITCHES]) {
22 for (
auto &mux : muxes) {
29 auto mux_value = mux.state;
30 if (mux_value < 0 || 4 <= mux_value)
31 return ConfigResult::err(
"TBlock: Mux must be interval [0, 3]");
32 connections[idx] = mux_value;
35 return ConfigResult::ok(
true);
38std::array<uint8_t, TBlockHAL::NUM_SWITCHES> TBlock::get_connections()
const {
return connections; }
40void TBlock::set_connections(
const std::array<uint8_t, TBlockHAL::NUM_SWITCHES> &connections) { this->connections = connections; }
42void TBlock::extract(entities::ExtractVisitor &collector) {
44 if (!collector.include_configuration())
return;
45 auto &item = collector.create(pb_Item_switch_config_tag);
46 auto &switch_config = item.kind.switch_config = pb_SwitchConfig_init_default;
48 auto &idx = switch_config.muxes_count = 0;
49 for (; idx < connections.size(); ++idx) {
50 switch_config.muxes[idx] = {
52 .state = connections[idx],
58 return lane_idx * 4 + dst_sector;
61UnitResult TBlock::connect(Sector src_sector, Sector dst_sector, uint8_t lane_idx) {
63 return UnitResult::err(
"Invalid lane. Remember that TBlock lanes are allways counted from 0 to 23");
65 connections[
mux_idx(dst_sector, lane_idx)] = src_sector;
66 return UnitResult::ok();
69TBlock::Sector TBlock::src_of_signal(Sector dst_sector, uint8_t lane_idx)
const {
73 return static_cast<Sector
>(connections[
mux_idx(dst_sector, lane_idx)]);
76void TBlock::reset(entities::ResetAction action) {
77 Entity::reset(action);
78 if (action.has(entities::ResetAction::CIRCUIT_RESET)) {
81 if (action.has(entities::ResetAction::EVERYTHING))
85void TBlock::reset_connections() {
88 connections = {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, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2,
92 Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
93 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2,
94 Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
95 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2,
96 Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0,
97 Sector::CL1, Sector::CL2, Sector::BPL, Sector::CL0, Sector::CL1, Sector::CL2};
100UnitResult TBlock::write_to_hardware() {
101 TRY(Entity::write_to_hardware());
102 if (!hardware->write_muxes(connections))
103 return UnitResult::err(
"Error writing mux settings to hardware.");
105 hardware->reset_mux_disable();
107 hardware->set_mux_disable();
108 return UnitResult::ok();
111bool TBlock::is_enabled()
const {
return enabled; }
113void TBlock::set_enabled(
bool enabled_) { enabled = enabled_; }
115TBlockBackplane::TBlockBackplane(TBlockBackplaneHAL *hardware) : FunctionBlock(
"T_BPL", hardware), hardware(hardware) {
116 classifier.class_enum = CLASS_;
119UnitResult TBlockBackplane::connect(Sector src_sector, Sector dst_sector, uint8_t lane_idx) {
121 return UnitResult::err(
"lane_idx is invalid! Maximum is 7!");
123 if (src_sector == dst_sector)
124 return UnitResult::err(
"src_sector is equal to dst_sector! This connection is impossible!");
127 uint8_t switch_setting = src_sector;
128 if (src_sector == Sector::EXT0)
129 switch_setting = dst_sector;
131 connections[dst_sector + lane_idx * 9] = switch_setting;
133 return UnitResult::ok();
136TBlockBackplane::Sector TBlockBackplane::src_of_signal(Sector dst_sector, uint8_t lane_idx)
const {
140 uint8_t switch_setting = connections[dst_sector + lane_idx * 9];
141 if (switch_setting == dst_sector)
144 return static_cast<Sector
>(switch_setting);
147void TBlockBackplane::reset(entities::ResetAction action) {
148 Entity::reset(action);
149 if (action.has(entities::ResetAction::CIRCUIT_RESET)) {
152 if (action.has(entities::ResetAction::EVERYTHING))
156void TBlockBackplane::reset_connections() {
160 std::fill(connections.begin(), connections.end(), random() % 9);
163UnitResult TBlockBackplane::write_to_hardware() {
164 TRY(Entity::write_to_hardware());
165 if (!hardware->write_muxes(connections))
166 return UnitResult::err(
"Error writing mux settings to hardware.");
168 hardware->reset_mux_disable();
170 hardware->set_mux_disable();
171 return UnitResult::ok();
174std::array<uint8_t, TBlockBackplaneHAL::NUM_SWITCHES> TBlockBackplane::get_connections()
const {
return connections; }
176void TBlockBackplane::set_connections(
const std::array<uint8_t, TBlockBackplaneHAL::NUM_SWITCHES> &connections_) { connections = connections_; }
178bool TBlockBackplane::is_enabled()
const {
return enabled; }
180void TBlockBackplane::set_enabled(
bool enabled_) { enabled = enabled_; }
182ConfigResult TBlockBackplane::config(
const pb_Item &item) {
183 if (item.which_kind == pb_Item_bpl_switch_config_tag) {
184 auto &switch_config = item.kind.bpl_switch_config;
185 return apply_muxes(switch_config.muxes);
188 return ConfigResult::ok(
false);
191ConfigResult TBlockBackplane::apply_muxes(
const pb_Mux (&muxes)[TBlockBackplaneHAL::NUM_SWITCHES]) {
192 for (
size_t i = 0; i < TBlockBackplaneHAL::NUM_SWITCHES; i++) {
193 if (!muxes[i].has_state)
196 auto mux_value = muxes[i].state;
198 return ConfigResult::err(
"TBlockBackplane::apply_muxes: mux value is invalid, must be between [0, 7]!");
199 connections[i] = mux_value;
202 return ConfigResult::ok(
true);
205void TBlockBackplane::extract(entities::ExtractVisitor &collector) {
206 if (!collector.include_configuration())
return;
207 auto &item = collector.create(pb_Item_bpl_switch_config_tag);
208 auto &switch_config = item.kind.bpl_switch_config = pb_BPLSwitchConfig_init_default;
210 auto &idx = switch_config.muxes_count = 0;
211 for (; idx < connections.size(); ++idx) {
212 switch_config.muxes[idx] = {.has_state =
true, .state = connections[idx]};
uint32_t mux_idx(TBlock::Sector dst_sector, uint8_t lane_idx)