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
14FLASHMEM blocks::IBlockHAL_V_1_2_X::IBlockHAL_V_1_2_X(bus::addr_t block_address)
15 : f_meta(block_address), f_cmd{bus::replace_function_idx(block_address, 2)},
16 f_imatrix_reset{bus::replace_function_idx(block_address, 4)}, f_imatrix_sync{bus::replace_function_idx(
17 block_address, 3)},
18 scaling_register{bus::replace_function_idx(block_address, 5), true},
19 scaling_register_sync{bus::replace_function_idx(block_address, 6)} {}
20
21FLASHMEM bool blocks::IBlockHAL_V_1_2_X::write_outputs(const std::array<uint32_t, 16> &outputs) {
22 f_imatrix_reset.trigger();
23 delayNanoseconds(420);
24
25 // TODO: This can be further improved by not naively iterating over the output indizes.
26 // For each output, send the corresponding 32bit commands.
27 // For output_idx < 7, the first two MT8816 chips are used, for >8 the later two.
28 // This means, we can set two outputs simultaneously.
29 // When setting later outputs, we need to *not* overwrite previous outputs on the other chips
30 // Thus we remember what we send them and just send them the same thing again
31 uint32_t remembered_command = 0;
32 for (decltype(outputs.size()) output_idx = 0; output_idx < outputs.size() / 2; output_idx++) {
33 uint32_t command = 0;
34 const auto oidx_one_two = output_idx;
35 const auto oidx_three_four = output_idx + outputs.size() / 2;
36 if (!outputs[oidx_one_two] && !outputs[oidx_three_four])
37 continue;
38
39 // We can always set one output in range (0,15) and one in (16,31) in for each output
40 for (uint8_t input_idx = 0; input_idx < NUM_INPUTS / 2; input_idx++) {
41
42 command = 0;
43
44 const auto iidx_one_three = input_idx;
45 const auto iidx_two_four = input_idx + NUM_INPUTS / 2;
46 bool actual_data = false;
47 // First chip combines oidx_one_two and iidx_one_three
48 if (outputs[oidx_one_two] & INPUT_BITMASK(iidx_one_three)) {
49 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_one_three, oidx_one_two);
50 actual_data = true;
51 } else {
52 command |= (remembered_command & 0xFF);
53 }
54 // Similar combination for second chip
55 if (outputs[oidx_one_two] & INPUT_BITMASK(iidx_two_four)) {
56 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_two_four, oidx_one_two) << 8;
57 actual_data = true;
58 } else {
59 command |= (remembered_command & 0xFF00);
60 }
61 // Third chip
62 if (outputs[oidx_three_four] & INPUT_BITMASK(iidx_one_three)) {
63 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_one_three, oidx_three_four) << 16;
64 actual_data = true;
65 } else {
66 command |= (remembered_command & 0xFF0000);
67 }
68 // Fourth chip
69 if (outputs[oidx_three_four] & INPUT_BITMASK(iidx_two_four)) {
70 command |= functions::ICommandRegisterFunction::chip_cmd_word(iidx_two_four, oidx_three_four) << 24;
71 actual_data = true;
72 } else {
73 command |= (remembered_command & 0xFF000000);
74 }
75
76 if (actual_data) {
77 remembered_command = command;
78 // Send out data
79 if (!f_cmd.transfer32(command)) {
80 LOG(ANABRID_PEDANTIC, __PRETTY_FUNCTION__);
81 return false;
82 }
83 // Apply command
84 f_imatrix_sync.trigger();
85 }
86 }
87 }
88 return true;
89}
90
91FLASHMEM bool blocks::IBlockHAL_V_1_2_X::write_upscaling(std::bitset<32> upscaling) {
92 if (!scaling_register.transfer32(upscaling.to_ulong()))
93 return false;
94 scaling_register_sync.trigger();
95 return true;
96}
bool write_upscaling(std::bitset< 32 > upscaling) override
Definition iblock.cpp:91
IBlockHAL_V_1_2_X(bus::addr_t block_address)
Definition iblock.cpp:14
bool write_outputs(const std::array< uint32_t, 16 > &outputs) override
Definition iblock.cpp:21
static uint8_t chip_cmd_word(uint8_t chip_input_idx, uint8_t chip_output_idx, bool connect=true)
Definition icmd.cpp:18
Definition bus.h:21
uint32_t
Definition flasher.cpp:195