REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
run_manager.cpp
Go to the documentation of this file.
1#include "run/run_manager.h"
2#include "mode/counters.h"
3
4#include <Arduino.h>
5#include <cmath>
6#include <cstdlib>
7
8#include <daq/daq.h>
9#include <utils/logging.h>
10
11// This is an interim hacky solution to introduce another kind of RunDataHandler
12#include <mode/mode.h>
13#include <mode/teensy/mode.h>
14#include <protocol/protocol_oob.h>
15#include <run/run.h>
16
17namespace run {
18
19// NOT FLASHMEM
20void run_next_flexio(Run &run, RunStateChangeHandler *state_change_handler, RunDataHandler *run_data_handler) {
21 run_data_handler->prepare(run);
22 bool daq_error = false;
23
25 if (!mode::FlexIOControl::init(run.config.ic_time, run.config.op_time,
26 run.config.halt_on_overload ? mode::OnOverload::HALT
27 : mode::OnOverload::IGNORE,
28 mode::OnExtHalt::IGNORE)) {
29 LOG_ERROR("Error while initializing state machine.")
30 auto change = run.to(RunState::ERROR, 0);
31 state_change_handler->handle(change, run);
32 return;
33 }
34
35 auto data_stream = daq::stream::get(run, run_data_handler);
36 run_data_handler->init();
37
39 delayMicroseconds(1);
40
42 if (!data_stream.process()) {
43 LOG_ERROR("Streaming error, most likely data overflow.");
44 daq_error = true;
45 break;
46 }
47 }
49
50 // When a data sample must be gathered very close to the end of OP duration,
51 // it takes a few microseconds for it to end up in the DMA buffer.
52 // This is hard to check for, since the DMA active flag is only set once the DMA
53 // is triggered by the last CLK pulse.
54 // Easiest solution is to wait for it.
55 delayMicroseconds(20);
56 // Stream out remaining partially filled buffer
57 if (!data_stream.process(true)) {
58 LOG_ERROR("Streaming error during final partial stream.");
59 daq_error = true;
60 }
61
62 auto actual_op_time = mode::FlexIOControl::get_actual_op_time();
63
64 auto &perf = mode::PerformanceCounter::get();
65 perf.add(mode::Mode::IC, run.config.ic_time / 1000);
66 perf.add(mode::Mode::OP, actual_op_time / 1000);
67 perf.increase_run();
68
69 if (daq_error) {
70 auto change = run.to(RunState::ERROR, actual_op_time);
71 state_change_handler->handle(change, run);
72 return;
73 }
74
75 // DONE
76 auto change = run.to(RunState::DONE, actual_op_time);
77 state_change_handler->handle(change, run);
78}
79
80void RunManager::run_next_hal(Run &run, RunStateChangeHandler *state_change_handler,
81 RunDataHandler *run_data_handler,
82 client::StreamingRunDataNotificationHandler *alt_run_data_handler) {
83
84 if (run.config.streaming)
85 run_next_flexio(run, state_change_handler, run_data_handler);
86 else
87 run_next_traditional(run, state_change_handler, run_data_handler, alt_run_data_handler);
88}
89
90} // namespace run
static void to_end()
Definition mode.cpp:399
static unsigned long long get_actual_op_time()
Definition mode.cpp:461
static bool is_done()
Definition mode.cpp:476
static void reset()
Definition mode.cpp:405
static void force_start()
Definition mode.cpp:373
static bool init(unsigned long long ic_time_ns, unsigned long long op_time_ns, mode::OnOverload on_overload=mode::OnOverload::HALT, mode::OnExtHalt on_ext_halt=mode::OnExtHalt::IGNORE, mode::Sync sync=mode::Sync::NONE)
Definition mode.cpp:95
void run_next_flexio(Run &run, RunStateChangeHandler *state_change_handler, RunDataHandler *run_data_handler)