Skip to content

Commit c2cf0d2

Browse files
committed
inputmodule-control: Add commands for B1display and C1minimal
Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 6c8990e commit c2cf0d2

File tree

5 files changed

+272
-104
lines changed

5 files changed

+272
-104
lines changed

inputmodule-control/src/b1display.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use clap::Parser;
2+
3+
/// B1 Display
4+
#[derive(Parser, Debug)]
5+
#[command(arg_required_else_help = true)]
6+
pub struct B1DisplaySubcommand {
7+
/// Set sleep status or get, if no value provided
8+
#[arg(long)]
9+
pub sleeping: Option<Option<bool>>,
10+
11+
/// Jump to the bootloader
12+
#[arg(long)]
13+
pub bootloader: bool,
14+
15+
/// Crash the firmware (TESTING ONLY!)
16+
#[arg(long)]
17+
pub panic: bool,
18+
19+
/// Serial device, like /dev/ttyACM0 or COM0
20+
#[arg(long)]
21+
pub serial_dev: Option<String>,
22+
23+
/// Get the device version
24+
#[arg(short, long)]
25+
pub version: bool,
26+
27+
/// Turn display on/off
28+
// TODO: Allow getting current state
29+
#[arg(long)]
30+
pub display_on: Option<bool>,
31+
32+
/// Invert screen on/off
33+
// TODO: Allow getting current state
34+
#[arg(long)]
35+
pub invert_screen: Option<bool>,
36+
}

inputmodule-control/src/c1minimal.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use clap::Parser;
2+
3+
#[derive(Clone, Copy, Debug, PartialEq, clap::ValueEnum)]
4+
pub enum Color {
5+
White,
6+
Black,
7+
Red,
8+
Green,
9+
Blue,
10+
Yellow,
11+
Cyan,
12+
Purple,
13+
}
14+
15+
#[derive(Parser, Debug)]
16+
#[command(arg_required_else_help = true)]
17+
pub struct C1MinimalSubcommand {
18+
/// Set sleep status or get, if no value provided
19+
#[arg(long)]
20+
pub sleeping: Option<Option<bool>>,
21+
22+
/// Jump to the bootloader
23+
#[arg(long)]
24+
pub bootloader: bool,
25+
26+
/// Crash the firmware (TESTING ONLY!)
27+
#[arg(long)]
28+
pub panic: bool,
29+
30+
/// Serial device, like /dev/ttyACM0 or COM0
31+
#[arg(long)]
32+
pub serial_dev: Option<String>,
33+
34+
/// Get the device version
35+
#[arg(short, long)]
36+
pub version: bool,
37+
38+
/// Set color
39+
// TODO: Allow getting current state
40+
#[arg(long)]
41+
#[clap(value_enum)]
42+
pub set_color: Option<Color>,
43+
}

inputmodule-control/src/inputmodule.rs

Lines changed: 88 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@ use std::thread;
22
use std::time::Duration;
33

44
use chrono::Local;
5-
use clap::Parser;
65
use image::{io::Reader as ImageReader, Luma};
76
use rand::prelude::*;
87
use serialport::{SerialPort, SerialPortInfo};
98

9+
use crate::c1minimal::Color;
1010
use crate::font::{convert_font, convert_symbol};
11+
use crate::ledmatrix::Pattern;
1112

1213
const FWK_MAGIC: &[u8] = &[0x32, 0xAC];
1314
const FRAMEWORK_VID: u16 = 0x32AC;
1415
const LED_MATRIX_PID: u16 = 0x0020;
1516
const B1_LCD_PID: u16 = 0x0021;
1617

18+
// Commands
1719
const BRIGHTNESS: u8 = 0x00;
1820
const PERCENTAGE: u8 = 0x01;
1921
const PATTERN: u8 = 0x01;
@@ -25,113 +27,19 @@ const DISPLAY_BW_IMAGE: u8 = 0x06;
2527
const SEND_COL: u8 = 0x07;
2628
const COMMIT_COLS: u8 = 0x08;
2729
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;
2836
const VERSION: u8 = 0x20;
2937

3038
const WIDTH: usize = 9;
3139
const HEIGHT: usize = 34;
3240

3341
const SERIAL_TIMEOUT: Duration = Duration::from_millis(20);
3442

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-
13543
fn find_serialdevs(ports: &[SerialPortInfo], requested: &Option<String>) -> Vec<String> {
13644
if let Some(requested) = requested {
13745
for p in ports {
@@ -169,14 +77,21 @@ pub fn serial_commands(args: &crate::ClapCli) {
16977
Some(crate::Commands::LedMatrix(ledmatrix_args)) => {
17078
find_serialdevs(&ports, &ledmatrix_args.serial_dev)
17179
}
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![],
17387
};
17488
if serialdevs.is_empty() {
17589
println!("Failed to find serial devivce. Please manually specify with --serial-dev");
17690
return;
17791
};
17892

17993
match &args.command {
94+
// TODO: Handle generic commands without code deduplication
18095
Some(crate::Commands::LedMatrix(ledmatrix_args)) => {
18196
for serialdev in &serialdevs {
18297
if args.verbose {
@@ -248,7 +163,55 @@ pub fn serial_commands(args: &crate::ClapCli) {
248163
clock_cmd(&serialdevs);
249164
}
250165
}
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+
}
252215
_ => {}
253216
}
254217
}
@@ -625,3 +588,25 @@ fn show_symbols(serialdev: &str, symbols: &Vec<String>) {
625588
let font_items: Vec<Vec<u8>> = symbols.iter().map(|x| convert_symbol(x)).collect();
626589
show_font(serialdev, &font_items);
627590
}
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

Comments
 (0)