REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
daq.h
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#pragma once
6
7#include <array>
8
9#include <ArduinoJson.h>
10
11#ifdef ARDUINO
12#include <DMAChannel.h>
13#include <FlexIO_t4.h>
14#endif
15
16#include "daq/base.h"
17#include "run/run.h"
18#include "utils/error.h"
19#include "utils/running_avg.h"
20
21namespace carrier {
22
23// Forward declaration for calibration
24class Carrier;
25
26} // namespace carrier
27
29
47namespace daq {
48
50status init();
51
60
62float raw_to_float(const uint16_t raw, const int16_t raw_zero_offset);
64std::array<float, daq::NUM_CHANNELS> raw_to_float(std::array<uint16_t, daq::NUM_CHANNELS> raw);
66std::array<uint16_t, 8> raw_to_offset_corrected(std::array<uint16_t, NUM_CHANNELS> raw);
68size_t raw_to_normalized(uint16_t raw);
71const char *raw_to_str(uint16_t raw);
72
74void enable();
76void disable();
78void reset();
79
81std::array<uint16_t, NUM_CHANNELS> sample_raw();
83std::array<float, NUM_CHANNELS> sample();
84
95template <typename T>
96std::array<T, NUM_CHANNELS> average(std::array<T, NUM_CHANNELS> (*sample_function)(), size_t samples = 100,
97 unsigned int delay_us = 33) {
98 // Prevent overflows when using raw values
99 using T_larger = typename std::conditional<std::is_same<T, uint16_t>::value, uint32_t, T>::type;
100
102 for (size_t i = 0; i < samples; i++) {
103 avg.add(utils::convert<T_larger>(sample_function()));
104 delayMicroseconds(delay_us);
105 }
106 return utils::convert<T>(avg.get_average());
107}
108
110std::array<float, NUM_CHANNELS> average(size_t samples = 100, unsigned int delay_us = 10);
111
113namespace stream {
114
116status start(const run::Run &run, run::RunDataHandler *const data_handler);
118status stop(const run::Run &run);
121status process(const run::Run &run, run::RunDataHandler *const data_handler, bool partial = false);
122
131class Scope {
132public:
134 const run::Run &run;
137
138public:
140 Scope(const run::Run &run, run::RunDataHandler *data_handler, bool start_ = true)
141 : run(run), run_data_handler(data_handler) {
142 if (start_)
143 (void)start(run, run_data_handler);
144 }
145
147 virtual ~Scope() { (void)stop(run); }
148
149 /*
150 * Process incoming data during a continuous acquisition.
151 *
152 * Continuous acquisition fills a ring buffer, which contents are processed with this function.
153 * Data is processed in fixed-size chunks equal to half the size of the internal buffer.
154 *
155 * If enough data for one chunk is available, the process function calls the data handler's handle
156 * function with the appropriate memory destination and size. See run::RunDataHandler::handle for more
157 * details.
158 *
159 * If not enough data is available, the function does nothing and returns immediately,
160 * unless \p partial is set. If \p partial is set, any amount of data currently available is processed
161 * and the ring buffer write position is reset to its beginning.
162 *
163 * You should call process() regularly and call process(partial=true) once at the end.
164 */
165 status process(bool partial = false) { return stream::process(run, run_data_handler, partial); }
166};
167
169Scope get(const run::Run &run, run::RunDataHandler *const data_handler);
170
171namespace details {
172
173// BUFFER_SIZE *must* be a power-of-two number of bytes
174constexpr size_t BUFFER_SIZE = 32 * NUM_CHANNELS;
175
176std::array<volatile uint32_t, BUFFER_SIZE> get_buffer();
177
178unsigned int get_number_of_data_vectors_in_buffer();
179
180} // namespace details
181
182} // namespace stream
183
184namespace details {
185
186static constexpr uint16_t RAW_MINUS_ONE_POINT_TWO_FIVE = 0;
187static constexpr uint16_t RAW_ZERO_IDEAL = 8192;
188static constexpr uint16_t RAW_PLUS_ONE_POINT_TWO_FIVE = 16383;
189static constexpr uint16_t RAW_SUSPICIOUS_VALUE = 11111;
190
191extern std::array<int16_t, NUM_CHANNELS> raw_zero_offsets;
192
193constexpr uint8_t PIN_CNVST = 7;
194constexpr uint8_t PIN_CLK = 6;
195constexpr uint8_t PIN_GATE = 32;
196constexpr std::array<uint8_t, NUM_CHANNELS> PINS_MISO = {34, 35, 36, 37, 11, 10, 9, 8};
197
198namespace flexio {
199
200static constexpr uint8_t _gated_timer_idx = 0;
201static constexpr uint8_t _sample_timer_idx = 1;
202static constexpr uint8_t _cnvst_timer_idx = 2;
203static constexpr uint8_t _delay_timer_idx = 3;
204static constexpr uint8_t _clk_timer_idx = 4;
205
206inline FlexIOHandler *get_flexio() { return FlexIOHandler::flexIOHandler_list[1]; }
207
208status _init_once();
209void _init_timers();
210void _init_shifters();
211
212} // namespace flexio
213
214} // namespace details
215
216} // namespace daq
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
run::RunDataHandler *const run_data_handler
The run::RunDataHandler instance that will handle incoming data via process().
Definition daq.h:136
const run::Run & run
The run associated with this continuous acquisition, relevant for the run's ID and DAQConfig.
Definition daq.h:134
Scope(const run::Run &run, run::RunDataHandler *data_handler, bool start_=true)
Construct a scoped continuous acquisition, starting it by default. Consider using get() instead.
Definition daq.h:140
virtual ~Scope()
Deconstruct a scoped continuous acquisition, stopping it.
Definition daq.h:147
status process(bool partial=false)
Definition daq.h:165
Definition run.h:47
void add(const T &data)
Definition running_avg.h:64
A recoverable error, inspired from https://abseil.io/docs/cpp/guides/status and https://github....
Definition error.h:35
uint32_t
Definition flasher.cpp:195
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
constexpr std::array< Type, Size > convert(const std::array< OtherType, Size > source, const Types... data)
Definition running_avg.h:49