Included pin subcommand with auditing and assignment

This commit is contained in:
Eric Ratliff
2026-02-19 16:58:41 -06:00
parent 9bda9123ea
commit 68e618feef
7 changed files with 2111 additions and 1 deletions

View File

@@ -119,6 +119,60 @@ enum Commands {
#[arg(long, short = 'd', value_name = "DIR")]
dir: Option<String>,
},
/// View pin maps, assign pins, and audit wiring
Pin {
/// Capability filter (pwm, analog, spi, i2c, uart, interrupt)
/// or pin/bus name for --assign / --remove
name: Option<String>,
/// Pin number or alias for --assign (e.g. 13, A0, SDA)
pin: Option<String>,
/// Assign a pin or bus group
#[arg(long, conflicts_with_all = ["remove", "audit", "generate", "capabilities", "init_from"])]
assign: bool,
/// Remove a pin or bus assignment
#[arg(long, conflicts_with_all = ["assign", "audit", "generate", "capabilities", "init_from"])]
remove: bool,
/// Show wiring audit report
#[arg(long, conflicts_with_all = ["assign", "remove", "generate", "capabilities", "init_from"])]
audit: bool,
/// Show only the wiring checklist (with --audit)
#[arg(long, requires = "audit")]
brief: bool,
/// Generate lib/hal/pins.h
#[arg(long, conflicts_with_all = ["assign", "remove", "audit", "capabilities", "init_from"])]
generate: bool,
/// List capabilities supported by the board
#[arg(long, conflicts_with_all = ["assign", "remove", "audit", "generate", "init_from"])]
capabilities: bool,
/// Copy pin assignments from another board
#[arg(long, value_name = "BOARD", conflicts_with_all = ["assign", "remove", "audit", "generate", "capabilities"])]
init_from: Option<String>,
/// Pin mode (input, output, input_pullup, pwm, analog)
#[arg(long, value_name = "MODE")]
mode: Option<String>,
/// SPI chip-select pin (with --assign spi)
#[arg(long, value_name = "PIN")]
cs: Option<String>,
/// Target board (defaults to project default)
#[arg(long, short = 'b', value_name = "BOARD")]
board: Option<String>,
/// Path to project directory (defaults to current directory)
#[arg(long, short = 'd', value_name = "DIR")]
dir: Option<String>,
},
}
fn main() -> Result<()> {
@@ -225,6 +279,108 @@ fn main() -> Result<()> {
commands::board::list_boards(dir.as_deref())
}
}
Commands::Pin {
name, pin, assign, remove, audit, brief,
generate, capabilities, init_from, mode, cs, board, dir,
} => {
if capabilities {
commands::pin::show_capabilities(
board.as_deref(),
dir.as_deref(),
)
} else if audit {
commands::pin::audit_pins(
board.as_deref(),
brief,
dir.as_deref(),
)
} else if generate {
commands::pin::generate_pins_header(
board.as_deref(),
dir.as_deref(),
)
} else if remove {
let pin_name = name.as_deref().ok_or_else(|| {
anyhow::anyhow!(
"Name required.\n\
Usage: anvil pin --remove red_led\n\
Audit current: anvil pin --audit"
)
})?;
commands::pin::remove_assignment(
pin_name,
board.as_deref(),
dir.as_deref(),
)
} else if let Some(ref source) = init_from {
let target = board.as_deref().ok_or_else(|| {
anyhow::anyhow!(
"Target board required.\n\
Usage: anvil pin --init-from uno --board mega"
)
})?;
commands::pin::init_from(
source,
target,
dir.as_deref(),
)
} else if assign {
let assign_name = name.as_deref().ok_or_else(|| {
anyhow::anyhow!(
"Name required.\n\
Usage: anvil pin --assign red_led 13\n\
Usage: anvil pin --assign spi --cs 10\n\
See pins: anvil pin"
)
})?;
// Check if this is a bus group assignment
let is_bus = {
let board_name = board.as_deref().unwrap_or("uno");
anvil::board::pinmap::find_pinmap_fuzzy(board_name)
.map(|pm| pm.groups.iter().any(|g| {
g.name == assign_name.to_lowercase()
}))
.unwrap_or(false)
};
if is_bus {
let mut user_pins: Vec<(&str, &str)> = Vec::new();
if let Some(ref cs_pin) = cs {
user_pins.push(("cs", cs_pin.as_str()));
}
commands::pin::assign_bus(
assign_name,
&user_pins,
board.as_deref(),
dir.as_deref(),
)
} else {
let pin_str = pin.as_deref().ok_or_else(|| {
anyhow::anyhow!(
"Pin number required.\n\
Usage: anvil pin --assign {} 13\n\
See pins: anvil pin",
assign_name
)
})?;
commands::pin::assign_pin(
assign_name,
pin_str,
mode.as_deref(),
board.as_deref(),
dir.as_deref(),
)
}
} else {
// Default: show pin map, optionally filtered
commands::pin::show_pin_map(
board.as_deref(),
name.as_deref(),
dir.as_deref(),
)
}
}
}
}