|
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 |
| -
|
141 |
| -pub mod prelude { |
142 |
| - pub use pico_common::{ |
143 |
| - ChannelConfig, Driver, PicoChannel, PicoCoupling, PicoError, PicoInfo, PicoRange, |
144 |
| - PicoStatus, PicoResult, |
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 |
158 |
| -pub mod common { |
159 |
| - pub use pico_common::*; |
160 |
| -} |
161 |
| - |
162 |
| -/// Dynamically loaded unsafe bindings for every Pico oscilloscope driver |
163 |
| -pub mod sys { |
164 |
| - pub use pico_sys_dynamic::*; |
165 |
| -} |
166 |
| - |
167 |
| -/// Dynamic loading, unsafe and safe wrappers for Pico drivers |
168 |
| -pub mod driver { |
169 |
| - pub use pico_driver::*; |
170 |
| -} |
171 |
| - |
172 |
| -/// Device abstraction that uses Pico drivers |
173 |
| -pub mod device { |
174 |
| - pub use pico_device::*; |
175 |
| -} |
176 |
| - |
177 |
| -/// Downloads Pico driver binaries for your platform |
178 |
| -pub mod download { |
179 |
| - pub use pico_download::*; |
180 |
| -} |
181 |
| - |
182 |
| -/// Enumerates connected Pico devices from all supported drivers |
183 |
| -pub mod enumeration { |
184 |
| - pub use pico_enumeration::*; |
185 |
| -} |
186 |
| - |
187 |
| -/// Implements gap-less streaming on top of `PicoDevice` |
188 |
| -pub mod streaming { |
189 |
| - pub use pico_streaming::*; |
190 |
| -} |
| 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 | +
|
| 141 | +pub mod prelude { |
| 142 | + pub use pico_common::{ |
| 143 | + ChannelConfig, Driver, PicoChannel, PicoCoupling, PicoError, PicoInfo, PicoRange, |
| 144 | + PicoStatus, PicoResult, SigGenArbitraryMinMaxValues, |
| 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 |
| 158 | +pub mod common { |
| 159 | + pub use pico_common::*; |
| 160 | +} |
| 161 | + |
| 162 | +/// Dynamically loaded unsafe bindings for every Pico oscilloscope driver |
| 163 | +pub mod sys { |
| 164 | + pub use pico_sys_dynamic::*; |
| 165 | +} |
| 166 | + |
| 167 | +/// Dynamic loading, unsafe and safe wrappers for Pico drivers |
| 168 | +pub mod driver { |
| 169 | + pub use pico_driver::*; |
| 170 | +} |
| 171 | + |
| 172 | +/// Device abstraction that uses Pico drivers |
| 173 | +pub mod device { |
| 174 | + pub use pico_device::*; |
| 175 | +} |
| 176 | + |
| 177 | +/// Downloads Pico driver binaries for your platform |
| 178 | +pub mod download { |
| 179 | + pub use pico_download::*; |
| 180 | +} |
| 181 | + |
| 182 | +/// Enumerates connected Pico devices from all supported drivers |
| 183 | +pub mod enumeration { |
| 184 | + pub use pico_enumeration::*; |
| 185 | +} |
| 186 | + |
| 187 | +/// Implements gap-less streaming on top of `PicoDevice` |
| 188 | +pub mod streaming { |
| 189 | + pub use pico_streaming::*; |
| 190 | +} |
0 commit comments