1use super::{PicoCoupling, PicoRange};
2use num_derive::*;
3use std::convert::From;
4
5#[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq)]
7pub enum TimeUnits {
8 FS = 0,
9 PS = 1,
10 NS = 2,
11 US = 3,
12 MS = 4,
13 S = 5,
14}
15
16impl From<TimeUnits> for u32 {
17 fn from(value: TimeUnits) -> Self {
18 num_traits::ToPrimitive::to_u32(&value).expect("Non-valid time unit")
19 }
20}
21
22impl From<TimeUnits> for i16 {
23 fn from(value: TimeUnits) -> Self {
24 num_traits::ToPrimitive::to_i16(&value).expect("Non-valid time unit")
25 }
26}
27
28impl From<i32> for TimeUnits {
29 fn from(value: i32) -> Self {
30 num_traits::FromPrimitive::from_i32(value).expect("Non-valid time unit")
31 }
32}
33
34impl TimeUnits {
35 pub fn get_multiplier(self) -> f64 {
36 match self {
37 TimeUnits::S => 1.0,
38 TimeUnits::MS => 1e-3,
39 TimeUnits::US => 1e-6,
40 TimeUnits::NS => 1e-9,
41 TimeUnits::PS => 1e-12,
42 TimeUnits::FS => 1e-15,
43 }
44 }
45}
46
47#[derive(Debug, Clone, Copy)]
49pub struct SampleConfig {
50 pub interval: u32,
51 pub units: TimeUnits,
52}
53
54impl SampleConfig {
55 pub fn new(interval: u32, units: TimeUnits) -> SampleConfig {
56 SampleConfig { interval, units }
57 }
58
59 pub fn from_samples_per_second(samples_per_second: u32) -> SampleConfig {
60 let interval: f64 = (1f64 / (samples_per_second as f64)) * 1_000_000_000_f64;
61
62 SampleConfig {
63 interval: interval as u32,
64 units: TimeUnits::NS,
65 }
66 }
67
68 pub fn get_interval(self) -> f64 {
69 self.units.get_multiplier() * (self.interval as f64)
70 }
71
72 pub fn samples_per_second(self) -> u32 {
73 (1f64 / self.get_interval()) as u32
74 }
75
76 pub fn with_interval(self, interval: u32) -> SampleConfig {
77 SampleConfig { interval, ..self }
78 }
79}
80
81impl Default for SampleConfig {
82 fn default() -> Self {
83 SampleConfig::new(1, TimeUnits::MS)
84 }
85}
86
87#[cfg(test)]
88#[allow(clippy::float_cmp)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn from_samples_per_second() {
94 let sc = SampleConfig::from_samples_per_second(1);
95 assert_eq!(sc.interval, 1_000_000_000);
96 assert_eq!(sc.units, TimeUnits::NS);
97 assert_eq!(sc.samples_per_second(), 1);
98
99 let sc = SampleConfig::from_samples_per_second(1000);
100 assert_eq!(sc.interval, 1_000_000);
101 assert_eq!(sc.units, TimeUnits::NS);
102 assert_eq!(sc.samples_per_second(), 1000);
103
104 let sc = SampleConfig::from_samples_per_second(15657);
105 assert_eq!(sc.interval, 63_869);
106 assert_eq!(sc.units, TimeUnits::NS);
107 assert_eq!(sc.samples_per_second(), 15657);
108 }
109
110 #[test]
111 fn get_interval() {
112 let sc = SampleConfig::from_samples_per_second(1000);
113 assert_eq!(sc.get_interval(), 0.001);
114
115 let sc = SampleConfig::from_samples_per_second(1234);
116 assert_eq!(sc.get_interval(), 0.000_810_372_000_000_000_1);
117 }
118}
119
120#[derive(Debug, Clone, Copy)]
122#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
123pub struct ChannelConfig {
124 pub coupling: PicoCoupling,
125 pub range: PicoRange,
126 pub offset: f64,
127}
128
129impl ChannelConfig {
130 pub fn new() -> ChannelConfig {
131 ChannelConfig {
132 coupling: PicoCoupling::DC,
133 range: PicoRange::X1_PROBE_20V,
134 offset: 0.0,
135 }
136 }
137}
138
139impl Default for ChannelConfig {
140 fn default() -> Self {
141 ChannelConfig::new()
142 }
143}