1+ // This Source Code Form is subject to the terms of the Mozilla Public
2+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+ use anyhow:: { anyhow, Result } ;
16use humility_cli:: ExecutionContext ;
27use humility_hiffy:: IpcError ;
3- use std:: mem:: MaybeUninit ;
48use std:: fmt;
5- use anyhow :: { anyhow , Result } ;
6-
9+ use std :: mem :: MaybeUninit ;
10+
711use device:: gpioa:: RegisterBlock ;
812use humility_hiffy:: HiffyFunction ;
913use std:: collections:: BTreeMap ;
@@ -38,27 +42,30 @@ impl fmt::Display for PinConfig {
3842 }
3943}
4044
45+ /// Store an STM32H7 GPIO group ID ('A', 'B', etc.) and the associated GPIO
46+ /// configuration register block to avoid repeated IO for each Pin.
4147struct ConfigCache {
42- cache : BTreeMap < String , RegisterBlock > ,
48+ cache : BTreeMap < char , RegisterBlock > ,
4349}
4450
4551impl ConfigCache {
4652 fn new ( ) -> ConfigCache {
47- let cache: BTreeMap < String , RegisterBlock > = BTreeMap :: new ( ) ;
53+ let cache: BTreeMap < char , RegisterBlock > = BTreeMap :: new ( ) ;
4854 Self { cache }
4955 }
5056
5157 fn get_pin_config (
5258 & mut self ,
5359 context : & mut ExecutionContext ,
54- group : & str ,
60+ chip : & str ,
61+ group : char ,
5562 pin : u32 ,
5663 ) -> Result < PinConfig > {
57- let rb = match self . cache . get ( group) {
64+ let rb = match self . cache . get ( & group) {
5865 None => {
59- let rb = read_gpio_register_block ( context, group) ?;
60- self . cache . insert ( group. to_string ( ) , rb) ;
61- self . cache . get ( group) . unwrap ( )
66+ let rb = read_gpio_register_block ( context, chip , group) ?;
67+ self . cache . insert ( group, rb) ;
68+ self . cache . get ( & group) . unwrap ( )
6269 }
6370 Some ( rb) => rb,
6471 } ;
@@ -143,30 +150,52 @@ impl ConfigCache {
143150 }
144151}
145152
146- fn stm32h753_gpio_registerblock_addr ( group : & str ) -> Option < u32 > {
153+ /// Lookup STM32H7 GPIO configuration register addresses.
154+ fn stm32h753_gpio_registerblock_addr ( group : char ) -> Option < u32 > {
147155 // Section 11.4: GPIO registers
148156 match group {
149- "A" => Some ( device:: GPIOA :: ptr ( ) as u32 ) ,
150- "B" => Some ( device:: GPIOB :: ptr ( ) as u32 ) ,
151- "C" => Some ( device:: GPIOC :: ptr ( ) as u32 ) ,
152- "D" => Some ( device:: GPIOD :: ptr ( ) as u32 ) ,
153- "E" => Some ( device:: GPIOE :: ptr ( ) as u32 ) ,
154- "F" => Some ( device:: GPIOF :: ptr ( ) as u32 ) ,
155- "G" => Some ( device:: GPIOG :: ptr ( ) as u32 ) ,
156- "H" => Some ( device:: GPIOH :: ptr ( ) as u32 ) ,
157- "I" => Some ( device:: GPIOI :: ptr ( ) as u32 ) ,
158- "J" => Some ( device:: GPIOJ :: ptr ( ) as u32 ) ,
159- "K" => Some ( device:: GPIOK :: ptr ( ) as u32 ) ,
157+ 'A' => Some ( device:: GPIOA :: ptr ( ) as u32 ) ,
158+ 'B' => Some ( device:: GPIOB :: ptr ( ) as u32 ) ,
159+ 'C' => Some ( device:: GPIOC :: ptr ( ) as u32 ) ,
160+ 'D' => Some ( device:: GPIOD :: ptr ( ) as u32 ) ,
161+ 'E' => Some ( device:: GPIOE :: ptr ( ) as u32 ) ,
162+ 'F' => Some ( device:: GPIOF :: ptr ( ) as u32 ) ,
163+ 'G' => Some ( device:: GPIOG :: ptr ( ) as u32 ) ,
164+ 'H' => Some ( device:: GPIOH :: ptr ( ) as u32 ) ,
165+ 'I' => Some ( device:: GPIOI :: ptr ( ) as u32 ) ,
166+ 'J' => Some ( device:: GPIOJ :: ptr ( ) as u32 ) ,
167+ 'K' => Some ( device:: GPIOK :: ptr ( ) as u32 ) ,
160168 _ => None ,
161169 }
162170}
163171
172+ // Several other STM32 families share the same GPIO register format as the
173+ // STM32H7 series:
174+ // - STM32F7 series
175+ // - STM32G4 series
176+ // Support for those chips can be added if needed.
177+ // Note: verify that the non-STM32H7 series are using the same addressing or adapt.
178+ fn chip_has_group ( chip : & str , group : char ) -> Result < bool > {
179+ let name = chip. to_ascii_lowercase ( ) ;
180+
181+ if name. starts_with ( "stm32h753" ) {
182+ Ok ( matches ! ( group, 'A' ..='K' ) )
183+ } else if name. starts_with ( "stm32h743" ) {
184+ Ok ( matches ! ( group, 'A' ..='I' ) )
185+ } else {
186+ Err ( anyhow ! ( "unknown STM32H7 chip '{}'" , chip) )
187+ }
188+ }
189+
164190fn read_gpio_register_block (
165191 context : & mut ExecutionContext ,
166- group : & str ,
192+ chip : & str ,
193+ group : char ,
167194) -> Result < RegisterBlock > {
168195 let core = & mut * * context. core . as_mut ( ) . unwrap ( ) ;
169- let addr = stm32h753_gpio_registerblock_addr ( group) . ok_or ( anyhow ! ( "no address for GPIO group {}" , group) ) ?;
196+ chip_has_group ( chip, group) ?;
197+ let addr = stm32h753_gpio_registerblock_addr ( group)
198+ . ok_or ( anyhow ! ( "no address for GPIO group {}" , group) ) ?;
170199 let mut buffer = vec ! [ 0u8 ; std:: mem:: size_of:: <RegisterBlock >( ) ] ;
171200 core. read_8 ( addr, & mut buffer) ?;
172201
@@ -183,15 +212,21 @@ fn read_gpio_register_block(
183212pub fn show_gpio_with_config (
184213 context : & mut ExecutionContext ,
185214 gpio_input : & HiffyFunction ,
215+ chip : & str ,
186216 args : & [ ( u16 , Option < u8 > , String ) ] ,
187217 results : & [ Result < Vec < u8 > , IpcError > ] ,
188218) -> Result < ( ) > {
189219 let mut config_cache = ConfigCache :: new ( ) ;
190220 for ( ndx, arg) in args. iter ( ) . enumerate ( ) {
191221 match arg. 1 {
192222 Some ( pin) => {
193- let config =
194- config_cache. get_pin_config ( context, & arg. 2 , pin as u32 ) ?;
223+ let group = arg
224+ . 2
225+ . chars ( )
226+ . next ( )
227+ . ok_or ( anyhow ! ( "invalid group '{}'" , arg. 2 ) ) ?;
228+ let config = config_cache
229+ . get_pin_config ( context, chip, group, pin as u32 ) ?;
195230 println ! (
196231 "{}:{:<2} = {} {}" ,
197232 arg. 2 ,
@@ -219,8 +254,13 @@ pub fn show_gpio_with_config(
219254 let v = u16:: from_le_bytes ( * arr) ;
220255
221256 for i in 0 ..16 {
257+ let group = arg
258+ . 2
259+ . chars ( )
260+ . next ( )
261+ . ok_or ( anyhow ! ( "invalid group '{}'" , arg. 2 ) ) ?;
222262 let config = config_cache
223- . get_pin_config ( context, & arg . 2 , i as u32 ) ?;
263+ . get_pin_config ( context, chip , group , i as u32 ) ?;
224264 println ! (
225265 "{}:{:<2} = {} {}" ,
226266 arg. 2 ,
0 commit comments