REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
iblock.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 <block/iblock.h>
6#include <bus/functions.h>
7#include <entity/meta.h>
8#include <utils/is_number.h>
9#include <utils/logging.h>
10
11#include "teensy/iblock.h"
12#include "teensy/icmd.h"
13
14blocks::IBlock *blocks::IBlock::from_entity_classifier(entities::EntityClassifier classifier,
15 bus::addr_t block_address) {
16 if (!classifier or classifier.class_enum != CLASS_)
17 return nullptr;
18
19 // Currently, there are no different variants
20 if (classifier.variant != entities::EntityClassifier::DEFAULT_)
21 return nullptr;
22
23 if (classifier.version < entities::Version(1, 2))
24 return nullptr;
25 if (classifier.version < entities::Version(1, 3)) {
26 auto *new_block = new IBlock(new IBlockHAL_V_1_2_X(block_address));
27 new_block->classifier = classifier;
28 return new_block;
29 }
30 if (classifier.version < entities::Version(1, 4)) {
31 auto *new_block = new IBlock(new IBlockHAL_V_1_3_X(block_address));
32 new_block->classifier = classifier;
33 return new_block;
34 }
35 return nullptr;
36}
37
39 : IBlockHAL_Parent(block_address, 5), f_cmd{bus::replace_function_idx(block_address, 2), 5},
40 f_imatrix_reset{bus::replace_function_idx(block_address, 4)}, f_imatrix_sync{bus::replace_function_idx(
41 block_address, 3)},
42 scaling_register{bus::replace_function_idx(block_address, 5), 6, true},
43 scaling_register_sync{bus::replace_function_idx(block_address, 6)} {}
44
45bool blocks::IBlockHAL_V_1_2_X::write_outputs(const std::array<uint32_t, 16> &outputs) {
46 f_imatrix_reset.trigger();
47 delayNanoseconds(420);
48
49 // TODO: This can be further improved by not naively iterating over the output indizes.
50 // For each output, send the corresponding 32bit commands.
51 // For output_idx < 7, the first two MT8816 chips are used, for >8 the later two.
52 // This means, we can set two outputs simultaneously.
53 // When setting later outputs, we need to *not* overwrite previous outputs on the other chips
54 // Thus we remember what we send them and just send them the same thing again
55 uint32_t remembered_command = 0;
56 for (decltype(outputs.size()) output_idx = 0; output_idx < outputs.size() / 2; output_idx++) {
57 uint32_t command = 0;
58 const auto oidx_one_two = output_idx;
59 const auto oidx_three_four = output_idx + outputs.size() / 2;
60 if (!outputs[oidx_one_two] && !outputs[oidx_three_four])
61 continue;
62
63 // We can always set one output in range (0,15) and one in (16,31) in for each output
64 for (uint8_t input_idx = 0; input_idx < NUM_INPUTS / 2; input_idx++) {
65
66 command = 0;
67
68 const auto iidx_one_three = input_idx;
69 const auto iidx_two_four = input_idx + NUM_INPUTS / 2;
70 bool actual_data = false;
71 // First chip combines oidx_one_two and iidx_one_three
72 if (outputs[oidx_one_two] & INPUT_BITMASK(iidx_one_three)) {
73 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_one_three, oidx_one_two);
74 actual_data = true;
75 } else {
76 command |= (remembered_command & 0xFF);
77 }
78 // Similar combination for second chip
79 if (outputs[oidx_one_two] & INPUT_BITMASK(iidx_two_four)) {
80 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_two_four, oidx_one_two) << 8;
81 actual_data = true;
82 } else {
83 command |= (remembered_command & 0xFF00);
84 }
85 // Third chip
86 if (outputs[oidx_three_four] & INPUT_BITMASK(iidx_one_three)) {
87 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_one_three, oidx_three_four) << 16;
88 actual_data = true;
89 } else {
90 command |= (remembered_command & 0xFF0000);
91 }
92 // Fourth chip
93 if (outputs[oidx_three_four] & INPUT_BITMASK(iidx_two_four)) {
94 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_two_four, oidx_three_four) << 24;
95 actual_data = true;
96 } else {
97 command |= (remembered_command & 0xFF000000);
98 }
99
100 if (actual_data) {
101 remembered_command = command;
102 // Send out data
103 if (!f_cmd.transfer32(command)) {
104 LOG(ANABRID_PEDANTIC, __PRETTY_FUNCTION__);
105 return false;
106 }
107 // Apply command
108 f_imatrix_sync.trigger();
109 }
110 }
111 }
112 return true;
113}
114
115bool blocks::IBlockHAL_V_1_2_X::write_upscaling(std::bitset<32> upscaling) {
116 if (!scaling_register.transfer32(upscaling.to_ulong()))
117 return false;
118 scaling_register_sync.trigger();
119 return true;
120}
121
123 : IBlockHAL_V_1_2_X(block_address), f_cmd{bus::replace_function_idx(block_address, 2), 0xff},
124 f_imatrix_reset{bus::replace_function_idx(block_address, 4)}, f_imatrix_sync{bus::replace_function_idx(
125 block_address, 3)},
126 scaling_register{bus::replace_function_idx(block_address, 5), 0xff, true},
127 scaling_register_sync{bus::replace_function_idx(block_address, 0xff)} {}
bool write_outputs(const std::array< uint32_t, 16 > &outputs) override
Definition iblock.cpp:45
const functions::TriggerFunction f_imatrix_reset
Definition iblock.h:17
const functions::TriggerFunction scaling_register_sync
Definition iblock.h:21
const functions::SR74HCT595 scaling_register
Definition iblock.h:20
const functions::TriggerFunction f_imatrix_sync
Definition iblock.h:18
const functions::ICommandRegisterFunction f_cmd
Definition iblock.h:16
IBlockHAL_V_1_2_X(bus::addr_t block_address)
Definition iblock.cpp:38
bool write_upscaling(std::bitset< 32 > upscaling) override
Definition iblock.cpp:115
const functions::SR74HCT595 scaling_register
Definition iblock.h:37
const functions::TriggerFunction scaling_register_sync
Definition iblock.h:38
const functions::ICommandRegisterFunction f_cmd
Definition iblock.h:33
const functions::TriggerFunction f_imatrix_reset
Definition iblock.h:34
IBlockHAL_V_1_3_X(bus::addr_t block_address)
Definition iblock.cpp:122
const functions::TriggerFunction f_imatrix_sync
Definition iblock.h:35
static uint8_t chip_cmd_word(uint8_t chip_input_idx, uint8_t chip_output_idx, bool connect=true)
Definition icmd.cpp:18
uint32_t
Definition flasher.cpp:195
entities::EntitySharedHardware< IBlockHAL > IBlockHAL_Parent
Definition iblock.h:12
Definition bus.h:21