Feature/source plugins #1

Merged
martino merged 130 commits from feature/source-plugins into main 2026-11-04 07:35:21 +01:00
5 changed files with 24 additions and 4 deletions
Showing only changes of commit 6245811699 - Show all commits

No files matched your search

+2 -1
View File
@@ -137,7 +137,8 @@ whether the handshake may answer status 2 ("code ignored"; one reference accepts
source accepts it); the first frame id; and the maximum frame size. Two further things
are worth a look on a board even though the mock's header does not flag them: the calibration memory layout and
its coefficient type, and the status word's bits, in particular whether the "scan running" bit stays set while the
board waits for a trigger (the source restarts a scan that reads as stopped when auto-restart is on). The DIFF input
board waits for a trigger (with auto-restart on, the source restarts a scan that reads as stopped only when no
trigger is configured, so as not to reset the wait for the edge; this is unverified on hardware). The DIFF input
numbering (channel + 8) and the filler byte after scan start are agreed by both references. The scan overrun count
is approximate: the board does not say how many scans it dropped, so the frame after a restart reports one lost.
Errors (no device, a rejected connection code, a timeout, the scan socket closing) are written to stderr as
+1 -1
View File
@@ -48,7 +48,7 @@ What feeds `Acquisition` is a `DataSource`, one of the registered *kinds*.
`e1608_source` is the `DataSource`; `e1608_kind` and `e1608_panels` are the UI. A change to the wire
never reaches the UI files.
- The E-1608 source runs **everything inside `poll()`** on the producer thread: posted commands, the
connect state machine (Down, Scanning, Halted), the scan read, the 500 ms status check, the digital
connect state machine (Down, Scanning, Halted), the scan read, the 500 ms status check (its not-running restart is skipped when a hardware trigger is configured), the digital
input/counter poll and the 20 ms waveform tick. There is no second thread. A connect attempt (discovery,
handshake, calibration read, scan start) can block `poll()` for as long as the command timeout allows each
step; that delays only the command queue. Every exception is caught inside `poll()`: an escape would end
+17 -1
View File
@@ -186,6 +186,7 @@ void E1608Source::open(SourceSink& sink) {
void E1608Source::close() {
if (state_ == State::Scanning) dev_.scan_stop();
scan_started_ = false;
link_.close();
connected_.store(false, std::memory_order_relaxed);
}
@@ -212,6 +213,15 @@ void E1608Source::note(const std::string& msg) {
}
void E1608Source::fail(const std::string& msg, bool fatal) {
if (scan_started_) {
// The scan may have started before a later connect step failed: tell the board to stop, so it
// is not left scanning with nobody reading. Best effort; it must never throw out of here.
try {
dev_.scan_stop();
} catch (...) {
}
scan_started_ = false;
}
link_.close();
const bool was_up = connected_.exchange(false, std::memory_order_relaxed);
note(msg);
@@ -283,6 +293,7 @@ void E1608Source::connect_and_start() {
}
link_.connect(host, cfg_.port, cfg_.code, cfg_.timeout_ms);
scan_started_ = false;
cal_ = Calibration{};
if (cfg_.calibrate && !dev_.read_calibration(cal_))
note("calibration memory refused; using nominal values");
@@ -419,13 +430,16 @@ void E1608Source::check_status() {
sink_->on_event(SourceEvent::Error, "scan overrun; restarting");
restart_scan();
pending_lost_ = 1;
} else if (!(st & 2) && cfg_.auto_restart) {
} else if (!(st & 2) && cfg_.auto_restart && cfg_.trigger == Trigger::None) {
// With a hardware trigger the board may report "not running" while it waits for the edge;
// restarting then would reset the wait forever, so only the overrun bit restarts the scan.
restart_scan();
}
}
void E1608Source::restart_scan() {
dev_.scan_stop();
scan_started_ = false;
pending_.clear();
for (auto& r : ready_) r.clear();
start_scan();
@@ -437,6 +451,7 @@ void E1608Source::start_scan() {
throw LinkError(LinkError::Kind::Command, "the aggregate rate exceeds 250 kS/s");
try {
dev_.scan_start(queue_, cfg_.aggregate(), cfg_.ext_clock, cfg_.trigger);
scan_started_ = true;
} catch (...) {
// The board may have accepted the start (0x11) before a later step failed (the filler byte):
// tell it to stop, so it is not left scanning with nobody reading.
@@ -444,6 +459,7 @@ void E1608Source::start_scan() {
dev_.scan_stop();
} catch (...) {
}
scan_started_ = false;
throw;
}
}
+1
View File
@@ -124,6 +124,7 @@ class E1608Source final : public DataSource {
E1608Settings cfg_;
SourceSink* sink_ = nullptr;
State state_ = State::Down;
bool scan_started_ = false; ///< a scan start succeeded and no stop has followed
Link link_;
Device dev_{link_};
Calibration cal_;
+3 -1
View File
@@ -327,7 +327,9 @@ class Board:
self.first_conn = time.monotonic()
close_quietly(old)
if first and self.args.drop_after > 0:
threading.Timer(self.args.drop_after, self.drop).start()
timer = threading.Timer(self.args.drop_after, self.drop)
timer.daemon = True
timer.start()
try:
while True:
b = conn.recv(1)