Skip to content

Commit

Permalink
shell completions
Browse files Browse the repository at this point in the history
  • Loading branch information
dotcypress committed Apr 17, 2024
1 parent ec78430 commit 60f965e
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 41 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ edition = "2021"

[dependencies]
clap = "4.4.6"
clap_complete = "4.5.2"
rmp-serde = "1.1.2"
rusb = "0.9"
serde = { version = "1.0.188", features = ["serde_derive"] }
Expand Down
2 changes: 0 additions & 2 deletions extender/src/upico.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@ impl<B: UsbBus> UsbClass<B> for UpicoClass {
let state = u32::from_le_bytes(xfer.data()[0..4].try_into().unwrap());
self.tx.write(0b01100000_00000000);
self.tx.write(state);

self.pin_dirs = u32::from_le_bytes(xfer.data()[4..8].try_into().unwrap());
self.tx.write(0b01100000_10000000);
self.tx.write(self.pin_dirs);

xfer.accept()
}
0x01 => {
Expand Down
4 changes: 2 additions & 2 deletions pcb/upico.kicad_pcb
Original file line number Diff line number Diff line change
Expand Up @@ -34972,7 +34972,7 @@
(justify left bottom)
)
)
(gr_text "A04/A06 "
(gr_text "CM4"
(at 62.970156 113.09376 0)
(layer "F.SilkS" knockout)
(uuid "c7b887b0-9c62-497e-b5c2-bd9dc8fe502a")
Expand All @@ -34985,7 +34985,7 @@
(justify left bottom)
)
)
(gr_text "R01/CM4"
(gr_text "R01"
(at 62.9666 118.3386 0)
(layer "F.SilkS" knockout)
(uuid "d0788985-f076-4320-a2f3-5a6b0c6acd27")
Expand Down
2 changes: 1 addition & 1 deletion pcb/upico.kicad_prl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"board": {
"active_layer": 0,
"active_layer": 37,
"active_layer_preset": "",
"auto_track_width": true,
"hidden_netclasses": [],
Expand Down
1 change: 0 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ See other examples: https://github.com/raspberrypi/pico-examples

### CM4 core & uPico PCB rev:0x02

* External 5V(AUX) programmable switch isn't supported, 5V is always present on pin header.
* Overcurrent reporting feature isn't supported.

## License
Expand Down
6 changes: 3 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ pub mod platform {

#[cfg(feature = "cm4")]
pub mod platform {
pub const AUX_SWITCH: bool = true;
pub const OCP_REPORTING: bool = false;
pub const AUX_SWITCH: bool = false;
pub const PIN_PICO_BOOT: usize = 27;
pub const PIN_VDD_EN: usize = 26;
pub const PIN_USB_EN: usize = 21;
pub const PIN_PICO_RUN: usize = 6;
pub const PIN_AUX_EN: usize = 16;
//TODO: fix pcb routing
pub const PIN_PICO_RUN: usize = 22;
pub const PIN_AUX_EN: usize = 23;
pub const PIN_AUX_OCP: usize = 29;
pub const PIN_VDD_OCP: usize = 25;
pub const PIN_USB_OCP: usize = 20;
Expand Down
85 changes: 53 additions & 32 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use clap::{builder::PossibleValue, *};
use clap_complete::{generate, Shell};
use config::*;
use extender::*;
use gpio::*;
Expand Down Expand Up @@ -78,6 +79,15 @@ fn cli() -> Command {
.arg(dev_arg.clone())
.about("Reset Pico and enter USB bootloader"),
)
.subcommand(
Command::new("generate")
.arg(
Arg::new("generator")
.required(true)
.value_parser(value_parser!(Shell)),
)
.about("Generate shell completions"),
)
.subcommand(
Command::new("gpio")
.about("GPIO utils")
Expand Down Expand Up @@ -160,12 +170,16 @@ fn print_power_state(line: &str, state: PowerState) {
println!(
"{line}: {} {}",
if state.on { "ON " } else { "OFF" },
if state.ocp { "[OCP]" } else { "" }
if platform::OCP_REPORTING && state.ocp {
"[OCP]"
} else {
""
}
);
}

fn parse_power_line(cmd: &ArgMatches) -> Result<PowerLine, AppError> {
cmd.get_one::<String>("LINE")
fn parse_power_line(args: &ArgMatches) -> Result<PowerLine, AppError> {
args.get_one::<String>("LINE")
.unwrap()
.try_into()
.map_err(|_| AppError::InvalidLine)
Expand Down Expand Up @@ -210,8 +224,13 @@ fn mount_pico(disk: &str) -> Result<String, AppError> {
fn run() -> AppResult {
match cli().get_matches().subcommand() {
Some(("service", _)) => Service::start()?,
Some(("pinout", cmd)) => {
if cmd.get_flag("full") {
Some(("generate", args)) => {
if let Some(generator) = args.get_one::<Shell>("generator") {
generate(*generator, &mut cli(), "upico", &mut io::stdout());
}
}
Some(("pinout", args)) => {
if args.get_flag("full") {
println!("{}", include_str!("resources/pinout_full.ansi"));
} else {
println!("{}", include_str!("resources/pinout.ansi"));
Expand All @@ -220,53 +239,55 @@ fn run() -> AppResult {
Some(("reset", _)) => {
Service::send(Request::Reset)?;
}
Some(("boot", cmd)) => {
Some(("boot", args)) => {
Service::send(Request::EnterBootloader)?;
if cmd.get_flag("mount") {
let disk = cmd.get_one::<String>("PICO_DEV").unwrap();
if args.get_flag("mount") {
let disk = args.get_one::<String>("PICO_DEV").unwrap();
mount_pico(disk)?;
}
}
Some(("install", cmd)) => {
Some(("install", args)) => {
Service::send(Request::EnterBootloader)?;
let mut path = if cmd.get_flag("mount") {
let disk = cmd.get_one::<String>("PICO_DEV").unwrap();
let mut path = if args.get_flag("mount") {
let disk = args.get_one::<String>("PICO_DEV").unwrap();
mount_pico(disk)?
} else {
let path = cmd.get_one::<String>("PICO_PATH").unwrap().to_string();
let path = args.get_one::<String>("PICO_PATH").unwrap().to_string();
wait_for_path(Path::new(&path));
path
};
path.push_str("/fw.uf2");
let firmware = cmd.get_one::<String>("FIRMWARE").unwrap();
let firmware = args.get_one::<String>("FIRMWARE").unwrap();
fs::copy(firmware, path).map_err(AppError::IoError)?;
}
Some(("power", cmd)) => match cmd.subcommand() {
Some(("on", cmd)) => {
let line = parse_power_line(cmd)?;
Some(("power", args)) => match args.subcommand() {
Some(("on", args)) => {
let line = parse_power_line(args)?;
Service::send(Request::PowerOn(line))?;
}
Some(("off", cmd)) => {
let line = parse_power_line(cmd)?;
Some(("off", args)) => {
let line = parse_power_line(args)?;
Service::send(Request::PowerOff(line))?;
}
Some(("cycle", cmd)) => {
let line = parse_power_line(cmd)?;
Some(("cycle", args)) => {
let line = parse_power_line(args)?;
Service::send(Request::PowerCycle(line))?;
}
Some(("status", _)) if platform::OCP_REPORTING => {
Some(("status", _)) => {
if let Response::PowerReport(report) = Service::send(Request::PowerStatus)? {
print_power_state("AUX", report.aux);
if platform::AUX_SWITCH {
print_power_state("AUX", report.aux);
}
print_power_state("VDD", report.vdd);
print_power_state("USB", report.usb);
}
}
_ => {}
},
Some(("gpio", cmd)) => match cmd.subcommand() {
Some(("set", cmd)) => {
Some(("gpio", args)) => match args.subcommand() {
Some(("set", args)) => {
let mut gpio_state = Extender::read_digital().map_err(AppError::UsbError)?;
if let Some(configs) = cmd.get_many::<String>("CONFIG") {
if let Some(configs) = args.get_many::<String>("CONFIG") {
for pin_config in configs {
if let Some((pin, mode)) = pin_config.split_once('=') {
let pin: u8 = pin.parse().map_err(AppError::ParseIntError)?;
Expand All @@ -290,8 +311,8 @@ fn run() -> AppResult {
}
Extender::write_digital(gpio_state).map_err(AppError::UsbError)?;
}
Some(("get", cmd)) => {
if let Some(pin) = cmd
Some(("get", args)) => {
if let Some(pin) = args
.get_one::<String>("PIN")
.map(|s| s.parse::<u8>().unwrap_or_default())
{
Expand Down Expand Up @@ -325,7 +346,7 @@ fn run() -> AppResult {
}
}
}
Some(("led", cmd)) => match cmd.get_one::<String>("STATUS") {
Some(("led", args)) => match args.get_one::<String>("STATUS") {
Some(status) => match status.as_str() {
"on" => Extender::set_led(true).map_err(AppError::UsbError)?,
"off" => Extender::set_led(false).map_err(AppError::UsbError)?,
Expand All @@ -334,13 +355,13 @@ fn run() -> AppResult {
_ => return Err(AppError::InvalidLedMode),
},

Some(("install", cmd)) => {
Some(("install", args)) => {
Service::send(Request::EnterBootloader)?;
let mut path = if cmd.get_flag("mount") {
let disk = cmd.get_one::<String>("PICO_DEV").unwrap();
let mut path = if args.get_flag("mount") {
let disk = args.get_one::<String>("PICO_DEV").unwrap();
mount_pico(disk)?
} else {
let path = cmd.get_one::<String>("PICO_PATH").unwrap().to_string();
let path = args.get_one::<String>("PICO_PATH").unwrap().to_string();
wait_for_path(Path::new(&path));
path
};
Expand Down

0 comments on commit 60f965e

Please sign in to comment.