REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
daq.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 <Arduino.h>
6#include <algorithm>
7#include <bitset>
8
9#include "daq/daq.h"
10
11#include "carrier/carrier.h"
12#include "utils/logging.h"
13#include "utils/running_avg.h"
14
15size_t daq::raw_to_normalized(uint16_t raw) {
16 // exact conversion is 0.152658243301, but we only care about so much precision
17 return std::max(std::min((static_cast<unsigned int>(raw) * 1527u) / 10000u, 2500u), 0u);
18}
19
20#ifdef ARDUINO
21
22namespace daq {
23
24namespace stream {
25
26namespace details {
27
28// We need a memory segment to implement a ring buffer.
29// Its size should be a power-of-2-multiple of NUM_CHANNELS.
30// The DMA implements ring buffer by restricting the N lower bits of the destination address to change.
31// That means the memory segment must start at a memory address with enough lower bits being zero,
32// see manual "data queues [with] power-of-2 size bytes, [...] should start at a 0-modulo-size address".
33// One can put this into DMAMEM for increased performance, but that did not work for me right away.
34// *MUST* be at least 2*NUM_CHANNELS, otherwise some math later does not work.
35__attribute__((aligned(BUFFER_SIZE * 4))) std::array<volatile uint32_t, BUFFER_SIZE> buffer = {0};
36
37DMAChannel channel(false);
38const run::Run *run = nullptr;
39run::RunDataHandler *run_data_handler = nullptr;
40volatile bool first_data = false;
41volatile bool last_data = false;
42volatile bool overflow_data = false;
43
44// NOT FLASHMEM
45void interrupt() {
46 // Serial.println(__PRETTY_FUNCTION__);
47 auto is_half = (channel.TCD->CITER != channel.TCD->BITER);
48 if (is_half) {
49 overflow_data |= first_data;
50 first_data = true;
51 } else {
52 overflow_data |= last_data;
53 last_data = true;
54 }
55
56 // Clear interrupt
57 channel.clearInterrupt();
58 // Memory barrier
59#ifdef ARDUINO
60 asm("DSB");
61#endif
62}
63
64} // namespace details
65
66} // namespace stream
67
68} // namespace daq
69
70#endif
71
72const char *daq::raw_to_str(uint16_t raw) {
73 PROGMEM static constexpr std::array<char[7], 2501> normalized_to_float_str_arr = {
74 " 1.250", " 1.249", " 1.248", " 1.247", " 1.246", " 1.245", " 1.244", " 1.243", " 1.242", " 1.241",
75 " 1.240", " 1.239", " 1.238", " 1.237", " 1.236", " 1.235", " 1.234", " 1.233", " 1.232", " 1.231",
76 " 1.230", " 1.229", " 1.228", " 1.227", " 1.226", " 1.225", " 1.224", " 1.223", " 1.222", " 1.221",
77 " 1.220", " 1.219", " 1.218", " 1.217", " 1.216", " 1.215", " 1.214", " 1.213", " 1.212", " 1.211",
78 " 1.210", " 1.209", " 1.208", " 1.207", " 1.206", " 1.205", " 1.204", " 1.203", " 1.202", " 1.201",
79 " 1.200", " 1.199", " 1.198", " 1.197", " 1.196", " 1.195", " 1.194", " 1.193", " 1.192", " 1.191",
80 " 1.190", " 1.189", " 1.188", " 1.187", " 1.186", " 1.185", " 1.184", " 1.183", " 1.182", " 1.181",
81 " 1.180", " 1.179", " 1.178", " 1.177", " 1.176", " 1.175", " 1.174", " 1.173", " 1.172", " 1.171",
82 " 1.170", " 1.169", " 1.168", " 1.167", " 1.166", " 1.165", " 1.164", " 1.163", " 1.162", " 1.161",
83 " 1.160", " 1.159", " 1.158", " 1.157", " 1.156", " 1.155", " 1.154", " 1.153", " 1.152", " 1.151",
84 " 1.150", " 1.149", " 1.148", " 1.147", " 1.146", " 1.145", " 1.144", " 1.143", " 1.142", " 1.141",
85 " 1.140", " 1.139", " 1.138", " 1.137", " 1.136", " 1.135", " 1.134", " 1.133", " 1.132", " 1.131",
86 " 1.130", " 1.129", " 1.128", " 1.127", " 1.126", " 1.125", " 1.124", " 1.123", " 1.122", " 1.121",
87 " 1.120", " 1.119", " 1.118", " 1.117", " 1.116", " 1.115", " 1.114", " 1.113", " 1.112", " 1.111",
88 " 1.110", " 1.109", " 1.108", " 1.107", " 1.106", " 1.105", " 1.104", " 1.103", " 1.102", " 1.101",
89 " 1.100", " 1.099", " 1.098", " 1.097", " 1.096", " 1.095", " 1.094", " 1.093", " 1.092", " 1.091",
90 " 1.090", " 1.089", " 1.088", " 1.087", " 1.086", " 1.085", " 1.084", " 1.083", " 1.082", " 1.081",
91 " 1.080", " 1.079", " 1.078", " 1.077", " 1.076", " 1.075", " 1.074", " 1.073", " 1.072", " 1.071",
92 " 1.070", " 1.069", " 1.068", " 1.067", " 1.066", " 1.065", " 1.064", " 1.063", " 1.062", " 1.061",
93 " 1.060", " 1.059", " 1.058", " 1.057", " 1.056", " 1.055", " 1.054", " 1.053", " 1.052", " 1.051",
94 " 1.050", " 1.049", " 1.048", " 1.047", " 1.046", " 1.045", " 1.044", " 1.043", " 1.042", " 1.041",
95 " 1.040", " 1.039", " 1.038", " 1.037", " 1.036", " 1.035", " 1.034", " 1.033", " 1.032", " 1.031",
96 " 1.030", " 1.029", " 1.028", " 1.027", " 1.026", " 1.025", " 1.024", " 1.023", " 1.022", " 1.021",
97 " 1.020", " 1.019", " 1.018", " 1.017", " 1.016", " 1.015", " 1.014", " 1.013", " 1.012", " 1.011",
98 " 1.010", " 1.009", " 1.008", " 1.007", " 1.006", " 1.005", " 1.004", " 1.003", " 1.002", " 1.001",
99 " 1.000", " 0.999", " 0.998", " 0.997", " 0.996", " 0.995", " 0.994", " 0.993", " 0.992", " 0.991",
100 " 0.990", " 0.989", " 0.988", " 0.987", " 0.986", " 0.985", " 0.984", " 0.983", " 0.982", " 0.981",
101 " 0.980", " 0.979", " 0.978", " 0.977", " 0.976", " 0.975", " 0.974", " 0.973", " 0.972", " 0.971",
102 " 0.970", " 0.969", " 0.968", " 0.967", " 0.966", " 0.965", " 0.964", " 0.963", " 0.962", " 0.961",
103 " 0.960", " 0.959", " 0.958", " 0.957", " 0.956", " 0.955", " 0.954", " 0.953", " 0.952", " 0.951",
104 " 0.950", " 0.949", " 0.948", " 0.947", " 0.946", " 0.945", " 0.944", " 0.943", " 0.942", " 0.941",
105 " 0.940", " 0.939", " 0.938", " 0.937", " 0.936", " 0.935", " 0.934", " 0.933", " 0.932", " 0.931",
106 " 0.930", " 0.929", " 0.928", " 0.927", " 0.926", " 0.925", " 0.924", " 0.923", " 0.922", " 0.921",
107 " 0.920", " 0.919", " 0.918", " 0.917", " 0.916", " 0.915", " 0.914", " 0.913", " 0.912", " 0.911",
108 " 0.910", " 0.909", " 0.908", " 0.907", " 0.906", " 0.905", " 0.904", " 0.903", " 0.902", " 0.901",
109 " 0.900", " 0.899", " 0.898", " 0.897", " 0.896", " 0.895", " 0.894", " 0.893", " 0.892", " 0.891",
110 " 0.890", " 0.889", " 0.888", " 0.887", " 0.886", " 0.885", " 0.884", " 0.883", " 0.882", " 0.881",
111 " 0.880", " 0.879", " 0.878", " 0.877", " 0.876", " 0.875", " 0.874", " 0.873", " 0.872", " 0.871",
112 " 0.870", " 0.869", " 0.868", " 0.867", " 0.866", " 0.865", " 0.864", " 0.863", " 0.862", " 0.861",
113 " 0.860", " 0.859", " 0.858", " 0.857", " 0.856", " 0.855", " 0.854", " 0.853", " 0.852", " 0.851",
114 " 0.850", " 0.849", " 0.848", " 0.847", " 0.846", " 0.845", " 0.844", " 0.843", " 0.842", " 0.841",
115 " 0.840", " 0.839", " 0.838", " 0.837", " 0.836", " 0.835", " 0.834", " 0.833", " 0.832", " 0.831",
116 " 0.830", " 0.829", " 0.828", " 0.827", " 0.826", " 0.825", " 0.824", " 0.823", " 0.822", " 0.821",
117 " 0.820", " 0.819", " 0.818", " 0.817", " 0.816", " 0.815", " 0.814", " 0.813", " 0.812", " 0.811",
118 " 0.810", " 0.809", " 0.808", " 0.807", " 0.806", " 0.805", " 0.804", " 0.803", " 0.802", " 0.801",
119 " 0.800", " 0.799", " 0.798", " 0.797", " 0.796", " 0.795", " 0.794", " 0.793", " 0.792", " 0.791",
120 " 0.790", " 0.789", " 0.788", " 0.787", " 0.786", " 0.785", " 0.784", " 0.783", " 0.782", " 0.781",
121 " 0.780", " 0.779", " 0.778", " 0.777", " 0.776", " 0.775", " 0.774", " 0.773", " 0.772", " 0.771",
122 " 0.770", " 0.769", " 0.768", " 0.767", " 0.766", " 0.765", " 0.764", " 0.763", " 0.762", " 0.761",
123 " 0.760", " 0.759", " 0.758", " 0.757", " 0.756", " 0.755", " 0.754", " 0.753", " 0.752", " 0.751",
124 " 0.750", " 0.749", " 0.748", " 0.747", " 0.746", " 0.745", " 0.744", " 0.743", " 0.742", " 0.741",
125 " 0.740", " 0.739", " 0.738", " 0.737", " 0.736", " 0.735", " 0.734", " 0.733", " 0.732", " 0.731",
126 " 0.730", " 0.729", " 0.728", " 0.727", " 0.726", " 0.725", " 0.724", " 0.723", " 0.722", " 0.721",
127 " 0.720", " 0.719", " 0.718", " 0.717", " 0.716", " 0.715", " 0.714", " 0.713", " 0.712", " 0.711",
128 " 0.710", " 0.709", " 0.708", " 0.707", " 0.706", " 0.705", " 0.704", " 0.703", " 0.702", " 0.701",
129 " 0.700", " 0.699", " 0.698", " 0.697", " 0.696", " 0.695", " 0.694", " 0.693", " 0.692", " 0.691",
130 " 0.690", " 0.689", " 0.688", " 0.687", " 0.686", " 0.685", " 0.684", " 0.683", " 0.682", " 0.681",
131 " 0.680", " 0.679", " 0.678", " 0.677", " 0.676", " 0.675", " 0.674", " 0.673", " 0.672", " 0.671",
132 " 0.670", " 0.669", " 0.668", " 0.667", " 0.666", " 0.665", " 0.664", " 0.663", " 0.662", " 0.661",
133 " 0.660", " 0.659", " 0.658", " 0.657", " 0.656", " 0.655", " 0.654", " 0.653", " 0.652", " 0.651",
134 " 0.650", " 0.649", " 0.648", " 0.647", " 0.646", " 0.645", " 0.644", " 0.643", " 0.642", " 0.641",
135 " 0.640", " 0.639", " 0.638", " 0.637", " 0.636", " 0.635", " 0.634", " 0.633", " 0.632", " 0.631",
136 " 0.630", " 0.629", " 0.628", " 0.627", " 0.626", " 0.625", " 0.624", " 0.623", " 0.622", " 0.621",
137 " 0.620", " 0.619", " 0.618", " 0.617", " 0.616", " 0.615", " 0.614", " 0.613", " 0.612", " 0.611",
138 " 0.610", " 0.609", " 0.608", " 0.607", " 0.606", " 0.605", " 0.604", " 0.603", " 0.602", " 0.601",
139 " 0.600", " 0.599", " 0.598", " 0.597", " 0.596", " 0.595", " 0.594", " 0.593", " 0.592", " 0.591",
140 " 0.590", " 0.589", " 0.588", " 0.587", " 0.586", " 0.585", " 0.584", " 0.583", " 0.582", " 0.581",
141 " 0.580", " 0.579", " 0.578", " 0.577", " 0.576", " 0.575", " 0.574", " 0.573", " 0.572", " 0.571",
142 " 0.570", " 0.569", " 0.568", " 0.567", " 0.566", " 0.565", " 0.564", " 0.563", " 0.562", " 0.561",
143 " 0.560", " 0.559", " 0.558", " 0.557", " 0.556", " 0.555", " 0.554", " 0.553", " 0.552", " 0.551",
144 " 0.550", " 0.549", " 0.548", " 0.547", " 0.546", " 0.545", " 0.544", " 0.543", " 0.542", " 0.541",
145 " 0.540", " 0.539", " 0.538", " 0.537", " 0.536", " 0.535", " 0.534", " 0.533", " 0.532", " 0.531",
146 " 0.530", " 0.529", " 0.528", " 0.527", " 0.526", " 0.525", " 0.524", " 0.523", " 0.522", " 0.521",
147 " 0.520", " 0.519", " 0.518", " 0.517", " 0.516", " 0.515", " 0.514", " 0.513", " 0.512", " 0.511",
148 " 0.510", " 0.509", " 0.508", " 0.507", " 0.506", " 0.505", " 0.504", " 0.503", " 0.502", " 0.501",
149 " 0.500", " 0.499", " 0.498", " 0.497", " 0.496", " 0.495", " 0.494", " 0.493", " 0.492", " 0.491",
150 " 0.490", " 0.489", " 0.488", " 0.487", " 0.486", " 0.485", " 0.484", " 0.483", " 0.482", " 0.481",
151 " 0.480", " 0.479", " 0.478", " 0.477", " 0.476", " 0.475", " 0.474", " 0.473", " 0.472", " 0.471",
152 " 0.470", " 0.469", " 0.468", " 0.467", " 0.466", " 0.465", " 0.464", " 0.463", " 0.462", " 0.461",
153 " 0.460", " 0.459", " 0.458", " 0.457", " 0.456", " 0.455", " 0.454", " 0.453", " 0.452", " 0.451",
154 " 0.450", " 0.449", " 0.448", " 0.447", " 0.446", " 0.445", " 0.444", " 0.443", " 0.442", " 0.441",
155 " 0.440", " 0.439", " 0.438", " 0.437", " 0.436", " 0.435", " 0.434", " 0.433", " 0.432", " 0.431",
156 " 0.430", " 0.429", " 0.428", " 0.427", " 0.426", " 0.425", " 0.424", " 0.423", " 0.422", " 0.421",
157 " 0.420", " 0.419", " 0.418", " 0.417", " 0.416", " 0.415", " 0.414", " 0.413", " 0.412", " 0.411",
158 " 0.410", " 0.409", " 0.408", " 0.407", " 0.406", " 0.405", " 0.404", " 0.403", " 0.402", " 0.401",
159 " 0.400", " 0.399", " 0.398", " 0.397", " 0.396", " 0.395", " 0.394", " 0.393", " 0.392", " 0.391",
160 " 0.390", " 0.389", " 0.388", " 0.387", " 0.386", " 0.385", " 0.384", " 0.383", " 0.382", " 0.381",
161 " 0.380", " 0.379", " 0.378", " 0.377", " 0.376", " 0.375", " 0.374", " 0.373", " 0.372", " 0.371",
162 " 0.370", " 0.369", " 0.368", " 0.367", " 0.366", " 0.365", " 0.364", " 0.363", " 0.362", " 0.361",
163 " 0.360", " 0.359", " 0.358", " 0.357", " 0.356", " 0.355", " 0.354", " 0.353", " 0.352", " 0.351",
164 " 0.350", " 0.349", " 0.348", " 0.347", " 0.346", " 0.345", " 0.344", " 0.343", " 0.342", " 0.341",
165 " 0.340", " 0.339", " 0.338", " 0.337", " 0.336", " 0.335", " 0.334", " 0.333", " 0.332", " 0.331",
166 " 0.330", " 0.329", " 0.328", " 0.327", " 0.326", " 0.325", " 0.324", " 0.323", " 0.322", " 0.321",
167 " 0.320", " 0.319", " 0.318", " 0.317", " 0.316", " 0.315", " 0.314", " 0.313", " 0.312", " 0.311",
168 " 0.310", " 0.309", " 0.308", " 0.307", " 0.306", " 0.305", " 0.304", " 0.303", " 0.302", " 0.301",
169 " 0.300", " 0.299", " 0.298", " 0.297", " 0.296", " 0.295", " 0.294", " 0.293", " 0.292", " 0.291",
170 " 0.290", " 0.289", " 0.288", " 0.287", " 0.286", " 0.285", " 0.284", " 0.283", " 0.282", " 0.281",
171 " 0.280", " 0.279", " 0.278", " 0.277", " 0.276", " 0.275", " 0.274", " 0.273", " 0.272", " 0.271",
172 " 0.270", " 0.269", " 0.268", " 0.267", " 0.266", " 0.265", " 0.264", " 0.263", " 0.262", " 0.261",
173 " 0.260", " 0.259", " 0.258", " 0.257", " 0.256", " 0.255", " 0.254", " 0.253", " 0.252", " 0.251",
174 " 0.250", " 0.249", " 0.248", " 0.247", " 0.246", " 0.245", " 0.244", " 0.243", " 0.242", " 0.241",
175 " 0.240", " 0.239", " 0.238", " 0.237", " 0.236", " 0.235", " 0.234", " 0.233", " 0.232", " 0.231",
176 " 0.230", " 0.229", " 0.228", " 0.227", " 0.226", " 0.225", " 0.224", " 0.223", " 0.222", " 0.221",
177 " 0.220", " 0.219", " 0.218", " 0.217", " 0.216", " 0.215", " 0.214", " 0.213", " 0.212", " 0.211",
178 " 0.210", " 0.209", " 0.208", " 0.207", " 0.206", " 0.205", " 0.204", " 0.203", " 0.202", " 0.201",
179 " 0.200", " 0.199", " 0.198", " 0.197", " 0.196", " 0.195", " 0.194", " 0.193", " 0.192", " 0.191",
180 " 0.190", " 0.189", " 0.188", " 0.187", " 0.186", " 0.185", " 0.184", " 0.183", " 0.182", " 0.181",
181 " 0.180", " 0.179", " 0.178", " 0.177", " 0.176", " 0.175", " 0.174", " 0.173", " 0.172", " 0.171",
182 " 0.170", " 0.169", " 0.168", " 0.167", " 0.166", " 0.165", " 0.164", " 0.163", " 0.162", " 0.161",
183 " 0.160", " 0.159", " 0.158", " 0.157", " 0.156", " 0.155", " 0.154", " 0.153", " 0.152", " 0.151",
184 " 0.150", " 0.149", " 0.148", " 0.147", " 0.146", " 0.145", " 0.144", " 0.143", " 0.142", " 0.141",
185 " 0.140", " 0.139", " 0.138", " 0.137", " 0.136", " 0.135", " 0.134", " 0.133", " 0.132", " 0.131",
186 " 0.130", " 0.129", " 0.128", " 0.127", " 0.126", " 0.125", " 0.124", " 0.123", " 0.122", " 0.121",
187 " 0.120", " 0.119", " 0.118", " 0.117", " 0.116", " 0.115", " 0.114", " 0.113", " 0.112", " 0.111",
188 " 0.110", " 0.109", " 0.108", " 0.107", " 0.106", " 0.105", " 0.104", " 0.103", " 0.102", " 0.101",
189 " 0.100", " 0.099", " 0.098", " 0.097", " 0.096", " 0.095", " 0.094", " 0.093", " 0.092", " 0.091",
190 " 0.090", " 0.089", " 0.088", " 0.087", " 0.086", " 0.085", " 0.084", " 0.083", " 0.082", " 0.081",
191 " 0.080", " 0.079", " 0.078", " 0.077", " 0.076", " 0.075", " 0.074", " 0.073", " 0.072", " 0.071",
192 " 0.070", " 0.069", " 0.068", " 0.067", " 0.066", " 0.065", " 0.064", " 0.063", " 0.062", " 0.061",
193 " 0.060", " 0.059", " 0.058", " 0.057", " 0.056", " 0.055", " 0.054", " 0.053", " 0.052", " 0.051",
194 " 0.050", " 0.049", " 0.048", " 0.047", " 0.046", " 0.045", " 0.044", " 0.043", " 0.042", " 0.041",
195 " 0.040", " 0.039", " 0.038", " 0.037", " 0.036", " 0.035", " 0.034", " 0.033", " 0.032", " 0.031",
196 " 0.030", " 0.029", " 0.028", " 0.027", " 0.026", " 0.025", " 0.024", " 0.023", " 0.022", " 0.021",
197 " 0.020", " 0.019", " 0.018", " 0.017", " 0.016", " 0.015", " 0.014", " 0.013", " 0.012", " 0.011",
198 " 0.010", " 0.009", " 0.008", " 0.007", " 0.006", " 0.005", " 0.004", " 0.003", " 0.002", " 0.001",
199 "-0.000", "-0.001", "-0.002", "-0.003", "-0.004", "-0.005", "-0.006", "-0.007", "-0.008", "-0.009",
200 "-0.010", "-0.011", "-0.012", "-0.013", "-0.014", "-0.015", "-0.016", "-0.017", "-0.018", "-0.019",
201 "-0.020", "-0.021", "-0.022", "-0.023", "-0.024", "-0.025", "-0.026", "-0.027", "-0.028", "-0.029",
202 "-0.030", "-0.031", "-0.032", "-0.033", "-0.034", "-0.035", "-0.036", "-0.037", "-0.038", "-0.039",
203 "-0.040", "-0.041", "-0.042", "-0.043", "-0.044", "-0.045", "-0.046", "-0.047", "-0.048", "-0.049",
204 "-0.050", "-0.051", "-0.052", "-0.053", "-0.054", "-0.055", "-0.056", "-0.057", "-0.058", "-0.059",
205 "-0.060", "-0.061", "-0.062", "-0.063", "-0.064", "-0.065", "-0.066", "-0.067", "-0.068", "-0.069",
206 "-0.070", "-0.071", "-0.072", "-0.073", "-0.074", "-0.075", "-0.076", "-0.077", "-0.078", "-0.079",
207 "-0.080", "-0.081", "-0.082", "-0.083", "-0.084", "-0.085", "-0.086", "-0.087", "-0.088", "-0.089",
208 "-0.090", "-0.091", "-0.092", "-0.093", "-0.094", "-0.095", "-0.096", "-0.097", "-0.098", "-0.099",
209 "-0.100", "-0.101", "-0.102", "-0.103", "-0.104", "-0.105", "-0.106", "-0.107", "-0.108", "-0.109",
210 "-0.110", "-0.111", "-0.112", "-0.113", "-0.114", "-0.115", "-0.116", "-0.117", "-0.118", "-0.119",
211 "-0.120", "-0.121", "-0.122", "-0.123", "-0.124", "-0.125", "-0.126", "-0.127", "-0.128", "-0.129",
212 "-0.130", "-0.131", "-0.132", "-0.133", "-0.134", "-0.135", "-0.136", "-0.137", "-0.138", "-0.139",
213 "-0.140", "-0.141", "-0.142", "-0.143", "-0.144", "-0.145", "-0.146", "-0.147", "-0.148", "-0.149",
214 "-0.150", "-0.151", "-0.152", "-0.153", "-0.154", "-0.155", "-0.156", "-0.157", "-0.158", "-0.159",
215 "-0.160", "-0.161", "-0.162", "-0.163", "-0.164", "-0.165", "-0.166", "-0.167", "-0.168", "-0.169",
216 "-0.170", "-0.171", "-0.172", "-0.173", "-0.174", "-0.175", "-0.176", "-0.177", "-0.178", "-0.179",
217 "-0.180", "-0.181", "-0.182", "-0.183", "-0.184", "-0.185", "-0.186", "-0.187", "-0.188", "-0.189",
218 "-0.190", "-0.191", "-0.192", "-0.193", "-0.194", "-0.195", "-0.196", "-0.197", "-0.198", "-0.199",
219 "-0.200", "-0.201", "-0.202", "-0.203", "-0.204", "-0.205", "-0.206", "-0.207", "-0.208", "-0.209",
220 "-0.210", "-0.211", "-0.212", "-0.213", "-0.214", "-0.215", "-0.216", "-0.217", "-0.218", "-0.219",
221 "-0.220", "-0.221", "-0.222", "-0.223", "-0.224", "-0.225", "-0.226", "-0.227", "-0.228", "-0.229",
222 "-0.230", "-0.231", "-0.232", "-0.233", "-0.234", "-0.235", "-0.236", "-0.237", "-0.238", "-0.239",
223 "-0.240", "-0.241", "-0.242", "-0.243", "-0.244", "-0.245", "-0.246", "-0.247", "-0.248", "-0.249",
224 "-0.250", "-0.251", "-0.252", "-0.253", "-0.254", "-0.255", "-0.256", "-0.257", "-0.258", "-0.259",
225 "-0.260", "-0.261", "-0.262", "-0.263", "-0.264", "-0.265", "-0.266", "-0.267", "-0.268", "-0.269",
226 "-0.270", "-0.271", "-0.272", "-0.273", "-0.274", "-0.275", "-0.276", "-0.277", "-0.278", "-0.279",
227 "-0.280", "-0.281", "-0.282", "-0.283", "-0.284", "-0.285", "-0.286", "-0.287", "-0.288", "-0.289",
228 "-0.290", "-0.291", "-0.292", "-0.293", "-0.294", "-0.295", "-0.296", "-0.297", "-0.298", "-0.299",
229 "-0.300", "-0.301", "-0.302", "-0.303", "-0.304", "-0.305", "-0.306", "-0.307", "-0.308", "-0.309",
230 "-0.310", "-0.311", "-0.312", "-0.313", "-0.314", "-0.315", "-0.316", "-0.317", "-0.318", "-0.319",
231 "-0.320", "-0.321", "-0.322", "-0.323", "-0.324", "-0.325", "-0.326", "-0.327", "-0.328", "-0.329",
232 "-0.330", "-0.331", "-0.332", "-0.333", "-0.334", "-0.335", "-0.336", "-0.337", "-0.338", "-0.339",
233 "-0.340", "-0.341", "-0.342", "-0.343", "-0.344", "-0.345", "-0.346", "-0.347", "-0.348", "-0.349",
234 "-0.350", "-0.351", "-0.352", "-0.353", "-0.354", "-0.355", "-0.356", "-0.357", "-0.358", "-0.359",
235 "-0.360", "-0.361", "-0.362", "-0.363", "-0.364", "-0.365", "-0.366", "-0.367", "-0.368", "-0.369",
236 "-0.370", "-0.371", "-0.372", "-0.373", "-0.374", "-0.375", "-0.376", "-0.377", "-0.378", "-0.379",
237 "-0.380", "-0.381", "-0.382", "-0.383", "-0.384", "-0.385", "-0.386", "-0.387", "-0.388", "-0.389",
238 "-0.390", "-0.391", "-0.392", "-0.393", "-0.394", "-0.395", "-0.396", "-0.397", "-0.398", "-0.399",
239 "-0.400", "-0.401", "-0.402", "-0.403", "-0.404", "-0.405", "-0.406", "-0.407", "-0.408", "-0.409",
240 "-0.410", "-0.411", "-0.412", "-0.413", "-0.414", "-0.415", "-0.416", "-0.417", "-0.418", "-0.419",
241 "-0.420", "-0.421", "-0.422", "-0.423", "-0.424", "-0.425", "-0.426", "-0.427", "-0.428", "-0.429",
242 "-0.430", "-0.431", "-0.432", "-0.433", "-0.434", "-0.435", "-0.436", "-0.437", "-0.438", "-0.439",
243 "-0.440", "-0.441", "-0.442", "-0.443", "-0.444", "-0.445", "-0.446", "-0.447", "-0.448", "-0.449",
244 "-0.450", "-0.451", "-0.452", "-0.453", "-0.454", "-0.455", "-0.456", "-0.457", "-0.458", "-0.459",
245 "-0.460", "-0.461", "-0.462", "-0.463", "-0.464", "-0.465", "-0.466", "-0.467", "-0.468", "-0.469",
246 "-0.470", "-0.471", "-0.472", "-0.473", "-0.474", "-0.475", "-0.476", "-0.477", "-0.478", "-0.479",
247 "-0.480", "-0.481", "-0.482", "-0.483", "-0.484", "-0.485", "-0.486", "-0.487", "-0.488", "-0.489",
248 "-0.490", "-0.491", "-0.492", "-0.493", "-0.494", "-0.495", "-0.496", "-0.497", "-0.498", "-0.499",
249 "-0.500", "-0.501", "-0.502", "-0.503", "-0.504", "-0.505", "-0.506", "-0.507", "-0.508", "-0.509",
250 "-0.510", "-0.511", "-0.512", "-0.513", "-0.514", "-0.515", "-0.516", "-0.517", "-0.518", "-0.519",
251 "-0.520", "-0.521", "-0.522", "-0.523", "-0.524", "-0.525", "-0.526", "-0.527", "-0.528", "-0.529",
252 "-0.530", "-0.531", "-0.532", "-0.533", "-0.534", "-0.535", "-0.536", "-0.537", "-0.538", "-0.539",
253 "-0.540", "-0.541", "-0.542", "-0.543", "-0.544", "-0.545", "-0.546", "-0.547", "-0.548", "-0.549",
254 "-0.550", "-0.551", "-0.552", "-0.553", "-0.554", "-0.555", "-0.556", "-0.557", "-0.558", "-0.559",
255 "-0.560", "-0.561", "-0.562", "-0.563", "-0.564", "-0.565", "-0.566", "-0.567", "-0.568", "-0.569",
256 "-0.570", "-0.571", "-0.572", "-0.573", "-0.574", "-0.575", "-0.576", "-0.577", "-0.578", "-0.579",
257 "-0.580", "-0.581", "-0.582", "-0.583", "-0.584", "-0.585", "-0.586", "-0.587", "-0.588", "-0.589",
258 "-0.590", "-0.591", "-0.592", "-0.593", "-0.594", "-0.595", "-0.596", "-0.597", "-0.598", "-0.599",
259 "-0.600", "-0.601", "-0.602", "-0.603", "-0.604", "-0.605", "-0.606", "-0.607", "-0.608", "-0.609",
260 "-0.610", "-0.611", "-0.612", "-0.613", "-0.614", "-0.615", "-0.616", "-0.617", "-0.618", "-0.619",
261 "-0.620", "-0.621", "-0.622", "-0.623", "-0.624", "-0.625", "-0.626", "-0.627", "-0.628", "-0.629",
262 "-0.630", "-0.631", "-0.632", "-0.633", "-0.634", "-0.635", "-0.636", "-0.637", "-0.638", "-0.639",
263 "-0.640", "-0.641", "-0.642", "-0.643", "-0.644", "-0.645", "-0.646", "-0.647", "-0.648", "-0.649",
264 "-0.650", "-0.651", "-0.652", "-0.653", "-0.654", "-0.655", "-0.656", "-0.657", "-0.658", "-0.659",
265 "-0.660", "-0.661", "-0.662", "-0.663", "-0.664", "-0.665", "-0.666", "-0.667", "-0.668", "-0.669",
266 "-0.670", "-0.671", "-0.672", "-0.673", "-0.674", "-0.675", "-0.676", "-0.677", "-0.678", "-0.679",
267 "-0.680", "-0.681", "-0.682", "-0.683", "-0.684", "-0.685", "-0.686", "-0.687", "-0.688", "-0.689",
268 "-0.690", "-0.691", "-0.692", "-0.693", "-0.694", "-0.695", "-0.696", "-0.697", "-0.698", "-0.699",
269 "-0.700", "-0.701", "-0.702", "-0.703", "-0.704", "-0.705", "-0.706", "-0.707", "-0.708", "-0.709",
270 "-0.710", "-0.711", "-0.712", "-0.713", "-0.714", "-0.715", "-0.716", "-0.717", "-0.718", "-0.719",
271 "-0.720", "-0.721", "-0.722", "-0.723", "-0.724", "-0.725", "-0.726", "-0.727", "-0.728", "-0.729",
272 "-0.730", "-0.731", "-0.732", "-0.733", "-0.734", "-0.735", "-0.736", "-0.737", "-0.738", "-0.739",
273 "-0.740", "-0.741", "-0.742", "-0.743", "-0.744", "-0.745", "-0.746", "-0.747", "-0.748", "-0.749",
274 "-0.750", "-0.751", "-0.752", "-0.753", "-0.754", "-0.755", "-0.756", "-0.757", "-0.758", "-0.759",
275 "-0.760", "-0.761", "-0.762", "-0.763", "-0.764", "-0.765", "-0.766", "-0.767", "-0.768", "-0.769",
276 "-0.770", "-0.771", "-0.772", "-0.773", "-0.774", "-0.775", "-0.776", "-0.777", "-0.778", "-0.779",
277 "-0.780", "-0.781", "-0.782", "-0.783", "-0.784", "-0.785", "-0.786", "-0.787", "-0.788", "-0.789",
278 "-0.790", "-0.791", "-0.792", "-0.793", "-0.794", "-0.795", "-0.796", "-0.797", "-0.798", "-0.799",
279 "-0.800", "-0.801", "-0.802", "-0.803", "-0.804", "-0.805", "-0.806", "-0.807", "-0.808", "-0.809",
280 "-0.810", "-0.811", "-0.812", "-0.813", "-0.814", "-0.815", "-0.816", "-0.817", "-0.818", "-0.819",
281 "-0.820", "-0.821", "-0.822", "-0.823", "-0.824", "-0.825", "-0.826", "-0.827", "-0.828", "-0.829",
282 "-0.830", "-0.831", "-0.832", "-0.833", "-0.834", "-0.835", "-0.836", "-0.837", "-0.838", "-0.839",
283 "-0.840", "-0.841", "-0.842", "-0.843", "-0.844", "-0.845", "-0.846", "-0.847", "-0.848", "-0.849",
284 "-0.850", "-0.851", "-0.852", "-0.853", "-0.854", "-0.855", "-0.856", "-0.857", "-0.858", "-0.859",
285 "-0.860", "-0.861", "-0.862", "-0.863", "-0.864", "-0.865", "-0.866", "-0.867", "-0.868", "-0.869",
286 "-0.870", "-0.871", "-0.872", "-0.873", "-0.874", "-0.875", "-0.876", "-0.877", "-0.878", "-0.879",
287 "-0.880", "-0.881", "-0.882", "-0.883", "-0.884", "-0.885", "-0.886", "-0.887", "-0.888", "-0.889",
288 "-0.890", "-0.891", "-0.892", "-0.893", "-0.894", "-0.895", "-0.896", "-0.897", "-0.898", "-0.899",
289 "-0.900", "-0.901", "-0.902", "-0.903", "-0.904", "-0.905", "-0.906", "-0.907", "-0.908", "-0.909",
290 "-0.910", "-0.911", "-0.912", "-0.913", "-0.914", "-0.915", "-0.916", "-0.917", "-0.918", "-0.919",
291 "-0.920", "-0.921", "-0.922", "-0.923", "-0.924", "-0.925", "-0.926", "-0.927", "-0.928", "-0.929",
292 "-0.930", "-0.931", "-0.932", "-0.933", "-0.934", "-0.935", "-0.936", "-0.937", "-0.938", "-0.939",
293 "-0.940", "-0.941", "-0.942", "-0.943", "-0.944", "-0.945", "-0.946", "-0.947", "-0.948", "-0.949",
294 "-0.950", "-0.951", "-0.952", "-0.953", "-0.954", "-0.955", "-0.956", "-0.957", "-0.958", "-0.959",
295 "-0.960", "-0.961", "-0.962", "-0.963", "-0.964", "-0.965", "-0.966", "-0.967", "-0.968", "-0.969",
296 "-0.970", "-0.971", "-0.972", "-0.973", "-0.974", "-0.975", "-0.976", "-0.977", "-0.978", "-0.979",
297 "-0.980", "-0.981", "-0.982", "-0.983", "-0.984", "-0.985", "-0.986", "-0.987", "-0.988", "-0.989",
298 "-0.990", "-0.991", "-0.992", "-0.993", "-0.994", "-0.995", "-0.996", "-0.997", "-0.998", "-0.999",
299 "-1.000", "-1.001", "-1.002", "-1.003", "-1.004", "-1.005", "-1.006", "-1.007", "-1.008", "-1.009",
300 "-1.010", "-1.011", "-1.012", "-1.013", "-1.014", "-1.015", "-1.016", "-1.017", "-1.018", "-1.019",
301 "-1.020", "-1.021", "-1.022", "-1.023", "-1.024", "-1.025", "-1.026", "-1.027", "-1.028", "-1.029",
302 "-1.030", "-1.031", "-1.032", "-1.033", "-1.034", "-1.035", "-1.036", "-1.037", "-1.038", "-1.039",
303 "-1.040", "-1.041", "-1.042", "-1.043", "-1.044", "-1.045", "-1.046", "-1.047", "-1.048", "-1.049",
304 "-1.050", "-1.051", "-1.052", "-1.053", "-1.054", "-1.055", "-1.056", "-1.057", "-1.058", "-1.059",
305 "-1.060", "-1.061", "-1.062", "-1.063", "-1.064", "-1.065", "-1.066", "-1.067", "-1.068", "-1.069",
306 "-1.070", "-1.071", "-1.072", "-1.073", "-1.074", "-1.075", "-1.076", "-1.077", "-1.078", "-1.079",
307 "-1.080", "-1.081", "-1.082", "-1.083", "-1.084", "-1.085", "-1.086", "-1.087", "-1.088", "-1.089",
308 "-1.090", "-1.091", "-1.092", "-1.093", "-1.094", "-1.095", "-1.096", "-1.097", "-1.098", "-1.099",
309 "-1.100", "-1.101", "-1.102", "-1.103", "-1.104", "-1.105", "-1.106", "-1.107", "-1.108", "-1.109",
310 "-1.110", "-1.111", "-1.112", "-1.113", "-1.114", "-1.115", "-1.116", "-1.117", "-1.118", "-1.119",
311 "-1.120", "-1.121", "-1.122", "-1.123", "-1.124", "-1.125", "-1.126", "-1.127", "-1.128", "-1.129",
312 "-1.130", "-1.131", "-1.132", "-1.133", "-1.134", "-1.135", "-1.136", "-1.137", "-1.138", "-1.139",
313 "-1.140", "-1.141", "-1.142", "-1.143", "-1.144", "-1.145", "-1.146", "-1.147", "-1.148", "-1.149",
314 "-1.150", "-1.151", "-1.152", "-1.153", "-1.154", "-1.155", "-1.156", "-1.157", "-1.158", "-1.159",
315 "-1.160", "-1.161", "-1.162", "-1.163", "-1.164", "-1.165", "-1.166", "-1.167", "-1.168", "-1.169",
316 "-1.170", "-1.171", "-1.172", "-1.173", "-1.174", "-1.175", "-1.176", "-1.177", "-1.178", "-1.179",
317 "-1.180", "-1.181", "-1.182", "-1.183", "-1.184", "-1.185", "-1.186", "-1.187", "-1.188", "-1.189",
318 "-1.190", "-1.191", "-1.192", "-1.193", "-1.194", "-1.195", "-1.196", "-1.197", "-1.198", "-1.199",
319 "-1.200", "-1.201", "-1.202", "-1.203", "-1.204", "-1.205", "-1.206", "-1.207", "-1.208", "-1.209",
320 "-1.210", "-1.211", "-1.212", "-1.213", "-1.214", "-1.215", "-1.216", "-1.217", "-1.218", "-1.219",
321 "-1.220", "-1.221", "-1.222", "-1.223", "-1.224", "-1.225", "-1.226", "-1.227", "-1.228", "-1.229",
322 "-1.230", "-1.231", "-1.232", "-1.233", "-1.234", "-1.235", "-1.236", "-1.237", "-1.238", "-1.239",
323 "-1.240", "-1.241", "-1.242", "-1.243", "-1.244", "-1.245", "-1.246", "-1.247", "-1.248", "-1.249",
324 "-1.250"};
325 return normalized_to_float_str_arr[raw_to_normalized(raw)];
326}
327
328FLASHMEM void daq::enable() { details::flexio::get_flexio()->port().CTRL |= FLEXIO_CTRL_FLEXEN; }
329
330FLASHMEM void daq::disable() { details::flexio::get_flexio()->port().CTRL &= ~FLEXIO_CTRL_FLEXEN; }
331
332FLASHMEM void daq::reset() {
333 disable();
334 details::flexio::get_flexio()->port().CTRL |= FLEXIO_CTRL_SWRST;
335 delayNanoseconds(100);
336 details::flexio::get_flexio()->port().CTRL &= ~FLEXIO_CTRL_SWRST;
337 delayNanoseconds(100);
338}
339
340std::array<int16_t, daq::NUM_CHANNELS> daq::details::raw_zero_offsets = {0};
341
342FLASHMEM status daq::details::flexio::_init_once() {
343 // Configure and enable clock
344 get_flexio()->setClockSettings(3, 0, 0);
345 get_flexio()->hardware().clock_gate_register |= get_flexio()->hardware().clock_gate_mask;
346
347 // Put MOSI pins into flexio mode
348 uint8_t _flexio_pin_cnvst = get_flexio()->mapIOPinToFlexPin(PIN_CNVST);
349 uint8_t _flexio_pin_clk = get_flexio()->mapIOPinToFlexPin(PIN_CLK);
350 uint8_t _flexio_pin_gate = get_flexio()->mapIOPinToFlexPin(PIN_GATE);
351 // Check if any of the pins could not be mapped to the same FlexIO module
352 if (_flexio_pin_cnvst == 0xff or _flexio_pin_clk == 0xff or _flexio_pin_gate == 0xff)
353 return status("Could not map pins to FlexIO module.");
354 get_flexio()->setIOPinToFlexMode(PIN_CNVST);
355 get_flexio()->setIOPinToFlexMode(PIN_CLK);
356 get_flexio()->setIOPinToFlexMode(PIN_GATE);
357
358 // Put MISO pins into flexio mode
359 for (auto pin_miso : PINS_MISO) {
360 if (get_flexio()->mapIOPinToFlexPin(pin_miso) == 0xff)
361 return status("Could not map pins to FlexIO module.");
362 get_flexio()->setIOPinToFlexMode(pin_miso);
363 }
364
365 return status::success();
366}
367
368FLASHMEM void daq::details::flexio::_init_timers() {
369 get_flexio()->port().TIMCTL[_gated_timer_idx] = 0;
370 get_flexio()->port().TIMCFG[_gated_timer_idx] = 0;
371 get_flexio()->port().TIMCMP[_gated_timer_idx] = 0;
372
373 get_flexio()->port().TIMCTL[_sample_timer_idx] = 0;
374 get_flexio()->port().TIMCFG[_sample_timer_idx] = 0;
375 get_flexio()->port().TIMCMP[_sample_timer_idx] = 0;
376
377 get_flexio()->port().TIMCTL[_cnvst_timer_idx] =
378 FLEXIO_TIMCTL_PINSEL(get_flexio()->mapIOPinToFlexPin(PIN_CNVST)) | FLEXIO_TIMCTL_PINCFG(0b11) |
379 FLEXIO_TIMCTL_TRGSRC | FLEXIO_TIMCTL_TRGSEL(4 * _sample_timer_idx + 3) | FLEXIO_TIMCTL_TIMOD(0b10);
380 get_flexio()->port().TIMCFG[_cnvst_timer_idx] = FLEXIO_TIMCFG_TIMDIS(0b010) | FLEXIO_TIMCFG_TIMENA(0b111);
381 get_flexio()->port().TIMCMP[_cnvst_timer_idx] = 0x0000'10'FF;
382
383 // Add a delay timer to control delay between CNVST and first CLK.
384 // Basically a second CNVST timer which is slightly longer and used to trigger first CLK.
385 get_flexio()->port().TIMCTL[_delay_timer_idx] =
386 FLEXIO_TIMCTL_TRGSRC | FLEXIO_TIMCTL_TRGSEL(4 * _sample_timer_idx + 3) | FLEXIO_TIMCTL_TIMOD(0b11);
387 get_flexio()->port().TIMCFG[_delay_timer_idx] = FLEXIO_TIMCFG_TIMDIS(0b010) | FLEXIO_TIMCFG_TIMENA(0b111);
388 get_flexio()->port().TIMCMP[_delay_timer_idx] = 300;
389
390 get_flexio()->port().TIMCTL[_clk_timer_idx] =
391 FLEXIO_TIMCTL_PINSEL(get_flexio()->mapIOPinToFlexPin(PIN_CLK)) | FLEXIO_TIMCTL_PINCFG(0b11) |
392 FLEXIO_TIMCTL_TRGSRC | FLEXIO_TIMCTL_TRGSEL(4 * _delay_timer_idx + 3) | FLEXIO_TIMCTL_TRGPOL |
393 FLEXIO_TIMCTL_TIMOD(0b01);
394 get_flexio()->port().TIMCFG[_clk_timer_idx] = FLEXIO_TIMCFG_TIMDIS(0b010) | FLEXIO_TIMCFG_TIMENA(0b110);
395 // langsam
396 // flexio->port().TIMCMP[_clk_timer_idx] = 0x0000'1F'60;
397 // vielfaches von bit-bang algorithm:
398 get_flexio()->port().TIMCMP[_clk_timer_idx] = 0x0000'1B'07;
399 // maximal schnell
400 // flexio->port().TIMCMP[_clk_timer_idx] = 0x0000'1F'05;
401}
402
403FLASHMEM void daq::details::flexio::_init_shifters() {
404 for (auto _pin_miso_idx = 0u; _pin_miso_idx < PINS_MISO.size(); _pin_miso_idx++) {
405 // Trigger all shifters from CLK
406 get_flexio()->port().SHIFTCTL[_pin_miso_idx] =
407 FLEXIO_SHIFTCTL_TIMSEL(_clk_timer_idx) | FLEXIO_SHIFTCTL_TIMPOL |
408 FLEXIO_SHIFTCTL_PINSEL(get_flexio()->mapIOPinToFlexPin(PINS_MISO[_pin_miso_idx])) |
409 FLEXIO_SHIFTCTL_SMOD(1);
410 get_flexio()->port().SHIFTCFG[_pin_miso_idx] = 0;
411 }
412}
413
414FLASHMEM status daq::init() {
415 RETURN_IF_FAILED(details::flexio::_init_once());
416 details::flexio::_init_timers();
417 details::flexio::_init_shifters();
418 enable();
419 return status::success();
420}
421
423 LOG(ANABRID_DEBUG_CALIBRATION, __PRETTY_FUNCTION__);
424 LOG(ANABRID_DEBUG_CALIBRATION, "Resetting current ADC connections...");
425 // Disconnect all signal connections in ADC switching matrix to force them to a zero
426 auto old_adc_channels = carrier.get_adc_channels();
427 carrier.reset_adc_channels();
428 // Ensure the ADC bus is actually the one connected to the ADCs (and not the SH gain measurement)
429 auto old_adc_bus = carrier.ctrl_block->get_adc_bus();
430 carrier.ctrl_block->reset_adc_bus();
431 // Write to hardware
432 if (!carrier.write_to_hardware())
433 return status("Error writing disconnect of ADCs to hardware.");
434
435 // Read zero offsets and save them
436 LOG(ANABRID_DEBUG_CALIBRATION, "Reading ADC zero offsets:");
437 auto zeros_raw = daq::average(daq::sample_raw);
438 std::transform(zeros_raw.begin(), zeros_raw.end(), details::raw_zero_offsets.begin(),
439 [](auto zero_raw) { return details::RAW_ZERO_IDEAL - zero_raw; });
440 for (auto raw_zero_offset: details::raw_zero_offsets)
441 LOG(ANABRID_DEBUG_CALIBRATION, raw_zero_offset);
442
443 // Reset previous changes
444 LOG(ANABRID_DEBUG_CALIBRATION, "Restoring previous ADC connections...");
445 static_cast<void>(carrier.set_adc_channels(old_adc_channels));
446 carrier.ctrl_block->set_adc_bus(old_adc_bus);
447 // Write to hardware
448 if (!carrier.write_to_hardware())
449 return status("Error writing previous connections of ADCs to hardware.");
450
451 // Sanity check, otherwise return successful
452 if (std::any_of(details::raw_zero_offsets.begin(), details::raw_zero_offsets.end(),
453 [](auto value) { return abs(value) > 100; }))
454 return status("Zero offsets of ADCs are suspiciously large.");
455 return status::success();
456}
457
458float daq::raw_to_float(const uint16_t raw, const int16_t raw_zero_offset) {
459 return ((static_cast<float>(raw + raw_zero_offset) - details::RAW_MINUS_ONE_POINT_TWO_FIVE) /
460 (details::RAW_PLUS_ONE_POINT_TWO_FIVE - details::RAW_MINUS_ONE_POINT_TWO_FIVE)) *
461 -2.5f +
462 1.25f;
463}
464
465std::array<float, daq::NUM_CHANNELS> daq::raw_to_float(std::array<uint16_t, NUM_CHANNELS> raw) {
466 static_assert(NUM_CHANNELS == 8, "Adapt raw_to_float when changing NUM_CHANNELS.");
467 // Maybe easier to optimize for the compiler than std::transform
468 return {
469 raw_to_float(raw[0], details::raw_zero_offsets[0]), raw_to_float(raw[1], details::raw_zero_offsets[1]),
470 raw_to_float(raw[2], details::raw_zero_offsets[2]), raw_to_float(raw[3], details::raw_zero_offsets[3]),
471 raw_to_float(raw[4], details::raw_zero_offsets[4]), raw_to_float(raw[5], details::raw_zero_offsets[5]),
472 raw_to_float(raw[6], details::raw_zero_offsets[6]), raw_to_float(raw[7], details::raw_zero_offsets[7])};
473}
474
475std::array<uint16_t, daq::NUM_CHANNELS> daq::raw_to_offset_corrected(std::array<uint16_t, NUM_CHANNELS> raw) {
476 static_assert(NUM_CHANNELS == 8, "Adapt raw_to_corrected when changing NUM_CHANNELS.");
477 // Maybe easier to optimize for the compiler than std::transform
478 return {static_cast<uint16_t>(raw[0] + details::raw_zero_offsets[0]), static_cast<uint16_t>(raw[1] + details::raw_zero_offsets[1]),
479 static_cast<uint16_t>(raw[2] + details::raw_zero_offsets[2]), static_cast<uint16_t>(raw[3] + details::raw_zero_offsets[3]),
480 static_cast<uint16_t>(raw[4] + details::raw_zero_offsets[4]), static_cast<uint16_t>(raw[5] + details::raw_zero_offsets[5]),
481 static_cast<uint16_t>(raw[6] + details::raw_zero_offsets[6]), static_cast<uint16_t>(raw[7] + details::raw_zero_offsets[7])};
482}
483
484FLASHMEM std::array<uint16_t, daq::NUM_CHANNELS> daq::sample_raw() {
485 using namespace details::flexio;
486
487 // Clear SHIFTSTAT (by writing 0xFF (sic!)), which might be partially set by a previous acquisition
488 get_flexio()->port().SHIFTSTAT = 0xFF;
489
490 // Disable and reset _sample_timer_idx
491 get_flexio()->port().TIMCTL[_sample_timer_idx] = 0;
492 get_flexio()->port().TIMCFG[_sample_timer_idx] = 0;
493 delayNanoseconds(42);
494 // Generate just one sample pulse
495 get_flexio()->port().TIMCMP[_sample_timer_idx] = 1;
496 get_flexio()->port().TIMCTL[_sample_timer_idx] = FLEXIO_TIMCTL_TIMOD(0b11);
497 get_flexio()->port().TIMCFG[_sample_timer_idx] = FLEXIO_TIMCFG_TIMDIS(0b010);
498
499 // Wait until shift buffer is filled or timeout in case of hardware errors
500 for (auto _ = 0u; _ < 50; _++) {
501 if (get_flexio()->port().SHIFTSTAT & 0xFF)
502 return {static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[0]),
503 static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[1]),
504 static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[2]),
505 static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[3]),
506 static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[4]),
507 static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[5]),
508 static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[6]),
509 static_cast<uint16_t>(get_flexio()->port().SHIFTBUFBIS[7])};
510 delayNanoseconds(100);
511 }
512 // Returning zero in error case may hide the error
513 // Of course, returning RAW_SUSPICIOUS_VALUE is only slightly better :)
514 return {details::RAW_SUSPICIOUS_VALUE, details::RAW_SUSPICIOUS_VALUE, details::RAW_SUSPICIOUS_VALUE,
515 details::RAW_SUSPICIOUS_VALUE, details::RAW_SUSPICIOUS_VALUE, details::RAW_SUSPICIOUS_VALUE,
516 details::RAW_SUSPICIOUS_VALUE, details::RAW_SUSPICIOUS_VALUE};
517}
518
519FLASHMEM std::array<float, daq::NUM_CHANNELS> daq::sample() { return raw_to_float(sample_raw()); }
520
521FLASHMEM std::array<float, daq::NUM_CHANNELS> daq::average(size_t samples, unsigned int delay_us) {
522 return average(daq::sample, samples, delay_us);
523}
524
526 return {run, data_handler};
527}
528
529FLASHMEM unsigned int daq::stream::details::get_number_of_data_vectors_in_buffer() {
530 // Note that this does not consider whether these have been streamed out yet
531 return channel.TCD->BITER - channel.TCD->CITER;
532}
533
534FLASHMEM std::array<volatile uint32_t, daq::stream::details::BUFFER_SIZE> daq::stream::details::get_buffer() {
535 return buffer;
536}
537
538// NOT FLASHMEM
539status daq::stream::process(const run::Run &run, run::RunDataHandler *const data_handler, bool partial) {
540 // Pointer to the part of the buffer which (may) contain partial data at end of acquisition time
541 static auto partial_buffer_part = details::buffer.data();
542
543 if (!run.daq_config)
544 return status("Invalid DAQ configuration.");
545 if (details::overflow_data)
546 return status("DMA overflow.");
547
548 // Default values for streaming
549 volatile uint32_t *active_buffer_part;
550 size_t outer_count = details::BUFFER_SIZE / run.daq_config.get_num_channels() / 2;
551
552 // Change streaming parameters depending on whether the first or second half of buffer is streamed
553 if (details::first_data) {
554 active_buffer_part = details::buffer.data();
555 partial_buffer_part = details::buffer.data() + details::BUFFER_SIZE / 2;
556 details::first_data = false;
557 } else if (details::last_data) {
558 active_buffer_part = details::buffer.data() + details::BUFFER_SIZE / 2;
559 partial_buffer_part = details::buffer.data();
560 details::last_data = false;
561 } else if (partial) {
562 // Stream the remaining partially filled part of the buffer.
563 // This should be done exactly once, after the data acquisition stopped.
564 active_buffer_part = partial_buffer_part;
565 if (partial_buffer_part == details::buffer.data())
566 // If we have streamed out the second part the last time,
567 // the partial data is in the first part of the buffer
568 // and get_number_of_data_vectors_in_buffer returns only
569 // the number of partial data vectors to stream.
570 outer_count = details::get_number_of_data_vectors_in_buffer();
571 else
572 // If we have streamed out the first part the last time,
573 // the partial data is in the second half,
574 // and get_number_of_data_vectors_in_buffer does not consider this
575 // and returns number of vectors in first_half plus number of partials
576 // in second half, and we have to subtract the number in the first half.
577 outer_count = details::get_number_of_data_vectors_in_buffer() - outer_count;
578 // In case of multi-cycle OP computations (e.g. quantum circuits), we want to
579 // do a partial stream after each OP cycle. When acquisition continues in the next cycle,
580 // it is easiest to fill the buffer from the beginning again and reset all relevant counters.
581 details::channel.TCD->CITER = details::channel.TCD->BITER;
582 details::channel.TCD->DADDR = details::buffer.data();
583 details::first_data = details::last_data = details::overflow_data = false;
584 if (!outer_count) {
585 return status::success();
586 }
587 } else
588 return status::success();
589
590 data_handler->handle(active_buffer_part, outer_count, run.daq_config.get_num_channels(), run);
591 return status::success();
592}
593
595 details::channel.disable();
596
597 // TODO: In case of streams not synchronized with OP state,
598 // this function should probably actually stop the timers.
599
600 auto flexio = FlexIOHandler::flexIOHandler_list[1];
601 // Disable DMA trigger generation
602 flexio->port().SHIFTSDEN = 0;
603 // Clear global data for ::daq::dma::interrupt
604 details::run_data_handler = nullptr;
605 details::run = nullptr;
606 details::first_data = details::last_data = details::overflow_data = false;
607
608 // Check shifter errors
609 // Unused channels (when get_num_channels() < 8) always go into SHIFTERR,
610 // since they are written to due to always being active, but not read from by the DMA.
611 uint32_t _shifterr_mask =
612 (run.daq_config.get_num_channels() > 1) ? ((1u << run.daq_config.get_num_channels()) - 1) : 1u;
613 if (flexio->port().SHIFTERR & _shifterr_mask)
614 return status("SHIFTERR was asserted during stream.");
615 // Clear all SHIFTERR
616 flexio->port().SHIFTERR = 0xFF;
617
618 return status::success();
619}
620
621FLASHMEM status daq::stream::start(const run::Run &run, run::RunDataHandler *const data_handler) {
622 using namespace daq::details::flexio;
623 // Care: FlexIO clock is enabled in _init_once() and this function will get stuck without it
624
625 disable();
626 // Reset is necessary before each continuous acquisition,
627 // otherwise internal counter values are not reset and result in unwanted behaviour
628 reset();
629 _init_timers();
630 _init_shifters();
631
632 auto _flexio_pin_gate = get_flexio()->mapIOPinToFlexPin(daq::details::PIN_GATE);
633 get_flexio()->port().TIMCTL[_gated_timer_idx] = FLEXIO_TIMCTL_TRGSEL(2 * _flexio_pin_gate) |
634 FLEXIO_TIMCTL_TRGPOL | FLEXIO_TIMCTL_TRGSRC |
635 FLEXIO_TIMCTL_TIMOD(0b11);
636 get_flexio()->port().TIMCFG[_gated_timer_idx] = FLEXIO_TIMCFG_TIMDIS(0b011) | FLEXIO_TIMCFG_TIMENA(0b110);
637 get_flexio()->port().TIMCMP[_gated_timer_idx] = 239;
638
639 get_flexio()->port().TIMCTL[_sample_timer_idx] =
640 FLEXIO_TIMCTL_TRGSEL(4 * _gated_timer_idx + 3) | FLEXIO_TIMCTL_TRGSRC | FLEXIO_TIMCTL_TIMOD(0b11);
641 get_flexio()->port().TIMCFG[_sample_timer_idx] = FLEXIO_TIMCFG_TIMDEC(0b01) | FLEXIO_TIMCFG_TIMENA(0b110);
642 get_flexio()->port().TIMCMP[_sample_timer_idx] = (1'000'000 / run.daq_config.get_sample_rate()) * 2 - 1;
643
644 enable();
645
646 // Update global pointers for ::daq::dma::interrupt
647 details::run_data_handler = data_handler;
648 details::run = &run;
649
650 /*
651 * Configure DMA
652 */
653
654 // Select shifter zero to generate DMA events.
655 // Which shifter is selected should not matter, as long as it is used.
656 uint8_t shifter_dma_idx = 0;
657 // Set shifter to generate DMA events.
658 get_flexio()->port().SHIFTSDEN = 1 << shifter_dma_idx;
659 // Configure DMA channel
660 details::channel.begin();
661
662 // Configure minor and major loop of DMA process.
663 // One DMA request (SHIFTBUF store) triggers one major loop.
664 // A major loop consists of several minor loops.
665 // For each loop, source address and destination address is adjusted and data is copied.
666 // The number of minor loops is implicitly defined by how much data they should copy.
667 // The approach here is to use the minor loops to copy all shift registers when one triggers the DMA.
668 // That means each major loop copies over NUM_CHANNELS data points.
669 // Triggering multiple major loops fills up the ring buffer.
670 // Once all major loops are done, the ring buffer is full and an interrupt is triggered to handle the data.
671 // For such configurations DMAChannel provides sourceCircular() and destinationCircular() functions,
672 // which are not quite able to handle our case (BITER/CITER and ATTR_DST must be different).
673 // That's why we do it by hand :)
674
675 // BITER "beginning iteration count" is the number of major loops.
676 // Each major loop fills part (see TCD->NBYTES) of the ring buffer.
677 details::channel.TCD->BITER = details::buffer.size() / run.daq_config.get_num_channels();
678 // CITER "current major loop iteration count" is the current number of major loops left to perform.
679 // It can be used to check progress of the process. It's reset to BITER whe we filled the buffer once.
680 details::channel.TCD->CITER = details::buffer.size() / run.daq_config.get_num_channels();
681
682 // Configure source address and its adjustments.
683 // We want to circularly copy from SHIFTBUFBIS.
684 // In principle, we are only interested in the last 16 bits of each SHIFTBUFBIS.
685 // Unfortunately, configuring it in such a way was not successful -- maybe in the future.
686 // Instead, we copy the full 32 bit of data.
687 // SADDR "source address start" is where the DMA process starts.
688 // Set it to the beginning of the SHIFTBUFBIS array.
689 details::channel.TCD->SADDR = get_flexio()->port().SHIFTBUFBIS;
690 // NBYTES "minor byte transfer count" is the number of bytes transferred in one minor loop.
691 // Set it such that the whole SHIFTBUFBIS array is copied, which is 4 bytes * NUM_CHANNELS
692 details::channel.TCD->NBYTES = 4 * run.daq_config.get_num_channels();
693 // SOFF "source address offset" is the offset added onto SADDR for each minor loop.
694 // Set it to 4 bytes, equaling the 32 bits each shift register has.
695 details::channel.TCD->SOFF = 4;
696 // ATTR_SRC "source address attribute" is an attribute setting the circularity and the transfer size.
697 // The format is [5bit MOD][3bit SIZE].
698 // The 5bit MOD is the number of lower address bites allowed to change, effectively circling back to SADDR.
699 // The 3bit SIZE defines the source data transfer size.
700 // Set MOD to 5, allowing the address bits to change until the end of the SHIFTBUFBIS array and cycling.
701 // MOD = 5 because 2^5 = 32, meaning address cycles after 32 bytes, which are 8*32 bits.
702 // Set SIZE to 0b010 for 32 bit transfer size.
703 uint8_t MOD_SRC = __builtin_ctz(run.daq_config.get_num_channels() * 4);
704 details::channel.TCD->ATTR_SRC = ((MOD_SRC & 0b11111) << 3) | 0b010;
705 // SLAST "last source address adjustment" is an adjustment applied to SADDR after all major iterations.
706 // We don't want any adjustments, since we already use ATTR_SRC to implement a circular buffer.
707 details::channel.TCD->SLAST = 0;
708
709 // Configure destination address and its adjustments.
710 // We want to circularly copy into a memory ring buffer.
711 // Since we always copy 32 bit from SADDR, we will have the memory buffer in a 32 bit layout as well,
712 // even though we are again only interested in the lower 16 bits.
713 // DADDR "destination address start" is the start of the destination ring buffer.
714 // Set to address of ring buffer.
715 details::channel.TCD->DADDR = details::buffer.data();
716 // DOOFF "destination address offset" is the offset added to DADDR for each minor loop.
717 // Set to 4 bytes, equaling the 32 bits each shift register has.
718 details::channel.TCD->DOFF = 4;
719 // ATTR_SRC "destination address attribute" is analogous to ATTR_SRC
720 // Set first 5 bit MOD according to size of ring buffer.
721 // Since only power-of-two number of channels N<=8 is allowed, N*NUM_CHANNELS will always fit for each N.
722 // Set last 3 bits to 0b010 for 32 bit transfer size.
723 uint8_t MOD = __builtin_ctz(details::BUFFER_SIZE * 4);
724 // Check if memory buffer address is aligned such that MOD lower bits are zero (maybe this is too pedantic?)
725 if (reinterpret_cast<uintptr_t>(details::buffer.data()) & ~(~static_cast<uintptr_t>(0) << MOD)) {
726 return ("DMA buffer memory range is not sufficiently aligned.");
727 }
728 details::channel.TCD->ATTR_DST = ((MOD & 0b11111) << 3) | 0b010;
729 // DLASTSGA "last destination address adjustment or next TCD" is similar to SLAST.
730 // We don't want any adjustments, since we already use ATTR_DST to implement a circular buffer.
731 details::channel.TCD->SLAST = 0;
732
733 // Call an interrupt when done
734 details::channel.attachInterrupt(details::interrupt);
735 details::channel.interruptAtCompletion();
736 details::channel.interruptAtHalf();
737 // Trigger from "shifter full" DMA event
738 details::channel.triggerAtHardwareEvent(get_flexio()->shiftersDMAChannel(shifter_dma_idx));
739 // Enable dma channel
740 details::channel.enable();
741 if (details::channel.error()) {
742 return ("dma::channel.error");
743 }
744
745 return status::success();
746}
Top-level hierarchy controlled by a single microcontroller.
Definition carrier.h:38
Automatically starts and stops a continuous acquisition in the current scope.
Definition daq.h:131
virtual void handle(volatile uint32_t *data, size_t outer_count, size_t inner_count, const run::Run &run)=0
Definition run.h:47
A recoverable error, inspired from https://abseil.io/docs/cpp/guides/status and https://github....
Definition error.h:35
static status success()
Syntactic sugar for success.
Definition error.h:104
utils::status status
Definition daq.h:28
#define RETURN_IF_FAILED(status)
Definition error.h:12
uint32_t
Definition flasher.cpp:195
#define LOG(LOG_FLAG, message)
Definition logging.h:36
Scope get(const run::Run &run, run::RunDataHandler *const data_handler)
Construct and return a scoped continuous acquisition. See the introductory example on how to use.
Definition daq.cpp:525
status stop(const run::Run &run)
Manually stop a previously started continuous data acquisition. Consider using get() instead.
Definition daq.cpp:594
status start(const run::Run &run, run::RunDataHandler *const data_handler)
Manually start a continuous data acquisition. You must stop it with stop(). Consider using get() inst...
Definition daq.cpp:621
status process(const run::Run &run, run::RunDataHandler *const data_handler, bool partial=false)
Manually process incoming data during a continuous acquisition.
Definition daq.cpp:539
Routines for data acquisition (DAQ) using the internal analog-to-digital converters (ADC).
Definition base.h:12
std::array< uint16_t, 8 > raw_to_offset_corrected(std::array< uint16_t, NUM_CHANNELS > raw)
Convert a raw vector to one with previously calibrated offsets removed.
Definition daq.cpp:475
void reset()
Reset the daq system, clearing all internal state.
Definition daq.cpp:332
status init()
Initialize the daq system. Needs to be called once before any sampling can happen.
Definition daq.cpp:414
const char * raw_to_str(uint16_t raw)
Convert a single raw value to a formatted string with 0.001 step size with a look-up table.
Definition daq.cpp:72
float raw_to_float(const uint16_t raw, const int16_t raw_zero_offset)
Convert a single raw value to float.
Definition daq.cpp:458
constexpr uint8_t NUM_CHANNELS
Number of channels available in the daq system.
Definition base.h:15
std::array< T, NUM_CHANNELS > average(std::array< T, NUM_CHANNELS >(*sample_function)(), size_t samples=100, unsigned int delay_us=33)
Acquire an averaged sample (either raw or float).
Definition daq.h:96
std::array< float, NUM_CHANNELS > sample()
Acquire one one-demand sample. Can not be used during a continuous acquisition.
Definition daq.cpp:519
status calibrate(carrier::Carrier &carrier)
Calibrate the daq system.
Definition daq.cpp:422
size_t raw_to_normalized(uint16_t raw)
Convert a single raw value to a so-called "normalized" value in range [0, 2500], used in raw_to_str()...
Definition daq.cpp:15
void disable()
Disable the daq system.
Definition daq.cpp:330
std::array< uint16_t, NUM_CHANNELS > sample_raw()
Acquire one one-demand raw sample. Can not be used during a continuous acquisition.
Definition daq.cpp:484
void enable()
Enable the daq system. Automatically done by init().
Definition daq.cpp:328
Definition run.h:14