Skip to content

Commit

Permalink
Reintroduce settings object
Browse files Browse the repository at this point in the history
Make sure the operation is torn down and stop() called
on the old and consistent settings before applying the new
ones.
  • Loading branch information
frankosterfeld committed Sep 27, 2023
1 parent 0eb8fa5 commit 520d1cf
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 37 deletions.
32 changes: 16 additions & 16 deletions blocklib/picoscope4000a/picoscope4000a.cc
Original file line number Diff line number Diff line change
Expand Up @@ -472,16 +472,16 @@ std::error_code Picoscope4000a::driver_configure()
{
int32_t max_samples;
auto status = ps4000aMemorySegments(
state.handle, static_cast<uint32_t>(rapid_block_nr_captures), &max_samples);
state.handle, static_cast<uint32_t>(ps_settings.rapid_block_nr_captures), &max_samples);
if (status != PICO_OK) {
fmt::println(
std::cerr, "ps4000aMemorySegments: {}", ps4000a_get_error_message(status));
return make_pico_4000a_error_code(status);
}

if (acquisition_mode == acquisition_mode_t::RAPID_BLOCK) {
if (ps_settings.acquisition_mode == acquisition_mode_t::RAPID_BLOCK) {
status = ps4000aSetNoOfCaptures(state.handle,
static_cast<uint32_t>(rapid_block_nr_captures));
static_cast<uint32_t>(ps_settings.rapid_block_nr_captures));
if (status != PICO_OK) {
fmt::println(std::cerr,
"ps4000aSetNoOfCaptures: {}",
Expand Down Expand Up @@ -514,15 +514,15 @@ std::error_code Picoscope4000a::driver_configure()

// apply trigger configuration
if (trigger.value.is_analog() &&
acquisition_mode == acquisition_mode_t::RAPID_BLOCK) {
const auto channel = convert_to_ps4000a_channel(trigger.value.source);
ps_settings.acquisition_mode == acquisition_mode_t::RAPID_BLOCK) {
const auto channel = convert_to_ps4000a_channel(ps_settings.trigger.source);
assert(channel);
status = ps4000aSetSimpleTrigger(
state.handle,
true, // enable
*channel,
convert_voltage_to_ps4000a_raw_logic_value(trigger.value.threshold),
convert_to_ps4000a_threshold_direction(trigger.value.direction),
convert_voltage_to_ps4000a_raw_logic_value(ps_settings.trigger.threshold),
convert_to_ps4000a_threshold_direction(ps_settings.trigger.direction),
0, // delay
-1); // auto trigger
if (status != PICO_OK) {
Expand Down Expand Up @@ -551,21 +551,21 @@ std::error_code Picoscope4000a::driver_configure()

// In order to validate desired frequency before startup
double actual_freq;
convert_frequency_to_ps4000a_timebase(state.handle, sample_rate, actual_freq);
convert_frequency_to_ps4000a_timebase(state.handle, ps_settings.sample_rate, actual_freq);

return std::error_code{};
}

std::error_code Picoscope4000a::driver_arm()
{
if (acquisition_mode == acquisition_mode_t::RAPID_BLOCK) {
if (ps_settings.acquisition_mode == acquisition_mode_t::RAPID_BLOCK) {
uint32_t timebase = convert_frequency_to_ps4000a_timebase(
state.handle, sample_rate, state.actual_sample_rate);
state.handle, ps_settings.sample_rate, state.actual_sample_rate);

auto status = ps4000aRunBlock(
state.handle,
static_cast<int32_t>(pre_samples),
static_cast<int32_t>(post_samples),
static_cast<int32_t>(ps_settings.pre_samples),
static_cast<int32_t>(ps_settings.post_samples),
timebase, // timebase
nullptr, // time indispossed
0, // segment index
Expand All @@ -578,22 +578,22 @@ std::error_code Picoscope4000a::driver_arm()
}
}
else {
set_buffers(driver_buffer_size, 0);
set_buffers(ps_settings.driver_buffer_size, 0);

ps4000a_unit_interval_t unit_int =
convert_frequency_to_ps4000a_time_units_and_interval(
sample_rate, state.actual_sample_rate);
ps_settings.sample_rate, state.actual_sample_rate);

auto status = ps4000aRunStreaming(
state.handle,
&unit_int.interval, // sample interval
unit_int.unit, // time unit of sample interval
0, // pre-triggersamples (unused)
static_cast<uint32_t>(driver_buffer_size),
static_cast<uint32_t>(ps_settings.driver_buffer_size),
false,
1, // downsampling factor // TODO reconsider if we need downsampling support
PS4000A_RATIO_MODE_NONE,
static_cast<uint32_t>(driver_buffer_size));
static_cast<uint32_t>(ps_settings.driver_buffer_size));

if (status != PICO_OK) {
fmt::println(
Expand Down
77 changes: 56 additions & 21 deletions gr-picoscope/picoscope.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,15 @@ struct channel_setting_t {
coupling_t coupling = coupling_t::AC_1M;
};

using ChannelMap = std::map<std::string, channel_setting_t, std::less<>>;

struct port_setting_t {
float logic_level = 1.5;
bool enabled = false;
};

using PortMap = std::map<std::string, port_setting_t, std::less<>>;

struct GetValuesResult {
std::error_code error;
std::size_t samples;
Expand Down Expand Up @@ -109,6 +113,22 @@ struct Error {
std::error_code error;
};

struct Settings {
std::string serial_number;
double sample_rate = 10000.;
acquisition_mode_t acquisition_mode = acquisition_mode_t::STREAMING;
std::size_t pre_samples = 1000;
std::size_t post_samples = 9000;
std::size_t rapid_block_nr_captures = 1;
bool trigger_once = false;
double streaming_mode_poll_rate = 0.001;
std::size_t driver_buffer_size = 100000;
bool auto_arm = true;
ChannelMap enabled_channels;
PortMap enabled_ports;
trigger_setting_t trigger;
};

struct State {
std::vector<Channel> channels;
std::atomic<std::size_t> data_available = 0;
Expand Down Expand Up @@ -141,13 +161,8 @@ using fair::graph::Visible;

template <typename PSImpl>
struct Picoscope : public fair::graph::node<PSImpl> {
using ChannelMap = std::map<std::string, channel_setting_t, std::less<>>;
using PortMap = std::map<std::string, port_setting_t, std::less<>>;

A<std::string, "serial number", Visible> serial_number;
A<double, "sample rate", Visible> sample_rate = 10000.;
A<acquisition_mode_t, "acquisition mode", Visible> acquisition_mode =
acquisition_mode_t::STREAMING;
// TODO any way to get custom enums into pmtv??
A<std::string, "acquisition mode as string", Visible> acquisition_mode_string =
std::string("STREAMING");
Expand All @@ -164,6 +179,8 @@ struct Picoscope : public fair::graph::node<PSImpl> {
A<trigger_setting_t, "trigger settings", Visible> trigger;

detail::State state;
detail::Settings ps_settings;

detail::streaming_callback_function_t _streaming_callback;

explicit Picoscope()
Expand Down Expand Up @@ -201,9 +218,9 @@ struct Picoscope : public fair::graph::node<PSImpl> {
}
}

enabled_channels = std::move(channels);
enabled_ports = std::move(ports);
trigger = std::move(trigger_);
ps_settings.enabled_channels = enabled_channels = std::move(channels);
ps_settings.enabled_ports = enabled_ports = std::move(ports);
ps_settings.trigger = trigger = std::move(trigger_);

auto channel_outputs = self().channel_outputs();
state.channels.reserve(enabled_channels.value.size());
Expand Down Expand Up @@ -233,11 +250,29 @@ struct Picoscope : public fair::graph::node<PSImpl> {
void settings_changed(const fair::graph::property_map& /*old_settings*/,
const fair::graph::property_map& /*new_settings*/)
{
acquisition_mode = acquisition_mode_string == "STREAMING"
? acquisition_mode_t::STREAMING
: acquisition_mode_t::RAPID_BLOCK;
if (state.started) {
const auto was_started = state.started;
if (was_started) {
stop();
}
auto s = detail::Settings{
.serial_number = serial_number,
.sample_rate = sample_rate,
.acquisition_mode = acquisition_mode_string == "STREAMING"
? acquisition_mode_t::STREAMING
: acquisition_mode_t::RAPID_BLOCK,
.pre_samples = pre_samples,
.post_samples = post_samples,
.rapid_block_nr_captures = rapid_block_nr_captures,
.trigger_once = trigger_once,
.streaming_mode_poll_rate = streaming_mode_poll_rate,
.driver_buffer_size = driver_buffer_size,
.auto_arm = auto_arm,
.enabled_channels = enabled_channels,
.enabled_ports = enabled_ports,
.trigger = trigger
};
std::swap(ps_settings, s);
if (was_started) {
start();
}
}
Expand Down Expand Up @@ -278,10 +313,10 @@ struct Picoscope : public fair::graph::node<PSImpl> {
try {
initialize();
configure();
if (auto_arm) {
if (ps_settings.auto_arm) {
arm();
}
if (acquisition_mode == acquisition_mode_t::STREAMING) {
if (ps_settings.acquisition_mode == acquisition_mode_t::STREAMING) {
start_poll_thread();
}
state.started = true;
Expand All @@ -305,7 +340,7 @@ struct Picoscope : public fair::graph::node<PSImpl> {
disarm();
close();

if (acquisition_mode == acquisition_mode_t::STREAMING) {
if (ps_settings.acquisition_mode == acquisition_mode_t::STREAMING) {
stop_poll_thread();
}
}
Expand All @@ -316,7 +351,7 @@ struct Picoscope : public fair::graph::node<PSImpl> {
return;
}
const auto poll_duration =
std::chrono::seconds(1) * streaming_mode_poll_rate.value;
std::chrono::seconds(1) * ps_settings.streaming_mode_poll_rate;

if (state.poller_state == detail::poller_state_t::EXIT) {
state.poller_state = detail::poller_state_t::IDLE;
Expand Down Expand Up @@ -410,7 +445,7 @@ struct Picoscope : public fair::graph::node<PSImpl> {
}

state.armed = true;
if (acquisition_mode == acquisition_mode_t::STREAMING) {
if (ps_settings.acquisition_mode == acquisition_mode_t::STREAMING) {
state.poller_state = detail::poller_state_t::RUNNING;
}
}
Expand All @@ -421,7 +456,7 @@ struct Picoscope : public fair::graph::node<PSImpl> {
return;
}

if (acquisition_mode == acquisition_mode_t::STREAMING) {
if (ps_settings.acquisition_mode == acquisition_mode_t::STREAMING) {
state.poller_state = detail::poller_state_t::IDLE;
}

Expand Down Expand Up @@ -495,8 +530,8 @@ struct Picoscope : public fair::graph::node<PSImpl> {
report_error(ec);
return;
}
const auto samples = pre_samples + post_samples;
for (std::size_t capture = 0; capture < rapid_block_nr_captures; ++capture) {
const auto samples = ps_settings.pre_samples + ps_settings.post_samples;
for (std::size_t capture = 0; capture < ps_settings.rapid_block_nr_captures; ++capture) {

const auto get_values_result =
self().driver_rapid_block_get_values(capture, samples);
Expand All @@ -509,7 +544,7 @@ struct Picoscope : public fair::graph::node<PSImpl> {
process_driver_data(get_values_result.samples, 0);
}

if (trigger_once) {
if (ps_settings.trigger_once) {
state.data_finished = true;
}
}
Expand Down

0 comments on commit 520d1cf

Please sign in to comment.