@@ -2,18 +2,20 @@ use std::thread;
2
2
use std:: time:: Duration ;
3
3
4
4
use chrono:: Local ;
5
- use clap:: Parser ;
6
5
use image:: { io:: Reader as ImageReader , Luma } ;
7
6
use rand:: prelude:: * ;
8
7
use serialport:: { SerialPort , SerialPortInfo } ;
9
8
9
+ use crate :: c1minimal:: Color ;
10
10
use crate :: font:: { convert_font, convert_symbol} ;
11
+ use crate :: ledmatrix:: Pattern ;
11
12
12
13
const FWK_MAGIC : & [ u8 ] = & [ 0x32 , 0xAC ] ;
13
14
const FRAMEWORK_VID : u16 = 0x32AC ;
14
15
const LED_MATRIX_PID : u16 = 0x0020 ;
15
16
const B1_LCD_PID : u16 = 0x0021 ;
16
17
18
+ // Commands
17
19
const BRIGHTNESS : u8 = 0x00 ;
18
20
const PERCENTAGE : u8 = 0x01 ;
19
21
const PATTERN : u8 = 0x01 ;
@@ -25,113 +27,19 @@ const DISPLAY_BW_IMAGE: u8 = 0x06;
25
27
const SEND_COL : u8 = 0x07 ;
26
28
const COMMIT_COLS : u8 = 0x08 ;
27
29
const _B1_RESERVED: u8 = 0x09 ;
30
+ const _START_GAME: u8 = 0x10 ;
31
+ const _GAME_CONTROL: u8 = 0x11 ;
32
+ const _GAME_STATUS: u8 = 0x12 ;
33
+ const SET_COLOR : u8 = 0x13 ;
34
+ const DISPLAY_ON : u8 = 0x14 ;
35
+ const INVERT_SCREEN : u8 = 0x15 ;
28
36
const VERSION : u8 = 0x20 ;
29
37
30
38
const WIDTH : usize = 9 ;
31
39
const HEIGHT : usize = 34 ;
32
40
33
41
const SERIAL_TIMEOUT : Duration = Duration :: from_millis ( 20 ) ;
34
42
35
- #[ derive( Clone , Copy , Debug , PartialEq , clap:: ValueEnum ) ]
36
- enum Pattern {
37
- // Percentage = 0
38
- Gradient = 1 ,
39
- DoubleGradient = 2 ,
40
- LotusSideways = 3 ,
41
- Zigzag = 4 ,
42
- AllOn = 5 ,
43
- Panic = 6 ,
44
- LotusTopDown = 7 ,
45
- //AllBrightnesses
46
- }
47
-
48
- /// LED Matrix
49
- #[ derive( Parser , Debug ) ]
50
- #[ command( arg_required_else_help = true ) ]
51
- pub struct LedMatrixSubcommand {
52
- /// Set LED max brightness percentage or get, if no value provided
53
- #[ arg( long) ]
54
- brightness : Option < Option < u8 > > ,
55
-
56
- /// Set sleep status or get, if no value provided
57
- #[ arg( long) ]
58
- sleeping : Option < Option < bool > > ,
59
-
60
- /// Jump to the bootloader
61
- #[ arg( long) ]
62
- bootloader : bool ,
63
-
64
- /// Display a percentage (0-100)
65
- #[ arg( long) ]
66
- percentage : Option < u8 > ,
67
-
68
- /// Start/stop animation
69
- #[ arg( long) ]
70
- animate : Option < Option < bool > > ,
71
-
72
- /// Display a pattern
73
- #[ arg( long) ]
74
- #[ clap( value_enum) ]
75
- pattern : Option < Pattern > ,
76
-
77
- /// Show every brightness, one per pixel
78
- #[ arg( long) ]
79
- all_brightnesses : bool ,
80
-
81
- /// Blink the current pattern once a second
82
- #[ arg( long) ]
83
- blinking : bool ,
84
-
85
- /// Breathing brightness of the current pattern
86
- #[ arg( long) ]
87
- breathing : bool ,
88
-
89
- /// Display black&white image
90
- #[ arg( long) ]
91
- image_bw : Option < String > ,
92
-
93
- /// Display grayscale image
94
- #[ arg( long) ]
95
- image_gray : Option < String > ,
96
-
97
- /// Random EQ
98
- #[ arg( long) ]
99
- random_eq : bool ,
100
-
101
- /// EQ with custom values
102
- #[ arg( long, num_args( 9 ) ) ]
103
- eq : Option < Vec < u8 > > ,
104
-
105
- /// Clock
106
- #[ arg( long) ]
107
- clock : bool ,
108
-
109
- /// Display a string (max 5 chars)
110
- #[ arg( long) ]
111
- string : Option < String > ,
112
-
113
- /// Display a string (max 5 symbols)
114
- #[ arg( long, num_args( 0 ..6 ) ) ]
115
- symbols : Option < Vec < String > > ,
116
-
117
- /// Crash the firmware (TESTING ONLY!)
118
- #[ arg( long) ]
119
- panic : bool ,
120
-
121
- /// Serial device, like /dev/ttyACM0 or COM0
122
- #[ arg( long) ]
123
- serial_dev : Option < String > ,
124
-
125
- /// Get the device version
126
- #[ arg( short, long) ]
127
- version : bool ,
128
- }
129
-
130
- /// B1 Display
131
- #[ derive( Parser , Debug ) ]
132
- #[ command( arg_required_else_help = true ) ]
133
- pub struct B1DisplaySubcommand { }
134
-
135
43
fn find_serialdevs ( ports : & [ SerialPortInfo ] , requested : & Option < String > ) -> Vec < String > {
136
44
if let Some ( requested) = requested {
137
45
for p in ports {
@@ -169,14 +77,21 @@ pub fn serial_commands(args: &crate::ClapCli) {
169
77
Some ( crate :: Commands :: LedMatrix ( ledmatrix_args) ) => {
170
78
find_serialdevs ( & ports, & ledmatrix_args. serial_dev )
171
79
}
172
- _ => vec ! [ ] ,
80
+ Some ( crate :: Commands :: B1Display ( ledmatrix_args) ) => {
81
+ find_serialdevs ( & ports, & ledmatrix_args. serial_dev )
82
+ }
83
+ Some ( crate :: Commands :: C1Minimal ( c1minimal_args) ) => {
84
+ find_serialdevs ( & ports, & c1minimal_args. serial_dev )
85
+ }
86
+ None => vec ! [ ] ,
173
87
} ;
174
88
if serialdevs. is_empty ( ) {
175
89
println ! ( "Failed to find serial devivce. Please manually specify with --serial-dev" ) ;
176
90
return ;
177
91
} ;
178
92
179
93
match & args. command {
94
+ // TODO: Handle generic commands without code deduplication
180
95
Some ( crate :: Commands :: LedMatrix ( ledmatrix_args) ) => {
181
96
for serialdev in & serialdevs {
182
97
if args. verbose {
@@ -248,7 +163,55 @@ pub fn serial_commands(args: &crate::ClapCli) {
248
163
clock_cmd ( & serialdevs) ;
249
164
}
250
165
}
251
- Some ( crate :: Commands :: B1Display ( _b1display_args) ) => { }
166
+ Some ( crate :: Commands :: B1Display ( b1display_args) ) => {
167
+ for serialdev in & serialdevs {
168
+ if args. verbose {
169
+ println ! ( "Selected serialdev: {:?}" , serialdev) ;
170
+ }
171
+
172
+ if b1display_args. bootloader {
173
+ bootloader_cmd ( serialdev) ;
174
+ }
175
+ if let Some ( sleeping_arg) = b1display_args. sleeping {
176
+ sleeping_cmd ( serialdev, sleeping_arg) ;
177
+ }
178
+ if b1display_args. panic {
179
+ simple_cmd ( serialdev, PANIC , & [ 0x00 ] ) ;
180
+ }
181
+ if b1display_args. version {
182
+ get_device_version ( serialdev) ;
183
+ }
184
+ if let Some ( display_on) = b1display_args. display_on {
185
+ display_on_cmd ( serialdev, display_on) ;
186
+ }
187
+ if let Some ( invert_screen) = b1display_args. invert_screen {
188
+ invert_screen_cmd ( serialdev, invert_screen) ;
189
+ }
190
+ }
191
+ }
192
+ Some ( crate :: Commands :: C1Minimal ( c1minimal_args) ) => {
193
+ for serialdev in & serialdevs {
194
+ if args. verbose {
195
+ println ! ( "Selected serialdev: {:?}" , serialdev) ;
196
+ }
197
+
198
+ if c1minimal_args. bootloader {
199
+ bootloader_cmd ( serialdev) ;
200
+ }
201
+ if let Some ( sleeping_arg) = c1minimal_args. sleeping {
202
+ sleeping_cmd ( serialdev, sleeping_arg) ;
203
+ }
204
+ if c1minimal_args. panic {
205
+ simple_cmd ( serialdev, PANIC , & [ 0x00 ] ) ;
206
+ }
207
+ if c1minimal_args. version {
208
+ get_device_version ( serialdev) ;
209
+ }
210
+ if let Some ( color) = c1minimal_args. set_color {
211
+ set_color_cmd ( serialdev, color) ;
212
+ }
213
+ }
214
+ }
252
215
_ => { }
253
216
}
254
217
}
@@ -625,3 +588,25 @@ fn show_symbols(serialdev: &str, symbols: &Vec<String>) {
625
588
let font_items: Vec < Vec < u8 > > = symbols. iter ( ) . map ( |x| convert_symbol ( x) ) . collect ( ) ;
626
589
show_font ( serialdev, & font_items) ;
627
590
}
591
+
592
+ fn display_on_cmd ( serialdev : & str , display_on : bool ) {
593
+ simple_cmd ( serialdev, DISPLAY_ON , & [ display_on as u8 ] ) ;
594
+ }
595
+
596
+ fn invert_screen_cmd ( serialdev : & str , invert_on : bool ) {
597
+ simple_cmd ( serialdev, INVERT_SCREEN , & [ invert_on as u8 ] ) ;
598
+ }
599
+
600
+ fn set_color_cmd ( serialdev : & str , color : Color ) {
601
+ let args = match color {
602
+ Color :: White => & [ 0xFF , 0xFF , 0xFF ] ,
603
+ Color :: Black => & [ 0x00 , 0x00 , 0x00 ] ,
604
+ Color :: Red => & [ 0xFF , 0x00 , 0x00 ] ,
605
+ Color :: Green => & [ 0x00 , 0xFF , 0x00 ] ,
606
+ Color :: Blue => & [ 0x00 , 0x00 , 0xFF ] ,
607
+ Color :: Yellow => & [ 0xFF , 0xFF , 0x00 ] ,
608
+ Color :: Cyan => & [ 0x00 , 0xFF , 0xFF ] ,
609
+ Color :: Purple => & [ 0xFF , 0x00 , 0xFF ] ,
610
+ } ;
611
+ simple_cmd ( serialdev, SET_COLOR , args) ;
612
+ }
0 commit comments