REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
lucidac.cpp
Go to the documentation of this file.
1// Copyright (c) 2024 anabrid GmbH
2// Contact: https://www.anabrid.com/licensing/
3//
4// SPDX-License-Identifier: MIT OR GPL-2.0-or-later
5
6#include <lucidac/lucidac.h>
7#include <utils/mac.h>
8
9#include "teensy/lucidac.h"
10#include <block/teensy/icmd.h>
11#include <chips/SR74HCT595.h>
12#include <chips/TMP127Q1.h>
13
14carrier::Carrier &carrier::Carrier::get() {
15 static carrier::Carrier *instance;
16
17 if (!instance) {
18 instance = detect();
19
20 if (!instance) {
21 // Can we continue to work without knowing about the detailed nature of a Carrier? Of course we can: We
22 // just assume a LUCIDAC. This is absolutely reasonable makes the code less error prone then just
23 // aborting because the Carrier EEPROM does not hold anything meaningful. However, next to this, there is
24 // an even more important reason why to create an instance of LUCIDAC here: In early LUCIDACs (until S/N
25 // 7) programmers were not aware of the EEPROM on the carrier and just thought there was none. To pay the
26 // penalty for their ignorance, this workaround will be here forever ;-)
27 LOG_ALWAYS("Warning: Carrier board EEPROM not in use. Falling back to Carrier Type = LUCIDAC.");
28 instance = new platform::LUCIDAC(new platform::Teensy_LUCIDAC_HAL);
29 }
30 }
31
32 return *instance;
33}
34
35platform::LUCIDAC *platform::LUCIDAC::from_entity_classifier(entities::EntityClassifier classifier,
36 __attribute__((__unused__))
37 const bus::addr_t block_address) {
38 if (!classifier or classifier.type != static_cast<uint8_t>(TYPES::LUCIDAC))
39 return nullptr;
40
41 if (classifier.version < entities::Version(1, 1))
42 return nullptr;
43 if (classifier.version < entities::Version(1, 2)) {
44 auto *new_carrier = new LUCIDAC(new Teensy_LUCIDAC_HAL);
45 new_carrier->classifier = classifier;
46 return new_carrier;
47 }
48 return nullptr;
49}
50
52 4'000'000, MSBFIRST, SPI_MODE2 /* chip expects SPI MODE0, but CLK is inverted on the way */};
53
64
65bool platform::Teensy_LUCIDAC_HAL::write_acl(std::array<Teensy_LUCIDAC_HAL::ACL, 8> acl) {
66 uint8_t sr = 0;
67 for (size_t idx = 0; idx < acl.size(); idx++) {
68 if (acl[idx] == ACL::EXTERNAL_) {
69 sr |= 1 << idx;
70 }
71 }
72 if (!f_acl_prg.transfer8(sr))
73 return false;
74 f_acl_upd.trigger();
75 return true;
76}
77
79 f_acl_clr.trigger();
80 f_acl_upd.trigger();
81}
82
83bool platform::Teensy_LUCIDAC_HAL::write_adc_bus_mux(const std::array<int8_t, 8> &channels) {
84 // Reset previous connections
85 // It's easier to do a full reset then to remember all previous connections
87 delayNanoseconds(420);
88
89 // Write data to chip
90 for (uint8_t output_idx = 0; output_idx < channels.size(); output_idx++) {
91 if (channels[output_idx] >= 0) {
92 auto cmd = decltype(f_adc_switcher_prg)::chip_cmd_word(channels[output_idx], output_idx);
93 if (!f_adc_switcher_prg.transfer8(cmd))
94 return false;
95 f_adc_switcher_sync.trigger();
96 }
97 }
98 return true;
99}
100
const functions::TriggerFunction f_adc_switcher_sr_reset
Definition lucidac.h:45
static constexpr uint8_t ACL_UPD_FADDR
Definition lucidac.h:31
bool write_adc_bus_mux(const std::array< int8_t, 8 > &channels) override
Write channel selection to ADC bus muxer.
Definition lucidac.cpp:83
const functions::SR74HCT595 f_acl_prg
Definition lucidac.h:36
const functions::TriggerFunction f_adc_switcher_matrix_reset
Definition lucidac.h:46
void reset_acl() override
Definition lucidac.cpp:78
const functions::ICommandRegisterFunction f_adc_switcher_prg
Definition lucidac.h:43
static constexpr uint8_t ADC_STROBE_FADDR
Definition lucidac.h:29
static constexpr uint8_t ACL_CRL_FADDR
Definition lucidac.h:32
static constexpr uint8_t CARRIER_MADDR
Definition lucidac.h:22
static constexpr uint8_t ACL_PRG_FADDR
Definition lucidac.h:30
const functions::TriggerFunction f_acl_upd
Definition lucidac.h:37
static const SPISettings F_ADC_SWITCHER_PRG_SPI_SETTINGS
Definition lucidac.h:51
const functions::TriggerFunction f_acl_clr
Definition lucidac.h:38
const functions::TriggerFunction f_adc_switcher_sync
Definition lucidac.h:44
static constexpr uint8_t ADC_RESET_SR_FADDR
Definition lucidac.h:28
bool write_acl(std::array< ACL, 8 > acl) override
Write bits to ACL shift register, from I-block input 24 (first element) to 31 (last element)
Definition lucidac.cpp:65
static constexpr uint8_t ADC_PRG_FADDR
Definition lucidac.h:26
void reset_adc_bus_mux() override
Definition lucidac.cpp:101
static constexpr uint8_t ADC_RESET_8816_FADDR
Definition lucidac.h:27
__attribute__((section(".fastrun"), noinline, noclone, optimize("Os"))) int flash_sector_not_erased(uint32_t address)
Definition flasher.cpp:114
Definition bus.h:21
entities::EntitySharedHardware< LUCIDAC_HAL > LUCIDAC_HAL_Parent
Definition lucidac.h:17