|
59 | 59 | //! ```console |
60 | 60 | //! $ humility gpio --input |
61 | 61 | //! humility: attached via ST-Link V3 |
| 62 | +//! Chip: STM32H753ZITx |
62 | 63 | //! Pin 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
63 | 64 | //! ----------------------------------------------------------------------- |
64 | 65 | //! Port A 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 |
|
68 | 69 | //! Port E 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
69 | 70 | //! Port F 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
70 | 71 | //! Port G 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
71 | | -//! Port H 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
72 | | -//! Port I 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
73 | | -//! Port J 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
74 | | -//! Port K 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
| 72 | +//! Port H 0 0 . . . . . . . . . . . . . . |
75 | 73 | //! ``` |
76 | | -//! To get input values with STM32H753 GPIO configuration settings, |
77 | | -//! use the `--with-config` or `-w` flag with --input: |
| 74 | +//! |
| 75 | +//! Note that the chip name is displayed, and GPIO groups are filtered based on |
| 76 | +//! the specific chip variant. For partially populated GPIO groups (like Port H |
| 77 | +//! above with only 2 pins), non-existent pins are shown as `.` |
| 78 | +//! |
| 79 | +//! If a chip name is not in the internal database of chip names, then the |
| 80 | +//! old behavior of this program is used; no GPIO config info will be shown |
| 81 | +//! and it will be assumed that the part has 176 GPIO pins in groups A to K. |
| 82 | +//! |
| 83 | +//! To print input values with STM32H7 series GPIO configuration settings, |
| 84 | +//! use the `--with-config` or `-w` flag with `--input`: |
78 | 85 | //! |
79 | 86 | //! ```console |
80 | | -//! $ humility gpio --input -with-config --pins B:0,B:14,E:1 |
| 87 | +//! $ humility gpio --input --with-config --pins B:0,B:14,E:1 |
81 | 88 | //! humility: attached to 0483:3754:002F00174741500820383733 via ST-Link V3 |
| 89 | +//! Chip: STM32H753ZITx |
82 | 90 | //! B:0 = 0 Analog:OutPushPull:LowSpeed:NoPull:AF0:Unlocked:InZero:OutZero |
83 | 91 | //! B:14 = 1 Input:OutPushPull:HighSpeed:NoPull:AF5:Unlocked:InOne:OutZero |
84 | 92 | //! E:1 = 0 Alternate:OutPushPull:VeryHighSpeed:NoPull:AF12:Unlocked:InZero:OutZero |
85 | 93 | //! ``` |
86 | 94 | //! |
87 | | -//! If no pins are specified, then the pin names, values and config settings |
88 | | -//! are printed one per line for all GPIO pins. |
| 95 | +//! If you query pins that don't exist on the chip variant, they will show as `None`: |
| 96 | +//! |
| 97 | +//! ```console |
| 98 | +//! $ humility gpio --input --pins J:4,K:9 |
| 99 | +//! humility: attached via ST-Link V3 |
| 100 | +//! Chip: STM32H753ZITx |
| 101 | +//! J:4 = None |
| 102 | +//! K:9 = None |
| 103 | +//! ``` |
| 104 | +//! |
| 105 | +//! With `--with-config`, non-existent pins or groups show `None` for configuration: |
| 106 | +//! |
| 107 | +//! ```console |
| 108 | +//! $ humility gpio --input --with-config --pins H:5,J:4 |
| 109 | +//! humility: attached via ST-Link V3 |
| 110 | +//! Chip: STM32H753ZITx |
| 111 | +//! H:5 = 0 None |
| 112 | +//! J:4 = 0 None |
| 113 | +//! ``` |
| 114 | +//! |
| 115 | +//! If no pins are specified with `--with-config`, then the pin names, values |
| 116 | +//! and config settings are printed one per line for all available GPIO pins on |
| 117 | +//! the chip variant. |
89 | 118 | //! |
90 | 119 | //! ### Configure |
91 | 120 | //! |
|
105 | 134 | //! ``` |
106 | 135 | //! |
107 | 136 |
|
| 137 | +mod config_cache; |
108 | 138 | mod stm32h7; |
| 139 | +mod stm32h7_parts; |
| 140 | +#[cfg(test)] |
| 141 | +mod stm32h7_testdata; |
109 | 142 |
|
110 | 143 | use humility_cli::{ExecutionContext, Subcommand}; |
111 | 144 | use humility_cmd::{Archive, Attach, Command, CommandKind, Validate}; |
@@ -310,33 +343,98 @@ fn gpio(context: &mut ExecutionContext) -> Result<()> { |
310 | 343 |
|
311 | 344 | let results = hiffy_context.run(core, ops.as_slice(), None)?; |
312 | 345 |
|
| 346 | + // Get chip info for filtering and display |
| 347 | + let chip_name = hubris.chip(); |
| 348 | + let (max_group, chip_part) = if let Some(chip) = &chip_name { |
| 349 | + if chip.to_ascii_lowercase().starts_with("stm32h7") { |
| 350 | + use crate::stm32h7_parts::Stm32H7Series; |
| 351 | + let part = Stm32H7Series::find_part(chip, true); |
| 352 | + |
| 353 | + // Warn about unknown chips |
| 354 | + if !part.is_known() { |
| 355 | + eprintln!( |
| 356 | + "Warning: Unknown STM32H7 chip '{}'. Using default GPIO layout (groups A-K).", |
| 357 | + chip |
| 358 | + ); |
| 359 | + eprintln!( |
| 360 | + " Configuration display (--with-config) is not available for unknown chips." |
| 361 | + ); |
| 362 | + } |
| 363 | + |
| 364 | + (Some(part.max_group()), Some(part)) |
| 365 | + } else { |
| 366 | + (None, None) |
| 367 | + } |
| 368 | + } else { |
| 369 | + (None, None) |
| 370 | + }; |
| 371 | + |
313 | 372 | if subargs.input { |
314 | 373 | let mut header = false; |
315 | 374 |
|
316 | 375 | if subargs.with_config { |
| 376 | + // Print chip name |
| 377 | + if let Some(chip) = &chip_name { |
| 378 | + println!("Chip: {}", chip); |
| 379 | + } |
317 | 380 | show_gpio_with_config(context, &gpio_input, &args, &results)?; |
318 | 381 | } else { |
| 382 | + // Print chip name for grid display too |
| 383 | + if let Some(chip) = &chip_name { |
| 384 | + println!("Chip: {}", chip); |
| 385 | + } |
| 386 | + |
319 | 387 | for (ndx, arg) in args.iter().enumerate() { |
| 388 | + // Check if this group exists on the chip |
| 389 | + let group = arg.2.chars().next(); |
| 390 | + let group_exists = |
| 391 | + if let (Some(g), Some(max_g)) = (group, max_group) { |
| 392 | + g >= 'A' && g <= max_g |
| 393 | + } else { |
| 394 | + true // If we can't determine, assume it exists |
| 395 | + }; |
| 396 | + |
320 | 397 | match arg.1 { |
321 | 398 | Some(pin) => { |
322 | | - println!( |
323 | | - "{}:{:<2} = {}", |
324 | | - arg.2, |
325 | | - pin, |
326 | | - match results[ndx] { |
327 | | - Err(code) => { |
328 | | - gpio_input.strerror(code) |
329 | | - } |
330 | | - Ok(ref val) => { |
331 | | - let arr: &[u8; 2] = val[0..2].try_into()?; |
332 | | - let v = u16::from_le_bytes(*arr); |
333 | | - format!("{}", (v >> pin) & 1) |
| 399 | + // Check if pin exists (group exists and pin within range) |
| 400 | + let pin_exists = |
| 401 | + if let (Some(g), Some(part)) = (group, chip_part) { |
| 402 | + g >= 'A' |
| 403 | + && g <= part.max_group() |
| 404 | + && pin < part.pins_in_group(g) |
| 405 | + } else { |
| 406 | + group_exists // Fall back to group-level check |
| 407 | + }; |
| 408 | + |
| 409 | + if !pin_exists { |
| 410 | + // Pin doesn't exist on this chip |
| 411 | + println!("{}:{:<2} = None", arg.2, pin); |
| 412 | + } else { |
| 413 | + println!( |
| 414 | + "{}:{:<2} = {}", |
| 415 | + arg.2, |
| 416 | + pin, |
| 417 | + match results[ndx] { |
| 418 | + Err(code) => { |
| 419 | + gpio_input.strerror(code) |
| 420 | + } |
| 421 | + Ok(ref val) => { |
| 422 | + let arr: &[u8; 2] = |
| 423 | + val[0..2].try_into()?; |
| 424 | + let v = u16::from_le_bytes(*arr); |
| 425 | + format!("{}", (v >> pin) & 1) |
| 426 | + } |
334 | 427 | } |
335 | | - } |
336 | | - ); |
| 428 | + ); |
| 429 | + } |
337 | 430 | } |
338 | 431 |
|
339 | 432 | None => { |
| 433 | + // Skip ports that don't exist on this chip variant |
| 434 | + if !group_exists { |
| 435 | + continue; |
| 436 | + } |
| 437 | + |
340 | 438 | if !header { |
341 | 439 | print!("{:7}", "Pin"); |
342 | 440 |
|
@@ -365,8 +463,21 @@ fn gpio(context: &mut ExecutionContext) -> Result<()> { |
365 | 463 | let arr: &[u8; 2] = val[0..2].try_into()?; |
366 | 464 | let v = u16::from_le_bytes(*arr); |
367 | 465 |
|
| 466 | + // Determine how many pins exist in this group |
| 467 | + let max_pin = if let (Some(g), Some(part)) = |
| 468 | + (group, chip_part) |
| 469 | + { |
| 470 | + part.pins_in_group(g) |
| 471 | + } else { |
| 472 | + 16 // Default to all 16 if we can't determine |
| 473 | + }; |
| 474 | + |
368 | 475 | for i in 0..16 { |
369 | | - print!("{:4}", (v >> i) & 1) |
| 476 | + if i < max_pin { |
| 477 | + print!("{:4}", (v >> i) & 1) |
| 478 | + } else { |
| 479 | + print!(" .") |
| 480 | + } |
370 | 481 | } |
371 | 482 | println!(); |
372 | 483 | } |
|
0 commit comments