pico_sdk/lib.rs
1#![forbid(unsafe_code)]
2
3//! [](https://crates.io/crates/pico-sdk)
4//! [](https://docs.rs/pico-sdk/)
5//!
6//! # Unofficial Rust bindings and wrappers for Pico Technology oscilloscope drivers
7//!
8//! This is a meta-crate re-exporting functionality from a number of sub-crates. These
9//! crates expose common, high-performance, high-level APIs that hide the differences between the
10//! numerous Pico drivers.
11//!
12//! ## Sub Crates
13//!
14//! - ### `pico-common` [](https://crates.io/crates/pico-common)
15//! Common enums, structs and traits.
16//! - ### `pico-sys-dynamic` [](https://crates.io/crates/pico-sys-dynamic)
17//! Dynamically loaded unsafe bindings for every Pico oscilloscope driver. **This crate contains unsafe code.**
18//! - ### `pico-driver` [](https://crates.io/crates/pico-driver)
19//! Common, safe wrappers implementing the `PicoDriver` trait. **This crate contains unsafe code.**
20//! - ### `pico-download` [](https://crates.io/crates/pico-download)
21//! Download missing drivers on any platform.
22//! - ### `pico-device` [](https://crates.io/crates/pico-device)
23//! Device abstraction over `PicoDriver` trait. Detects available channels and valid ranges.
24//! - ### `pico-enumeration` [](https://crates.io/crates/pico-enumeration)
25//! Cross driver device enumeration. Detects devices via USB Vendor ID and only loads the required drivers.
26//! - ### `pico-streaming` [](https://crates.io/crates/pico-streaming)
27//! Implements continuous gap-less streaming on top of `PicoDevice`.
28//!
29//! # Prerequisites
30//! On linux `pico-enumeration` [requires
31//! `libudev-dev`](https://github.com/meatysolutions/pico-sdk/blob/700ab24efe81063316baffff638988cf626c6ffe/.github/workflows/build-and-publish.yml#L32)
32//! to be installed.
33//!
34//! # Tests
35//! Some tests open and stream from devices and these fail if devices are not available, for example when run in CI.
36//! To run these tests, ensure that ignored tests are run too:
37//!
38//! `cargo test -- --ignored`
39//!
40//! # Examples
41//!
42//! There are a number of examples which demonstrate how the wrappers can be used
43//!
44//! `cargo run --example streaming_cli`
45//!
46//! Displays an interactive command line interface that allows selection of device, channel configuration
47//! and sample rate. Once capturing, the streaming rate is displayed along with channel values.
48//!
49//! `cargo run --example enumerate`
50//!
51//! Attempts to enumerate devices and downloads drivers which were not found in the cache location.
52//!
53//! `cargo run --example open <driver> <serial>`
54//!
55//! Loads the specified driver and attempts open the optionally specified device serial.
56//!
57//!
58//! # Usage Examples
59//! Opening and configuring a specific ps2000 device as a `PicoDevice`:
60//! ```no_run
61//! # fn run() -> Result<(),Box<dyn std::error::Error>> {
62//! use std::sync::Arc;
63//! use pico_sdk::prelude::*;
64//!
65//! let driver = Driver::PS2000.try_load()?;
66//! let device = PicoDevice::try_open(&driver, Some("ABC/123"))?;
67//! # Ok(())
68//! # }
69//! ```
70//!
71//! Enumerate all required Pico oscilloscope drivers, configure the first device that's returned and stream
72//! gap-less data from it:
73//! ```no_run
74//! # fn run() -> Result<(),Box<dyn std::error::Error>> {
75//! use std::sync::Arc;
76//! use pico_sdk::prelude::*;
77//!
78//! let enumerator = DeviceEnumerator::new();
79//! // Enumerate, ignore all failures and get the first device
80//! let enum_device = enumerator
81//! .enumerate()
82//! .into_iter()
83//! .flatten()
84//! .next()
85//! .expect("No device found");
86//!
87//! let device = enum_device.open()?;
88//!
89//! // Get a streaming device
90//! let stream_device = device.into_streaming_device();
91//!
92//! // Enable and configure 2 channels
93//! stream_device.enable_channel(PicoChannel::A, PicoRange::X1_PROBE_2V, PicoCoupling::DC);
94//! stream_device.enable_channel(PicoChannel::B, PicoRange::X1_PROBE_1V, PicoCoupling::AC);
95//!
96//! struct StdoutHandler;
97//!
98//! impl NewDataHandler for StdoutHandler {
99//! fn handle_event(&self, event: &StreamingEvent) {
100//! println!("Sample count: {}", event.length);
101//! }
102//! }
103//!
104//! // When handler goes out of scope, the subscription is dropped
105//! let handler = Arc::new(StdoutHandler);
106//!
107//! // Subscribe to streaming events
108//! stream_device.new_data.subscribe(handler.clone());
109//!
110//! // Start streaming with 1k sample rate
111//! stream_device.start(1_000)?;
112//! # Ok(())
113//! # }
114//! ```
115//!
116//! Enumerate all required Pico oscilloscope drivers. If a device is found but no matching
117//! driver is available, attempt to download missing drivers and try enumerating again:
118//! ```no_run
119//! # fn run() -> Result<(),Box<dyn std::error::Error>> {
120//! use pico_sdk::prelude::*;
121//!
122//! let enumerator = DeviceEnumerator::with_resolution(cache_resolution());
123//!
124//! loop {
125//! let results = enumerator.enumerate();
126//!
127//! println!("{:#?}", results);
128//!
129//! let missing_drivers = results.missing_drivers();
130//!
131//! if !missing_drivers.is_empty() {
132//! download_drivers_to_cache(&missing_drivers)?;
133//! } else {
134//! break;
135//! }
136//! }
137//! # Ok(())
138//! # }
139//! ```
140
141pub mod prelude {
142 pub use pico_common::{
143 ChannelConfig, Driver, PicoChannel, PicoCoupling, PicoError, PicoInfo, PicoRange,
144 PicoStatus,
145 };
146 pub use pico_device::PicoDevice;
147 pub use pico_download::{cache_resolution, download_drivers_to_cache};
148 pub use pico_driver::{
149 kernel_driver, DriverLoadError, EnumerationResult, LoadDriverExt, PicoDriver, Resolution,
150 };
151 pub use pico_enumeration::{
152 DeviceEnumerator, EnumResultHelpers, EnumeratedDevice, EnumerationError,
153 };
154 pub use pico_streaming::{NewDataHandler, PicoStreamingDevice, StreamingEvent, ToStreamDevice};
155}
156
157/// Common enums, structs and traits
158pub mod common {
159 pub use pico_common::*;
160}
161
162/// Dynamically loaded unsafe bindings for every Pico oscilloscope driver
163pub mod sys {
164 pub use pico_sys_dynamic::*;
165}
166
167/// Dynamic loading, unsafe and safe wrappers for Pico drivers
168pub mod driver {
169 pub use pico_driver::*;
170}
171
172/// Device abstraction that uses Pico drivers
173pub mod device {
174 pub use pico_device::*;
175}
176
177/// Downloads Pico driver binaries for your platform
178pub mod download {
179 pub use pico_download::*;
180}
181
182/// Enumerates connected Pico devices from all supported drivers
183pub mod enumeration {
184 pub use pico_enumeration::*;
185}
186
187/// Implements gap-less streaming on top of `PicoDevice`
188pub mod streaming {
189 pub use pico_streaming::*;
190}