@@ -15,36 +15,6 @@ use longan_nano::{
1515use riscv_rt:: entry;
1616use ushell:: { autocomplete:: * , history:: * , * } ;
1717
18- const MAX_COMMAND_LEN : usize = 16 ;
19- const HISTORY_SIZE : usize = 4 ;
20- const COMMANDS : usize = 5 ;
21-
22- const SHELL_PROMPT : & str = "#> " ;
23- const CR : & str = "\r \n " ;
24- const HELP : & str = "\r \n \
25- \x1b [31mL\x1b [32mE\x1b [34mD\x1b [33m Shell\x1b [0m\r \n \r \n \
26- USAGE:\r \n \
27- \t command [arg]\r \n \r \n \
28- COMMANDS:\r \n \
29- \t on <ch> Switch led channel on [r,g,b,a]\r \n \
30- \t off <ch> Switch led channel off [r,g,b,a]\r \n \
31- \t status Get leds status\r \n \
32- \t clear Clear screen\r \n \
33- \t help Print this message\r \n
34- " ;
35-
36- struct Context {
37- red : RED ,
38- green : GREEN ,
39- blue : BLUE ,
40- shell : UShell <
41- ushell:: Serial < u8 , Tx < USART0 > , Rx < USART0 > > ,
42- StaticAutocomplete < { COMMANDS } > ,
43- LRUHistory < { MAX_COMMAND_LEN } , { HISTORY_SIZE } > ,
44- { MAX_COMMAND_LEN } ,
45- > ,
46- }
47-
4818#[ entry]
4919fn main ( ) -> ! {
5020 let dp = pac:: Peripherals :: take ( ) . unwrap ( ) ;
@@ -62,6 +32,11 @@ fn main() -> ! {
6232 let gpioa = dp. GPIOA . split ( & mut rcu) ;
6333 let gpioc = dp. GPIOC . split ( & mut rcu) ;
6434
35+ let ( mut red, mut green, mut blue) = rgb ( gpioc. pc13 , gpioa. pa1 , gpioa. pa2 ) ;
36+ red. off ( ) ;
37+ green. off ( ) ;
38+ blue. off ( ) ;
39+
6540 let tx = gpioa. pa9 . into_alternate_push_pull ( ) ;
6641 let rx = gpioa. pa10 . into_floating_input ( ) ;
6742
@@ -72,90 +47,115 @@ fn main() -> ! {
7247 } ;
7348 let uart = serial:: Serial :: new ( dp. USART0 , ( tx, rx) , config, & mut afio, & mut rcu) ;
7449 let ( tx, rx) = uart. split ( ) ;
50+ let serial = ushell:: Serial :: from_parts ( tx, rx) ;
7551
7652 let autocomplete = StaticAutocomplete ( [ "clear" , "help" , "status" , "off " , "on " ] ) ;
77- let history = LRUHistory :: default ( ) ;
78- let shell = UShell :: new ( ushell:: Serial :: from_parts ( tx, rx) , autocomplete, history) ;
79-
80- let ( mut red, mut green, mut blue) = rgb ( gpioc. pc13 , gpioa. pa1 , gpioa. pa2 ) ;
81- red. off ( ) ;
82- green. off ( ) ;
83- blue. off ( ) ;
84-
85- let mut ctx = Context {
86- shell,
87- red,
88- green,
89- blue,
90- } ;
53+ let mut shell = UShell :: new ( serial, autocomplete, LRUHistory :: default ( ) ) ;
54+ let mut env = Env { red, green, blue } ;
9155
9256 loop {
93- poll_serial ( & mut ctx ) ;
57+ shell . spin ( & mut env ) . ok ( ) ;
9458 }
9559}
9660
97- fn poll_serial ( ctx : & mut Context ) {
98- match ctx. shell . poll ( ) {
99- Ok ( Some ( Input :: Command ( ( cmd, args) ) ) ) => {
100- match cmd {
101- "help" => {
102- ctx. shell . write_str ( HELP ) . ok ( ) ;
103- }
104- "clear" => {
105- ctx. shell . clear ( ) . ok ( ) ;
106- }
107- "status" => {
108- let red = if ctx. red . is_on ( ) { "On" } else { "Off" } ;
109- let green = if ctx. green . is_on ( ) { "On" } else { "Off" } ;
110- let blue = if ctx. blue . is_on ( ) { "On" } else { "Off" } ;
111- write ! (
112- ctx. shell,
113- "{0:}Red: {1:}{0:}Green: {2:}{0:}Blue: {3:}{0:}" ,
114- CR , red, green, blue,
115- )
116- . ok ( ) ;
117- }
118- "on" => {
119- match args {
120- "r" | "red" => ctx. red . on ( ) ,
121- "g" | "green" => ctx. green . on ( ) ,
122- "b" | "blue" => ctx. blue . on ( ) ,
123- "a" | "all" => {
124- ctx. red . on ( ) ;
125- ctx. green . on ( ) ;
126- ctx. blue . on ( ) ;
127- }
128- _ => {
129- write ! ( ctx. shell, "{0:}unsupported color channel" , CR ) . ok ( ) ;
130- }
131- }
132- ctx. shell . write_str ( CR ) . ok ( ) ;
133- }
134- "off" => {
135- match args {
136- "r" | "red" => ctx. red . off ( ) ,
137- "g" | "green" => ctx. green . off ( ) ,
138- "b" | "blue" => ctx. blue . off ( ) ,
139- "a" | "all" => {
140- ctx. red . off ( ) ;
141- ctx. green . off ( ) ;
142- ctx. blue . off ( ) ;
143- }
144- _ => {
145- write ! ( ctx. shell, "{0:}unsupported color channel" , CR ) . ok ( ) ;
146- }
147- }
148- ctx. shell . write_str ( CR ) . ok ( ) ;
149- }
150- "" => {
151- ctx. shell . write_str ( CR ) . ok ( ) ;
152- }
153- _ => {
154- write ! ( ctx. shell, "{0:}unsupported command{0:}" , CR ) . ok ( ) ;
155- }
61+ const CMD_LEN : usize = 16 ;
62+ const HISTORY_SIZE : usize = 4 ;
63+ const COMMANDS : usize = 5 ;
64+
65+ type Serial = ushell:: Serial < u8 , Tx < USART0 > , Rx < USART0 > > ;
66+ type Autocomplete = StaticAutocomplete < { COMMANDS } > ;
67+ type History = LRUHistory < { CMD_LEN } , { HISTORY_SIZE } > ;
68+ type Shell = UShell < Serial , Autocomplete , History , { CMD_LEN } > ;
69+
70+ struct Env {
71+ red : RED ,
72+ green : GREEN ,
73+ blue : BLUE ,
74+ }
75+
76+ type EnvResult = SpinResult < Serial , ( ) > ;
77+
78+ impl Env {
79+ fn on_cmd ( & mut self , shell : & mut Shell , args : & str ) -> EnvResult {
80+ match args {
81+ "r" | "red" => self . red . on ( ) ,
82+ "g" | "green" => self . green . on ( ) ,
83+ "b" | "blue" => self . blue . on ( ) ,
84+ "a" | "all" => {
85+ self . red . on ( ) ;
86+ self . green . on ( ) ;
87+ self . blue . on ( ) ;
88+ }
89+ _ => {
90+ write ! ( shell, "{0:}unsupported color channel" , CR ) . ok ( ) ;
15691 }
157- ctx. shell . write_str ( SHELL_PROMPT ) . ok ( ) ;
15892 }
159- _ => { }
93+ shell. write_str ( CR ) ?;
94+ Ok ( ( ) )
95+ }
96+
97+ fn off_cmd ( & mut self , shell : & mut Shell , args : & str ) -> EnvResult {
98+ match args {
99+ "r" | "red" => self . red . off ( ) ,
100+ "g" | "green" => self . green . off ( ) ,
101+ "b" | "blue" => self . blue . off ( ) ,
102+ "a" | "all" => {
103+ self . red . off ( ) ;
104+ self . green . off ( ) ;
105+ self . blue . off ( ) ;
106+ }
107+ _ => {
108+ write ! ( shell, "{0:}unsupported color channel" , CR ) . ok ( ) ;
109+ }
110+ }
111+ shell. write_str ( CR ) ?;
112+ Ok ( ( ) )
113+ }
114+
115+ fn status_cmd ( & mut self , shell : & mut Shell , _args : & str ) -> EnvResult {
116+ let red = if self . red . is_on ( ) { "On" } else { "Off" } ;
117+ let green = if self . green . is_on ( ) { "On" } else { "Off" } ;
118+ let blue = if self . blue . is_on ( ) { "On" } else { "Off" } ;
119+ write ! (
120+ shell,
121+ "{0:}Red: {1:}{0:}Green: {2:}{0:}Blue: {3:}{0:}" ,
122+ CR , red, green, blue,
123+ ) ?;
124+
125+ Ok ( ( ) )
160126 }
161127}
128+
129+ impl Environment < Serial , Autocomplete , History , ( ) , { CMD_LEN } > for Env {
130+ fn command ( & mut self , shell : & mut Shell , cmd : & str , args : & str ) -> EnvResult {
131+ match cmd {
132+ "clear" => shell. clear ( ) ?,
133+ "help" => shell. write_str ( HELP ) ?,
134+ "status" => self . status_cmd ( shell, args) ?,
135+ "on" => self . on_cmd ( shell, args) ?,
136+ "off" => self . off_cmd ( shell, args) ?,
137+ "" => shell. write_str ( CR ) ?,
138+ _ => write ! ( shell, "{0:}unsupported command: \" {1:}\" {0:}" , CR , cmd) ?,
139+ }
140+ shell. write_str ( SHELL_PROMPT ) ?;
141+ Ok ( ( ) )
142+ }
143+
144+ fn control ( & mut self , _shell : & mut Shell , _code : u8 ) -> EnvResult {
145+ Ok ( ( ) )
146+ }
147+ }
148+
149+ const SHELL_PROMPT : & str = "#> " ;
150+ const CR : & str = "\r \n " ;
151+ const HELP : & str = "\r \n \
152+ \x1b [31mL\x1b [32mE\x1b [34mD\x1b [33m Shell\x1b [0m\r \n \r \n \
153+ USAGE:\r \n \
154+ \x20 command [arg]\r \n \r \n \
155+ COMMANDS:\r \n \
156+ \x20 on <ch> Switch led channel on [r,g,b,a]\r \n \
157+ \x20 off <ch> Switch led channel off [r,g,b,a]\r \n \
158+ \x20 status Get leds status\r \n \
159+ \x20 clear Clear screen\r \n \
160+ \x20 help Print this message\r \n
161+ " ;
0 commit comments