Permalink
Cannot retrieve contributors at this time
#![feature(no_std)] | |
#![feature(macro_reexport)] | |
#![feature(unboxed_closures)] | |
#![feature(lang_items, asm)] | |
#![feature(convert)] | |
#![no_std] | |
#![feature(core, alloc, collections)] | |
#![allow(dead_code)] | |
#![allow(non_snake_case)] | |
extern crate core; | |
extern crate alloc; | |
extern crate cli; | |
use core::prelude::*; | |
pub mod runtime_support; | |
pub mod serial_demo_api; | |
#[macro_use] | |
#[macro_reexport(vec, format)] | |
pub extern crate collections; | |
//use collections::Vec; | |
//use collections::String; | |
//use collections::prelude::*; | |
//#[macro_use] | |
//#[macro_reexport(vec, format)] | |
//extern crate "collections" as core_collections; | |
use serial_demo_api::*; | |
use cli::*; | |
use collections::string::*; | |
use collections::Vec; | |
use alloc::boxed::Box; | |
#[no_mangle] | |
pub extern fn serial_demo_main_loop() -> ! { | |
let mut usart2 = STM32_USART::new(STM32_USART_Device::USART2); | |
// http://wiki.bash-hackers.org/scripting/terminalcodes | |
let mut usart2_cli = CliPromptAutocompleteBuffer::new("\x1b[36mclidemo\x1b[39m \x1b[1m#\x1b[0m ".to_string()); | |
usart2.println(""); | |
usart2.println(""); | |
usart2.println("STM32 Rust CLI demo"); | |
usart2_cli.print_prompt(&usart2); | |
// cli commands | |
let mut commands = { | |
let mut cmds = Vec::new(); | |
{ | |
let help = CliCommandKeyword { | |
keyword: "help".to_string(), | |
action: |line, cli| { | |
cli.output_line("Hey, help here!"); | |
} | |
}; | |
cmds.push(Box::new(help) as Box<CliCommand>); | |
} | |
{ | |
let green = CliPropertyVar { | |
var_name: "led_green".to_string(), | |
val_hint: "on|off".to_string(), | |
var_value: false, | |
var_output: |v| { | |
(if *v == true { "on" } else { "off" }).to_string() | |
}, | |
var_input: |v| { | |
match v { | |
"on" => { | |
stm32_enable(STM32Led::Green); | |
Some(true) | |
} | |
"off" => { | |
stm32_disable(STM32Led::Green); | |
Some(false) | |
} | |
_ => None | |
} | |
} | |
}; | |
let blue = CliPropertyVar { | |
var_name: "led_blue".to_string(), | |
val_hint: "on|off".to_string(), | |
var_value: false, | |
var_output: |v| { | |
(if *v == true { "on" } else { "off" }).to_string() | |
}, | |
var_input: |v| { | |
match v { | |
"on" => { | |
stm32_enable(STM32Led::Blue); | |
Some(true) | |
} | |
"off" => { | |
stm32_disable(STM32Led::Blue); | |
Some(false) | |
} | |
_ => None | |
} | |
} | |
}; | |
let red = CliPropertyVar { | |
var_name: "led_red".to_string(), | |
val_hint: "on|off".to_string(), | |
var_value: false, | |
var_output: |v| { | |
(if *v == true { "on" } else { "off" }).to_string() | |
}, | |
var_input: |v| { | |
match v { | |
"on" => { | |
stm32_enable(STM32Led::Red); | |
Some(true) | |
} | |
"off" => { | |
stm32_disable(STM32Led::Red); | |
Some(false) | |
} | |
_ => None | |
} | |
} | |
}; | |
let orange = CliPropertyVar { | |
var_name: "led_orange".to_string(), | |
val_hint: "on|off".to_string(), | |
var_value: false, | |
var_output: |v| { | |
(if *v == true { "on" } else { "off" }).to_string() | |
}, | |
var_input: |v| { | |
match v { | |
"on" => { | |
stm32_enable(STM32Led::Orange); | |
Some(true) | |
} | |
"off" => { | |
stm32_disable(STM32Led::Orange); | |
Some(false) | |
} | |
_ => None | |
} | |
} | |
}; | |
cmds.push(Box::new(green) as Box<CliCommand>); | |
cmds.push(Box::new(blue) as Box<CliCommand>); | |
cmds.push(Box::new(red) as Box<CliCommand>); | |
cmds.push(Box::new(orange) as Box<CliCommand>); | |
} | |
{ | |
let some_int = CliPropertyVar { | |
var_name: "some_int".to_string(), | |
val_hint: "positive integer".to_string(), | |
var_value: 100, | |
var_output: |v| { | |
v.to_string() | |
}, | |
var_input: |v| { | |
let n = v.parse::<i32>().ok(); | |
match n { | |
Some(n) if n >= 0 => Some(n), | |
_ => None | |
} | |
} | |
}; | |
cmds.push(Box::new(some_int) as Box<CliCommand>); | |
} | |
cmds | |
}; | |
// note: the input handling would usually be implemented in an interrupt, | |
// but for demonstration purposes a loop is good enough. interrupts would | |
// require at least some mutexes (when handling multiple terminals with a | |
// single global CLI command set). | |
loop { | |
let u2_byte = usart2.try_read_byte(); | |
match u2_byte { | |
Some(b) => { | |
usart2_cli.handle_received_byte(b, &usart2.clone(), commands.as_mut_slice(), &mut usart2); | |
} | |
_ => {} | |
} | |
delay(1); | |
} | |
} |