Skip to content

Commit 2f9d318

Browse files
committed
Reorder functions to define callers before callees
1 parent 295f9df commit 2f9d318

File tree

1 file changed

+155
-154
lines changed

1 file changed

+155
-154
lines changed

stm32-data-gen/src/generator.rs

Lines changed: 155 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -12,62 +12,50 @@ use crate::chips::{Chip, ChipGroup};
1212
use crate::gpio_af::parse_signal_name;
1313
use crate::normalize_peris::normalize_peri_name;
1414

15-
/// Merge AF information from GPIO file into peripheral pins.
16-
///
17-
/// `core_pins` is modified in-place and updated with AF information from `af_pins`.
18-
/// Also does some chip-specific adjustments, so we need `chip_name` and `periph_name`.
19-
fn merge_periph_pins_info(
20-
chip_name: &str,
21-
periph_name: &str,
22-
core_pins: &mut [stm32_data_serde::chip::core::peripheral::Pin],
23-
af_pins: &[stm32_data_serde::chip::core::peripheral::Pin],
24-
) {
25-
if chip_name.contains("STM32F1") {
26-
// TODO: actually handle the F1 AFIO information when it will be extracted
27-
return;
28-
}
29-
30-
// convert to hashmap
31-
let af_pins: HashMap<(&str, &str), Option<u8>> = af_pins
32-
.iter()
33-
.map(|v| ((v.pin.as_str(), v.signal.as_str()), v.af))
34-
.collect();
35-
36-
for pin in &mut core_pins[..] {
37-
let af = af_pins.get(&(&pin.pin, &pin.signal)).copied().flatten();
15+
#[allow(clippy::too_many_arguments)]
16+
pub fn dump_all_chips(
17+
chip_groups: Vec<ChipGroup>,
18+
headers: header::Headers,
19+
af: gpio_af::Af,
20+
chip_interrupts: interrupts::ChipInterrupts,
21+
peripheral_to_clock: rcc::ParsedRccs,
22+
dma_channels: dma::DmaChannels,
23+
chips: std::collections::HashMap<String, Chip>,
24+
docs: docs::Docs,
25+
) -> Result<(), anyhow::Error> {
26+
std::fs::create_dir_all("build/data/chips")?;
3827

39-
// try to look for a signal with another name
40-
let af = af.or_else(|| {
41-
if pin.signal == "CTS" {
42-
// for some godforsaken reason UART4's and UART5's CTS are called CTS_NSS in the GPIO xml
43-
// so try to match with these
44-
af_pins.get(&(pin.pin.as_str(), "CTS_NSS")).copied().flatten()
45-
} else if chip_name.starts_with("STM32F0") && periph_name == "I2C1" {
46-
// it appears that for __some__ STM32 MCUs there is no AFIO specified in GPIO file
47-
// (notably - STM32F030C6 with it's I2C1 on PF6 and PF7)
48-
// but the peripheral can actually be mapped to different pins
49-
// this breaks embassy's model, so we pretend that it's AF 0
50-
// Reference Manual states that there's no GPIOF_AFR register
51-
// but according to Cube-generated core it's OK to write to AFIO reg, it seems to be ignored
52-
// TODO: are there any more signals that have this "feature"
53-
Some(0)
54-
} else {
55-
None
56-
}
57-
});
28+
#[cfg(feature = "rayon")]
29+
{
30+
use rayon::prelude::*;
5831

59-
if let Some(af) = af {
60-
pin.af = Some(af);
61-
}
32+
chip_groups.into_par_iter().try_for_each(|group| {
33+
process_group(
34+
group,
35+
&headers,
36+
&af,
37+
&chip_interrupts,
38+
&peripheral_to_clock,
39+
&dma_channels,
40+
&chips,
41+
&docs,
42+
)
43+
})
6244
}
63-
64-
// apply some renames
65-
if chip_name.starts_with("STM32C0") || chip_name.starts_with("STM32G0") {
66-
for pin in &mut core_pins[..] {
67-
if pin.signal == "MCO" {
68-
pin.signal = "MCO_1".to_string()
69-
}
70-
}
45+
#[cfg(not(feature = "rayon"))]
46+
{
47+
chip_groups.into_iter().try_for_each(|group| {
48+
process_group(
49+
group,
50+
&headers,
51+
&af,
52+
&chip_interrupts,
53+
&peripheral_to_clock,
54+
&dma_channels,
55+
&chips,
56+
&docs,
57+
)
58+
})
7159
}
7260
}
7361

@@ -224,60 +212,6 @@ fn process_core(
224212
Ok(core)
225213
}
226214

227-
/// Merge core xml info with GPIO xml info for the given peripheral.
228-
///
229-
/// The GPIO XMLs contain information about AFs for each pin, but the Core XMLs do not.
230-
/// The core XMLs, on the other hand, contain information about available signals on each pin,
231-
/// which the GPIO XMLs do not.
232-
///
233-
/// This function takes the core pins from `periph_pins` and the AFs from `chip_af`
234-
/// for the peripheral `pname`, merges the two using [merge_periph_pins_info] and returns
235-
/// the combined `Pin`s.
236-
fn merge_afs_into_core_pins(
237-
chip_name: &str,
238-
chip_af: Option<&HashMap<String, Vec<Pin>>>,
239-
periph_pins: &HashMap<String, Vec<Pin>>,
240-
pname: &String,
241-
) -> Vec<Pin> {
242-
if let Some(pins) = periph_pins.get(pname) {
243-
let mut pins = pins.clone();
244-
if let Some(af_pins) = chip_af.and_then(|x| x.get(pname)) {
245-
merge_periph_pins_info(chip_name, pname, &mut pins, af_pins.as_slice());
246-
}
247-
return pins;
248-
}
249-
Vec::new()
250-
}
251-
252-
/// Merge I2Sx pins into SPIx pins.
253-
///
254-
/// SPIx peripherals have I2Sx pins which are not explicitly listed in the peripheral's pins.
255-
/// This function merges the I2Sx pins from `chip_af` into the SPIx pins of `periph_pins`,
256-
/// with a prefix "I2S_". If the peripheral `pname` does not start with "SPI", it returns imediately.
257-
fn merge_i2s_into_spi_pins(
258-
chip_name: &str,
259-
chip_af: Option<&HashMap<String, Vec<Pin>>>,
260-
periph_pins: &HashMap<String, Vec<Pin>>,
261-
pname: &str,
262-
) -> Vec<Pin> {
263-
if !pname.starts_with("SPI") {
264-
return Vec::new();
265-
}
266-
let i2s_name = "I2S".to_owned() + pname.trim_start_matches("SPI");
267-
// Do we have I2Sx pins in the peripheral pins and I2Sx AFs in the chip?
268-
if let Some(i2s_pins) = periph_pins.get(&i2s_name) {
269-
let mut i2s_pins = i2s_pins.clone();
270-
if let Some(af_pins) = chip_af.and_then(|x| x.get(&i2s_name)) {
271-
merge_periph_pins_info(chip_name, &i2s_name, &mut i2s_pins, af_pins.as_slice());
272-
}
273-
for p in &mut i2s_pins {
274-
p.signal = "I2S_".to_owned() + &p.signal;
275-
}
276-
return i2s_pins;
277-
}
278-
Vec::new()
279-
}
280-
281215
/// Create a short core name from a long name.
282216
///
283217
/// Parse a string like "ARM Cortex-M4" or "ARM Cortex-M7 secure" and return a
@@ -476,6 +410,120 @@ fn extract_pins_from_chip_group(group: &ChipGroup) -> HashMap<String, Vec<Pin>>
476410
periph_pins
477411
}
478412

413+
/// Merge core xml info with GPIO xml info for the given peripheral.
414+
///
415+
/// The GPIO XMLs contain information about AFs for each pin, but the Core XMLs do not.
416+
/// The core XMLs, on the other hand, contain information about available signals on each pin,
417+
/// which the GPIO XMLs do not.
418+
///
419+
/// This function takes the core pins from `periph_pins` and the AFs from `chip_af`
420+
/// for the peripheral `pname`, merges the two using [merge_periph_pins_info] and returns
421+
/// the combined `Pin`s.
422+
fn merge_afs_into_core_pins(
423+
chip_name: &str,
424+
chip_af: Option<&HashMap<String, Vec<Pin>>>,
425+
periph_pins: &HashMap<String, Vec<Pin>>,
426+
pname: &String,
427+
) -> Vec<Pin> {
428+
if let Some(pins) = periph_pins.get(pname) {
429+
let mut pins = pins.clone();
430+
if let Some(af_pins) = chip_af.and_then(|x| x.get(pname)) {
431+
merge_periph_pins_info(chip_name, pname, &mut pins, af_pins.as_slice());
432+
}
433+
return pins;
434+
}
435+
Vec::new()
436+
}
437+
438+
/// Merge I2Sx pins into SPIx pins.
439+
///
440+
/// SPIx peripherals have I2Sx pins which are not explicitly listed in the peripheral's pins.
441+
/// This function merges the I2Sx pins from `chip_af` into the SPIx pins of `periph_pins`,
442+
/// with a prefix "I2S_". If the peripheral `pname` does not start with "SPI", it returns imediately.
443+
fn merge_i2s_into_spi_pins(
444+
chip_name: &str,
445+
chip_af: Option<&HashMap<String, Vec<Pin>>>,
446+
periph_pins: &HashMap<String, Vec<Pin>>,
447+
pname: &str,
448+
) -> Vec<Pin> {
449+
if !pname.starts_with("SPI") {
450+
return Vec::new();
451+
}
452+
let i2s_name = "I2S".to_owned() + pname.trim_start_matches("SPI");
453+
// Do we have I2Sx pins in the peripheral pins and I2Sx AFs in the chip?
454+
if let Some(i2s_pins) = periph_pins.get(&i2s_name) {
455+
let mut i2s_pins = i2s_pins.clone();
456+
if let Some(af_pins) = chip_af.and_then(|x| x.get(&i2s_name)) {
457+
merge_periph_pins_info(chip_name, &i2s_name, &mut i2s_pins, af_pins.as_slice());
458+
}
459+
for p in &mut i2s_pins {
460+
p.signal = "I2S_".to_owned() + &p.signal;
461+
}
462+
return i2s_pins;
463+
}
464+
Vec::new()
465+
}
466+
467+
468+
/// Merge AF information from GPIO file into peripheral pins.
469+
///
470+
/// `core_pins` is modified in-place and updated with AF information from `af_pins`.
471+
/// Also does some chip-specific adjustments, so we need `chip_name` and `periph_name`.
472+
fn merge_periph_pins_info(
473+
chip_name: &str,
474+
periph_name: &str,
475+
core_pins: &mut [stm32_data_serde::chip::core::peripheral::Pin],
476+
af_pins: &[stm32_data_serde::chip::core::peripheral::Pin],
477+
) {
478+
if chip_name.contains("STM32F1") {
479+
// TODO: actually handle the F1 AFIO information when it will be extracted
480+
return;
481+
}
482+
483+
// convert to hashmap
484+
let af_pins: HashMap<(&str, &str), Option<u8>> = af_pins
485+
.iter()
486+
.map(|v| ((v.pin.as_str(), v.signal.as_str()), v.af))
487+
.collect();
488+
489+
for pin in &mut core_pins[..] {
490+
let af = af_pins.get(&(&pin.pin, &pin.signal)).copied().flatten();
491+
492+
// try to look for a signal with another name
493+
let af = af.or_else(|| {
494+
if pin.signal == "CTS" {
495+
// for some godforsaken reason UART4's and UART5's CTS are called CTS_NSS in the GPIO xml
496+
// so try to match with these
497+
af_pins.get(&(pin.pin.as_str(), "CTS_NSS")).copied().flatten()
498+
} else if chip_name.starts_with("STM32F0") && periph_name == "I2C1" {
499+
// it appears that for __some__ STM32 MCUs there is no AFIO specified in GPIO file
500+
// (notably - STM32F030C6 with it's I2C1 on PF6 and PF7)
501+
// but the peripheral can actually be mapped to different pins
502+
// this breaks embassy's model, so we pretend that it's AF 0
503+
// Reference Manual states that there's no GPIOF_AFR register
504+
// but according to Cube-generated core it's OK to write to AFIO reg, it seems to be ignored
505+
// TODO: are there any more signals that have this "feature"
506+
Some(0)
507+
} else {
508+
None
509+
}
510+
});
511+
512+
if let Some(af) = af {
513+
pin.af = Some(af);
514+
}
515+
}
516+
517+
// apply some renames
518+
if chip_name.starts_with("STM32C0") || chip_name.starts_with("STM32G0") {
519+
for pin in &mut core_pins[..] {
520+
if pin.signal == "MCO" {
521+
pin.signal = "MCO_1".to_string()
522+
}
523+
}
524+
}
525+
}
526+
479527
/// Resolve the address of a peripheral.
480528
///
481529
/// In the case of FDCANRAM, the address can be different depending on the chip. The STM32H7 (not RS) has a single
@@ -699,50 +747,3 @@ fn process_chip(
699747
std::fs::write(format!("build/data/chips/{chip_name}.json"), dump)?;
700748
Ok(())
701749
}
702-
703-
#[allow(clippy::too_many_arguments)]
704-
pub fn dump_all_chips(
705-
chip_groups: Vec<ChipGroup>,
706-
headers: header::Headers,
707-
af: gpio_af::Af,
708-
chip_interrupts: interrupts::ChipInterrupts,
709-
peripheral_to_clock: rcc::ParsedRccs,
710-
dma_channels: dma::DmaChannels,
711-
chips: std::collections::HashMap<String, Chip>,
712-
docs: docs::Docs,
713-
) -> Result<(), anyhow::Error> {
714-
std::fs::create_dir_all("build/data/chips")?;
715-
716-
#[cfg(feature = "rayon")]
717-
{
718-
use rayon::prelude::*;
719-
720-
chip_groups.into_par_iter().try_for_each(|group| {
721-
process_group(
722-
group,
723-
&headers,
724-
&af,
725-
&chip_interrupts,
726-
&peripheral_to_clock,
727-
&dma_channels,
728-
&chips,
729-
&docs,
730-
)
731-
})
732-
}
733-
#[cfg(not(feature = "rayon"))]
734-
{
735-
chip_groups.into_iter().try_for_each(|group| {
736-
process_group(
737-
group,
738-
&headers,
739-
&af,
740-
&chip_interrupts,
741-
&peripheral_to_clock,
742-
&dma_channels,
743-
&chips,
744-
&docs,
745-
)
746-
})
747-
}
748-
}

0 commit comments

Comments
 (0)