1
1
#![ doc = include_str ! ( "../README.md" ) ]
2
+ use num_enum:: { IntoPrimitive , TryFromPrimitive } ;
2
3
use serialport:: SerialPort ;
3
4
use std:: { borrow:: Cow , io, ops:: Range , string:: FromUtf8Error , time:: Duration } ;
4
5
use thiserror:: Error ;
@@ -22,7 +23,7 @@ pub enum Error {
22
23
Io ( #[ from] io:: Error ) ,
23
24
#[ error( "Utf8 error {0}" ) ]
24
25
Utf8 ( #[ from] FromUtf8Error ) ,
25
- #[ error( "Parse" ) ]
26
+ #[ error( "Parse error in \" {0} \" " ) ]
26
27
Parse ( String ) ,
27
28
}
28
29
@@ -35,15 +36,15 @@ pub struct Ppk2 {
35
36
impl Ppk2 {
36
37
pub fn new < ' a > ( path : impl Into < Cow < ' a , str > > ) -> Result < Self > {
37
38
let port = serialport:: new ( path, 9600 )
38
- . timeout ( Duration :: from_millis ( 500 ) )
39
+ . timeout ( Duration :: from_millis ( 10000 ) )
39
40
. open ( ) ?;
40
41
Ok ( Self { port } )
41
42
}
42
43
43
- pub fn get_metadata ( & mut self ) -> Result < Modifiers > {
44
+ pub fn get_metadata ( & mut self ) -> Result < Metadata > {
44
45
let response = self . send_command ( Command :: GetMetaData ) ?;
45
46
46
- Modifiers :: parse ( response, None )
47
+ Metadata :: parse ( response, None )
47
48
}
48
49
49
50
pub fn reset ( & mut self ) -> Result < ( ) > {
@@ -54,59 +55,164 @@ impl Ppk2 {
54
55
pub fn send_command ( & mut self , command : Command ) -> Result < Vec < u8 > > {
55
56
self . port . write_all ( & Vec :: from_iter ( command. bytes ( ) ) ) ?;
56
57
// Doesn't allocate if expected response length is 0
57
- let mut buf = Vec :: with_capacity ( command. expected_response_len ( ) ) ;
58
- self . port . read_exact ( & mut buf) ?;
59
- Ok ( buf)
58
+ let mut response = Vec :: with_capacity ( command. expected_response_len ( ) ) ;
59
+ let mut buf = [ 0u8 ; 128 ] ;
60
+ while !command. response_complete ( & response) {
61
+ let n = self . port . read ( & mut buf) ?;
62
+ response. extend_from_slice ( & buf[ ..n] ) ;
63
+ }
64
+
65
+ Ok ( response)
60
66
}
61
67
}
62
68
63
69
#[ derive( Debug ) ]
64
70
pub struct Modifiers {
65
71
r : [ f32 ; 5 ] ,
66
- gs : [ u8 ; 5 ] ,
67
- gi : [ u8 ; 5 ] ,
68
- o : [ u8 ; 5 ] ,
69
- s : [ u8 ; 5 ] ,
70
- i : [ u8 ; 5 ] ,
71
- ug : [ u8 ; 5 ] ,
72
- }
73
-
74
- impl Modifiers {
75
- pub fn merge ( & mut self , incomplete : IncompleteModifiers ) {
76
- merge ! ( r, incomplete) ;
77
- }
72
+ gs : [ f32 ; 5 ] ,
73
+ gi : [ f32 ; 5 ] ,
74
+ o : [ f32 ; 5 ] ,
75
+ s : [ f32 ; 5 ] ,
76
+ i : [ f32 ; 5 ] ,
77
+ ug : [ f32 ; 5 ] ,
78
78
}
79
79
80
80
impl Default for Modifiers {
81
81
fn default ( ) -> Self {
82
82
Self {
83
83
r : [ 1031.64 , 101.65 , 10.15 , 0.94 , 0.043 ] ,
84
- gs : [ 1 , 1 , 1 , 1 , 1 ] ,
85
- gi : [ 1 , 1 , 1 , 1 , 1 ] ,
86
- o : [ 0 , 0 , 0 , 0 , 0 ] ,
87
- s : [ 0 , 0 , 0 , 0 , 0 ] ,
88
- i : [ 0 , 0 , 0 , 0 , 0 ] ,
89
- ug : [ 1 , 1 , 1 , 1 , 1 ] ,
84
+ gs : [ 1. , 1. , 1. , 1. , 1. ] ,
85
+ gi : [ 1. , 1. , 1. , 1. , 1. ] ,
86
+ o : [ 0. , 0. , 0. , 0. , 0. ] ,
87
+ s : [ 0. , 0. , 0. , 0. , 0. ] ,
88
+ i : [ 0. , 0. , 0. , 0. , 0. ] ,
89
+ ug : [ 1. , 1. , 1. , 1. , 1. ] ,
90
90
}
91
91
}
92
92
}
93
93
94
- impl Modifiers {
95
- pub fn parse ( bytes : Vec < u8 > , modifiers : Option < Modifiers > ) -> Result < Self > {
96
- use Error :: Parse ;
94
+ #[ repr( u8 ) ]
95
+ #[ derive( TryFromPrimitive , IntoPrimitive , Default , Debug ) ]
96
+ pub enum Mode {
97
+ #[ default]
98
+ Source = 0x01 ,
99
+ Ampere = 0x02 ,
100
+ }
97
101
98
- let mut modifiers = modifiers. unwrap_or_default ( ) ;
102
+ #[ derive( Default , Debug ) ]
103
+ pub struct Metadata {
104
+ modifiers : Modifiers ,
105
+ calibrated : bool ,
106
+ vdd : u16 ,
107
+ hw : u32 ,
108
+ mode : Mode ,
109
+ ia : u32 ,
110
+ }
99
111
100
- let metadata = String :: from_utf8 ( bytes) ?;
101
- dbg ! ( & metadata) ; // TODO may be JSON
102
- if !metadata. ends_with ( "END" ) {
103
- return Err ( Parse ( metadata) ) ;
112
+ impl Metadata {
113
+ /// Example metadata:
114
+ /// ```
115
+ /// Calibrated: 0
116
+ /// R0: 1003.3506
117
+ /// R1: 101.5865
118
+ /// R2: 10.3027
119
+ /// R3: 0.9636
120
+ /// R4: 0.0564
121
+ /// GS0: 0.0000
122
+ /// GS1: 112.7890
123
+ /// GS2: 18.0115
124
+ /// GS3: 2.4217
125
+ /// GS4: 0.0729
126
+ /// GI0: 1.0000
127
+ /// GI1: 0.9695
128
+ /// GI2: 0.9609
129
+ /// GI3: 0.9519
130
+ /// GI4: 0.9582
131
+ /// O0: 112.9420
132
+ /// O1: 75.4627
133
+ /// O2: 64.6020
134
+ /// O3: 50.4983
135
+ /// O4: 87.2177
136
+ /// VDD: 3000
137
+ /// HW: 9173
138
+ /// mode: 2
139
+ /// S0: 0.000000048
140
+ /// S1: 0.000000596
141
+ /// S2: 0.000005281
142
+ /// S3: 0.000062577
143
+ /// S4: 0.002940743
144
+ /// I0: -0.000000104
145
+ /// I1: -0.000001443
146
+ /// I2: 0.000036439
147
+ /// I3: -0.000374119
148
+ /// I4: -0.009388455
149
+ /// UG0: 1.00
150
+ /// UG1: 1.00
151
+ /// UG2: 1.00
152
+ /// UG3: 1.00
153
+ /// UG4: 1.00
154
+ /// IA: 56
155
+ /// END
156
+ /// ```
157
+ #[ rustfmt:: skip]
158
+ pub fn parse ( bytes : Vec < u8 > , metadata : Option < Metadata > ) -> Result < Self > {
159
+ use Error :: Parse ;
160
+
161
+ let mut metadata = metadata. unwrap_or_default ( ) ;
162
+ let raw_metadata = String :: from_utf8 ( bytes) ?;
163
+ if !raw_metadata. ends_with ( "END\n " ) {
164
+ return Err ( Parse ( raw_metadata) ) ;
104
165
}
105
- let lines = metadata. lines ( ) ;
166
+
167
+ let lines = raw_metadata. lines ( ) ;
106
168
for line in lines {
107
- todo ! ( "PArse line by line" )
169
+ // TODO kill this beast
170
+ match line. split_once ( ": " ) {
171
+ Some ( ( "Calibrated" , calibrated) ) => metadata. calibrated = calibrated != "0" ,
172
+ Some ( ( "R0" , r0) ) => metadata. modifiers . r [ 0 ] = r0. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
173
+ Some ( ( "R1" , r1) ) => metadata. modifiers . r [ 1 ] = r1. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
174
+ Some ( ( "R2" , r2) ) => metadata. modifiers . r [ 2 ] = r2. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
175
+ Some ( ( "R3" , r3) ) => metadata. modifiers . r [ 3 ] = r3. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
176
+ Some ( ( "R4" , r4) ) => metadata. modifiers . r [ 4 ] = r4. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
177
+ Some ( ( "GS0" , gs0) ) => metadata. modifiers . gs [ 0 ] = gs0. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
178
+ Some ( ( "GS1" , gs1) ) => metadata. modifiers . gs [ 1 ] = gs1. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
179
+ Some ( ( "GS2" , gs2) ) => metadata. modifiers . gs [ 2 ] = gs2. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
180
+ Some ( ( "GS3" , gs3) ) => metadata. modifiers . gs [ 3 ] = gs3. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
181
+ Some ( ( "GS4" , gs4) ) => metadata. modifiers . gs [ 4 ] = gs4. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
182
+ Some ( ( "GI0" , gi0) ) => metadata. modifiers . gi [ 0 ] = gi0. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
183
+ Some ( ( "GI1" , gi1) ) => metadata. modifiers . gi [ 1 ] = gi1. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
184
+ Some ( ( "GI2" , gi2) ) => metadata. modifiers . gi [ 2 ] = gi2. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
185
+ Some ( ( "GI3" , gi3) ) => metadata. modifiers . gi [ 3 ] = gi3. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
186
+ Some ( ( "GI4" , gi4) ) => metadata. modifiers . gi [ 4 ] = gi4. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
187
+ Some ( ( "O0" , o0) ) => metadata. modifiers . o [ 0 ] = o0. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
188
+ Some ( ( "O1" , o1) ) => metadata. modifiers . o [ 1 ] = o1. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
189
+ Some ( ( "O2" , o2) ) => metadata. modifiers . o [ 2 ] = o2. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
190
+ Some ( ( "O3" , o3) ) => metadata. modifiers . o [ 3 ] = o3. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
191
+ Some ( ( "O4" , o4) ) => metadata. modifiers . o [ 4 ] = o4. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
192
+ Some ( ( "VDD" , vdd) ) => metadata. vdd = vdd. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
193
+ Some ( ( "HW" , hw) ) => metadata. hw = hw. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
194
+ Some ( ( "mode" , mode) ) => metadata. mode = mode. parse :: < u8 > ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?. try_into ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
195
+ Some ( ( "S0" , s0) ) => metadata. modifiers . s [ 0 ] = s0. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
196
+ Some ( ( "S1" , s1) ) => metadata. modifiers . s [ 0 ] = s1. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
197
+ Some ( ( "S2" , s2) ) => metadata. modifiers . s [ 0 ] = s2. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
198
+ Some ( ( "S3" , s3) ) => metadata. modifiers . s [ 0 ] = s3. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
199
+ Some ( ( "S4" , s4) ) => metadata. modifiers . s [ 0 ] = s4. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
200
+ Some ( ( "I0" , i0) ) => metadata. modifiers . i [ 0 ] = i0. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
201
+ Some ( ( "I1" , i1) ) => metadata. modifiers . i [ 0 ] = i1. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
202
+ Some ( ( "I2" , i2) ) => metadata. modifiers . i [ 0 ] = i2. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
203
+ Some ( ( "I3" , i3) ) => metadata. modifiers . i [ 0 ] = i3. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
204
+ Some ( ( "I4" , i4) ) => metadata. modifiers . i [ 0 ] = i4. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
205
+ Some ( ( "UG0" , ug0) ) => metadata. modifiers . ug [ 0 ] = ug0. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
206
+ Some ( ( "UG1" , ug1) ) => metadata. modifiers . ug [ 0 ] = ug1. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
207
+ Some ( ( "UG2" , ug2) ) => metadata. modifiers . ug [ 0 ] = ug2. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
208
+ Some ( ( "UG3" , ug3) ) => metadata. modifiers . ug [ 0 ] = ug3. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
209
+ Some ( ( "UG4" , ug4) ) => metadata. modifiers . ug [ 0 ] = ug4. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
210
+ Some ( ( "IA" , ia) ) => metadata. ia = ia. parse ( ) . map_err ( |_| Parse ( line. to_owned ( ) ) ) ?,
211
+ None if line == "END" => return Ok ( metadata) ,
212
+ _ => return Err ( Parse ( line. to_owned ( ) ) ) ,
213
+ }
108
214
}
109
215
110
- todo ! ( ) ;
216
+ Ok ( metadata )
111
217
}
112
218
}
0 commit comments