rigless 0.3.0

Virtual hardware-in-the-loop runtime: run unmodified firmware on an emulated MCU with every peripheral, chip model and unit of virtual time in Rust, and a CPU core of its own that translates the firmware's instructions to host code
Documentation
The STM32H743 as a Rigless SoC: the vendor's own register description turned into Rust a person can implement peripherals against.

## What is here

| Path | Contents |
|---|---|
| `../stm32h743.rs` | The index: `CPU`, `MEMORY`, and `builder()`, the part's tables with every correction, for a test that wants the tables alone |
| `STM32H743.svd` | ST's CMSIS-SVD file for the SoC, committed unchanged |
| `generated.rs`, `generated/` | What `rigless svd generate` emits from it: for each register layout the `Register` enum, a constant per field, and the table. They're never edited by hand |
| `memory_map.rs` | What the SVD can't say: the memory map from RM0433 rev 9, and every correction where the file disagrees with the manual, with its section named |
| `peripherals.rs`, `peripherals/` | `Stm32h743`, the whole part, holding a model per instance as a field, and the models, one module per register layout. `flash` is the embedded flash memory interface, both banks. `gpio`, `exti`, `syscfg`, `rng` and `dbg` are the eleven ports, the extended interrupt controller, the system configuration controller, the random number generator and the debug unit. `rcc` and `pwr` are the clock tree and the power controller, `tim` the fourteen timers, `usart` the eight serial ports, `spi` and `i2c` the serial peripheral and inter-integrated circuit interfaces, `dma`, `dmamux` and `bdma` the DMA controllers and their request multiplexers, and `adc` the three converters and their common blocks. `otg` is the USB cores' reset register and nothing else, and `sdmmc` the card interfaces with nothing in the slot, two partials that say so |

Every other instance answers from its register file alone, and a run reports each register the firmware reaches there as an unimplemented gap.

## The SVD

| | |
|---|---|
| Origin | ST, as published in ST's STM32H7 system view description pack V2.8, `en.stm32h7_svd.zip` on the STM32H743's product page, `STM32H7_svd_V2.8/STM32H743.svd` |
| Version | SVD version 2.4, copyright 2025 ST |
| License | Apache-2.0, stated in the file's own header |
| Corrections | The reset values below, the write rule of the three EXTI pending registers, the width of `SYSCFG_PWRCR.ODEN`, the access of `SYSCFG_CCCSR.READY`, the clear-on-zero of `RNG_SR`'s two interrupt flags, the typing of a few flash fields and registers, the typing of five fields and two registers on each of the six SPI instances, and twenty-seven instances' interrupt lines, all in `memory_map.rs`, which writes the three of every port's for all eleven so that none is right by inheriting port A's. The eleven GPIO ports derive from port A, so the file gives all of them port A's `MODER`, `OSPEEDR` and `PUPDR`, where sections 11.4.1, 11.4.3 and 11.4.4 give ports A and B their own and every other port all pins analog with no speed or pull. And port A's own `PUPDR` it gives as `0x1210_0000`, where 11.4.4 gives `0x6400_0000`. `RCC_CR` it gives as `0x83` where section 8.7.2 gives `0x0000 0001`. `RCC_RSR`, `RCC_APB4ENR` and the nine low-power enables of sections 8.7.49 to 8.7.57 it gives as zero, and their processor copies `C1_` too, where Tables 65 and 74 to 83 give each set bits. `PWR_CR3` it gives revision Y's value, where this part is revision V. `FLASH_CR1` it gives as zero, unlocked, where section 4.9.4 gives `0x0000 0031`, and `FLASH_CR2` it gets right. `FLASH_OPTCR` at both its mappings and the two `FLASH_CRCCRx` it gives as zero. The twenty option registers, `FLASH_OPTSR_CUR` and `_PRG`, `FLASH_BOOT_CURR` and `_PRGR`, and each bank's current and programming `FLASH_PRAR`, `FLASH_SCAR` and `FLASH_WPSN`, it gives as zero too, where Table 21 gives their default factory values and Table 28 gives each reset value as `X`. It types `LOCK1`, `LOCK2` and `OPTLOCK` read-write where sections 4.9.4, 4.9.25 and 4.9.7 type them `rs`, `SWAP_BANK` read-write where 4.9.7 types it `r`, and eight registers read-write where every bit is `r`, among them both status registers. On each SPI it types `CSTART` and `IOLOCK` of `CR1` and `TSER` of `CR2` read-only, where sections 50.11.1 and 50.11.2 type them `rs`, `TXPIE` and `DXPIE` of `IER` read-only, where 50.11.5 types them `rs` and ES0392 item 2.22.4's workaround needs software to clear them, and `TXCRC` and `RXCRC` read-write, where 50.11.11 and 50.11.12 type every bit `r`. On each of the four I2C instances it types `START`, `STOP`, `NACK` and `PECBYTE` of `CR2` and `TXE` and `TXIS` of `ISR` write-one-to-set, where sections 47.9.2 and 47.9.7 type them `rs`. And `DBGMCU_IDC` it gives as `0x1000_6450`, a revision section 60.5.8 doesn't name, where revision V is `0x2003`. Both USB cores' `OTG_GRSTCTL` it gives as `0x2000_0000`, a reserved bit set and `AHBIDL` clear, where section 57.14.5 gives `0x8000 0000`, the master idle. Both cores' device blocks it ends at `0xBFF`, where sections 57.14.65, 57.14.62, 57.14.66 and 57.14.64 place OUT endpoint 8's registers from `0xC00` to `0xC17`, so `builder()` grows each block to `0xC1F` and the four answer as undefined space until a model of the device block takes them. That's the part's own answer: Table 8, note 1, says undefined space in a peripheral returns zeros, and `builder()` reads it so for every instance. And it gives twenty-seven instances the wrong interrupt lines against section 19.1.2's Table 147: TIM12 to TIM14 TIM2's line where they share TIM8's, ADC2 ADC3's where it shares ADC1's, DMA1's streams 2 to 6 to DMA2, the FPU's line to the EXTI, HRTIM's seven blocks each one place on, a USB controller's global line to both host blocks, both SD controllers' lines to each, the wakeup pins' line to the three delay blocks where it belongs to PWR, and nothing to the DAC or the three RAM ECC monitors, which share lines of the table's. The clock controller and power controller add their own, in `rcc_corrections` and `pwr_corrections`: the ready flags, `SWS`, `LSERDY`, `LSECSSD` and the reset flags of `RCC_CR`, `RCC_CFGR`, `RCC_BDCR`, `RCC_CSR`, `RCC_RSR` and `RCC_C1_RSR` typed `r` where the file types them read-write, `RCC_CIFR` as a register no write changes, `HSECSSON` and `WW1RSC` as `rs` and `rw1`, `PWR_D3CR` reset at `0x0000_6000` for the `VOSRDY` section 6.8.6 reads as 1 where the file gives `0x0000_4000`, the six `PWR_WKUPFR` flags typed `r`, a clock gate on each of 111 instances' enables from section 8.5.10, a clock output on each of 53 instances and three more that no enable gates, and the write protection `PWR_CR1.DBP` puts on `RCC_BDCR` and the RTC, section 6.8.1. The timers add theirs in `timer_corrections`: every `TIMx_SR` flag `rc_w0` where the file has no write rule, `TIMx_ARR` reset to all ones at the timer's width where the file gives zero, and `AF1` and `AF2` reset with the `BKIN` pin enabled, sections 38.4.5, 38.4.14 and 38.4.26 and their siblings in chapters 39 to 42. The converters add theirs in `adc_corrections`: `ADC_CR` and `ADC_CFGR` reset at `0x2000 0000` and `0x8000 0000`, `ADC_LTR1` and the three high thresholds at the values sections 25.6.9, 25.6.10, 25.6.22 and 25.6.24 give, the command bits of `ADC_CR` typed `rs`, revision V's two-bit `BOOST`, and `LDORDY` and `SMP0`, which the file leaves out. `INTERRUPTS` gives each the table's |

The file has no clusters and no arrays, every register is 32 bits wide, and 51 of its 123 peripherals derive their layout from a sibling. Eighteen registers are declared alternates of another at the same offset. Some of those are the same register under each revision's name: section 8.7.3's `RCC_ICSCR` is revision Y's, and 8.7.4's `RCC_HSICFGR` is revision V's, at offset `0x004` both. The flash block maps the registers both banks share a second time at `0x100` on, `FLASH_ACR`'s section 4.9.1 giving it "0x000 or 0x100", and the file names that copy with a trailing underscore, `ACR_` beside `ACR`, so its variant is `Acr_`.

To bump the file, replace it, regenerate, and review the diff of the tables:

```text
rigless svd generate src/soc/stm32h743
```

CI runs the same command and fails when the committed tables differ from the result.