Rename kamil_adc to rph_radar and fix its data path
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
// Exercise the production collector with a test-only SDK and a real PTY.
|
||||
#define main collector_program_main
|
||||
#include "../rph_radar_collector/src/main.cpp"
|
||||
#undef main
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
void test_source_session_restart() {
|
||||
char directory[] = "/tmp/rph-collector-XXXXXX";
|
||||
if (!::mkdtemp(directory)) { fail("mkdtemp failed"); }
|
||||
const std::string tty = std::string(directory) + "/tty", log = std::string(directory) + "/sdk.log";
|
||||
const auto child = ::fork();
|
||||
if (child == 0) {
|
||||
::setenv("RPH_SDK_LOG", log.c_str(), 1);
|
||||
Config cfg;
|
||||
cfg.tty_path = tty;
|
||||
cfg.switching = Json::parse(R"({"input":{"name":"input","driver_mode":"mock","positions":2,"default_position":0,"gpio_chip":"/dev/unused","pin_a":1,"pin_b":2},"output":{"name":"output","driver_mode":"mock","positions":2,"default_position":0,"gpio_chip":"/dev/unused","pin_a":3,"pin_b":4},"combos":[[0,0],[0,1]],"settling_ms":0})");
|
||||
try { ::_exit(run(cfg)); }
|
||||
catch (const std::exception& error) { std::cerr << error.what() << '\n'; ::_exit(2); }
|
||||
}
|
||||
if (child < 0) { std::filesystem::remove_all(directory); fail("collector fork failed"); }
|
||||
int fd = -1, status = 0;
|
||||
std::vector<unsigned char> packets;
|
||||
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(3);
|
||||
bool finished = false;
|
||||
const auto drain = [&]() {
|
||||
unsigned char bytes[4096];
|
||||
while (fd >= 0) {
|
||||
const auto count = ::read(fd, bytes, sizeof(bytes));
|
||||
if (count <= 0) { break; }
|
||||
packets.insert(packets.end(), bytes, bytes + count);
|
||||
}
|
||||
};
|
||||
while (!finished && std::chrono::steady_clock::now() < deadline) {
|
||||
if (fd < 0) { fd = ::open(tty.c_str(), O_RDONLY | O_NONBLOCK); }
|
||||
drain();
|
||||
finished = ::waitpid(child, &status, WNOHANG) == child;
|
||||
if (!finished) { ::usleep(1000); }
|
||||
}
|
||||
drain();
|
||||
if (fd >= 0) { ::close(fd); }
|
||||
if (!finished) { ::kill(child, SIGKILL); (void)::waitpid(child, &status, 0); }
|
||||
std::ifstream file(log);
|
||||
const std::string calls{std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
|
||||
std::filesystem::remove_all(directory);
|
||||
if (!finished || !WIFEXITED(status) || WEXITSTATUS(status)) { fail("SDK session regression did not finish successfully"); }
|
||||
const std::string session = "Create\nOpen\nStreamsStop\nStreamsDisable\nConfigure\nOutCycleLoadStart\nPrepareData\nSend\nOutCycleSetup WAIT_DONE\nStart\nOutCycleStop WAIT_DONE\nStreamsStop\nStreamsDisable\nClose\nFree\n";
|
||||
if (calls != session + session + session + session) { fail("SDK session/DOUT restart order changed: " + calls); }
|
||||
const auto read_le = [&packets](std::size_t offset, unsigned size) {
|
||||
uint64_t value = 0;
|
||||
for (unsigned i = 0; i < size; ++i) { value |= uint64_t{packets.at(offset + i)} << (8 * i); }
|
||||
return value;
|
||||
};
|
||||
unsigned clean = 0, total = 0;
|
||||
for (std::size_t offset = 0; offset < packets.size();) {
|
||||
if (packets.size() - offset < 48 || std::memcmp(packets.data() + offset, "RPH1", 4)) { fail("Invalid SDK fixture packet"); }
|
||||
const auto payload = read_le(offset + 4, 4), dirty = read_le(offset + 44, 4);
|
||||
if (payload != 16 || offset + 48 + payload > packets.size()) { fail("Incomplete phase sweep from SDK fixture"); }
|
||||
++total;
|
||||
if (!dirty) {
|
||||
++clean;
|
||||
if (read_le(offset + 8, 8) != 2 * clean || read_le(offset + 16, 8) != (clean + 1) / 2 ||
|
||||
read_le(offset + 40, 2) != 0 || read_le(offset + 42, 2) != (clean - 1) % 2 ||
|
||||
static_cast<int16_t>(read_le(offset + 52, 2)) != pack_raw_code_to_int16(10000 * clean)) {
|
||||
fail("Old ADC block crossed GPIO change, or source/cycle identity reset");
|
||||
}
|
||||
}
|
||||
offset += 48 + payload;
|
||||
}
|
||||
if (clean != 3 || total != 6) { fail("Expected only new-session full sweeps and dirty initial partials"); }
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
test_source_session_restart();
|
||||
for (const auto* period : {"do8_cycle_period:262145", "do8_cycle_period:4294967295"}) {
|
||||
std::vector<std::string> args{"collector", "profile:phase", "clock:internal", "tty:/tmp/unused",
|
||||
"do1_toggle_per_frame", "do1_pair_subtract_avg", "do8_freq_ref", period};
|
||||
std::vector<char*> argv;
|
||||
for (auto& arg : args) { argv.push_back(arg.data()); }
|
||||
bool rejected = false;
|
||||
try { (void)parse_args(static_cast<int>(argv.size()), argv.data()); }
|
||||
catch (const std::runtime_error& error) {
|
||||
rejected = std::string(error.what()).find("cyclic pattern exceeds") != std::string::npos;
|
||||
}
|
||||
if (!rejected) { throw std::runtime_error("DO8 overflow must be rejected before allocation or SDK access"); }
|
||||
}
|
||||
// Preserve the application's low-minus-high IQ averaging and quantization.
|
||||
Do1PairSubtractAverageState state;
|
||||
state.start_run(false);
|
||||
state.add_pair_sample(false, 1000, -3000);
|
||||
state.add_pair_sample(false, 5000, 1000);
|
||||
state.add_pair_sample(true, 200, -1000);
|
||||
state.add_pair_sample(true, 1000, -1000);
|
||||
if (state.diff_count != 2 || state.avg_diff_ch1() != 2400 || state.avg_diff_ch2() != 0 ||
|
||||
pack_raw_code_to_int16(X502_ADC_SCALE_CODE_MAX) != 32767 ||
|
||||
pack_raw_code_to_int16(-2 * X502_ADC_SCALE_CODE_MAX) != -32768) {
|
||||
throw std::runtime_error("phase IQ subtraction/averaging changed");
|
||||
}
|
||||
// An SDK teardown can hang or ignore SIGTERM; parent death must still
|
||||
// release the ADC. Reap the orphan here so the regression leaks nothing.
|
||||
if (::prctl(PR_SET_CHILD_SUBREAPER, 1) != 0) { throw std::runtime_error("subreaper failed"); }
|
||||
int ready[2], identity[2];
|
||||
if (::pipe(ready) != 0 || ::pipe(identity) != 0) { throw std::runtime_error("pipe failed"); }
|
||||
const auto owner = ::fork();
|
||||
if (owner == 0) {
|
||||
const auto collector = ::fork();
|
||||
if (collector < 0) { ::_exit(2); }
|
||||
if (collector == 0) {
|
||||
::close(ready[0]);
|
||||
::signal(SIGTERM, SIG_IGN);
|
||||
bind_to_parent();
|
||||
const char started = 1;
|
||||
if (::write(ready[1], &started, 1) != 1) { ::_exit(2); }
|
||||
for (;;) { ::pause(); }
|
||||
}
|
||||
::close(ready[1]);
|
||||
if (::write(identity[1], &collector, sizeof(collector)) != sizeof(collector)) { ::_exit(2); }
|
||||
char started = 0;
|
||||
::_exit(::read(ready[0], &started, 1) == 1 ? 0 : 2);
|
||||
}
|
||||
if (owner < 0) { throw std::runtime_error("fork failed"); }
|
||||
::close(ready[0]);
|
||||
::close(ready[1]);
|
||||
::close(identity[1]);
|
||||
int status = 0;
|
||||
(void)::waitpid(owner, &status, 0);
|
||||
pid_t child = 0;
|
||||
if (::read(identity[0], &child, sizeof(child)) != sizeof(child)) { throw std::runtime_error("missing child PID"); }
|
||||
::close(identity[0]);
|
||||
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(1);
|
||||
pid_t orphan = 0;
|
||||
while ((orphan = ::waitpid(-1, &status, WNOHANG)) == 0 && std::chrono::steady_clock::now() < deadline) {
|
||||
::usleep(1000);
|
||||
}
|
||||
if (orphan <= 0 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGKILL) {
|
||||
if (child > 0) { ::kill(child, SIGKILL); (void)::waitpid(child, &status, 0); }
|
||||
throw std::runtime_error("collector survived parent death or entered SIGTERM teardown");
|
||||
}
|
||||
std::cout << "collector regressions passed\n";
|
||||
} catch (const std::exception& error) {
|
||||
std::cerr << error.what() << '\n';
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "capture_file_writer.h"
|
||||
#include "channel_bundle_support.hpp"
|
||||
#include "data_preprocessor.hpp"
|
||||
#include "locator/tcp_server.hpp"
|
||||
@@ -7,6 +6,8 @@
|
||||
#include "runtime_wait.hpp"
|
||||
#include "shm_ring.hpp"
|
||||
#include "tty_protocol_writer.h"
|
||||
#include "switch_sequencer.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -307,40 +308,6 @@ void test_cosine_notch_taper() {
|
||||
}
|
||||
}
|
||||
|
||||
void test_csv_failures(const Workspace& workspace) {
|
||||
const auto csv = workspace.path / "capture.csv";
|
||||
const auto spool = workspace.path / "capture.capture_spool.bin";
|
||||
CaptureFileWriter writer(csv.string(), (workspace.path / "capture.svg").string(), "", "");
|
||||
writer.initialize_csv(2, false);
|
||||
CapturePacket packet{.ch1 = {1, 2}, .ch2 = {3, 4}, .di1 = {}};
|
||||
auto invalid_packet = packet;
|
||||
invalid_packet.ch2.pop_back();
|
||||
expect_error([&] { writer.append_csv_packet(invalid_packet); });
|
||||
require(std::filesystem::file_size(spool) == 16, "invalid packet partially changed the spool");
|
||||
writer.append_csv_packet(packet);
|
||||
std::filesystem::remove(csv);
|
||||
std::filesystem::create_symlink("/dev/full", csv);
|
||||
expect_error([&] { writer.write({packet}, 1000, 10); });
|
||||
require(std::filesystem::file_size(spool) > 16, "failed CSV write deleted the recovery spool");
|
||||
std::filesystem::remove(csv);
|
||||
writer.write({packet}, 1000, 10);
|
||||
require(!std::filesystem::exists(spool), "successful CSV export retained the spool");
|
||||
std::ifstream csv_input(csv);
|
||||
const std::string csv_text((std::istreambuf_iterator<char>(csv_input)), {});
|
||||
require(csv_text.find("1.000000000,3.000000000") != std::string::npos,
|
||||
"CSV retry lost channel samples");
|
||||
writer.initialize_csv(2, false);
|
||||
std::ofstream(spool, std::ios::binary | std::ios::app).put('x');
|
||||
expect_error([&] { writer.write({}, 1000, 10); });
|
||||
require(std::filesystem::exists(spool), "truncated packet header deleted the spool");
|
||||
writer.initialize_csv(2, false);
|
||||
const std::array<std::uint64_t, 4> corrupt_packet{0, 2, 0xffffffffffffffffULL, 0};
|
||||
std::ofstream(spool, std::ios::binary | std::ios::app).write(
|
||||
reinterpret_cast<const char*>(corrupt_packet.data()), sizeof(corrupt_packet));
|
||||
expect_error([&] { writer.write({}, 1000, 10); });
|
||||
require(std::filesystem::exists(spool), "oversized packet count deleted the spool");
|
||||
}
|
||||
|
||||
void test_asset_reload_preserves_data(const Workspace& workspace) {
|
||||
const auto save = [&](const char* name, float sample) {
|
||||
return save_bundle(workspace, name, {.traces = {
|
||||
@@ -497,10 +464,77 @@ void test_locator_packet_errors() {
|
||||
for (unsigned iteration = 0; iteration < 30; ++iteration) { server.start(); server.stop(); }
|
||||
}
|
||||
|
||||
void test_tty_sweep_overflow(const Workspace& workspace) {
|
||||
TtyProtocolWriter writer((workspace.path / "overflow_tty").string(), 32'096);
|
||||
const int fd = ::open(writer.path().c_str(), O_RDONLY | O_NONBLOCK);
|
||||
require(fd >= 0, "Cannot open test PTY");
|
||||
std::vector<std::uint16_t> words(8'000, 42);
|
||||
for (std::uint64_t id = 1; id <= 100; ++id) {
|
||||
writer.enqueue_sweep(words, {id, id, id * 100, id * 100 + 50, 1, 2, false});
|
||||
}
|
||||
require(writer.stats().ring_overflows > 0, "test did not overflow the queue");
|
||||
std::vector<std::uint8_t> received;
|
||||
std::uint64_t last_id = 0;
|
||||
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2);
|
||||
while (last_id < 100 && std::chrono::steady_clock::now() < deadline) {
|
||||
std::array<std::uint8_t, 8192> chunk{};
|
||||
const auto n = ::read(fd, chunk.data(), chunk.size());
|
||||
if (n > 0) { received.insert(received.end(), chunk.begin(), chunk.begin() + n); }
|
||||
while (received.size() >= 16'048) {
|
||||
require(std::memcmp(received.data(), "RPH1", 4) == 0, "overflow truncated a sweep header");
|
||||
const auto value = [&](std::size_t at, unsigned size) {
|
||||
std::uint64_t result = 0;
|
||||
for (unsigned i = 0; i < size; ++i) { result |= std::uint64_t{received[at + i]} << (8U * i); }
|
||||
return result;
|
||||
};
|
||||
require(value(4, 4) == 16'000 && value(8, 8) > last_id, "lost framing or source order");
|
||||
last_id = value(8, 8);
|
||||
require(value(16, 8) == last_id && value(24, 8) == last_id * 100 &&
|
||||
value(32, 8) == last_id * 100 + 50 && value(40, 2) == 1 && value(42, 2) == 2,
|
||||
"sweep lost source identity, timing, or combo");
|
||||
require(received[48] == 42 && received[16'047] == 0, "corrupt point payload");
|
||||
received.erase(received.begin(), received.begin() + 16'048);
|
||||
}
|
||||
if (n <= 0) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); }
|
||||
}
|
||||
::close(fd);
|
||||
require(last_id == 100 && received.empty(), "latest complete sweep did not arrive");
|
||||
}
|
||||
|
||||
void test_switch_backlog() {
|
||||
drivers::H7992MinimalDriverSettings settings{.mode = config::DriverMode::Mock};
|
||||
rph::SwitchSequencer sequencer({.combos = {{0, 0}, {0, 1}}},
|
||||
std::make_unique<drivers::H7992MinimalDriver>(settings),
|
||||
std::make_unique<drivers::H7992MinimalDriver>(settings));
|
||||
sequencer.open();
|
||||
sequencer.session_started();
|
||||
require(!sequencer.on_sweep_end(false), "duration limit requested a new session");
|
||||
require(sequencer.current_combo().output_pos == 0 && sequencer.cycle_id() == 1,
|
||||
"duration limit switched hardware before the physical sweep ended");
|
||||
require(sequencer.on_sweep_end(), "GPIO change must request a new source session");
|
||||
for (unsigned i = 0; i < 10; ++i) {
|
||||
require(sequencer.current_dirty(), "queued pre-switch sweep incorrectly clean");
|
||||
require(!sequencer.on_sweep_end(), "dirty backlog requested another session");
|
||||
require(sequencer.current_combo().output_pos == 1 && sequencer.cycle_id() == 1,
|
||||
"dirty backlog advanced the combo or cycle");
|
||||
}
|
||||
sequencer.session_started();
|
||||
require(!sequencer.current_dirty(), "new source session must permit a complete sweep");
|
||||
sequencer.on_sweep_end();
|
||||
require(sequencer.current_combo().output_pos == 0 && sequencer.cycle_id() == 2,
|
||||
"clean cycle did not advance");
|
||||
rph::SwitchSequencer single({.combos = {{0, 0}}},
|
||||
std::make_unique<drivers::H7992MinimalDriver>(settings),
|
||||
std::make_unique<drivers::H7992MinimalDriver>(settings));
|
||||
single.open(); single.session_started();
|
||||
require(!single.on_sweep_end() && single.cycle_id() == 2 && !single.current_dirty(),
|
||||
"unchanged combination restarted its source or stopped advancing cycles");
|
||||
}
|
||||
|
||||
void test_unread_tty_shutdown(const Workspace& workspace) {
|
||||
TtyProtocolWriter writer((workspace.path / "tty").string(), 160'000);
|
||||
TtyProtocolWriter writer((workspace.path / "tty").string(), 160'048);
|
||||
const std::vector<std::uint16_t> words(80'000, 42);
|
||||
writer.enqueue_encoded_frames(words.data(), words.size() / 4U);
|
||||
writer.enqueue_sweep(words, {1, 1, 100, 200});
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
writer.shutdown();
|
||||
@@ -524,9 +558,10 @@ int main(int argc, char** argv) {
|
||||
test_acquisition_identity();
|
||||
test_interruptible_wait();
|
||||
test_cosine_notch_taper();
|
||||
test_csv_failures(workspace);
|
||||
test_locator_packet_errors();
|
||||
test_tty_sweep_overflow(workspace);
|
||||
test_switch_backlog();
|
||||
test_unread_tty_shutdown(workspace);
|
||||
test_locator_packet_errors();
|
||||
std::cout << "native regressions passed (10,000 decoder mutations; 20,000 concurrent ring frames)\n";
|
||||
} catch (const std::exception& error) {
|
||||
std::cerr << "native regression failed: " << error.what() << '\n';
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// SDK contract fixture: Stop retains queued input; only a new descriptor is fresh.
|
||||
#include "x502api.h"
|
||||
#include "e502api.h"
|
||||
#include <algorithm>
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
struct Session { unsigned id; bool consumed = false; std::vector<uint32_t> input; };
|
||||
unsigned sessions = 0;
|
||||
void record(const char* name) { std::ofstream(std::getenv("RPH_SDK_LOG"), std::ios::app) << name << '\n'; }
|
||||
Session& session(t_x502_hnd hnd) { return *reinterpret_cast<Session*>(hnd); }
|
||||
void generate(Session& s) {
|
||||
for (unsigned sweep = 0; sweep < 4; ++sweep) {
|
||||
for (unsigned step = 0; step < 2; ++step) {
|
||||
for (unsigned n = 0; n < 8; ++n) {
|
||||
const bool high = n % 4 >= 2;
|
||||
s.input.push_back(high ? 0 : 10000 * s.id);
|
||||
s.input.push_back((1U << 13) | step | (high ? 2 : 0));
|
||||
}
|
||||
}
|
||||
for (unsigned n = 0; n < 4; ++n) { s.input.push_back(0); s.input.push_back(0); }
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
extern "C" int32_t E502_OpenUsb(t_x502_hnd hnd, const char *serial) { record("Open"); return 0; }
|
||||
extern "C" int32_t X502_AsyncOutDig(t_x502_hnd hnd, uint32_t val, uint32_t msk) { return 0; }
|
||||
extern "C" int32_t X502_Close(t_x502_hnd hnd) { record("Close"); return 0; }
|
||||
extern "C" int32_t X502_Configure(t_x502_hnd hnd, uint32_t flags) { record("Configure"); return 0; }
|
||||
extern "C" t_x502_hnd X502_Create(void) { record("Create"); auto* s = new Session{++sessions}; generate(*s); return reinterpret_cast<t_x502_hnd>(s); }
|
||||
extern "C" int32_t X502_Free(t_x502_hnd hnd) { record("Free"); delete &session(hnd); return 0; }
|
||||
extern "C" int32_t X502_GetAdcFreq(t_x502_hnd hnd, double *f_acq, double *f_frame) { *f_acq = 2000000; *f_frame = 1000000; return 0; }
|
||||
extern "C" const char* X502_GetErrorString(int32_t err) { return "SDK contract fixture"; }
|
||||
extern "C" int32_t X502_GetRecvReadyCount(t_x502_hnd hnd, uint32_t *rdy_cnt) { *rdy_cnt = session(hnd).input.size(); return 0; }
|
||||
extern "C" int32_t X502_OutCycleLoadStart(t_x502_hnd hnd, uint32_t size) { record("OutCycleLoadStart"); return 0; }
|
||||
extern "C" int32_t X502_OutCycleSetup(t_x502_hnd hnd, uint32_t flags) { if (flags != X502_OUT_CYCLE_FLAGS_WAIT_DONE) { return -1; } record("OutCycleSetup WAIT_DONE"); return 0; }
|
||||
extern "C" int32_t X502_OutCycleStop(t_x502_hnd hnd, uint32_t flags) { if (flags != X502_OUT_CYCLE_FLAGS_WAIT_DONE) { return -1; } record("OutCycleStop WAIT_DONE"); return 0; }
|
||||
extern "C" int32_t X502_PrepareData(t_x502_hnd hnd, const double* dac1, const double* dac2, const uint32_t* digout, uint32_t size, int32_t flags, uint32_t* out_buf) { record("PrepareData"); std::copy_n(digout, size, out_buf); return 0; }
|
||||
extern "C" int32_t X502_ProcessData(t_x502_hnd hnd, const uint32_t* src, uint32_t size, uint32_t flags, double *adc_data, uint32_t *adc_data_size, uint32_t *din_data, uint32_t *din_data_size) { *adc_data_size = *din_data_size = size / 2;
|
||||
for (unsigned n = 0; n < size / 2; ++n) {
|
||||
adc_data[n] = static_cast<int32_t>(src[2 * n]); din_data[n] = src[2 * n + 1];
|
||||
}
|
||||
return 0; }
|
||||
extern "C" int32_t X502_Recv(t_x502_hnd hnd, uint32_t* buf, uint32_t size, uint32_t tout) { auto& s = session(hnd); usleep(20000);
|
||||
if (s.consumed) { raise(SIGTERM); return 0; }
|
||||
if (size < s.input.size()) { return -1; }
|
||||
std::copy(s.input.begin(), s.input.end(), buf); s.consumed = true;
|
||||
return static_cast<int32_t>(s.input.size()); }
|
||||
extern "C" int32_t X502_Send(t_x502_hnd hnd, const uint32_t* buf, uint32_t size, uint32_t tout) { record("Send"); return size; }
|
||||
extern "C" int32_t X502_SetAdcFreq(t_x502_hnd hnd, double *f_acq, double *f_frame) { *f_acq = 2000000; if (f_frame) { *f_frame = 1000000; } return 0; }
|
||||
extern "C" int32_t X502_SetDigInPullup(t_x502_hnd hnd, uint32_t pullups) { return 0; }
|
||||
extern "C" int32_t X502_SetDinFreq(t_x502_hnd hnd, double *f_din) { return 0; }
|
||||
extern "C" int32_t X502_SetLChannel(t_x502_hnd hnd, uint32_t lch, uint32_t phy_ch, uint32_t mode, uint32_t range, uint32_t avg) { return 0; }
|
||||
extern "C" int32_t X502_SetLChannelCount(t_x502_hnd hnd, uint32_t lch_cnt) { return 0; }
|
||||
extern "C" int32_t X502_SetMode(t_x502_hnd hnd, uint32_t mode) { return 0; }
|
||||
extern "C" int32_t X502_SetOutFreq(t_x502_hnd hnd, double *f_dout) { return 0; }
|
||||
extern "C" int32_t X502_SetRefFreq(t_x502_hnd hnd, uint32_t freq) { return 0; }
|
||||
extern "C" int32_t X502_SetStreamBufSize(t_x502_hnd hnd, uint32_t ch, uint32_t size) { return 0; }
|
||||
extern "C" int32_t X502_SetStreamStep(t_x502_hnd hnd, uint32_t dma_ch, uint32_t step) { return 0; }
|
||||
extern "C" int32_t X502_SetSyncMode(t_x502_hnd hnd, uint32_t sync_mode) { return 0; }
|
||||
extern "C" int32_t X502_SetSyncStartMode(t_x502_hnd hnd, uint32_t sync_start_mode) { return 0; }
|
||||
extern "C" int32_t X502_StreamsDisable(t_x502_hnd hnd, uint32_t streams) { record("StreamsDisable"); return 0; }
|
||||
extern "C" int32_t X502_StreamsEnable(t_x502_hnd hnd, uint32_t streams) { return 0; }
|
||||
extern "C" int32_t X502_StreamsStart(t_x502_hnd hnd) { record("Start"); if (session(hnd).id == 4) { raise(SIGTERM); } return 0; }
|
||||
extern "C" int32_t X502_StreamsStop(t_x502_hnd hnd) { record("StreamsStop"); return 0; }
|
||||
Reference in New Issue
Block a user