diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 673a04a5b..eb1b9cd85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,6 +99,21 @@ jobs: fetch stm32-bsp-common https://github.com/STMicroelectronics/stm32-bsp-common.git 1e18c5afdf1f5971a35c8e2f88b6a21e5568ed92 python3 tests/vendor/stm32cubef4/run.py --st "$RUNNER_TEMP/st" --embsim build/${{ matrix.preset }}/bin/embsim python3 tests/vendor/stm32cubef4/run.py --st "$RUNNER_TEMP/st" --board nucleo_f446ze --embsim build/${{ matrix.preset }}/bin/embsim + - name: STM32CubeG4's examples on the NUCLEO-G474RE + if: matrix.name == 'linux-gcc' + # CubeG4 at a commit, its HAL, CMSIS device and Nucleo BSP at the submodule commits it pins + run: | + fetch() { # directory, repository, commit[, sparse paths] + git init -q "$RUNNER_TEMP/$1" + git -C "$RUNNER_TEMP/$1" fetch -q --depth 1 --filter=blob:none "$2" "$3" + if [ -n "$4" ]; then git -C "$RUNNER_TEMP/$1" sparse-checkout set $4; fi + git -C "$RUNNER_TEMP/$1" checkout -q FETCH_HEAD + } + fetch cubeg4 https://github.com/STMicroelectronics/STM32CubeG4.git 140db648b016ba49b05ca790b5b66e3477807839 "Projects/NUCLEO-G474RE Drivers/CMSIS/Include" + fetch cubeg4/Drivers/STM32G4xx_HAL_Driver https://github.com/STMicroelectronics/stm32g4xx_hal_driver.git a6001282dfacfff57e9710250f15e4333b578865 + fetch cubeg4/Drivers/CMSIS/Device/ST/STM32G4xx https://github.com/STMicroelectronics/cmsis_device_g4.git 25664ddc3a7624ae9627ae8c4c672073dc5b2539 + fetch cubeg4/Drivers/BSP/STM32G4xx_Nucleo https://github.com/STMicroelectronics/stm32g4xx-nucleo-bsp.git 33045a8df151b6a63565f2b5e1800f4358c396a1 + python3 tests/vendor/stm32cubeg4/run.py --cube "$RUNNER_TEMP/cubeg4" --embsim build/${{ matrix.preset }}/bin/embsim - name: The ST-LINK and the Debug Probe over USB/IP on the kernel's vhci-hcd, driven by stlink-tools and OpenOCD if: matrix.name == 'linux-gcc' run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index b7cd535f9..4dc03ecab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,112 @@ versions follow semantic versioning. There is no release yet. ## Unreleased +### The STM32G474RE and the NUCLEO-G474RE: a second STM32 family + +- Added `st/stm32g474re`, the STM32G474RE (Cortex-M4F at 170 MHz, 512 KiB + of dual-bank flash, 128 KiB of SRAM with the CCM SRAM), its register + description converted from ST's Apache-2.0 STM32G474.svd v3.0 by + `tools/importers/stm32g474_regs.sh` with the corrections RM0440, the CMSIS + header and the HAL give (RCC_CR's and EXTI's reset values, PWR_SR2's PVMO + bits, the timers' OCxM[3] bits ST's file leaves out, TIM2's 32-bit CNT, + the interrupts it puts on the wrong peripheral), its LQFP64 pinout, analog + inputs and alternate functions from ST's open pin data, and the DMAMUX's + request numbers. +- New models for the G4's own IP: `stm32g4-rcc` (HSI16, HSE, LSI, LSE, + HSI48 with their start-up times, the PLL's P, Q and R outputs, the kernel + clocks, the limits of the voltage ranges and flash wait states), + `stm32g4-pwr` (the voltage ranges and boost, the PVD, Stop 0 and 1, + Standby with SRAM2 and the pull configuration, Shutdown, the wake-up + pins), `stm32g4-flash` (double-word and fast programming, page and bank + erases with read-while-write between the banks, the option bytes with + their complements, OBL_LAUNCH, BOOT0 on PB8 or nBOOT0) and + `stm32-usart-v2` (the U(S)ARTs and LPUART of the ISR/ICR layout: FIFOs, + 7/8/9-bit frames, MSBFIRST, DATAINV, SWAP, DE, character match, receiver + timeout, wake-up from Stop). +- Shared models taught the G4's registers: GPIO's BRR, SYSCFG's G4 remaps + and CCM SRAM erase, EXTI's two banks of lines, the programmable CRC + (polynomial, size, input and output reversal), the IWDG's window and the + option bytes' hardware start and freeze, the WWDG's 3-bit prescaler, + DBGMCU's G4 names, the timers' TISEL clock inputs and freeze bits found + by name, a pin's analog entry listing several ADC groups. +- Added `emblink/nucleo_g474re` (MB1367): the 24 MHz HSE crystal X3 and + the LSE crystal X2, LD2 on PA5, B1 on PC13, B2, LD3, JP5's four supply + positions, JP6 (IDD), JP7, U11 and U12, the Arduino and morpho + connectors, the VCP on LPUART1, its option bytes as ST ships the board + (nSWBOOT0 0), original artwork, and seven fixtures (USB, VIN, E5V, VIN + without JP5, the IDD ammeter, B1, LD2 through Q1). +- A board can give its MCU's memory as it ships (`mcu.memory`: the + NUCLEO-G474RE's option bytes), and an MCU model can choose the boot + (`boot_pin`, `boot_system`: the G4's BOOT0 on PB8). +- `tests/vendor/stm32cubeg4/run.py` builds STM32CubeG4's examples for the + NUCLEO-G474RE unmodified; 24 run under scenarios (GPIO, EXTI, the HAL's + time base on TIM6, RCC's PLL moved between HSI16 and HSE, UART_Printf on + LPUART1, four CRC examples, the Cortex-M4's privilege modes, process + stack and SysTick, FLASH erase/program and fast program with their timing, the IWDG + with and without a window, the WWDG, Stop 0, TIM1's PWM and output + compare toggle, DMA from the flash to the SRAM with the HAL and with LL, + USART2 and LPUART1 through DMA on the virtual COM port), in CI's + linux-gcc job too. +- Added `stm32g4-dma` and `stm32g4-dmamux` (RM0440 12 and 13): DMA1 and + DMA2's eight channels (memory to memory, table 89's packing, circular + mode, HT, TC, TE and GIF, the bits locked while EN is set, a bus error's + TEIF), DMAMUX's sixteen channels on any of the 115 request lines, their + synchronisation on an EXTI line or a channel's event with NBREQ and SOF, + event generation, the four request generators with OF, DMAMUX_OVR. +- The SPI model learned the FIFO SPI of the STM32G4 (RM0440 42, and the + F0, F3, F7 and L4's): 4 to 16-bit frames, the 32-bit FIFOs with TXE, + FRXTH's RXNE threshold, FTLVL, FRLVL and OVR, packed 16-bit accesses, + LDMA_TX and LDMA_RX, CRCL's CRC8 and CRC16, NSSP; the G474RE's SPI1 to + SPI4 use it. CubeG4's SPI_FullDuplex_ComPolling and _ComDMA pairs run on + two boards (`tests/vendor/stm32cubeg4/run.py` builds an example's + _Master and _Slave projects; 26 examples). +- A pin given another alternate function hears its level at once: SPI1's + SCK on PB3, after the reset's AF0, saw no level until the first edge, and + a slave counted that edge as its baseline (STM32F4 and G4). +- A board's console is the UART the firmware muxes onto its bridge's pins + (`console.tx`, `console.rx`), not only the MCU's default unit: the + NUCLEO-G474RE's VCP hears USART2 on PA2/PA3 as it hears LPUART1. +- An EXTI line that SYSCFG gives another port sees the new pin's level at + once, an edge when it differs from the old pin's (STM32F4 and G4). +- Faster: an analog island counts as still when its branch currents move by + less than a nanoampere and a millionth of their value (node voltages keep + their microvolt test). An LED's current drifting by picoamps as it warms, + or a ferrite bead's sub-nanoampere numerical ringing between two + capacitors, kept a board's supply island stepping every quantum: the + NUCLEO-G474RE's example now runs in 9 s of CPU instead of 33. +- The NUCLEO-G474RE checked against UM2505 Rev 7 and DS12288 Rev 6: U4 + (STMPS2151STR) and LD4 in the STLINK-V3E's 5 V path, CN10 pins 35 and 37 + on USART1 (the factory solder bridges), VREF+ on its own net through JP8 + and the ferrite bead L2 (VDDA through L1), the crystals' parts; the fast + row's programming time is DS12288's 1.91 ms and the PVD's thresholds its + falling and rising ones. +- The NUCLEO-G474RE built from MB1367 D-01's schematic, every part with its + designator and value: U4's input and output capacitors, R8 on T_PWR_EN + and R1 with LD4 on its FAULT; U11's and U12's capacitors; VDD's, VDDA's, + VBAT's and VREF+'s decoupling; VREF from U14 (TL1431CL5T) and Q2 at + 3.26 V, on VREF+ through JP8's factory position (it was VDD); LD2 + switched by Q1 from 3V3 (R25, R29, R28), so its current no longer passes + JP6's ammeter; B1 active high, as the schematic draws it (VDD through + B1, R26 to ground, R27 and C35 on PC13; it was active low): the + example counts B1's rising edges, and CubeG4's GPIO_EXTI, which takes the + falling edge, toggles LD2 on the release, as it does on the board. +- Added `emblink/tl1431cl5t`, ST's TL1431 programmable shunt reference in + SOT23-5L (2.500 V, the open-loop gain of the datasheet's figure 19, Ioff, + a step response within figure 22's microsecond; five fixtures), and + `emblink/bsr14`, the BSR14 NPN with onsemi's SPICE model (VCE(sat) and + VBE(sat) at 150 mA and 500 mA, MB1367's LD2 circuit). +- The `regulator` primitive's output has a 1 mOhm resistance while it + regulates. An output capacitor held at its initial voltage at the + operating point (an LDO with full input at t = 0) no longer sets two + ideal sources against each other: the regulator starts in current limit + and charges it, as a real one does. +- Fixed: exception entry left CONTROL.SPSEL set when the thread ran on the + process stack, so a handler read CONTROL[1] as 1 (ARMv7-M's ExceptionTaken + clears it); CubeG4's CORTEXM_ProcessStack found it. +- `svd2regs.py`: `--strip-prefixes` (TIM2_CR1 in TIM2 named CR1), + `--rename`, and `--drop` leaving the peripherals derived from the dropped + one its registers. + ### DC motors and their driver: the first of the robot's parts (M7) - Added the analog primitive `dc_motor` (`core/analog/motor.c`, SPEC-004): a diff --git a/NOTICE b/NOTICE index ab4754780..ae5fd6158 100644 --- a/NOTICE +++ b/NOTICE @@ -88,6 +88,12 @@ carries its own licence beside it: 2.0), Copyright (c) 2024 STMicroelectronics; Apache-2.0 (catalog/mcus/st/stm32f446re/LICENSES/) + catalog/mcus/st/stm32g474re/registers.json + converted from STMicroelectronics' + STM32G474.svd (version 3.0, STM32G4 SVD + pack), Copyright (c) 2024 STMicroelectronics; + Apache-2.0 + (catalog/mcus/st/stm32g474re/LICENSES/) catalog/mcus/nordic/nrf52840/registers.json converted from Nordic Semiconductor's nrf52840.svd (nrfx 3.4.0), Copyright (c) diff --git a/catalog/boards/nucleo_g474re/artwork.svg b/catalog/boards/nucleo_g474re/artwork.svg new file mode 100644 index 000000000..d46ac45e3 --- /dev/null +++ b/catalog/boards/nucleo_g474re/artwork.svg @@ -0,0 +1,299 @@ + + + + + + + + + +USB STLINK-V3E + + +STM32F723IEK6 +LD1 COM +JP5 5V_SEL + + + +STLK + + + +VIN + + + +E5V + + + +CHGR +IDD + + +JP8 VREF1 + +USER +JP7 BOOT0 +RESET +LD2 +LD4 OC +LD3 5V_PWR + +STM32G474RET6 +X2 +X3 24MHz + +CN10 pin 1: CN10_1 + +CN10 pin 2: CN10_2 + +CN10 pin 3: CN10_3 + +CN10 pin 4: CN10_4 + +CN10 pin 5: CN10_5 + +CN10 pin 6: CN10_6 + +CN10 pin 7: CN10_7 + +CN10 pin 8: CN10_8 + +CN10 pin 9: CN10_9 + + + +CN10 pin 11: CN10_11 + +CN10 pin 12: CN10_12 + +CN10 pin 13: CN10_13 + +CN10 pin 14: CN10_14 + +CN10 pin 15: CN10_15 + +CN10 pin 16: CN10_16 + +CN10 pin 17: CN10_17 + +CN10 pin 18: CN10_18 + +CN10 pin 19: CN10_19 + +CN10 pin 20: CN10_20 + +CN10 pin 21: CN10_21 + +CN10 pin 22: CN10_22 + +CN10 pin 23: CN10_23 + +CN10 pin 24: CN10_24 + +CN10 pin 25: CN10_25 + +CN10 pin 26: CN10_26 + +CN10 pin 27: CN10_27 + +CN10 pin 28: CN10_28 + +CN10 pin 29: CN10_29 + +CN10 pin 30: CN10_30 + +CN10 pin 31: CN10_31 + +CN10 pin 32: CN10_32 + +CN10 pin 33: CN10_33 + +CN10 pin 34: CN10_34 + +CN10 pin 35: CN10_35 + + + +CN10 pin 37: CN10_37 + + + +CN5 pin 1: D8 +D8 + +CN5 pin 2: D9 +D9 + +CN5 pin 3: D10 +D10 + +CN5 pin 4: D11 +D11 + +CN5 pin 5: D12 +D12 + +CN5 pin 6: D13 +D13 + +CN5 pin 7: GND_D +GND_D + +CN5 pin 8: AREF +AREF + +CN5 pin 9: D14 +D14 + +CN5 pin 10: D15 +D15 + + + +CN6 pin 2: IOREF +IOREF + +CN6 pin 3: RESET +RESET + +CN6 pin 4: 3V3 +3V3 + +CN6 pin 5: 5V +5V + +CN6 pin 6: GND +GND + +CN6 pin 7: GND_2 +GND_2 + +CN6 pin 8: VIN +VIN + +CN7 pin 1: CN7_1 + +CN7 pin 2: CN7_2 + +CN7 pin 3: CN7_3 + +CN7 pin 4: CN7_4 + +CN7 pin 5: CN7_5 + +CN7 pin 6: E5V + +CN7 pin 7: CN7_7 + +CN7 pin 8: CN7_8 + + + + + + + +CN7 pin 12: CN7_12 + +CN7 pin 13: CN7_13 + +CN7 pin 14: CN7_14 + +CN7 pin 15: CN7_15 + +CN7 pin 16: CN7_16 + +CN7 pin 17: CN7_17 + +CN7 pin 18: CN7_18 + +CN7 pin 19: CN7_19 + +CN7 pin 20: CN7_20 + +CN7 pin 21: CN7_21 + +CN7 pin 22: CN7_22 + +CN7 pin 23: CN7_23 + +CN7 pin 24: CN7_24 + +CN7 pin 25: CN7_25 + + + +CN7 pin 27: CN7_27 + +CN7 pin 28: CN7_28 + + + +CN7 pin 30: CN7_30 + +CN7 pin 31: CN7_31 + +CN7 pin 32: CN7_32 + +CN7 pin 33: CN7_33 + +CN7 pin 34: CN7_34 + +CN7 pin 35: CN7_35 + +CN7 pin 36: CN7_36 + +CN7 pin 37: CN7_37 + +CN7 pin 38: CN7_38 + +CN8 pin 1: A0 +A0 + +CN8 pin 2: A1 +A1 + +CN8 pin 3: A2 +A2 + +CN8 pin 4: A3 +A3 + +CN8 pin 5: A4 +A4 + +CN8 pin 6: A5 +A5 + +CN9 pin 1: D0 +D0 + +CN9 pin 2: D1 +D1 + +CN9 pin 3: D2 +D2 + +CN9 pin 4: D3 +D3 + +CN9 pin 5: D4 +D4 + +CN9 pin 6: D5 +D5 + +CN9 pin 7: D6 +D6 + +CN9 pin 8: D7 +D7 +CN7 +CN10 +CN6 +CN5 +NUCLEO-G474RE + diff --git a/catalog/boards/nucleo_g474re/board.json b/catalog/boards/nucleo_g474re/board.json new file mode 100644 index 000000000..1de1dae9d --- /dev/null +++ b/catalog/boards/nucleo_g474re/board.json @@ -0,0 +1,2183 @@ +{ + "schema_version": 1, + "kind": "board", + "id": "emblink/nucleo_g474re", + "version": "1.0.0", + "name": "NUCLEO-G474RE", + "description": "ST's NUCLEO-G474RE (MB1367): an STM32G474RET6 with the 24 MHz HSE crystal X3 and the 32.768 kHz LSE crystal X2, the green user LED LD2 on PA5, the blue, active-high USER button on PC13, the black RESET button, the green power LED LD3, JP5 choosing the STLINK-V3E's USB, VIN, E5V or a USB charger, JP6 (IDD) to measure the MCU's current, the Arduino Uno V3 headers and the two ST morpho headers. The STLINK-V3E's virtual COM port is the session's serial console on LPUART1 (PA2/PA3), and a serial port on the host (embsim serve --serial).", + "keywords": [ + "nucleo", + "nucleo-64", + "stm32g4", + "stm32g474", + "stm32g474re", + "stm32", + "cortex-m4", + "stlink-v3e" + ], + "revision": "MB1367", + "mcu": { + "ref": "st/stm32g474re", + "package": "lqfp64", + "instance": "U13", + "memory": [ + { + "base": "0x1FFF7800", + "bytes": "aaf8effb55071004", + "doc": "USER and RDP as ST programs them on the NUCLEO-G474RE: 0xFBEFF8AA, nSWBOOT0 0 and nBOOT0 1, so the part boots its flash whatever PB8 (D15) is, as ST says the board ships (ST community, 2019)" + } + ] + }, + "oscillators": { + "hse": { + "hz": 24000000, + "source": "external_crystal", + "component": "X3" + }, + "lse": { + "hz": 32768, + "source": "external_crystal", + "component": "X2" + } + }, + "components": [ + { + "id": "C11", + "component": "emblink/capacitor", + "params": { + "capacitance": "1u", + "esr": 0.01 + }, + "doc": "C11 (1 uF ceramic, a 10 mOhm ESR): U4's input capacitor on 5V_USB_CHGR" + }, + { + "id": "U4", + "component": "emblink/stmps2151str", + "doc": "U4 STMPS2151STR: 5V_USB_CHGR (CN1's VBUS) to 5V_USB_STLK once the STLINK-V3E's T_PWR_EN is high, after the USB enumeration (UM2505 7.4.1); its current limit protects the PC's port" + }, + { + "id": "C5", + "component": "emblink/capacitor", + "params": { + "capacitance": "1u" + }, + "doc": "U4's output capacitor on 5V_USB_STLK" + }, + { + "id": "R8", + "component": "emblink/resistor", + "params": { + "resistance": "10k" + }, + "doc": "R8: T_PWR_EN pulled down (U4 off until the STLINK-V3E drives it)" + }, + { + "id": "R_TPWREN", + "component": "emblink/resistor", + "params": { + "resistance": 40 + }, + "doc": "The STLINK-V3E's T_PWR_EN (U5's PB0) driving U4's EN high, as after the host granted 500 mA: a stand-in for the STLINK's output" + }, + { + "id": "R1", + "component": "emblink/resistor", + "params": { + "resistance": "1k" + }, + "doc": "R1: LD4's series resistor from 5V_USB_CHGR" + }, + { + "id": "LD4", + "component": "emblink/led", + "params": { + "color": "red" + }, + "doc": "LD4 (red): U4's FAULT, more than 500 mA drawn from the STLINK-V3E's USB" + }, + { + "id": "C41", + "component": "emblink/capacitor", + "params": { + "capacitance": "10u", + "esr": 0.01 + }, + "doc": "C41 (10 uF ceramic, a 10 mOhm ESR): U11's input capacitor" + }, + { + "id": "U11", + "component": "emblink/regulator", + "params": { + "part": "LD1117S50" + }, + "doc": "U11 LD1117S50TR: 5V_VIN from VIN (7 to 12 V), to JP5's VIN position" + }, + { + "id": "C38", + "component": "emblink/capacitor", + "params": { + "capacitance": "10u" + }, + "doc": "U11's output capacitor" + }, + { + "id": "JP5_STLK", + "component": "emblink/toggle_switch", + "params": { + "initially_closed": true + }, + "doc": "JP5 (5V_SEL) on pins 1-2, STLK: +5V from 5V_USB_STLK, the STLINK-V3E's USB through U4 (the factory position)" + }, + { + "id": "JP5_VIN", + "component": "emblink/toggle_switch", + "doc": "JP5 on pins 3-4, 5V_VIN: +5V from U11" + }, + { + "id": "JP5_E5V", + "component": "emblink/toggle_switch", + "doc": "JP5 on pins 5-6, E5V: +5V from an external 5 V supply on CN7 pin 6" + }, + { + "id": "JP5_CHGR", + "component": "emblink/toggle_switch", + "doc": "JP5 on pins 7-8, CHG: +5V straight from the STLINK-V3E's USB connector (5V_USB_CHGR, also on CN10 pin 8), for a USB charger: no enumeration, no current limit" + }, + { + "id": "R7", + "component": "emblink/resistor", + "params": { + "resistance": 510 + }, + "doc": "R7: LD3's series resistor" + }, + { + "id": "LD3", + "component": "emblink/led", + "params": { + "color": "green" + }, + "doc": "LD3 (5V_PWR, green): +5V is present" + }, + { + "id": "C37", + "component": "emblink/capacitor", + "params": { + "capacitance": "1u" + }, + "doc": "U12's input capacitor" + }, + { + "id": "C36", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "U12's input capacitor" + }, + { + "id": "U12", + "component": "emblink/regulator", + "params": { + "part": "LD39050PU33R" + }, + "doc": "U12 LD39050PU33R: +3.3V from +5V (500 mA), its EN tied to its input" + }, + { + "id": "C39", + "component": "emblink/capacitor", + "params": { + "capacitance": "1u" + }, + "doc": "U12's output capacitor" + }, + { + "id": "C40", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "U12's output capacitor" + }, + { + "id": "JP6", + "component": "emblink/toggle_switch", + "params": { + "initially_closed": true + }, + "doc": "JP6 (IDD, on from the factory): +3.3V to the STM32's VDD; remove it and put an ammeter across IDD_3V3 and IDD_VDD" + }, + { + "id": "R35", + "component": "emblink/resistor", + "params": { + "resistance": 180 + }, + "doc": "R35: U14's cathode and Q2's base fed from +5V" + }, + { + "id": "U14", + "component": "emblink/tl1431cl5t", + "doc": "U14 TL1431CL5T: holds its REF at 2.5 V by pulling Q2's base down" + }, + { + "id": "Q2", + "component": "emblink/bsr14", + "doc": "Q2 BSR14: the emitter follower that supplies VREF" + }, + { + "id": "C51", + "component": "emblink/capacitor", + "params": { + "capacitance": "100p" + }, + "doc": "C51: the loop's compensation from U14's cathode to its REF" + }, + { + "id": "R33", + "component": "emblink/resistor", + "params": { + "resistance": "10k" + }, + "doc": "R33: VREF to U14's REF (SB14 off, the factory's: VREF 3.25 V)" + }, + { + "id": "R34", + "component": "emblink/resistor", + "params": { + "resistance": "33k" + }, + "doc": "R34: U14's REF to AGND" + }, + { + "id": "C50", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "VREF's decoupling" + }, + { + "id": "C46", + "component": "emblink/capacitor", + "params": { + "capacitance": "10u" + }, + "doc": "VREF's bulk capacitor" + }, + { + "id": "JP8_VREF", + "component": "emblink/toggle_switch", + "params": { + "initially_closed": true + }, + "doc": "JP8 on pins 1-2: VREF+ from VREF, 3.25 V (the factory position)" + }, + { + "id": "JP8_VDD", + "component": "emblink/toggle_switch", + "doc": "JP8 on pins 2-3: VREF+ from VDD" + }, + { + "id": "C47", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "C47: JP8's common pin decoupled to AGND" + }, + { + "id": "L2", + "component": "emblink/ferrite_bead", + "doc": "L2, 600 ohm at 100 MHz, to VREF+ (SB10 off: not shunted; its DC values the catalog's)" + }, + { + "id": "C48", + "component": "emblink/capacitor", + "params": { + "capacitance": "1u" + }, + "doc": "VREF+'s 1 uF" + }, + { + "id": "C49", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "VREF+'s 100 nF" + }, + { + "id": "L1", + "component": "emblink/ferrite_bead", + "doc": "L1, 600 ohm at 100 MHz, from VDD to VDDA (SB8 off: not shunted)" + }, + { + "id": "C43", + "component": "emblink/capacitor", + "params": { + "capacitance": "1u" + }, + "doc": "AVDD's 1 uF" + }, + { + "id": "C44", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "AVDD's 100 nF" + }, + { + "id": "C53", + "component": "emblink/capacitor", + "params": { + "capacitance": "1u" + }, + "doc": "VBAT's capacitor (VBAT from VDD through SB38)" + }, + { + "id": "C55", + "component": "emblink/capacitor", + "params": { + "capacitance": "4.7u" + }, + "doc": "VDD's bulk capacitor" + }, + { + "id": "C45", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "C45: VDD's decoupling at one of its four pins" + }, + { + "id": "C54", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "C54: VDD's decoupling at one of its four pins" + }, + { + "id": "C42", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "C42: VDD's decoupling at one of its four pins" + }, + { + "id": "C52", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "C52: VDD's decoupling at one of its four pins" + }, + { + "id": "R25", + "component": "emblink/resistor", + "params": { + "resistance": 510 + }, + "doc": "R25: LD2's series resistor from 3V3" + }, + { + "id": "LD2", + "component": "emblink/led", + "params": { + "color": "green" + }, + "doc": "LD2 (USER, green), switched by Q1: PA5 (Arduino D13, SB6 on) high lights it" + }, + { + "id": "Q1", + "component": "emblink/bsr14", + "doc": "Q1 BSR14: LD2's low-side switch, so LD2's current does not come from VDD" + }, + { + "id": "R29", + "component": "emblink/resistor", + "params": { + "resistance": "47k" + }, + "doc": "R29: PA5 to Q1's base" + }, + { + "id": "R28", + "component": "emblink/resistor", + "params": { + "resistance": "100k" + }, + "doc": "R28: Q1's base pulled down" + }, + { + "id": "B1", + "component": "emblink/push_button", + "doc": "B1 USER (blue): joins its node to VDD while pressed (active high)" + }, + { + "id": "R26", + "component": "emblink/resistor", + "params": { + "resistance": "100k" + }, + "doc": "R26: B1's node pulled down: PC13 low while B1 is released" + }, + { + "id": "R27", + "component": "emblink/resistor", + "params": { + "resistance": 330 + }, + "doc": "R27: B1's node to PC13 (B_USER, through SB16)" + }, + { + "id": "C35", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "C35: B_USER's filter capacitor, charged through R27 (about 33 us) when B1 is pressed" + }, + { + "id": "B2", + "component": "emblink/push_button", + "doc": "B2 RESET (black): pulls NRST low" + }, + { + "id": "C34", + "component": "emblink/capacitor", + "params": { + "capacitance": "100n" + }, + "doc": "C34, 100 nF on PG10-NRST (SB1 on): with the STM32's internal pull-up, it holds the part in reset at power-on" + }, + { + "id": "JP7", + "component": "emblink/toggle_switch", + "doc": "JP7 (not fitted): PB8-BOOT0 to R31, for when the option bytes' nSWBOOT0 makes PB8 the boot pin" + }, + { + "id": "R31", + "component": "emblink/resistor", + "params": { + "resistance": "10k" + }, + "doc": "R31: BOOT0's pull-down through JP7" + }, + { + "id": "X2", + "component": "emblink/crystal", + "params": { + "hz": 32768, + "c0": "1.5p", + "cm": "3f", + "lm": "7.8k", + "rm": "50k" + }, + "doc": "X2 NX3215SA-32.768kHz-EXS00A-MU00525 (6 pF load, 20 ppm) on PC14/PC15 (SB30, SB31 on), C57 and C58 5.1 pF; its motional values the catalog's 32.768 kHz equivalent" + }, + { + "id": "X3", + "component": "emblink/crystal", + "params": { + "hz": "24meg" + }, + "doc": "X3 NX2016SA-24MHz-EXS00A-CS10820 (6 pF load, 20 ppm) on PF0/PF1 (SB25, SB26 on), C56 and C59 6.8 pF" + }, + { + "id": "CN6", + "component": "emblink/header", + "params": { + "pins": 8 + }, + "doc": "Arduino power: NC IOREF RESET +3.3V +5V GND GND VIN" + }, + { + "id": "CN8", + "component": "emblink/header", + "params": { + "pins": 6 + }, + "doc": "Arduino analog: A0..A5" + }, + { + "id": "CN5", + "component": "emblink/header", + "params": { + "pins": 10 + }, + "doc": "Arduino digital: D8..D13 GND AREF D14 D15" + }, + { + "id": "CN9", + "component": "emblink/header", + "params": { + "pins": 8 + }, + "doc": "Arduino digital: D0..D7" + }, + { + "id": "CN7", + "component": "emblink/header", + "params": { + "pins": 38 + }, + "doc": "ST morpho, left (2 x 19)" + }, + { + "id": "CN10", + "component": "emblink/header", + "params": { + "pins": 38 + }, + "doc": "ST morpho, right (2 x 19)" + }, + { + "id": "CN1", + "component": "emblink/header", + "params": { + "pins": 5 + }, + "doc": "CN1, the STLINK-V3E's micro-USB: 1 VBUS (U5V), 2 D-, 3 D+, 4 ID, 5 GND" + } + ], + "nets": { + "U5V": [ + "CN1.1", + "C11.1", + "U4.IN", + "R_TPWREN.1", + "R1.1", + "JP5_CHGR.1", + "CN10.8" + ], + "T_PWR_EN": [ + "U4.EN", + "R8.1", + "R_TPWREN.2" + ], + "5V_USB_STLK": [ + "U4.OUT", + "C5.1", + "JP5_STLK.1" + ], + "LD4_A": [ + "R1.2", + "LD4.A" + ], + "USB_OC": [ + "LD4.K", + "U4.FAULT" + ], + "VIN": [ + "U11.IN", + "C41.1", + "CN6.8", + "CN7.24" + ], + "5V_VIN": [ + "U11.OUT", + "C38.1", + "JP5_VIN.1" + ], + "E5V": [ + "JP5_E5V.1", + "CN7.6" + ], + "5V": [ + "JP5_STLK.2", + "JP5_VIN.2", + "JP5_E5V.2", + "JP5_CHGR.2", + "R7.1", + "CN6.5", + "CN7.18", + "U12.IN", + "C37.1", + "C36.1", + "R35.1", + "Q2.C" + ], + "LD3_A": [ + "R7.2", + "LD3.A" + ], + "3V3": [ + "U12.OUT", + "C39.1", + "C40.1", + "JP6.1", + "CN6.2", + "CN6.4", + "CN7.12", + "CN7.16", + "R25.1" + ], + "VREF_K": [ + "R35.2", + "U14.CATHODE", + "Q2.B", + "C51.1" + ], + "VREF_FB": [ + "U14.REF", + "C51.2", + "R33.2", + "R34.1" + ], + "VREF": [ + "Q2.E", + "R33.1", + "C50.1", + "C46.1", + "JP8_VREF.1" + ], + "VDD": [ + "JP6.2", + "JP8_VDD.1", + "L1.1", + "U13.VDD", + "U13.VBAT", + "C53.1", + "C55.1", + "C45.1", + "C54.1", + "C42.1", + "C52.1", + "CN7.5", + "CN7.33", + "B1.1" + ], + "JP8_2": [ + "JP8_VREF.2", + "JP8_VDD.2", + "C47.1", + "L2.1" + ], + "VREFP": [ + "U13.VREFP", + "L2.2", + "C48.1", + "C49.1", + "CN5.8", + "CN10.7" + ], + "AVDD": [ + "U13.VDDA", + "L1.2", + "C43.1", + "C44.1" + ], + "GND": [ + "U4.GND", + "C11.2", + "C5.2", + "R8.2", + "U11.GND", + "C41.2", + "C38.2", + "LD3.K", + "U12.GND", + "C37.2", + "C36.2", + "C39.2", + "C40.2", + "U14.ANODE", + "R34.2", + "C50.2", + "C46.2", + "C47.2", + "C48.2", + "C49.2", + "C43.2", + "C44.2", + "C53.2", + "C55.2", + "C45.2", + "C54.2", + "C42.2", + "C52.2", + "Q1.E", + "R28.2", + "R26.2", + "C35.2", + "B2.2", + "C34.2", + "R31.2", + "U13.VSS", + "U13.VSSA", + "CN5.7", + "CN6.6", + "CN6.7", + "CN7.8", + "CN7.19", + "CN7.20", + "CN7.22", + "CN10.9", + "CN10.20", + "CN10.32", + "CN1.5" + ], + "LD2_A": [ + "R25.2", + "LD2.A" + ], + "LD2_K": [ + "LD2.K", + "Q1.C" + ], + "Q1_B": [ + "Q1.B", + "R29.2", + "R28.1" + ], + "B1_N": [ + "B1.2", + "R26.1", + "R27.1" + ], + "NRST": [ + "U13.NRST", + "B2.1", + "C34.1", + "CN6.3", + "CN7.14" + ], + "BOOT0": [ + "JP7.2", + "R31.1" + ], + "PC14": [ + "U13.PC14", + "X2.1" + ], + "PC15": [ + "U13.PC15", + "X2.2" + ], + "PF0": [ + "U13.PF0", + "X3.1" + ], + "PF1": [ + "U13.PF1", + "X3.2" + ], + "USB_DM": [ + "CN1.2" + ], + "USB_DP": [ + "CN1.3" + ], + "PC5": [ + "U13.PC5", + "CN9.1", + "CN10.6", + "CN10.37" + ], + "PC4": [ + "U13.PC4", + "CN9.2", + "CN10.34", + "CN10.35" + ], + "PA10": [ + "U13.PA10", + "CN9.3", + "CN10.33" + ], + "PB3": [ + "U13.PB3", + "CN9.4", + "CN10.31" + ], + "PB5": [ + "U13.PB5", + "CN9.5", + "CN10.29" + ], + "PB4": [ + "U13.PB4", + "CN9.6", + "CN10.27" + ], + "PB10": [ + "U13.PB10", + "CN9.7", + "CN10.25" + ], + "PA8": [ + "U13.PA8", + "CN9.8", + "CN10.23" + ], + "PA9": [ + "U13.PA9", + "CN5.1", + "CN10.21" + ], + "PC7": [ + "U13.PC7", + "CN5.2", + "CN10.19" + ], + "PB6": [ + "U13.PB6", + "CN5.3", + "CN10.17" + ], + "PA7": [ + "U13.PA7", + "CN5.4", + "CN10.15" + ], + "PA6": [ + "U13.PA6", + "CN5.5", + "CN10.13" + ], + "PA5": [ + "U13.PA5", + "CN5.6", + "CN10.11", + "R29.1" + ], + "PB9": [ + "U13.PB9", + "CN5.9", + "CN10.5" + ], + "PB8": [ + "U13.PB8", + "CN5.10", + "CN7.7", + "CN10.3", + "JP7.1" + ], + "PA0": [ + "U13.PA0", + "CN8.1", + "CN7.28" + ], + "PA1": [ + "U13.PA1", + "CN8.2", + "CN7.30" + ], + "PA4": [ + "U13.PA4", + "CN8.3", + "CN7.32" + ], + "PB0": [ + "U13.PB0", + "CN8.4", + "CN7.34" + ], + "PC1": [ + "U13.PC1", + "CN8.5", + "CN7.36" + ], + "PC0": [ + "U13.PC0", + "CN8.6", + "CN7.38" + ], + "PC10": [ + "U13.PC10", + "CN7.1" + ], + "PC11": [ + "U13.PC11", + "CN7.2" + ], + "PC12": [ + "U13.PC12", + "CN7.3" + ], + "PD2": [ + "U13.PD2", + "CN7.4" + ], + "PA13": [ + "U13.PA13", + "CN7.13" + ], + "PA14": [ + "U13.PA14", + "CN7.15" + ], + "PA15": [ + "U13.PA15", + "CN7.17" + ], + "PB7": [ + "U13.PB7", + "CN7.21" + ], + "PC13": [ + "U13.PC13", + "CN7.23", + "R27.2", + "C35.1" + ], + "PC2": [ + "U13.PC2", + "CN7.35" + ], + "PC3": [ + "U13.PC3", + "CN7.37" + ], + "PC9": [ + "U13.PC9", + "CN10.1" + ], + "PC8": [ + "U13.PC8", + "CN10.2" + ], + "PC6": [ + "U13.PC6", + "CN10.4" + ], + "PA12": [ + "U13.PA12", + "CN10.12" + ], + "PA11": [ + "U13.PA11", + "CN10.14" + ], + "PB12": [ + "U13.PB12", + "CN10.16" + ], + "PB11": [ + "U13.PB11", + "CN10.18" + ], + "PB2": [ + "U13.PB2", + "CN10.22" + ], + "PB1": [ + "U13.PB1", + "CN10.24" + ], + "PB15": [ + "U13.PB15", + "CN10.26" + ], + "PB14": [ + "U13.PB14", + "CN10.28" + ], + "PB13": [ + "U13.PB13", + "CN10.30" + ], + "CN7_25_NC": [ + "CN7.25" + ], + "CN7_27_NC": [ + "CN7.27" + ], + "PA2": [ + "U13.PA2" + ], + "PA3": [ + "U13.PA3" + ] + }, + "ports": { + "D0": { + "net": "PC5", + "connector": "CN9", + "pin": 1, + "doc": "PC5, USART1_RX" + }, + "D1": { + "net": "PC4", + "connector": "CN9", + "pin": 2, + "doc": "PC4, USART1_TX" + }, + "D2": { + "net": "PA10", + "connector": "CN9", + "pin": 3 + }, + "D3": { + "net": "PB3", + "connector": "CN9", + "pin": 4 + }, + "D4": { + "net": "PB5", + "connector": "CN9", + "pin": 5 + }, + "D5": { + "net": "PB4", + "connector": "CN9", + "pin": 6 + }, + "D6": { + "net": "PB10", + "connector": "CN9", + "pin": 7 + }, + "D7": { + "net": "PA8", + "connector": "CN9", + "pin": 8 + }, + "D8": { + "net": "PA9", + "connector": "CN5", + "pin": 1 + }, + "D9": { + "net": "PC7", + "connector": "CN5", + "pin": 2 + }, + "D10": { + "net": "PB6", + "connector": "CN5", + "pin": 3 + }, + "D11": { + "net": "PA7", + "connector": "CN5", + "pin": 4 + }, + "D12": { + "net": "PA6", + "connector": "CN5", + "pin": 5 + }, + "D13": { + "net": "PA5", + "connector": "CN5", + "pin": 6, + "doc": "PA5, LD2, SPI1_SCK" + }, + "D14": { + "net": "PB9", + "connector": "CN5", + "pin": 9, + "doc": "PB9, I2C1_SDA" + }, + "D15": { + "net": "PB8", + "connector": "CN5", + "pin": 10, + "doc": "PB8, I2C1_SCL; also BOOT0 when the option bytes' nSWBOOT0 is 1 (the board ships with it 0)" + }, + "GND_D": { + "net": "GND", + "connector": "CN5", + "pin": 7 + }, + "AREF": { + "net": "VREFP", + "connector": "CN5", + "pin": 8, + "doc": "VREFP, the STM32's VREF+ (JP8 chooses its source)" + }, + "IOREF": { + "net": "3V3", + "connector": "CN6", + "pin": 2 + }, + "RESET": { + "net": "NRST", + "connector": "CN6", + "pin": 3, + "doc": "NRST" + }, + "3V3": { + "net": "3V3", + "connector": "CN6", + "pin": 4, + "doc": "+3.3V from U12 (LD39050PU33R)" + }, + "5V": { + "net": "5V", + "connector": "CN6", + "pin": 5 + }, + "GND": { + "net": "GND", + "connector": "CN6", + "pin": 6 + }, + "GND_2": { + "net": "GND", + "connector": "CN6", + "pin": 7 + }, + "VIN": { + "net": "VIN", + "connector": "CN6", + "pin": 8, + "doc": "7 to 12 V into U11 (LD1117S50); JP5 must be on VIN (pins 3-4)" + }, + "A0": { + "net": "PA0", + "connector": "CN8", + "pin": 1 + }, + "A1": { + "net": "PA1", + "connector": "CN8", + "pin": 2 + }, + "A2": { + "net": "PA4", + "connector": "CN8", + "pin": 3 + }, + "A3": { + "net": "PB0", + "connector": "CN8", + "pin": 4 + }, + "A4": { + "net": "PC1", + "connector": "CN8", + "pin": 5 + }, + "A5": { + "net": "PC0", + "connector": "CN8", + "pin": 6 + }, + "CN7_1": { + "net": "PC10", + "connector": "CN7", + "pin": 1 + }, + "CN7_2": { + "net": "PC11", + "connector": "CN7", + "pin": 2 + }, + "CN7_3": { + "net": "PC12", + "connector": "CN7", + "pin": 3 + }, + "CN7_4": { + "net": "PD2", + "connector": "CN7", + "pin": 4 + }, + "CN7_5": { + "net": "VDD", + "connector": "CN7", + "pin": 5 + }, + "E5V": { + "net": "E5V", + "connector": "CN7", + "pin": 6, + "doc": "E5V: an external 5 V supply in, with JP5 on pins 5-6" + }, + "CN7_7": { + "net": "PB8", + "connector": "CN7", + "pin": 7, + "doc": "PB8 (BOOT0 when nSWBOOT0 is 1): JP7 pulls it down once fitted" + }, + "CN7_8": { + "net": "GND", + "connector": "CN7", + "pin": 8 + }, + "CN7_12": { + "net": "3V3", + "connector": "CN7", + "pin": 12 + }, + "CN7_13": { + "net": "PA13", + "connector": "CN7", + "pin": 13 + }, + "CN7_14": { + "net": "NRST", + "connector": "CN7", + "pin": 14 + }, + "CN7_15": { + "net": "PA14", + "connector": "CN7", + "pin": 15 + }, + "CN7_16": { + "net": "3V3", + "connector": "CN7", + "pin": 16 + }, + "CN7_17": { + "net": "PA15", + "connector": "CN7", + "pin": 17 + }, + "CN7_18": { + "net": "5V", + "connector": "CN7", + "pin": 18 + }, + "CN7_19": { + "net": "GND", + "connector": "CN7", + "pin": 19 + }, + "CN7_20": { + "net": "GND", + "connector": "CN7", + "pin": 20 + }, + "CN7_21": { + "net": "PB7", + "connector": "CN7", + "pin": 21 + }, + "CN7_22": { + "net": "GND", + "connector": "CN7", + "pin": 22 + }, + "CN7_23": { + "net": "PC13", + "connector": "CN7", + "pin": 23 + }, + "CN7_24": { + "net": "VIN", + "connector": "CN7", + "pin": 24 + }, + "CN7_25": { + "net": "CN7_25_NC", + "connector": "CN7", + "pin": 25, + "doc": "Not connected: PC14 is X2's (its bridge off)" + }, + "CN7_27": { + "net": "CN7_27_NC", + "connector": "CN7", + "pin": 27, + "doc": "Not connected: PC15 is X2's (its bridge off)" + }, + "CN7_28": { + "net": "PA0", + "connector": "CN7", + "pin": 28 + }, + "CN7_30": { + "net": "PA1", + "connector": "CN7", + "pin": 30 + }, + "CN7_32": { + "net": "PA4", + "connector": "CN7", + "pin": 32 + }, + "CN7_33": { + "net": "VDD", + "connector": "CN7", + "pin": 33 + }, + "CN7_34": { + "net": "PB0", + "connector": "CN7", + "pin": 34 + }, + "CN7_35": { + "net": "PC2", + "connector": "CN7", + "pin": 35 + }, + "CN7_36": { + "net": "PC1", + "connector": "CN7", + "pin": 36 + }, + "CN7_37": { + "net": "PC3", + "connector": "CN7", + "pin": 37 + }, + "CN7_38": { + "net": "PC0", + "connector": "CN7", + "pin": 38 + }, + "CN10_1": { + "net": "PC9", + "connector": "CN10", + "pin": 1 + }, + "CN10_2": { + "net": "PC8", + "connector": "CN10", + "pin": 2 + }, + "CN10_3": { + "net": "PB8", + "connector": "CN10", + "pin": 3 + }, + "CN10_4": { + "net": "PC6", + "connector": "CN10", + "pin": 4 + }, + "CN10_5": { + "net": "PB9", + "connector": "CN10", + "pin": 5 + }, + "CN10_6": { + "net": "PC5", + "connector": "CN10", + "pin": 6 + }, + "CN10_7": { + "net": "VREFP", + "connector": "CN10", + "pin": 7 + }, + "CN10_8": { + "net": "U5V", + "connector": "CN10", + "pin": 8 + }, + "CN10_9": { + "net": "GND", + "connector": "CN10", + "pin": 9 + }, + "CN10_11": { + "net": "PA5", + "connector": "CN10", + "pin": 11 + }, + "CN10_12": { + "net": "PA12", + "connector": "CN10", + "pin": 12 + }, + "CN10_13": { + "net": "PA6", + "connector": "CN10", + "pin": 13 + }, + "CN10_14": { + "net": "PA11", + "connector": "CN10", + "pin": 14 + }, + "CN10_15": { + "net": "PA7", + "connector": "CN10", + "pin": 15 + }, + "CN10_16": { + "net": "PB12", + "connector": "CN10", + "pin": 16 + }, + "CN10_17": { + "net": "PB6", + "connector": "CN10", + "pin": 17 + }, + "CN10_18": { + "net": "PB11", + "connector": "CN10", + "pin": 18 + }, + "CN10_19": { + "net": "PC7", + "connector": "CN10", + "pin": 19 + }, + "CN10_20": { + "net": "GND", + "connector": "CN10", + "pin": 20 + }, + "CN10_21": { + "net": "PA9", + "connector": "CN10", + "pin": 21 + }, + "CN10_22": { + "net": "PB2", + "connector": "CN10", + "pin": 22 + }, + "CN10_23": { + "net": "PA8", + "connector": "CN10", + "pin": 23 + }, + "CN10_24": { + "net": "PB1", + "connector": "CN10", + "pin": 24 + }, + "CN10_25": { + "net": "PB10", + "connector": "CN10", + "pin": 25 + }, + "CN10_26": { + "net": "PB15", + "connector": "CN10", + "pin": 26 + }, + "CN10_27": { + "net": "PB4", + "connector": "CN10", + "pin": 27 + }, + "CN10_28": { + "net": "PB14", + "connector": "CN10", + "pin": 28 + }, + "CN10_29": { + "net": "PB5", + "connector": "CN10", + "pin": 29 + }, + "CN10_30": { + "net": "PB13", + "connector": "CN10", + "pin": 30 + }, + "CN10_31": { + "net": "PB3", + "connector": "CN10", + "pin": 31 + }, + "CN10_32": { + "net": "GND", + "connector": "CN10", + "pin": 32 + }, + "CN10_33": { + "net": "PA10", + "connector": "CN10", + "pin": 33 + }, + "CN10_34": { + "net": "PC4", + "connector": "CN10", + "pin": 34 + }, + "CN10_35": { + "net": "PC4", + "connector": "CN10", + "pin": 35, + "doc": "PC4, USART1_TX, as Arduino D1 (SB13 on); PA2 (LPUART1_TX) with SB18 on instead" + }, + "CN10_37": { + "net": "PC5", + "connector": "CN10", + "pin": 37, + "doc": "PC5, USART1_RX, as Arduino D0 (SB19 on); PA3 (LPUART1_RX) with SB22 on instead" + }, + "U5V": { + "net": "U5V", + "doc": "The STLINK-V3E's USB 5 V (CN1, micro-B) from the host" + }, + "IDD_3V3": { + "net": "3V3", + "doc": "JP6 pin 1, the regulator's side: an ammeter's + lead" + }, + "IDD_VDD": { + "net": "VDD", + "doc": "JP6 pin 2, the STM32's side: an ammeter's - lead" + }, + "USB_VBUS": { + "net": "U5V", + "connector": "CN1", + "pin": 1, + "doc": "The STLINK-V3E's micro-USB VBUS: a computer's 5 V powers the board through JP5" + }, + "USB_DM": { + "net": "USB_DM", + "connector": "CN1", + "pin": 2, + "doc": "The STLINK-V3E's USB D- (its USB device not modelled)" + }, + "USB_DP": { + "net": "USB_DP", + "connector": "CN1", + "pin": 3, + "doc": "The STLINK-V3E's USB D+ (its USB device not modelled)" + } + }, + "leds": [ + { + "name": "user", + "component": "LD2", + "gpio": "PA5", + "active": "high", + "color": "green" + }, + { + "name": "power", + "component": "LD3", + "color": "green" + } + ], + "buttons": [ + { + "name": "user", + "component": "B1", + "gpio": "PC13", + "active": "high" + }, + { + "name": "reset", + "component": "B2", + "signal": "NRST", + "active": "low" + } + ], + "console": { + "peripheral": "LPUART1", + "tx": "PA2", + "rx": "PA3", + "baud": 115200, + "bridge": { + "part": "STM32F723IEK6 (STLINK-V3E)", + "usb": { + "vid": "0x0483", + "pid": "0x374E", + "product": "STLINK-V3" + } + } + }, + "bench": { + "thickness_mm": 1.6, + "standoff_mm": 3, + "headers": "female" + }, + "artwork": { + "svg": "artwork.svg", + "width_mm": 70.0, + "height_mm": 82.5, + "hotspots": [ + { + "port": "U5V", + "selector": "#pin-u5v" + }, + { + "component": "JP5_STLK", + "selector": "#jp5-stlk", + "input": "closed" + }, + { + "component": "JP5_VIN", + "selector": "#jp5-vin", + "input": "closed" + }, + { + "component": "JP5_E5V", + "selector": "#jp5-e5v", + "input": "closed" + }, + { + "component": "JP5_CHGR", + "selector": "#jp5-chgr", + "input": "closed" + }, + { + "component": "JP6", + "selector": "#jp6", + "input": "closed" + }, + { + "component": "JP7", + "selector": "#jp7", + "input": "closed" + }, + { + "component": "JP8_VREF", + "selector": "#jp8-vref", + "input": "closed" + }, + { + "component": "JP8_VDD", + "selector": "#jp8-vdd", + "input": "closed" + }, + { + "component": "LD4", + "selector": "#led-ld4", + "output": "luminance" + }, + { + "port": "IDD_3V3", + "selector": "#pin-idd_3v3" + }, + { + "port": "IDD_VDD", + "selector": "#pin-idd_vdd" + }, + { + "component": "B1", + "selector": "#btn-user", + "input": "pressed" + }, + { + "component": "B2", + "selector": "#btn-reset", + "input": "pressed" + }, + { + "component": "LD2", + "selector": "#led-ld2", + "output": "luminance" + }, + { + "component": "LD3", + "selector": "#led-ld3", + "output": "luminance" + }, + { + "port": "D0", + "selector": "#pin-d0" + }, + { + "port": "D1", + "selector": "#pin-d1" + }, + { + "port": "D2", + "selector": "#pin-d2" + }, + { + "port": "D3", + "selector": "#pin-d3" + }, + { + "port": "D4", + "selector": "#pin-d4" + }, + { + "port": "D5", + "selector": "#pin-d5" + }, + { + "port": "D6", + "selector": "#pin-d6" + }, + { + "port": "D7", + "selector": "#pin-d7" + }, + { + "port": "D8", + "selector": "#pin-d8" + }, + { + "port": "D9", + "selector": "#pin-d9" + }, + { + "port": "D10", + "selector": "#pin-d10" + }, + { + "port": "D11", + "selector": "#pin-d11" + }, + { + "port": "D12", + "selector": "#pin-d12" + }, + { + "port": "D13", + "selector": "#pin-d13" + }, + { + "port": "D14", + "selector": "#pin-d14" + }, + { + "port": "D15", + "selector": "#pin-d15" + }, + { + "port": "GND_D", + "selector": "#pin-gnd_d" + }, + { + "port": "AREF", + "selector": "#pin-aref" + }, + { + "port": "IOREF", + "selector": "#pin-ioref" + }, + { + "port": "RESET", + "selector": "#pin-reset" + }, + { + "port": "3V3", + "selector": "#pin-3v3" + }, + { + "port": "5V", + "selector": "#pin-5v" + }, + { + "port": "GND", + "selector": "#pin-gnd" + }, + { + "port": "GND_2", + "selector": "#pin-gnd_2" + }, + { + "port": "VIN", + "selector": "#pin-vin" + }, + { + "port": "A0", + "selector": "#pin-a0" + }, + { + "port": "A1", + "selector": "#pin-a1" + }, + { + "port": "A2", + "selector": "#pin-a2" + }, + { + "port": "A3", + "selector": "#pin-a3" + }, + { + "port": "A4", + "selector": "#pin-a4" + }, + { + "port": "A5", + "selector": "#pin-a5" + }, + { + "port": "CN7_1", + "selector": "#pin-cn7_1" + }, + { + "port": "CN7_2", + "selector": "#pin-cn7_2" + }, + { + "port": "CN7_3", + "selector": "#pin-cn7_3" + }, + { + "port": "CN7_4", + "selector": "#pin-cn7_4" + }, + { + "port": "CN7_5", + "selector": "#pin-cn7_5" + }, + { + "port": "E5V", + "selector": "#pin-e5v" + }, + { + "port": "CN7_7", + "selector": "#pin-cn7_7" + }, + { + "port": "CN7_8", + "selector": "#pin-cn7_8" + }, + { + "port": "CN7_12", + "selector": "#pin-cn7_12" + }, + { + "port": "CN7_13", + "selector": "#pin-cn7_13" + }, + { + "port": "CN7_14", + "selector": "#pin-cn7_14" + }, + { + "port": "CN7_15", + "selector": "#pin-cn7_15" + }, + { + "port": "CN7_16", + "selector": "#pin-cn7_16" + }, + { + "port": "CN7_17", + "selector": "#pin-cn7_17" + }, + { + "port": "CN7_18", + "selector": "#pin-cn7_18" + }, + { + "port": "CN7_19", + "selector": "#pin-cn7_19" + }, + { + "port": "CN7_20", + "selector": "#pin-cn7_20" + }, + { + "port": "CN7_21", + "selector": "#pin-cn7_21" + }, + { + "port": "CN7_22", + "selector": "#pin-cn7_22" + }, + { + "port": "CN7_23", + "selector": "#pin-cn7_23" + }, + { + "port": "CN7_24", + "selector": "#pin-cn7_24" + }, + { + "port": "CN7_25", + "selector": "#pin-cn7_25" + }, + { + "port": "CN7_27", + "selector": "#pin-cn7_27" + }, + { + "port": "CN7_28", + "selector": "#pin-cn7_28" + }, + { + "port": "CN7_30", + "selector": "#pin-cn7_30" + }, + { + "port": "CN7_32", + "selector": "#pin-cn7_32" + }, + { + "port": "CN7_33", + "selector": "#pin-cn7_33" + }, + { + "port": "CN7_34", + "selector": "#pin-cn7_34" + }, + { + "port": "CN7_35", + "selector": "#pin-cn7_35" + }, + { + "port": "CN7_36", + "selector": "#pin-cn7_36" + }, + { + "port": "CN7_37", + "selector": "#pin-cn7_37" + }, + { + "port": "CN7_38", + "selector": "#pin-cn7_38" + }, + { + "port": "CN10_1", + "selector": "#pin-cn10_1" + }, + { + "port": "CN10_2", + "selector": "#pin-cn10_2" + }, + { + "port": "CN10_3", + "selector": "#pin-cn10_3" + }, + { + "port": "CN10_4", + "selector": "#pin-cn10_4" + }, + { + "port": "CN10_5", + "selector": "#pin-cn10_5" + }, + { + "port": "CN10_6", + "selector": "#pin-cn10_6" + }, + { + "port": "CN10_7", + "selector": "#pin-cn10_7" + }, + { + "port": "CN10_8", + "selector": "#pin-cn10_8" + }, + { + "port": "CN10_9", + "selector": "#pin-cn10_9" + }, + { + "port": "CN10_11", + "selector": "#pin-cn10_11" + }, + { + "port": "CN10_12", + "selector": "#pin-cn10_12" + }, + { + "port": "CN10_13", + "selector": "#pin-cn10_13" + }, + { + "port": "CN10_14", + "selector": "#pin-cn10_14" + }, + { + "port": "CN10_15", + "selector": "#pin-cn10_15" + }, + { + "port": "CN10_16", + "selector": "#pin-cn10_16" + }, + { + "port": "CN10_17", + "selector": "#pin-cn10_17" + }, + { + "port": "CN10_18", + "selector": "#pin-cn10_18" + }, + { + "port": "CN10_19", + "selector": "#pin-cn10_19" + }, + { + "port": "CN10_20", + "selector": "#pin-cn10_20" + }, + { + "port": "CN10_21", + "selector": "#pin-cn10_21" + }, + { + "port": "CN10_22", + "selector": "#pin-cn10_22" + }, + { + "port": "CN10_23", + "selector": "#pin-cn10_23" + }, + { + "port": "CN10_24", + "selector": "#pin-cn10_24" + }, + { + "port": "CN10_25", + "selector": "#pin-cn10_25" + }, + { + "port": "CN10_26", + "selector": "#pin-cn10_26" + }, + { + "port": "CN10_27", + "selector": "#pin-cn10_27" + }, + { + "port": "CN10_28", + "selector": "#pin-cn10_28" + }, + { + "port": "CN10_29", + "selector": "#pin-cn10_29" + }, + { + "port": "CN10_30", + "selector": "#pin-cn10_30" + }, + { + "port": "CN10_31", + "selector": "#pin-cn10_31" + }, + { + "port": "CN10_32", + "selector": "#pin-cn10_32" + }, + { + "port": "CN10_33", + "selector": "#pin-cn10_33" + }, + { + "port": "CN10_34", + "selector": "#pin-cn10_34" + }, + { + "port": "CN10_35", + "selector": "#pin-cn10_35" + }, + { + "port": "CN10_37", + "selector": "#pin-cn10_37" + } + ] + }, + "toolchains": { + "embcc": { + "target": "thumbv7em-none-eabihf", + "linker_script": "stm32g474re.ld" + }, + "gcc-arm": { + "cpu": "cortex-m4", + "flags": [ + "-mthumb", + "-mcpu=cortex-m4", + "-mfpu=fpv4-sp-d16", + "-mfloat-abi=hard" + ], + "linker_script": "stm32g474re.ld" + }, + "clang": { + "target": "thumbv7em-none-eabihf", + "flags": [ + "-mcpu=cortex-m4", + "-mfpu=fpv4-sp-d16", + "-mfloat-abi=hard" + ], + "linker_script": "stm32g474re.ld" + } + }, + "fidelity": { + "functional": { + "claims": "Nets, ports, LD2 to LD4, B1, B2 and the jumpers as parts, as MB1367 D-01's schematic draws them; the STM32G474RE (U13) runs its firmware (see its description), its HSE the 24 MHz crystal X3 (HSEBYP clear, as on the real board) and its LSE the X2 crystal; its option bytes as ST ships the board (nSWBOOT0 0, nBOOT0 1: it boots its flash whatever PB8 is). The Arduino connectors carry UM2505's assignment (D0/D1 on PC5/PC4, USART1) and the morpho headers CN7 and CN10 every pin they bring out with the factory's solder bridges. The STLINK-V3E's virtual COM port is wired to PA2/PA3: the session's console, and a serial port on the host, is whichever UART the firmware muxes onto them (LPUART1 on AF12, as CubeG4's BSP does, or USART2 on AF7).", + "omissions": [ + "the STLINK-V3E itself (sheet 7's U5, STM32F723IEK6): its USB enumeration (0483:374E), the mass-storage drag-and-drop programming, SWD and its NRST drive, LD1 (COM), its own supply (U7, D1 to D3); the session programs and debugs the board (ADR-031)", + "the VCP's bytes reach the UART on PA2/PA3 directly, not as frames on PA3, whatever line settings the host's terminal has", + "the 41 solder bridges are fixed in their factory state as UM2505's table 12 and the schematic give them (PA2/PA3 on the VCP, PC4/PC5 on D1/D0 and CN10 pins 35 and 37, PB8 on D15 and CN7 pin 7, B1 on PC13, the crystals on PF0/PF1 and PC14/PC15 and not on the morpho headers)", + "a single JP5 or JP8 shunt sits on one position only; the switches here can all be closed", + "CubeG4's examples that take B1's falling edge (GPIO_EXTI and LL examples such as EXTI_ToggleLedOnIT_Init) act when B1 is released, as they would on the board: B1 is active high, their readmes say a press", + "in the functional policy the board's resistors are wires, so R29 and R28 join PA5 to GND and R27 and R26 join PC13 to GND: LD2 and B1 work in the electrical policy only (a resistor that passes a weak level in the functional policy is not modelled yet)" + ], + "validation": [ + "tests/*.json" + ] + }, + "timed": { + "claims": "As functional.", + "omissions": [ + "as functional" + ], + "validation": [ + "tests/*.json" + ] + }, + "electrical": { + "claims": "The power paths of MB1367 D-01's sheets 4, 6 and 7: CN1's VBUS (5V_USB_CHGR) through U4 (STMPS2151STR, its EN on T_PWR_EN with R8's pull-down, driven high as after the enumeration; LD4 with R1 on its FAULT) to 5V_USB_STLK and JP5 pins 1-2 to +5V; VIN (7 to 12 V) through U11 (LD1117S50, C41 and C38) and JP5 pins 3-4; E5V through pins 5-6; 5V_USB_CHGR directly through pins 7-8; U12 (LD39050PU33R, C36 to C40) makes +3.3V and JP6 (IDD) carries it to VDD (C55, C45, C54, C42, C52) and VBAT (C53), VDDA through the ferrite bead L1 (C43, C44); VREF from U14 (TL1431CL5T) and Q2 (BSR14) at 2.5 x (1 + R33 / R34) = 3.26 V with R35, C51, C50 and C46, to VREF+ through JP8 (pins 1-2, the factory's), C47 and the ferrite bead L2 (C48, C49). LD3 shows +5V through R7; LD2 is switched by Q1 from 3V3 through R25 (510 ohm), its base driven by PA5 through R29 (47 kOhm) against R28 (100 kOhm), so LD2's current does not come from VDD; B1 joins its node to VDD, R26 (100 kOhm) holds it low, R27 (330 ohm) takes it to PC13 with C35 (100 nF) there; C34 (100 nF) holds NRST low at power-on against the STM32's pull-up; JP7 (not fitted) and R31 pull BOOT0/PB8 down; X3 (NX2016SA 24 MHz) and X2 (NX3215SA 32.768 kHz) are crystals' equivalent circuits.", + "omissions": [ + "Q1 and Q2 (BSR14) are the catalog's P2N2222A, the same die in another package; L1 and L2 the catalog's ferrite bead (600 ohm at 100 MHz as the schematic names them, its default DC resistance); X2's motional values the catalog's 32.768 kHz crystal's; the crystals' load capacitors (C56, C57, C58, C59) are not parts", + "the capacitors are ideal, without ESR or ESL, except C11 and C41 on the board's inputs (U5V, VIN), given a ceramic's 10 mOhm: the schematic gives no dielectric or series resistance", + "T_PWR_EN: the STLINK-V3E's output is a stand-in driving U4's EN high from 5V_USB_CHGR; U4's current negotiation with the host (100 mA before the enumeration, 500 mA after it) is not modelled", + "the ESD protection (U6, U8, U9, U10) and the STLINK-V3E's own parts on sheet 7", + "the STM32's supply current: VDD carries only what the pins drive" + ], + "validation": [ + "tests/*.json" + ] + } + }, + "provenance": { + "author": "EmbSIM", + "license": "Apache-2.0", + "sources": [ + { + "title": "UM2505 STM32G4 Nucleo-64 boards (MB1367) user manual: JP5's positions, JP6, the regulators U11 and U12, LD1-LD3, as its search excerpts give them", + "url": "https://www.st.com/resource/en/user_manual/um2505-stm32g4-nucleo64-boards-mb1367-stmicroelectronics.pdf" + }, + { + "title": "MB1367 D-01 electrical schematics (NUCLEO64 STM32G4, variant G474RE, 26 Sep 2025): every part, value and designator modelled here", + "url": "https://www.st.com/resource/en/schematic_pack/mb1367-g474re-d01-schematic.pdf" + }, + { + "title": "Zephyr's nucleo_g474re board files (Apache-2.0): the LEDs, B1, the console, the Arduino and morpho connectors' pin assignment" + }, + { + "title": "ST community, 'NUCLEO-G474RE: what is the intended use of JP7' (2019): the board ships with nSWBOOT0 0, PB8 an ordinary I/O; JP7 pulls BOOT0/PB8 down" + }, + { + "title": "STM32CubeG4's NUCLEO-G474RE projects (BSD-3-Clause): HSE_VALUE 24 MHz, LPUART1 on PA2/PA3 (AF12) as the VCP, the BSP's B1 (rising edge, pull-down)" + } + ], + "notes": "Artwork is an original SVG drawn for EmbSIM to the Nucleo-64's 70 x 82.5 mm outline; no ST artwork or logo is used." + }, + "tests": [ + "tests/*.json" + ], + "i18n": { + "fr": { + "source": "873018dc7efe", + "description": "La NUCLEO-G474RE de ST (MB1367) : un STM32G474RET6 avec le quartz HSE X3 de 24 MHz et le quartz LSE X2 de 32,768 kHz, la LED utilisateur verte LD2 sur PA5, le bouton bleu USER, actif au niveau haut, sur PC13, le bouton noir RESET, la LED d'alimentation verte LD3, JP5 choisissant l'USB du STLINK-V3E, VIN, E5V ou un chargeur USB, JP6 (IDD) pour mesurer le courant du MCU, les connecteurs Arduino Uno V3 et les deux connecteurs morpho ST. Le port COM virtuel du STLINK-V3E est la console sรฉrie de la session sur le LPUART1 (PA2/PA3), et un port sรฉrie sur l'hรดte (embsim serve --serial).", + "fidelity": { + "functional": { + "claims": "Rรฉseaux, ports, LD2 ร  LD4, B1, B2 et les cavaliers comme composants, tels que les dessine le schรฉma de la MB1367 D-01 ; le STM32G474RE (U13) exรฉcute son micrologiciel (voir sa description), son HSE le quartz X3 de 24 MHz (HSEBYP ร  0, comme sur la vraie carte) et son LSE le quartz X2 ; ses octets d'option tels que ST livre la carte (nSWBOOT0 ร  0, nBOOT0 ร  1 : il dรฉmarre sur sa flash quel que soit PB8). Les connecteurs Arduino suivent l'affectation de l'UM2505 (D0/D1 sur PC5/PC4, l'USART1) et les connecteurs morpho CN7 et CN10 chaque broche qu'ils portent avec les ponts de soudure d'usine. Le port COM virtuel du STLINK-V3E est cรขblรฉ ร  PA2/PA3 : la console de la session, et un port sรฉrie sur l'hรดte, est l'UART que le micrologiciel y multiplexe (le LPUART1 en AF12, comme le fait la BSP de CubeG4, ou l'USART2 en AF7).", + "omissions": [ + "le STLINK-V3E lui-mรชme (U5 de la feuille 7, un STM32F723IEK6) : son รฉnumรฉration USB (0483:374E), la programmation par glisser-dรฉposer sur stockage de masse, le SWD et sa commande de NRST, LD1 (COM), sa propre alimentation (U7, D1 ร  D3) ; la session programme et dรฉbogue la carte (ADR-031)", + "les octets du VCP arrivent directement ร  l'UART de PA2/PA3, pas comme des trames sur PA3, quels que soient les rรฉglages de ligne du terminal de l'hรดte", + "les 41 ponts de soudure sont figรฉs dans leur รฉtat d'usine tel que le donnent la table 12 de l'UM2505 et le schรฉma (PA2/PA3 sur le VCP, PC4/PC5 sur D1/D0 et les broches 35 et 37 de CN10, PB8 sur D15 et la broche 7 de CN7, B1 sur PC13, les quartz sur PF0/PF1 et PC14/PC15 et pas sur les connecteurs morpho)", + "un seul cavalier JP5 ou JP8 ne tient que sur une position ; les interrupteurs ici peuvent tous รชtre fermรฉs", + "les exemples de CubeG4 qui prennent le front descendant de B1 (GPIO_EXTI et des exemples LL comme EXTI_ToggleLedOnIT_Init) agissent au relรขchement de B1, comme ils le feraient sur la carte : B1 est actif au niveau haut, leur readme parle d'un appui", + "dans la politique fonctionnelle les rรฉsistances de la carte sont des fils, si bien que R29 et R28 relient PA5 ร  GND et R27 et R26 PC13 ร  GND : LD2 et B1 ne fonctionnent que dans la politique รฉlectrique (une rรฉsistance qui transmet un niveau faible dans la politique fonctionnelle n'est pas encore modรฉlisรฉe)" + ] + }, + "timed": { + "claims": "Comme le niveau fonctionnel.", + "omissions": [ + "comme le niveau fonctionnel" + ] + }, + "electrical": { + "claims": "Les chemins d'alimentation des feuilles 4, 6 et 7 de la MB1367 D-01 : le VBUS de CN1 (5V_USB_CHGR) par U4 (STMPS2151STR, son EN sur T_PWR_EN avec le tirage vers le bas de R8, mis au niveau haut comme aprรจs l'รฉnumรฉration ; LD4 avec R1 sur sa sortie FAULT) vers 5V_USB_STLK et les broches 1-2 de JP5 vers +5V ; VIN (7 ร  12 V) par U11 (LD1117S50, C41 et C38) et les broches 3-4 de JP5 ; E5V par les broches 5-6 ; 5V_USB_CHGR directement par les broches 7-8 ; U12 (LD39050PU33R, C36 ร  C40) fait le +3,3V et JP6 (IDD) le porte vers VDD (C55, C45, C54, C42, C52) et VBAT (C53), vers VDDA par la ferrite L1 (C43, C44) ; VREF fourni par U14 (TL1431CL5T) et Q2 (BSR14) ร  2,5 x (1 + R33 / R34) = 3,26 V avec R35, C51, C50 et C46, vers VREF+ par JP8 (broches 1-2, la position d'usine), C47 et la ferrite L2 (C48, C49). LD3 indique le +5V par R7 ; LD2 est commutรฉe par Q1 depuis le 3V3 ร  travers R25 (510 ohms), sa base pilotรฉe par PA5 ร  travers R29 (47 kohms) face ร  R28 (100 kohms), si bien que le courant de LD2 ne vient pas de VDD ; B1 relie son nล“ud ร  VDD, R26 (100 kohms) le tient bas, R27 (330 ohms) le porte vers PC13 oรน se trouve C35 (100 nF) ; C34 (100 nF) tient NRST bas ร  la mise sous tension face au tirage interne du STM32 ; JP7 (non montรฉ) et R31 tirent BOOT0/PB8 vers le bas ; X3 (NX2016SA 24 MHz) et X2 (NX3215SA 32,768 kHz) sont les circuits รฉquivalents de quartz.", + "omissions": [ + "Q1 et Q2 (BSR14) sont le P2N2222A du catalogue, la mรชme puce dans un autre boรฎtier ; L1 et L2 la ferrite du catalogue (600 ohms ร  100 MHz comme le schรฉma les nomme, sa rรฉsistance continue par dรฉfaut) ; les valeurs motionnelles de X2 celles du quartz de 32,768 kHz du catalogue ; les condensateurs de charge des quartz (C56, C57, C58, C59) ne sont pas des composants", + "les condensateurs sont idรฉaux, sans ESR ni ESL, sauf C11 et C41 sur les entrรฉes de la carte (U5V, VIN), dotรฉs des 10 mohms d'un cรฉramique : le schรฉma ne donne ni diรฉlectrique ni rรฉsistance sรฉrie", + "T_PWR_EN : la sortie du STLINK-V3E est remplacรฉe par une commande mettant l'EN d'U4 au niveau haut depuis 5V_USB_CHGR ; la nรฉgociation de courant d'U4 avec l'hรดte (100 mA avant l'รฉnumรฉration, 500 mA aprรจs) n'est pas modรฉlisรฉe", + "la protection ESD (U6, U8, U9, U10) et les composants propres au STLINK-V3E de la feuille 7", + "le courant d'alimentation du STM32 : VDD ne porte que ce que pilotent les broches" + ] + } + } + } + } +} diff --git a/catalog/boards/nucleo_g474re/stm32g474re.ld b/catalog/boards/nucleo_g474re/stm32g474re.ld new file mode 100644 index 000000000..e79fc0ffe --- /dev/null +++ b/catalog/boards/nucleo_g474re/stm32g474re.ld @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* STM32G474RE: 512 KiB of flash at 0x08000000, 128 KiB of SRAM at 0x20000000 (SRAM1 80 KiB, SRAM2 16 KiB, then the CCM SRAM's 32 KiB alias) */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} +ENTRY(Reset_Handler) +_estack = ORIGIN(RAM) + LENGTH(RAM); +SECTIONS +{ + .isr_vector : { KEEP(*(.isr_vector)) } > FLASH + .text : { *(.text*) *(.rodata*) . = ALIGN(4); } > FLASH + .ARM.exidx : { *(.ARM.exidx*) } > FLASH + _sidata = LOADADDR(.data); + .data : { _sdata = .; *(.data*) . = ALIGN(4); _edata = .; } > RAM AT > FLASH + .bss (NOLOAD) : { _sbss = .; *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; } > RAM +} diff --git a/catalog/boards/nucleo_g474re/tests/e5v.json b/catalog/boards/nucleo_g474re/tests/e5v.json new file mode 100644 index 000000000..7463a6379 --- /dev/null +++ b/catalog/boards/nucleo_g474re/tests/e5v.json @@ -0,0 +1,77 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "e5v", + "description": "An external 5 V supply on E5V (CN7 pin 6) with JP5 on E5V (pins 5-6): +5V, LD3 and +3.3V without USB.", + "policy": "electrical", + "until": "20ms", + "circuit": { + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re" + } + ], + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "G", + "component": "emblink/gnd" + } + ], + "nets": { + "E5V": [ + "VS.+", + "B1.E5V" + ], + "GND": [ + "VS.-", + "G.GND", + "B1.GND" + ], + "R5": [ + "B1.5V" + ], + "VDD": [ + "B1.CN7_5" + ] + } + }, + "inputs": [ + { + "at": "0ms", + "target": "B1.JP5_STLK", + "input": "closed", + "value": false + }, + { + "at": "0ms", + "target": "B1.JP5_E5V", + "input": "closed", + "value": true + } + ], + "expect": { + "net:R5": { + "at": "10ms", + "min_v": 4.95, + "max_v": 5.0 + }, + "net:VDD": { + "at": "10ms", + "min_v": 3.25, + "max_v": 3.35 + }, + "output:B1.LD3.luminance": { + "at": "10ms", + "min": 0.05 + } + } +} diff --git a/catalog/boards/nucleo_g474re/tests/idd-ammeter.json b/catalog/boards/nucleo_g474re/tests/idd-ammeter.json new file mode 100644 index 000000000..4e83685a2 --- /dev/null +++ b/catalog/boards/nucleo_g474re/tests/idd-ammeter.json @@ -0,0 +1,82 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "idd-ammeter", + "description": "JP6 removed and an ammeter (1 ohm shunt) across its pins: VDD is powered through the meter.", + "policy": "electrical", + "until": "20ms", + "circuit": { + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re" + } + ], + "components": [ + { + "id": "HOST", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "CABLE", + "component": "emblink/resistor", + "params": { + "resistance": 0.25 + } + }, + { + "id": "G", + "component": "emblink/gnd" + }, + { + "id": "AM", + "component": "emblink/resistor", + "params": { + "resistance": 1.0 + } + } + ], + "nets": { + "HOSTV": [ + "HOST.+", + "CABLE.1" + ], + "VBUS": [ + "CABLE.2", + "B1.U5V" + ], + "GND": [ + "HOST.-", + "G.GND", + "B1.GND" + ], + "IA": [ + "B1.IDD_3V3", + "AM.1" + ], + "IB": [ + "B1.IDD_VDD", + "AM.2" + ] + } + }, + "inputs": [ + { + "at": "0ms", + "target": "B1.JP6", + "input": "closed", + "value": false + } + ], + "expect": { + "net:IB": { + "at": "10ms", + "min_v": 3.2, + "max_v": 3.35 + } + } +} diff --git a/catalog/boards/nucleo_g474re/tests/ld2-q1.json b/catalog/boards/nucleo_g474re/tests/ld2-q1.json new file mode 100644 index 000000000..a0952bf74 --- /dev/null +++ b/catalog/boards/nucleo_g474re/tests/ld2-q1.json @@ -0,0 +1,78 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "ld2-q1", + "description": "LD2 is switched by Q1: 3.3 V on D13 (PA5) from 5 ms lights LD2 from 3V3 through R25, the base driven through R29 against R28 (usb-powered checks LD2 dark).", + "policy": "electrical", + "until": "20ms", + "circuit": { + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re" + } + ], + "components": [ + { + "id": "HOST", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "CABLE", + "component": "emblink/resistor", + "params": { + "resistance": 0.25 + } + }, + { + "id": "G", + "component": "emblink/gnd" + }, + { + "id": "PA5", + "component": "emblink/vsource", + "params": { + "kind": "pulse", + "v1": 0, + "v2": 3.3, + "td": "5m", + "tr": "1u", + "tf": "1u", + "pw": "10m", + "per": "40m" + } + } + ], + "nets": { + "HOSTV": [ + "HOST.+", + "CABLE.1" + ], + "VBUS": [ + "CABLE.2", + "B1.U5V" + ], + "GND": [ + "HOST.-", + "G.GND", + "B1.GND", + "PA5.-" + ], + "D13": [ + "PA5.+", + "B1.D13" + ] + } + }, + "inputs": [], + "expect": { + "output:B1.LD2.luminance": { + "at": "10ms", + "min": 0.05 + } + } +} diff --git a/catalog/boards/nucleo_g474re/tests/usb-powered.json b/catalog/boards/nucleo_g474re/tests/usb-powered.json new file mode 100644 index 000000000..3ac9ea0e4 --- /dev/null +++ b/catalog/boards/nucleo_g474re/tests/usb-powered.json @@ -0,0 +1,110 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "usb-powered", + "description": "Plugged into a computer's USB port through a 0.25 ohm cable, JP5 on STLK (the factory position): +5V from the STLINK-V3E's USB, LD3 lights, U12 makes +3.3V and JP6 carries it to VDD and VBAT; U14 and Q2 make VREF and JP8 (pins 1-2) carries it to VREF+ (AREF), 2.5 x (1 + 10k / 33k) = 3.26 V once it has settled (R33 and R34 alone discharge C46 after the start-up's overshoot); PC13 (B1 released) is held low by R26, LD2 is dark with PA5 not driven (R28 holds Q1's base low) and PB8 (D15) floats with JP7 not fitted.", + "policy": "electrical", + "until": "31ms", + "circuit": { + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re" + } + ], + "components": [ + { + "id": "HOST", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "CABLE", + "component": "emblink/resistor", + "params": { + "resistance": 0.25 + } + }, + { + "id": "G", + "component": "emblink/gnd" + } + ], + "nets": { + "HOSTV": [ + "HOST.+", + "CABLE.1" + ], + "VBUS": [ + "CABLE.2", + "B1.U5V" + ], + "GND": [ + "HOST.-", + "G.GND", + "B1.GND" + ], + "R5": [ + "B1.5V" + ], + "R33": [ + "B1.3V3" + ], + "VDD": [ + "B1.CN7_5" + ], + "VBAT": [ + "B1.CN7_33" + ], + "BTN": [ + "B1.CN7_23" + ], + "VREFP": [ + "B1.AREF" + ] + } + }, + "inputs": [], + "expect": { + "net:R5": { + "at": "10ms", + "min_v": 4.85, + "max_v": 5.0 + }, + "net:R33": { + "at": "10ms", + "min_v": 3.25, + "max_v": 3.35 + }, + "net:VDD": { + "at": "10ms", + "min_v": 3.25, + "max_v": 3.35 + }, + "net:VBAT": { + "at": "10ms", + "min_v": 3.25, + "max_v": 3.35 + }, + "output:B1.LD3.luminance": { + "at": "10ms", + "min": 0.05 + }, + "net:BTN": { + "at": "10ms", + "max_v": 0.05 + }, + "net:VREFP": { + "at": "30ms", + "min_v": 3.24, + "max_v": 3.28 + }, + "output:B1.LD2.luminance": { + "at": "10ms", + "max": 0.001 + } + } +} diff --git a/catalog/boards/nucleo_g474re/tests/user-button.json b/catalog/boards/nucleo_g474re/tests/user-button.json new file mode 100644 index 000000000..9aed87ad6 --- /dev/null +++ b/catalog/boards/nucleo_g474re/tests/user-button.json @@ -0,0 +1,70 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "user-button", + "description": "B1 (USER) joins its node to VDD while pressed; with R27 (330 ohm) to PC13 and nothing loading it, PC13 reads VDD (usb-powered checks the released level, R26 holding it low).", + "policy": "electrical", + "until": "20ms", + "circuit": { + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re" + } + ], + "components": [ + { + "id": "HOST", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "CABLE", + "component": "emblink/resistor", + "params": { + "resistance": 0.25 + } + }, + { + "id": "G", + "component": "emblink/gnd" + } + ], + "nets": { + "HOSTV": [ + "HOST.+", + "CABLE.1" + ], + "VBUS": [ + "CABLE.2", + "B1.U5V" + ], + "GND": [ + "HOST.-", + "G.GND", + "B1.GND" + ], + "BTN": [ + "B1.CN7_23" + ] + } + }, + "inputs": [ + { + "at": "10ms", + "target": "B1.B1", + "input": "pressed", + "value": true + } + ], + "expect": { + "net:BTN": { + "at": "15ms", + "min_v": 3.25, + "max_v": 3.35 + } + } +} diff --git a/catalog/boards/nucleo_g474re/tests/vin-jp5.json b/catalog/boards/nucleo_g474re/tests/vin-jp5.json new file mode 100644 index 000000000..d6d9b03e6 --- /dev/null +++ b/catalog/boards/nucleo_g474re/tests/vin-jp5.json @@ -0,0 +1,86 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "vin-jp5", + "description": "9 V on VIN, JP5 moved to VIN (pins 3-4) and a 100 mA load on +5V: U11 (LD1117S50) supplies +5V and U12 still makes 3.3 V.", + "policy": "electrical", + "until": "20ms", + "circuit": { + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re" + } + ], + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 9.0 + } + }, + { + "id": "G", + "component": "emblink/gnd" + }, + { + "id": "RL", + "component": "emblink/resistor", + "params": { + "resistance": 50.0 + } + } + ], + "nets": { + "VIN": [ + "VS.+", + "B1.VIN" + ], + "GND": [ + "VS.-", + "G.GND", + "B1.GND", + "RL.2" + ], + "R5": [ + "B1.5V", + "RL.1" + ], + "VDD": [ + "B1.CN7_5" + ] + } + }, + "inputs": [ + { + "at": "0ms", + "target": "B1.JP5_STLK", + "input": "closed", + "value": false + }, + { + "at": "0ms", + "target": "B1.JP5_VIN", + "input": "closed", + "value": true + } + ], + "expect": { + "net:R5": { + "at": "15ms", + "min_v": 4.85, + "max_v": 5.1 + }, + "net:VDD": { + "at": "15ms", + "min_v": 3.25, + "max_v": 3.35 + }, + "output:B1.LD3.luminance": { + "at": "15ms", + "min": 0.05 + } + } +} diff --git a/catalog/boards/nucleo_g474re/tests/vin-needs-jp5.json b/catalog/boards/nucleo_g474re/tests/vin-needs-jp5.json new file mode 100644 index 000000000..b0ce9ebe8 --- /dev/null +++ b/catalog/boards/nucleo_g474re/tests/vin-needs-jp5.json @@ -0,0 +1,62 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "vin-needs-jp5", + "description": "9 V on VIN with JP5 still on STLK: U11 makes its 5 V, but nothing joins it to +5V, so the board stays dark (UM2505: JP5 must be moved to VIN).", + "policy": "electrical", + "until": "20ms", + "circuit": { + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re" + } + ], + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 9.0 + } + }, + { + "id": "G", + "component": "emblink/gnd" + } + ], + "nets": { + "VIN": [ + "VS.+", + "B1.VIN" + ], + "GND": [ + "VS.-", + "G.GND", + "B1.GND" + ], + "R5": [ + "B1.5V" + ], + "VDD": [ + "B1.CN7_5" + ] + } + }, + "inputs": [], + "expect": { + "net:R5": { + "at": "10ms", + "max_v": 0.3 + }, + "net:VDD": { + "at": "10ms", + "max_v": 0.3 + }, + "output:B1.LD3.luminance": { + "at": "10ms", + "max": 0.001 + } + } +} diff --git a/catalog/components/bsr14/component.json b/catalog/components/bsr14/component.json new file mode 100644 index 000000000..34b903270 --- /dev/null +++ b/catalog/components/bsr14/component.json @@ -0,0 +1,192 @@ +{ + "schema_version": 1, + "kind": "component", + "id": "emblink/bsr14", + "version": "1.0.0", + "name": "BSR14 NPN switching transistor", + "category": "transistors", + "subcategory": "bipolar_npn", + "description": "A BSR14 (marked U8), the 2N2222A's die (Fairchild's process 19) in SOT-23: a 40 V, 800 mA NPN for medium-power switching and amplification. The NUCLEO-G474RE's (MB1367) Q1, LD2's low-side switch, and Q2, the emitter follower of its VREF+ supply.", + "keywords": [ + "bjt", + "npn", + "transistor", + "bsr14", + "2n2222a", + "process 19", + "sot-23", + "nucleo" + ], + "pins": [ + { + "name": "B", + "number": 1, + "model": { + "kind": "analog" + }, + "doc": "Base (SOT-23 pin 1)" + }, + { + "name": "E", + "number": 2, + "model": { + "kind": "analog" + }, + "doc": "Emitter (pin 2)" + }, + { + "name": "C", + "number": 3, + "model": { + "kind": "analog" + }, + "doc": "Collector (pin 3)" + } + ], + "params": {}, + "model": { + "composite": { + "components": [ + { + "id": "Q", + "component": "emblink/bjt_npn", + "params": { + "part": "generic", + "is": "14.34f", + "bf": 255.9, + "br": 6.092, + "vaf": 74.03, + "rb": 10, + "rc": 1, + "cje": "22.01p", + "vje": 0.75, + "mje": 0.377, + "cjc": "7.306p", + "vjc": 0.75, + "mjc": 0.3416, + "fc": 0.5, + "tf": "411.1p", + "tr": "46.91n", + "bvcbo": 75, + "bvebo": 6 + } + } + ], + "nets": {}, + "ports": { + "B": "Q.B", + "E": "Q.E", + "C": "Q.C" + } + } + }, + "functional": { + "composite": { + "components": [], + "nets": {}, + "ports": {} + } + }, + "symbol": { + "svg": "symbol.svg", + "width": 60, + "height": 80, + "pins": { + "B": { + "x": 0, + "y": 40, + "side": "left" + }, + "C": { + "x": 40, + "y": 0, + "side": "top" + }, + "E": { + "x": 40, + "y": 80, + "side": "bottom" + } + } + }, + "fidelity": { + "functional": { + "claims": "Pins only: the functional policy has no base currents.", + "omissions": [ + "switching" + ], + "validation": [ + "tests/*.json" + ] + }, + "timed": { + "claims": "As electrical.", + "omissions": [] + }, + "electrical": { + "claims": "The datasheet's SPICE model (IS 14.34 fA, BF 255.9, BR 6.092, VAF 74.03 V, RB 10 ohm, RC 1 ohm, CJE 22.01 pF, CJC 7.306 pF with their grading, TF 411.1 ps, TR 46.91 ns) in the catalog's Ebers-Moll transistor with the Early effect and charge storage, the collector-base and emitter-base breakdowns at the ratings (75 V, 6 V); fixtures on the datasheet's VCE(sat) and VBE(sat) at 150 mA and 500 mA, and on MB1367's LD2 circuit.", + "omissions": [ + "the model's ISE, NE and IKF: the gain does not fall at low or high current (the datasheet's minimum hFE is 35 at 0.1 mA and 40 at 500 mA; the model's stays near 256)", + "temperature (XTI, EG, XTB): VBE's drift and the gain's rise", + "the SOT-23's pin numbers are the package's usual 1 B, 2 E, 3 C: the datasheet's outline draws the pins without numbers", + "the thermal limits (350 mW, 357 C/W on FR-4), the safe operating area and damage past the ratings", + "device-to-device spread within the datasheet's limits" + ], + "range": { + "voltage_v": [ + -6, + 40 + ], + "current_a": [ + -0.8, + 0.8 + ] + }, + "validation": [ + "tests/*.json" + ] + } + }, + "provenance": { + "author": "EmbSIM", + "license": "Apache-2.0", + "sources": [ + { + "title": "onsemi (Fairchild) BSR14 NPN General Purpose Amplifier datasheet, Rev. B0, September 2012: ratings, electrical characteristics and the SPICE model", + "url": "https://www.onsemi.com/download/data-sheet/pdf/bsr14-d.pdf", + "date": "2026-11-13", + "hash": "sha256:74685954721282967bb81c75fe87ad8805cb0201055cf0024fa1687029f1db32" + } + ] + }, + "tests": [ + "tests/*.json" + ], + "i18n": { + "fr": { + "source": "984e1fa77266", + "description": "Un BSR14 (marquรฉ U8), la puce du 2N2222A (le procรฉdรฉ 19 de Fairchild) en SOT-23 : un NPN de 40 V et 800 mA pour la commutation et l'amplification de moyenne puissance. Le Q1 de la NUCLEO-G474RE (MB1367), l'interrupteur cรดtรฉ bas de LD2, et son Q2, le collecteur commun de son alimentation VREF+.", + "fidelity": { + "functional": { + "claims": "Les broches seulement : la politique fonctionnelle n'a pas de courants de base.", + "omissions": [ + "la commutation" + ] + }, + "timed": { + "claims": "Comme le niveau รฉlectrique." + }, + "electrical": { + "claims": "Le modรจle SPICE de la fiche technique (IS 14,34 fA, BF 255,9, BR 6,092, VAF 74,03 V, RB 10 ohms, RC 1 ohm, CJE 22,01 pF, CJC 7,306 pF avec leur gradation, TF 411,1 ps, TR 46,91 ns) dans le transistor d'Ebers-Moll du catalogue avec l'effet Early et le stockage de charge, les claquages collecteur-base et รฉmetteur-base aux valeurs maximales (75 V, 6 V) ; des fixtures sur le VCE(sat) et le VBE(sat) de la fiche technique ร  150 mA et 500 mA, et sur le circuit de LD2 de la MB1367.", + "omissions": [ + "l'ISE, le NE et l'IKF du modรจle : le gain ne baisse pas ร  faible ou fort courant (le hFE minimal de la fiche technique est de 35 ร  0,1 mA et de 40 ร  500 mA ; celui du modรจle reste proche de 256)", + "la tempรฉrature (XTI, EG, XTB) : la dรฉrive de VBE et la hausse du gain", + "les numรฉros de broche du SOT-23 sont les habituels du boรฎtier, 1 B, 2 E, 3 C : le dessin de la fiche technique montre les broches sans numรฉros", + "les limites thermiques (350 mW, 357 C/W sur FR-4), l'aire de sรฉcuritรฉ et les dรฉgรขts au-delร  des valeurs maximales", + "la dispersion d'un composant ร  l'autre dans les limites de la fiche technique" + ] + } + } + } + } +} diff --git a/catalog/components/bsr14/symbol.svg b/catalog/components/bsr14/symbol.svg new file mode 100644 index 000000000..2feae29d4 --- /dev/null +++ b/catalog/components/bsr14/symbol.svg @@ -0,0 +1,2 @@ + + diff --git a/catalog/components/bsr14/tests/ld2.json b/catalog/components/bsr14/tests/ld2.json new file mode 100644 index 000000000..4bb83dea0 --- /dev/null +++ b/catalog/components/bsr14/tests/ld2.json @@ -0,0 +1,93 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "ld2", + "description": "MB1367's LD2 driver: 3.3 V on the base through R29 (47 kOhm) against R28 (100 kOhm), LD2 (green) and R25 (510 ohm) from 3.3 V: the transistor saturates and LD2 lights.", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/bsr14" + }, + { + "id": "V3", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 3.3 + } + }, + { + "id": "R29", + "component": "emblink/resistor", + "params": { + "resistance": 47000 + } + }, + { + "id": "R28", + "component": "emblink/resistor", + "params": { + "resistance": 100000 + } + }, + { + "id": "R25", + "component": "emblink/resistor", + "params": { + "resistance": 510 + } + }, + { + "id": "LD2", + "component": "emblink/led", + "params": { + "color": "green" + } + } + ], + "nets": { + "V3N": [ + "V3.+", + "R29.1", + "R25.1" + ], + "B": [ + "R29.2", + "R28.1", + "DUT.B" + ], + "A": [ + "R25.2", + "LD2.A" + ], + "C": [ + "LD2.K", + "DUT.C" + ], + "GND": [ + "V3.-", + "R28.2", + "DUT.E", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:C": { + "at": "1ms", + "max_v": 0.1 + }, + "output:LD2.luminance": { + "at": "1ms", + "min": 0.05 + } + } +} diff --git a/catalog/components/bsr14/tests/off.json b/catalog/components/bsr14/tests/off.json new file mode 100644 index 000000000..516952ca4 --- /dev/null +++ b/catalog/components/bsr14/tests/off.json @@ -0,0 +1,69 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "off", + "description": "No base drive (the base held at ground through 100 kOhm): the transistor is off and the collector sits at 5 V through 330 ohm.", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/bsr14" + }, + { + "id": "VC", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "RC", + "component": "emblink/resistor", + "params": { + "resistance": 330 + } + }, + { + "id": "RBE", + "component": "emblink/resistor", + "params": { + "resistance": 100000 + } + } + ], + "nets": { + "VCN": [ + "VC.+", + "RC.1" + ], + "C": [ + "RC.2", + "DUT.C" + ], + "GND": [ + "VC.-", + "DUT.E", + "RBE.2", + "G0.GND" + ], + "B": [ + "RBE.1", + "DUT.B" + ] + } + }, + "inputs": [], + "expect": { + "net:C": { + "at": "1ms", + "min_v": 4.99 + } + } +} diff --git a/catalog/components/bsr14/tests/sat-150ma.json b/catalog/components/bsr14/tests/sat-150ma.json new file mode 100644 index 000000000..08948ab76 --- /dev/null +++ b/catalog/components/bsr14/tests/sat-150ma.json @@ -0,0 +1,74 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "sat-150ma", + "description": "The datasheet's saturation point: about 150 mA from 5 V through 30 ohm, 15 mA into the base through 270 ohm: VCE(sat) at most 0.3 V and VBE(sat) 0.6 to 1.2 V.", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/bsr14" + }, + { + "id": "VC", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "RC", + "component": "emblink/resistor", + "params": { + "resistance": 30 + } + }, + { + "id": "RB", + "component": "emblink/resistor", + "params": { + "resistance": 270 + } + } + ], + "nets": { + "VCN": [ + "VC.+", + "RC.1", + "RB.1" + ], + "C": [ + "RC.2", + "DUT.C" + ], + "B": [ + "RB.2", + "DUT.B" + ], + "GND": [ + "VC.-", + "DUT.E", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:C": { + "at": "1ms", + "max_v": 0.3 + }, + "net:B": { + "at": "1ms", + "min_v": 0.6, + "max_v": 1.2 + } + } +} diff --git a/catalog/components/bsr14/tests/sat-500ma.json b/catalog/components/bsr14/tests/sat-500ma.json new file mode 100644 index 000000000..9b74fc42e --- /dev/null +++ b/catalog/components/bsr14/tests/sat-500ma.json @@ -0,0 +1,73 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "sat-500ma", + "description": "The datasheet's second saturation point: about 500 mA from 5 V through 9.1 ohm, 50 mA into the base through 82 ohm: VCE(sat) at most 1.0 V and VBE(sat) at most 2.0 V.", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/bsr14" + }, + { + "id": "VC", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "RC", + "component": "emblink/resistor", + "params": { + "resistance": 9.1 + } + }, + { + "id": "RB", + "component": "emblink/resistor", + "params": { + "resistance": 82 + } + } + ], + "nets": { + "VCN": [ + "VC.+", + "RC.1", + "RB.1" + ], + "C": [ + "RC.2", + "DUT.C" + ], + "B": [ + "RB.2", + "DUT.B" + ], + "GND": [ + "VC.-", + "DUT.E", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:C": { + "at": "1ms", + "max_v": 1.0 + }, + "net:B": { + "at": "1ms", + "max_v": 2.0 + } + } +} diff --git a/catalog/components/tl1431cl5t/component.json b/catalog/components/tl1431cl5t/component.json new file mode 100644 index 000000000..657cf8e4e --- /dev/null +++ b/catalog/components/tl1431cl5t/component.json @@ -0,0 +1,294 @@ +{ + "schema_version": 1, + "kind": "component", + "id": "emblink/tl1431cl5t", + "version": "1.0.0", + "name": "TL1431CL5T programmable shunt voltage reference", + "category": "analog_ics", + "subcategory": "voltage_references", + "description": "STMicroelectronics TL1431CL5T, a programmable shunt voltage reference (2.500 V, C grade) in SOT23-5L: between its cathode and anode it sinks what keeps REF at its reference, so two resistors set any voltage from VREF to 36 V. The NUCLEO-G474RE's (MB1367) U14, the reference of its VREF+ supply.", + "keywords": [ + "voltage reference", + "shunt reference", + "programmable", + "tl1431", + "tl431", + "tl1431cl5t", + "stmicroelectronics", + "sot23-5", + "nucleo" + ], + "pins": [ + { + "name": "NC1", + "number": 1, + "model": { + "kind": "nc" + }, + "required": false, + "doc": "Not connected (SOT23-5L pin 1)" + }, + { + "name": "NC2", + "number": 2, + "model": { + "kind": "nc" + }, + "required": false, + "doc": "Not connected (SOT23-5L pin 2)" + }, + { + "name": "CATHODE", + "number": 3, + "model": { + "kind": "analog" + }, + "doc": "Cathode (SOT23-5L pin 3): the shunt's input" + }, + { + "name": "REF", + "number": 4, + "model": { + "kind": "analog" + }, + "doc": "Reference input (SOT23-5L pin 4): held at VREF above the anode while the part regulates" + }, + { + "name": "ANODE", + "number": 5, + "model": { + "kind": "analog" + }, + "doc": "Anode (SOT23-5L pin 5), normally ground" + } + ], + "params": {}, + "model": { + "composite": { + "components": [ + { + "id": "VR", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 2.5045 + } + }, + { + "id": "EA", + "component": "emblink/opamp", + "params": { + "gain": "450", + "gbw": "2meg", + "rin": "1T", + "vpos": 5 + } + }, + { + "id": "VB", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 0.8 + } + }, + { + "id": "RB", + "component": "emblink/resistor", + "params": { + "resistance": "100k" + } + }, + { + "id": "QD", + "component": "emblink/bjt_npn" + }, + { + "id": "Q", + "component": "emblink/bjt_npn" + }, + { + "id": "RQ", + "component": "emblink/resistor", + "params": { + "resistance": "200meg" + } + } + ], + "nets": { + "VREF_INT": [ + "VR.+", + "EA.-" + ], + "ANODE": [ + "VR.-", + "EA.V-", + "Q.E", + "RQ.2" + ], + "CATHODE": [ + "Q.C", + "QD.C", + "RQ.1" + ], + "DRIVE": [ + "EA.OUT", + "VB.-" + ], + "DBASE": [ + "RB.2", + "QD.B" + ], + "BASE": [ + "QD.E", + "Q.B" + ], + "BIAS": [ + "VB.+", + "RB.1" + ] + }, + "ports": { + "CATHODE": "Q.C", + "REF": "EA.+", + "ANODE": "Q.E" + } + } + }, + "functional": { + "composite": { + "components": [], + "nets": {}, + "ports": {} + } + }, + "symbol": { + "svg": "symbol.svg", + "width": 60, + "height": 60, + "pins": { + "CATHODE": { + "x": 30, + "y": 0, + "side": "top" + }, + "ANODE": { + "x": 30, + "y": 60, + "side": "bottom" + }, + "REF": { + "x": 0, + "y": 30, + "side": "left" + }, + "NC1": { + "x": 60, + "y": 20, + "side": "right" + }, + "NC2": { + "x": 60, + "y": 40, + "side": "right" + } + } + }, + "fidelity": { + "functional": { + "claims": "Pins only: the functional policy has no voltages.", + "omissions": [ + "regulation" + ], + "validation": [ + "tests/*.json" + ] + }, + "timed": { + "claims": "As electrical.", + "omissions": [] + }, + "electrical": { + "claims": "The shunt as the datasheet's block diagram (figure 5) draws it: an error amplifier comparing REF with an internal reference and driving a Darlington from the cathode to the anode, so the cathode current is what holds REF at VREF and VKA = VREF x (1 + R1 / R2) with a divider. The amplifier has the open-loop gain of figure 19 (53 dB, falling to unity near 2 MHz); the reference is trimmed, as the part is, so VREF is the C grade's typical 2.500 V (2.490 to 2.510 V) with the amplifier's offset included; from 5 mA to 83 mA it moves under 1 mV (the datasheet's |zKA| is 0.2 ohm typical); REF draws no current (IREF 1.5 uA typical); off (REF below VREF) the cathode passes the datasheet's Ioff through 200 MOhm (180 nA at 36 V); it regulates from about 0.5 mA (Imin 0.5 mA typical) to 100 mA; a 1 mA step brings the cathode to VREF within a microsecond (figure 22). Fixtures: VKA = VREF, a 3.25 V divider, the off state, 83 mA, figure 22's step. Inside: the amplifier, reference, the output stage's 0.8 V bias and two transistors are the catalog's primitives, with the same outside.", + "omissions": [ + "the error amplifier runs from a 5 V internal rail, not from the cathode: the Darlington's first base current (about 10 uA at 100 mA) comes from that rail through 100 kOhm, and with REF above VREF while the cathode is held below VREF the part sources up to about 50 uA out of its cathode, where the real part cannot", + "the step response has no internal capacitance: the cathode reaches VREF in under 0.2 us without figure 22's 0.6 us rise and overshoot", + "VREF's spread (2.490 to 2.510 V) and drift with temperature (3 to 20 mV over the range), and its change with VKA (-1.1 mV/V): VREF is the typical 2.500 V", + "IREF (1.5 uA) and its drift: REF draws no current", + "the minimum cathode current's own curve below Imin, the stability boundaries with a capacitive load (figure 20)", + "the thermal limits and damage (36 V, 100 mA)" + ], + "range": { + "voltage_v": [ + -0.3, + 37 + ], + "current_a": [ + -0.1, + 0.15 + ] + }, + "validation": [ + "tests/*.json" + ] + } + }, + "provenance": { + "author": "EmbSIM", + "license": "Apache-2.0", + "sources": [ + { + "title": "STMicroelectronics TL1431 programmable shunt voltage reference datasheet: SOT23-5L pin connections (figure 3), operating conditions, electrical characteristics (VREF, IREF, Imin, Ioff, |zKA|)", + "url": "https://www.st.com/resource/en/datasheet/tl1431.pdf", + "date": "2026-11-12" + }, + { + "title": "Texas Instruments TL1431 datasheet (SLVS062O): the same part's functional block diagram and characteristics", + "url": "https://www.ti.com/lit/ds/symlink/tl1431.pdf", + "date": "2026-11-12" + }, + { + "title": "MB1367 D-01 schematics (NUCLEO-G474RE), Main power sheet: U14 TL1431CL5T with Q2 BSR14, R33 10 kOhm, R34 33 kOhm, R35 180 ohm, C51 100 pF", + "url": "https://www.st.com/resource/en/schematic_pack/mb1367-g474re-d01-schematic.pdf", + "date": "2026-11-12" + } + ] + }, + "tests": [ + "tests/*.json" + ], + "part": { + "mpn": "TL1431CL5T", + "manufacturer": "STMicroelectronics", + "package": "SOT23-5L", + "datasheet": "https://www.st.com/resource/en/datasheet/tl1431.pdf" + }, + "i18n": { + "fr": { + "source": "1c3a119f0636", + "description": "Le TL1431CL5T de STMicroelectronics, une rรฉfรฉrence de tension shunt programmable (2,500 V, classe C) en SOT23-5L : entre sa cathode et son anode il absorbe ce qui tient REF ร  sa rรฉfรฉrence, si bien que deux rรฉsistances fixent toute tension de VREF ร  36 V. L'U14 de la NUCLEO-G474RE (MB1367), la rรฉfรฉrence de son alimentation VREF+.", + "fidelity": { + "functional": { + "claims": "Les broches seulement : la politique fonctionnelle n'a pas de tensions.", + "omissions": [ + "la rรฉgulation" + ] + }, + "timed": { + "claims": "Comme le niveau รฉlectrique." + }, + "electrical": { + "claims": "Le shunt tel que le dessine le schรฉma fonctionnel de la fiche technique (figure 5) : un amplificateur d'erreur comparant REF ร  une rรฉfรฉrence interne et pilotant un Darlington de la cathode ร  l'anode, si bien que le courant de cathode est ce qui tient REF ร  VREF et que VKA = VREF x (1 + R1 / R2) avec un diviseur. L'amplificateur a le gain en boucle ouverte de la figure 19 (53 dB, tombant ร  l'unitรฉ vers 2 MHz) ; la rรฉfรฉrence est ajustรฉe, comme sur le composant, si bien que VREF est la valeur typique de 2,500 V de la classe C (2,490 ร  2,510 V), dรฉcalage de l'amplificateur compris ; de 5 mA ร  83 mA elle varie de moins de 1 mV (le |zKA| de la fiche technique est de 0,2 ohm typique) ; REF ne consomme aucun courant (IREF 1,5 uA typique) ; bloquรฉ (REF sous VREF), la cathode laisse passer l'Ioff de la fiche technique par 200 Mohms (180 nA ร  36 V) ; il rรฉgule d'environ 0,5 mA (Imin 0,5 mA typique) ร  100 mA ; un รฉchelon de 1 mA amรจne la cathode ร  VREF en moins d'une microseconde (figure 22). Fixtures : VKA = VREF, un diviseur ร  3,25 V, l'รฉtat bloquรฉ, 83 mA, l'รฉchelon de la figure 22. ร€ l'intรฉrieur : l'amplificateur, la rรฉfรฉrence, la polarisation de 0,8 V de l'รฉtage de sortie et les deux transistors sont les primitives du catalogue, avec le mรชme comportement vu de l'extรฉrieur.", + "omissions": [ + "l'amplificateur d'erreur est alimentรฉ par un rail interne de 5 V, pas par la cathode : le premier courant de base du Darlington (environ 10 uA ร  100 mA) vient de ce rail ร  travers 100 kohms, et avec REF au-dessus de VREF pendant que la cathode est tenue sous VREF le composant fournit jusqu'ร  environ 50 uA par sa cathode, ce que le vrai composant ne peut pas faire", + "la rรฉponse ร  un รฉchelon n'a pas de capacitรฉ interne : la cathode atteint VREF en moins de 0,2 us, sans la montรฉe de 0,6 us ni le dรฉpassement de la figure 22", + "la dispersion de VREF (2,490 ร  2,510 V), sa dรฉrive en tempรฉrature (3 ร  20 mV sur la plage) et sa variation avec VKA (-1,1 mV/V) : VREF est la valeur typique de 2,500 V", + "IREF (1,5 uA) et sa dรฉrive : REF ne consomme aucun courant", + "la courbe propre du courant de cathode minimal sous Imin, les limites de stabilitรฉ avec une charge capacitive (figure 20)", + "les limites thermiques et les dรฉgรขts (36 V, 100 mA)" + ] + } + } + } + } +} diff --git a/catalog/components/tl1431cl5t/symbol.svg b/catalog/components/tl1431cl5t/symbol.svg new file mode 100644 index 000000000..cccfc7bcb --- /dev/null +++ b/catalog/components/tl1431cl5t/symbol.svg @@ -0,0 +1,2 @@ + +KAREFTL1431 diff --git a/catalog/components/tl1431cl5t/tests/divider-3v25.json b/catalog/components/tl1431cl5t/tests/divider-3v25.json new file mode 100644 index 000000000..2d626a05d --- /dev/null +++ b/catalog/components/tl1431cl5t/tests/divider-3v25.json @@ -0,0 +1,84 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "divider-3v25", + "description": "MB1367's VREF divider without its follower: R1 10 kOhm from the cathode to REF and R2 33 kOhm from REF to the anode, fed through 180 ohm from 5 V: VKA = 2.5 x (1 + 10/33) = 3.258 V.", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/tl1431cl5t" + }, + { + "id": "RS", + "component": "emblink/resistor", + "params": { + "resistance": 180 + } + }, + { + "id": "R1", + "component": "emblink/resistor", + "params": { + "resistance": "10k" + } + }, + { + "id": "R2", + "component": "emblink/resistor", + "params": { + "resistance": "33k" + } + } + ], + "nets": { + "IN": [ + "VS.+", + "RS.1" + ], + "K": [ + "RS.2", + "DUT.CATHODE", + "R1.1" + ], + "REF": [ + "R1.2", + "R2.1", + "DUT.REF" + ], + "GND": [ + "VS.-", + "DUT.ANODE", + "R2.2", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:K": { + "at": "1ms", + "min_v": 3.24, + "max_v": 3.28 + }, + "net:REF": { + "at": "1ms", + "min_v": 2.49, + "max_v": 2.51 + } + } +} \ No newline at end of file diff --git a/catalog/components/tl1431cl5t/tests/off.json b/catalog/components/tl1431cl5t/tests/off.json new file mode 100644 index 000000000..9d3e19f37 --- /dev/null +++ b/catalog/components/tl1431cl5t/tests/off.json @@ -0,0 +1,58 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "off", + "description": "REF at the anode, the cathode fed through 100 kOhm from 5 V: the part off, its cathode current under a microamp (Ioff 180 nA typical), the cathode near 5 V.", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/tl1431cl5t" + }, + { + "id": "RS", + "component": "emblink/resistor", + "params": { + "resistance": "100k" + } + } + ], + "nets": { + "IN": [ + "VS.+", + "RS.1" + ], + "K": [ + "RS.2", + "DUT.CATHODE" + ], + "GND": [ + "VS.-", + "DUT.ANODE", + "DUT.REF", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:K": { + "at": "1ms", + "min_v": 4.9 + } + } +} \ No newline at end of file diff --git a/catalog/components/tl1431cl5t/tests/pulse.json b/catalog/components/tl1431cl5t/tests/pulse.json new file mode 100644 index 000000000..42648758f --- /dev/null +++ b/catalog/components/tl1431cl5t/tests/pulse.json @@ -0,0 +1,65 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "pulse", + "description": "The datasheet's figure 22: REF tied to the cathode (figure 6's circuit), a 1 mA step from a 5 V pulse through 2.5 kOhm: within 1.5 us of the edge the cathode is at VREF (figure 22 rises in about 0.6 us and settles near 2.4 V).", + "policy": "electrical", + "until": "40us", + "circuit": { + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "pulse", + "v1": 0, + "v2": 5, + "td": "10u", + "tr": "10n", + "tf": "10n", + "pw": "20u", + "per": "100u" + } + }, + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/tl1431cl5t" + }, + { + "id": "RS", + "component": "emblink/resistor", + "params": { + "resistance": 2500 + } + } + ], + "nets": { + "IN": [ + "VS.+", + "RS.1" + ], + "K": [ + "RS.2", + "DUT.CATHODE", + "DUT.REF" + ], + "GND": [ + "VS.-", + "DUT.ANODE", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:K": { + "at": "11.5us", + "min_v": 2.3, + "max_v": 2.6 + } + } +} diff --git a/catalog/components/tl1431cl5t/tests/regulation.json b/catalog/components/tl1431cl5t/tests/regulation.json new file mode 100644 index 000000000..049242d3c --- /dev/null +++ b/catalog/components/tl1431cl5t/tests/regulation.json @@ -0,0 +1,59 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "regulation", + "description": "REF tied to the cathode, fed through 30 ohm from 5 V (about 83 mA, near the 100 mA maximum): the cathode still within 15 mV of VREF (|zKA| 0.2 ohm typical).", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/tl1431cl5t" + }, + { + "id": "RS", + "component": "emblink/resistor", + "params": { + "resistance": 30 + } + } + ], + "nets": { + "IN": [ + "VS.+", + "RS.1" + ], + "K": [ + "RS.2", + "DUT.CATHODE", + "DUT.REF" + ], + "GND": [ + "VS.-", + "DUT.ANODE", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:K": { + "at": "1ms", + "min_v": 2.485, + "max_v": 2.53 + } + } +} \ No newline at end of file diff --git a/catalog/components/tl1431cl5t/tests/vka-vref.json b/catalog/components/tl1431cl5t/tests/vka-vref.json new file mode 100644 index 000000000..6f1ccf0ac --- /dev/null +++ b/catalog/components/tl1431cl5t/tests/vka-vref.json @@ -0,0 +1,59 @@ +{ + "schema_version": 1, + "kind": "component_test", + "name": "vka-vref", + "description": "REF tied to the cathode, fed from 5 V through 470 ohm (about 5 mA): the cathode at VREF, 2.500 V (the C grade's 2.490 to 2.510 V).", + "policy": "electrical", + "until": "2ms", + "circuit": { + "components": [ + { + "id": "VS", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5.0 + } + }, + { + "id": "G0", + "component": "emblink/gnd" + }, + { + "id": "DUT", + "component": "emblink/tl1431cl5t" + }, + { + "id": "RS", + "component": "emblink/resistor", + "params": { + "resistance": 470 + } + } + ], + "nets": { + "IN": [ + "VS.+", + "RS.1" + ], + "K": [ + "RS.2", + "DUT.CATHODE", + "DUT.REF" + ], + "GND": [ + "VS.-", + "DUT.ANODE", + "G0.GND" + ] + } + }, + "inputs": [], + "expect": { + "net:K": { + "at": "1ms", + "min_v": 2.49, + "max_v": 2.51 + } + } +} \ No newline at end of file diff --git a/catalog/mcus/st/stm32g474re/LICENSES/Apache-2.0.txt b/catalog/mcus/st/stm32g474re/LICENSES/Apache-2.0.txt new file mode 100644 index 000000000..439f2cf82 --- /dev/null +++ b/catalog/mcus/st/stm32g474re/LICENSES/Apache-2.0.txt @@ -0,0 +1,13 @@ +Copyright (c) 2026 Microchip Technology Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/catalog/mcus/st/stm32g474re/lqfp64.json b/catalog/mcus/st/stm32g474re/lqfp64.json new file mode 100644 index 000000000..c4cf33511 --- /dev/null +++ b/catalog/mcus/st/stm32g474re/lqfp64.json @@ -0,0 +1,281 @@ +{ + "schema_version": 1, + "kind": "package", + "id": "st/stm32g474re/lqfp64", + "name": "LQFP64", + "description": "LQFP64 package of the STM32G474R(B-C-E)Tx, its pinout from ST's open pin data; pin 7 is NRST (PG10-NRST) and PB8 doubles as BOOT0.", + "pins": [ + { + "number": 1, + "signal": "VBAT" + }, + { + "number": 2, + "signal": "PC13" + }, + { + "number": 3, + "signal": "PC14", + "doc": "PC14-OSC32_IN" + }, + { + "number": 4, + "signal": "PC15", + "doc": "PC15-OSC32_OUT" + }, + { + "number": 5, + "signal": "PF0", + "doc": "PF0-OSC_IN" + }, + { + "number": 6, + "signal": "PF1", + "doc": "PF1-OSC_OUT" + }, + { + "number": 7, + "signal": "NRST", + "doc": "PG10-NRST: the reset pin while the option bytes' NRST_MODE is 11 (bidirectional, the factory setting); PG10 is not modelled as a GPIO" + }, + { + "number": 8, + "signal": "PC0" + }, + { + "number": 9, + "signal": "PC1" + }, + { + "number": 10, + "signal": "PC2" + }, + { + "number": 11, + "signal": "PC3" + }, + { + "number": 12, + "signal": "PA0" + }, + { + "number": 13, + "signal": "PA1" + }, + { + "number": 14, + "signal": "PA2" + }, + { + "number": 15, + "signal": "VSS" + }, + { + "number": 16, + "signal": "VDD" + }, + { + "number": 17, + "signal": "PA3" + }, + { + "number": 18, + "signal": "PA4" + }, + { + "number": 19, + "signal": "PA5" + }, + { + "number": 20, + "signal": "PA6" + }, + { + "number": 21, + "signal": "PA7" + }, + { + "number": 22, + "signal": "PC4" + }, + { + "number": 23, + "signal": "PC5" + }, + { + "number": 24, + "signal": "PB0" + }, + { + "number": 25, + "signal": "PB1" + }, + { + "number": 26, + "signal": "PB2" + }, + { + "number": 27, + "signal": "VSSA" + }, + { + "number": 28, + "signal": "VREFP", + "doc": "VREF+" + }, + { + "number": 29, + "signal": "VDDA" + }, + { + "number": 30, + "signal": "PB10" + }, + { + "number": 31, + "signal": "VSS" + }, + { + "number": 32, + "signal": "VDD" + }, + { + "number": 33, + "signal": "PB11" + }, + { + "number": 34, + "signal": "PB12" + }, + { + "number": 35, + "signal": "PB13" + }, + { + "number": 36, + "signal": "PB14" + }, + { + "number": 37, + "signal": "PB15" + }, + { + "number": 38, + "signal": "PC6" + }, + { + "number": 39, + "signal": "PC7" + }, + { + "number": 40, + "signal": "PC8" + }, + { + "number": 41, + "signal": "PC9" + }, + { + "number": 42, + "signal": "PA8" + }, + { + "number": 43, + "signal": "PA9" + }, + { + "number": 44, + "signal": "PA10" + }, + { + "number": 45, + "signal": "PA11" + }, + { + "number": 46, + "signal": "PA12" + }, + { + "number": 47, + "signal": "VSS" + }, + { + "number": 48, + "signal": "VDD" + }, + { + "number": 49, + "signal": "PA13" + }, + { + "number": 50, + "signal": "PA14" + }, + { + "number": 51, + "signal": "PA15" + }, + { + "number": 52, + "signal": "PC10" + }, + { + "number": 53, + "signal": "PC11" + }, + { + "number": 54, + "signal": "PC12" + }, + { + "number": 55, + "signal": "PD2" + }, + { + "number": 56, + "signal": "PB3" + }, + { + "number": 57, + "signal": "PB4" + }, + { + "number": 58, + "signal": "PB5" + }, + { + "number": 59, + "signal": "PB6" + }, + { + "number": 60, + "signal": "PB7" + }, + { + "number": 61, + "signal": "PB8", + "doc": "PB8-BOOT0: sampled as BOOT0 at reset while the option bytes' nSWBOOT0 is 1 (the factory setting)" + }, + { + "number": 62, + "signal": "PB9" + }, + { + "number": 63, + "signal": "VSS" + }, + { + "number": 64, + "signal": "VDD" + } + ], + "provenance": { + "author": "EmbSIM", + "license": "Apache-2.0", + "sources": [ + { + "title": "STMicroelectronics STM32_open_pin_data 7d1f151, STM32G474R(B-C-E)Tx.xml (BSD-3-Clause), converted by tools/importers/stm32pins.py; pin 7 named NRST and VREF+ VREFP by hand" + } + ] + } +} diff --git a/catalog/mcus/st/stm32g474re/mcu.json b/catalog/mcus/st/stm32g474re/mcu.json new file mode 100644 index 000000000..02cf02b4e --- /dev/null +++ b/catalog/mcus/st/stm32g474re/mcu.json @@ -0,0 +1,2283 @@ +{ + "schema_version": 1, + "kind": "mcu", + "id": "st/stm32g474re", + "version": "1.0.0", + "name": "STM32G474RE", + "description": "STMicroelectronics STM32G474RE: an Arm Cortex-M4F at up to 170 MHz with an MPU, 512 KiB of dual-bank flash, 128 KiB of SRAM (80 KiB SRAM1, 16 KiB SRAM2, 32 KiB CCM SRAM), its mathematical accelerators, high-resolution timer and analog front end, in an LQFP64; the NUCLEO-G474RE's MCU.", + "keywords": [ + "stm32g474re", + "stm32g474", + "stm32g4", + "stm32", + "cortex-m4f", + "nucleo", + "nucleo-64" + ], + "vendor": "st", + "family": "stm32g4", + "core": { + "backend": "cortex-m", + "model": "cortex-m4", + "priority_bits": 4, + "timing_tier": "estimated", + "fpu": true, + "mpu": true, + "endian": "little", + "systick": { + "ref_div": 8, + "calib": "0x40000000" + } + }, + "dma_requests": { + "DMAMUX": { + "0": { + "1": [ + "DMAMUX_REQ_GEN0" + ], + "2": [ + "DMAMUX_REQ_GEN1" + ], + "3": [ + "DMAMUX_REQ_GEN2" + ], + "4": [ + "DMAMUX_REQ_GEN3" + ], + "5": [ + "ADC1" + ], + "6": [ + "DAC1_CH1" + ], + "7": [ + "DAC1_CH2" + ], + "8": [ + "TIM6_UP" + ], + "9": [ + "TIM7_UP" + ], + "10": [ + "SPI1_RX" + ], + "11": [ + "SPI1_TX" + ], + "12": [ + "SPI2_RX" + ], + "13": [ + "SPI2_TX" + ], + "14": [ + "SPI3_RX" + ], + "15": [ + "SPI3_TX" + ], + "16": [ + "I2C1_RX" + ], + "17": [ + "I2C1_TX" + ], + "18": [ + "I2C2_RX" + ], + "19": [ + "I2C2_TX" + ], + "20": [ + "I2C3_RX" + ], + "21": [ + "I2C3_TX" + ], + "22": [ + "I2C4_RX" + ], + "23": [ + "I2C4_TX" + ], + "24": [ + "USART1_RX" + ], + "25": [ + "USART1_TX" + ], + "26": [ + "USART2_RX" + ], + "27": [ + "USART2_TX" + ], + "28": [ + "USART3_RX" + ], + "29": [ + "USART3_TX" + ], + "30": [ + "UART4_RX" + ], + "31": [ + "UART4_TX" + ], + "32": [ + "UART5_RX" + ], + "33": [ + "UART5_TX" + ], + "34": [ + "LPUART1_RX" + ], + "35": [ + "LPUART1_TX" + ], + "36": [ + "ADC2" + ], + "37": [ + "ADC3" + ], + "38": [ + "ADC4" + ], + "39": [ + "ADC5" + ], + "40": [ + "QUADSPI" + ], + "41": [ + "DAC2_CH1" + ], + "42": [ + "TIM1_CH1" + ], + "43": [ + "TIM1_CH2" + ], + "44": [ + "TIM1_CH3" + ], + "45": [ + "TIM1_CH4" + ], + "46": [ + "TIM1_UP" + ], + "47": [ + "TIM1_TRIG" + ], + "48": [ + "TIM1_COM" + ], + "49": [ + "TIM8_CH1" + ], + "50": [ + "TIM8_CH2" + ], + "51": [ + "TIM8_CH3" + ], + "52": [ + "TIM8_CH4" + ], + "53": [ + "TIM8_UP" + ], + "54": [ + "TIM8_TRIG" + ], + "55": [ + "TIM8_COM" + ], + "56": [ + "TIM2_CH1" + ], + "57": [ + "TIM2_CH2" + ], + "58": [ + "TIM2_CH3" + ], + "59": [ + "TIM2_CH4" + ], + "60": [ + "TIM2_UP" + ], + "61": [ + "TIM3_CH1" + ], + "62": [ + "TIM3_CH2" + ], + "63": [ + "TIM3_CH3" + ], + "64": [ + "TIM3_CH4" + ], + "65": [ + "TIM3_UP" + ], + "66": [ + "TIM3_TRIG" + ], + "67": [ + "TIM4_CH1" + ], + "68": [ + "TIM4_CH2" + ], + "69": [ + "TIM4_CH3" + ], + "70": [ + "TIM4_CH4" + ], + "71": [ + "TIM4_UP" + ], + "72": [ + "TIM5_CH1" + ], + "73": [ + "TIM5_CH2" + ], + "74": [ + "TIM5_CH3" + ], + "75": [ + "TIM5_CH4" + ], + "76": [ + "TIM5_UP" + ], + "77": [ + "TIM5_TRIG" + ], + "78": [ + "TIM15_CH1" + ], + "79": [ + "TIM15_UP" + ], + "80": [ + "TIM15_TRIG" + ], + "81": [ + "TIM15_COM" + ], + "82": [ + "TIM16_CH1" + ], + "83": [ + "TIM16_UP" + ], + "84": [ + "TIM17_CH1" + ], + "85": [ + "TIM17_UP" + ], + "86": [ + "TIM20_CH1" + ], + "87": [ + "TIM20_CH2" + ], + "88": [ + "TIM20_CH3" + ], + "89": [ + "TIM20_CH4" + ], + "90": [ + "TIM20_UP" + ], + "93": [ + "TIM20_TRIG" + ], + "94": [ + "TIM20_COM" + ], + "95": [ + "HRTIM1_M" + ], + "96": [ + "HRTIM1_A" + ], + "97": [ + "HRTIM1_B" + ], + "98": [ + "HRTIM1_C" + ], + "99": [ + "HRTIM1_D" + ], + "100": [ + "HRTIM1_E" + ], + "101": [ + "HRTIM1_F" + ], + "102": [ + "DAC3_CH1" + ], + "103": [ + "DAC3_CH2" + ], + "104": [ + "DAC4_CH1" + ], + "105": [ + "DAC4_CH2" + ], + "106": [ + "SPI4_RX" + ], + "107": [ + "SPI4_TX" + ], + "108": [ + "SAI1_A" + ], + "109": [ + "SAI1_B" + ], + "110": [ + "FMAC_READ" + ], + "111": [ + "FMAC_WRITE" + ], + "112": [ + "CORDIC_READ" + ], + "113": [ + "CORDIC_WRITE" + ], + "114": [ + "UCPD1_RX" + ], + "115": [ + "UCPD1_TX" + ] + } + } + }, + "memory": [ + { + "name": "flash", + "base": "0x08000000", + "size": "512K", + "kind": "flash", + "erased": "0xFFFFFFFF", + "doc": "Main memory: bank 1 at 0x08000000 and bank 2 at 0x08040000, 128 pages of 2 KiB each in the factory's dual-bank mode (DBANK 1), or 128 of 4 KiB in single-bank mode" + }, + { + "name": "flash_alias", + "base": "0x00000000", + "size": "512K", + "kind": "alias", + "target": "0x08000000", + "doc": "Boot alias of the main flash when BOOT0 is low" + }, + { + "name": "sram", + "base": "0x20000000", + "size": "128K", + "kind": "ram", + "main": true, + "doc": "SRAM1 (80 KiB) and SRAM2 (16 KiB), contiguous, then the CCM SRAM's alias at 0x20018000 (RM0440 2.4)" + }, + { + "name": "ccm_sram", + "base": "0x10000000", + "size": "32K", + "kind": "alias", + "target": "0x20018000", + "doc": "CCM SRAM at its code-bus address, the same 32 KiB as at 0x20018000" + }, + { + "name": "system_memory", + "base": "0x1FFF0000", + "size": "28K", + "kind": "rom", + "doc": "ST's bootloader; contents not shipped" + }, + { + "name": "otp", + "base": "0x1FFF7000", + "size": "1K", + "kind": "flash", + "erased": "0xFFFFFFFF", + "doc": "One-time programmable area: 1 KiB, programmed by double words" + }, + { + "name": "device_id", + "base": "0x1FFF7500", + "size": 256, + "kind": "rom", + "erased": "0xFFFFFFFF", + "doc": "The engineering bytes (RM0440 48): the unique device ID, the flash size and the factory calibration values (DS12288 5.3.4, 5.3.25). Each real part has its own; these are one part's, with the datasheet's typical values: VREFINT 1.212 V and the temperature sensor's 0.76 V at 30 degC, 2.5 mV/degC, read at VREF+ 3.0 V", + "contents": [ + { + "offset": "0x00", + "bytes": "e0ff", + "doc": "PKG[4:0] 00000: LQFP64 (RM0440 48.3); the reserved bits as erased" + }, + { + "offset": "0x90", + "bytes": "35002100474d495331424d45", + "doc": "UID: X 0x35, Y 0x21 on wafer 0x47 of lot EMBSIM1" + }, + { + "offset": "0xA8", + "bytes": "0d04", + "doc": "TS_CAL1: 1037, the temperature sensor at 30 degC and VREF+ 3.0 V" + }, + { + "offset": "0xAA", + "bytes": "7606", + "doc": "VREFINT_CAL: 1654, VREFINT at 30 degC and VREF+ 3.0 V" + }, + { + "offset": "0xCA", + "bytes": "6305", + "doc": "TS_CAL2: 1379, the temperature sensor at 130 degC and VREF+ 3.0 V" + }, + { + "offset": "0xE0", + "bytes": "0002", + "doc": "FLASH_SIZE: 512 Kbytes" + } + ] + }, + { + "name": "option_bytes", + "base": "0x1FFF7800", + "size": 48, + "kind": "flash", + "erased": "0xFFFFFFFF", + "doc": "Bank 1's option bytes as the part leaves the factory (RM0440 5.4.1), each word followed by its complement: RDP level 0, dual bank, BOOT0 from PB8, NRST bidirectional, no write or code protection (the PCROP and WRP start pages above their end pages)", + "contents": [ + { + "offset": "0x00", + "bytes": "aaf8efff55071000", + "doc": "USER and RDP: 0xFFEFF8AA (RDP 0xAA level 0, BOR_LEV 0, the watchdogs by software, DBANK 1, nSWBOOT0 1 and nBOOT0 1: BOOT0 from PB8, NRST_MODE 11), then its complement" + }, + { + "offset": "0x08", + "bytes": "ff7f00000080ffff", + "doc": "PCROP1_STRT 0x7FFF, above PCROP1_END: no proprietary code protection" + }, + { + "offset": "0x10", + "bytes": "00000000ffffffff", + "doc": "PCROP1_END 0" + }, + { + "offset": "0x18", + "bytes": "7f00000080ffffff", + "doc": "WRP1A: start page 0x7F above end page 0, no write protection" + }, + { + "offset": "0x20", + "bytes": "7f00000080ffffff", + "doc": "WRP1B: likewise" + }, + { + "offset": "0x28", + "bytes": "00000000ffffffff", + "doc": "SEC1R: no securable area, BOOT_LOCK clear" + } + ] + }, + { + "name": "option_bytes_2", + "base": "0x1FFFF800", + "size": 48, + "kind": "flash", + "erased": "0xFFFFFFFF", + "doc": "Bank 2's option bytes as the part leaves the factory, each word followed by its complement: no write or code protection", + "contents": [ + { + "offset": "0x08", + "bytes": "ff7f00000080ffff", + "doc": "PCROP2_STRT 0x7FFF, above PCROP2_END: no proprietary code protection" + }, + { + "offset": "0x10", + "bytes": "00000000ffffffff", + "doc": "PCROP2_END 0" + }, + { + "offset": "0x18", + "bytes": "7f00000080ffffff", + "doc": "WRP2A: start page 0x7F above end page 0, no write protection" + }, + { + "offset": "0x20", + "bytes": "7f00000080ffffff", + "doc": "WRP2B: likewise" + }, + { + "offset": "0x28", + "bytes": "00000000ffffffff", + "doc": "SEC2R: no securable area" + } + ] + }, + { + "name": "sramcan", + "base": "0x4000A400", + "size": "0xA00", + "kind": "ram", + "doc": "The FDCANs' message RAM, 212 words each for FDCAN1 to FDCAN3 (RM0440 44.3.3)" + }, + { + "name": "usb_pma", + "base": "0x40006000", + "size": "1K", + "kind": "ram", + "doc": "The USB device's packet memory, 1 KiB (RM0440 45.5)" + } + ], + "clocks": { + "sources": [ + { + "name": "hsi", + "hz": 16000000, + "doc": "Internal 16 MHz RC (HSI16), the clock out of reset" + }, + { + "name": "hse", + "hz": "board", + "doc": "External crystal 4 to 48 MHz, or an external clock up to 48 MHz (bypass)" + }, + { + "name": "lsi", + "hz": 32000, + "doc": "Internal low-speed RC, 32 kHz" + }, + { + "name": "lse", + "hz": "board", + "doc": "External 32.768 kHz crystal" + }, + { + "name": "hsi48", + "hz": 48000000, + "doc": "Internal 48 MHz RC for the USB, trimmed by the CRS" + } + ], + "reset_core_hz": 16000000, + "max_core_hz": 170000000 + }, + "register_file": { + "format": "embsim", + "file": "registers.json", + "vendored": true, + "license": "Apache-2.0 (converted from STMicroelectronics' STM32G474.svd v3.0, Copyright (c) 2024 STMicroelectronics; LICENSES/Apache-2.0.txt)" + }, + "peripherals": [ + { + "match": "RCC", + "model": "stm32g4-rcc", + "order": 0 + }, + { + "match": "FLASH", + "model": "stm32g4-flash", + "order": 1 + }, + { + "match": "PWR", + "model": "stm32g4-pwr" + }, + { + "match": "SYSCFG", + "model": "stm32f4-syscfg" + }, + { + "match": "EXTI", + "model": "stm32-exti" + }, + { + "match": "GPIO*", + "model": "stm32f4-gpio" + }, + { + "match": "TIM*", + "model": "stm32-tim" + }, + { + "match": "USART*", + "model": "stm32-usart-v2" + }, + { + "match": "UART*", + "model": "stm32-usart-v2" + }, + { + "match": "LPUART1", + "model": "stm32-usart-v2" + }, + { + "match": "IWDG", + "model": "stm32-iwdg" + }, + { + "match": "WWDG", + "model": "stm32-wwdg" + }, + { + "match": "CRC", + "model": "stm32-crc" + }, + { + "match": "SPI*", + "model": "stm32-spi" + }, + { + "match": "DMA1", + "model": "stm32g4-dma" + }, + { + "match": "DMA2", + "model": "stm32g4-dma" + }, + { + "match": "DMAMUX", + "model": "stm32g4-dmamux" + }, + { + "match": "DBGMCU", + "model": "stm32f4-dbgmcu" + } + ], + "io": { + "family": "cmos_3v3", + "ports": [ + { + "name": "A", + "pins": 16 + }, + { + "name": "B", + "pins": 16 + }, + { + "name": "C", + "pins": 16 + }, + { + "name": "D", + "pins": 16 + }, + { + "name": "E", + "pins": 16 + }, + { + "name": "F", + "pins": 16 + }, + { + "name": "G", + "pins": 16 + } + ], + "electrical": { + "vdd": 3.3, + "voh": 2.9, + "vol": 0.4, + "rout": { + "low": 60, + "medium": 50, + "fast": 40, + "high": 30 + }, + "vih": 1.88, + "vil": 1.23, + "hysteresis": 0.2, + "rpull": 40000, + "leak_a": 1e-07, + "slew_v_per_us": { + "low": 40, + "medium": 200, + "fast": 400, + "high": 700 + }, + "ioh_max": 0.02, + "iol_max": 0.02 + }, + "analog": { + "PA0": "ADC12_IN1", + "PA1": "ADC12_IN2", + "PA2": "ADC1_IN3", + "PA3": "ADC1_IN4", + "PA4": "ADC2_IN17", + "PA5": "ADC2_IN13", + "PA6": "ADC2_IN3", + "PA7": "ADC2_IN4", + "PA8": "ADC5_IN1", + "PA9": "ADC5_IN2", + "PB0": "ADC1_IN15, ADC3_IN12", + "PB1": "ADC1_IN12, ADC3_IN1", + "PB2": "ADC2_IN12", + "PB11": "ADC12_IN14", + "PB12": "ADC1_IN11, ADC4_IN3", + "PB13": "ADC3_IN5", + "PB14": "ADC1_IN5, ADC4_IN4", + "PB15": "ADC2_IN15, ADC4_IN5", + "PC0": "ADC12_IN6", + "PC1": "ADC12_IN7", + "PC2": "ADC12_IN8", + "PC3": "ADC12_IN9", + "PC4": "ADC2_IN5", + "PC5": "ADC2_IN11", + "PF0": "ADC1_IN10", + "PF1": "ADC2_IN10" + }, + "alternate": { + "PA0": { + "1": [ + "TIM2_CH1" + ], + "2": [ + "TIM5_CH1" + ], + "7": [ + "USART2_CTS", + "USART2_NSS" + ], + "8": [ + "COMP1_OUT" + ], + "9": [ + "TIM8_BKIN" + ], + "10": [ + "TIM8_ETR" + ], + "14": [ + "TIM2_ETR" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA1": { + "0": [ + "RTC_REFIN" + ], + "1": [ + "TIM2_CH2" + ], + "2": [ + "TIM5_CH2" + ], + "7": [ + "USART2_DE", + "USART2_RTS" + ], + "9": [ + "TIM15_CH1N" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA2": { + "1": [ + "TIM2_CH3" + ], + "2": [ + "TIM5_CH3" + ], + "7": [ + "USART2_TX" + ], + "8": [ + "COMP2_OUT" + ], + "9": [ + "TIM15_CH1" + ], + "10": [ + "QUADSPI1_BK1_NCS" + ], + "12": [ + "LPUART1_TX" + ], + "14": [ + "UCPD1_FRSTX1", + "UCPD1_FRSTX2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA3": { + "1": [ + "TIM2_CH4" + ], + "2": [ + "TIM5_CH4" + ], + "3": [ + "SAI1_CK1" + ], + "7": [ + "USART2_RX" + ], + "9": [ + "TIM15_CH2" + ], + "10": [ + "QUADSPI1_CLK" + ], + "12": [ + "LPUART1_RX" + ], + "13": [ + "SAI1_MCLK_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA4": { + "2": [ + "TIM3_CH2" + ], + "5": [ + "SPI1_NSS" + ], + "6": [ + "I2S3_WS", + "SPI3_NSS" + ], + "7": [ + "USART2_CK" + ], + "13": [ + "SAI1_FS_B" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA5": { + "1": [ + "TIM2_CH1" + ], + "2": [ + "TIM2_ETR" + ], + "5": [ + "SPI1_SCK" + ], + "14": [ + "UCPD1_FRSTX1", + "UCPD1_FRSTX2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA6": { + "1": [ + "TIM16_CH1" + ], + "2": [ + "TIM3_CH1" + ], + "4": [ + "TIM8_BKIN" + ], + "5": [ + "SPI1_MISO" + ], + "6": [ + "TIM1_BKIN" + ], + "8": [ + "COMP1_OUT" + ], + "10": [ + "QUADSPI1_BK1_IO3" + ], + "12": [ + "LPUART1_CTS" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA7": { + "1": [ + "TIM17_CH1" + ], + "2": [ + "TIM3_CH2" + ], + "4": [ + "TIM8_CH1N" + ], + "5": [ + "SPI1_MOSI" + ], + "6": [ + "TIM1_CH1N" + ], + "8": [ + "COMP2_OUT" + ], + "10": [ + "QUADSPI1_BK1_IO2" + ], + "14": [ + "UCPD1_FRSTX1", + "UCPD1_FRSTX2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA8": { + "0": [ + "RCC_MCO" + ], + "2": [ + "I2C3_SCL" + ], + "4": [ + "I2C2_SDA" + ], + "5": [ + "I2S2_MCK" + ], + "6": [ + "TIM1_CH1" + ], + "7": [ + "USART1_CK" + ], + "8": [ + "COMP7_OUT" + ], + "10": [ + "TIM4_ETR" + ], + "11": [ + "FDCAN3_RX" + ], + "12": [ + "SAI1_CK2" + ], + "13": [ + "HRTIM1_CHA1" + ], + "14": [ + "SAI1_SCK_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA9": { + "2": [ + "I2C3_SMBA" + ], + "4": [ + "I2C2_SCL" + ], + "5": [ + "I2S3_MCK" + ], + "6": [ + "TIM1_CH2" + ], + "7": [ + "USART1_TX" + ], + "8": [ + "COMP5_OUT" + ], + "9": [ + "TIM15_BKIN" + ], + "10": [ + "TIM2_CH3" + ], + "13": [ + "HRTIM1_CHA2" + ], + "14": [ + "SAI1_FS_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA10": { + "1": [ + "TIM17_BKIN" + ], + "3": [ + "CRS_SYNC" + ], + "4": [ + "I2C2_SMBA" + ], + "5": [ + "SPI2_MISO" + ], + "6": [ + "TIM1_CH3" + ], + "7": [ + "USART1_RX" + ], + "8": [ + "COMP6_OUT" + ], + "10": [ + "TIM2_CH4" + ], + "11": [ + "TIM8_BKIN" + ], + "12": [ + "SAI1_D1" + ], + "13": [ + "HRTIM1_CHB1" + ], + "14": [ + "SAI1_SD_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA11": { + "5": [ + "I2S2_SD", + "SPI2_MOSI" + ], + "6": [ + "TIM1_CH1N" + ], + "7": [ + "USART1_CTS", + "USART1_NSS" + ], + "8": [ + "COMP1_OUT" + ], + "9": [ + "FDCAN1_RX" + ], + "10": [ + "TIM4_CH1" + ], + "11": [ + "TIM1_CH4" + ], + "12": [ + "TIM1_BKIN2" + ], + "13": [ + "HRTIM1_CHB2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA12": { + "1": [ + "TIM16_CH1" + ], + "5": [ + "I2S_CKIN" + ], + "6": [ + "TIM1_CH2N" + ], + "7": [ + "USART1_DE", + "USART1_RTS" + ], + "8": [ + "COMP2_OUT" + ], + "9": [ + "FDCAN1_TX" + ], + "10": [ + "TIM4_CH2" + ], + "11": [ + "TIM1_ETR" + ], + "13": [ + "HRTIM1_FLT1" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA13": { + "0": [ + "JTMS_SWDIO" + ], + "1": [ + "TIM16_CH1N" + ], + "3": [ + "I2C4_SCL" + ], + "4": [ + "I2C1_SCL" + ], + "5": [ + "IR_OUT" + ], + "7": [ + "USART3_CTS", + "USART3_NSS" + ], + "10": [ + "TIM4_CH3" + ], + "13": [ + "SAI1_SD_B" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA14": { + "0": [ + "JTCK_SWCLK" + ], + "1": [ + "LPTIM1_OUT" + ], + "3": [ + "I2C4_SMBA" + ], + "4": [ + "I2C1_SDA" + ], + "5": [ + "TIM8_CH2" + ], + "6": [ + "TIM1_BKIN" + ], + "7": [ + "USART2_TX" + ], + "13": [ + "SAI1_FS_B" + ], + "15": [ + "EVENTOUT" + ] + }, + "PA15": { + "0": [ + "JTDI" + ], + "1": [ + "TIM2_CH1" + ], + "2": [ + "TIM8_CH1" + ], + "4": [ + "I2C1_SCL" + ], + "5": [ + "SPI1_NSS" + ], + "6": [ + "I2S3_WS", + "SPI3_NSS" + ], + "7": [ + "USART2_RX" + ], + "8": [ + "UART4_DE", + "UART4_RTS" + ], + "9": [ + "TIM1_BKIN" + ], + "11": [ + "FDCAN3_TX" + ], + "13": [ + "HRTIM1_FLT2" + ], + "14": [ + "TIM2_ETR" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB0": { + "2": [ + "TIM3_CH3" + ], + "4": [ + "TIM8_CH2N" + ], + "6": [ + "TIM1_CH2N" + ], + "10": [ + "QUADSPI1_BK1_IO1" + ], + "13": [ + "HRTIM1_FLT5" + ], + "14": [ + "UCPD1_FRSTX1", + "UCPD1_FRSTX2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB1": { + "2": [ + "TIM3_CH4" + ], + "4": [ + "TIM8_CH3N" + ], + "6": [ + "TIM1_CH3N" + ], + "8": [ + "COMP4_OUT" + ], + "10": [ + "QUADSPI1_BK1_IO0" + ], + "12": [ + "LPUART1_DE", + "LPUART1_RTS" + ], + "13": [ + "HRTIM1_SCOUT" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB2": { + "0": [ + "RTC_OUT2" + ], + "1": [ + "LPTIM1_OUT" + ], + "2": [ + "TIM5_CH1" + ], + "3": [ + "TIM20_CH1" + ], + "4": [ + "I2C3_SMBA" + ], + "10": [ + "QUADSPI1_BK2_IO1" + ], + "13": [ + "HRTIM1_SCIN" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB3": { + "0": [ + "JTDO_SWO" + ], + "1": [ + "TIM2_CH2" + ], + "2": [ + "TIM4_ETR" + ], + "3": [ + "CRS_SYNC" + ], + "4": [ + "TIM8_CH1N" + ], + "5": [ + "SPI1_SCK" + ], + "6": [ + "I2S3_CK", + "SPI3_SCK" + ], + "7": [ + "USART2_TX" + ], + "10": [ + "TIM3_ETR" + ], + "11": [ + "FDCAN3_RX" + ], + "12": [ + "HRTIM1_SCOUT" + ], + "13": [ + "HRTIM1_EEV9" + ], + "14": [ + "SAI1_SCK_B" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB4": { + "0": [ + "JTRST" + ], + "1": [ + "TIM16_CH1" + ], + "2": [ + "TIM3_CH1" + ], + "4": [ + "TIM8_CH2N" + ], + "5": [ + "SPI1_MISO" + ], + "6": [ + "SPI3_MISO" + ], + "7": [ + "USART2_RX" + ], + "8": [ + "UART5_DE", + "UART5_RTS" + ], + "10": [ + "TIM17_BKIN" + ], + "11": [ + "FDCAN3_TX" + ], + "13": [ + "HRTIM1_EEV7" + ], + "14": [ + "SAI1_MCLK_B" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB5": { + "1": [ + "TIM16_BKIN" + ], + "2": [ + "TIM3_CH2" + ], + "3": [ + "TIM8_CH3N" + ], + "4": [ + "I2C1_SMBA" + ], + "5": [ + "SPI1_MOSI" + ], + "6": [ + "I2S3_SD", + "SPI3_MOSI" + ], + "7": [ + "USART2_CK" + ], + "8": [ + "I2C3_SDA" + ], + "9": [ + "FDCAN2_RX" + ], + "10": [ + "TIM17_CH1" + ], + "11": [ + "LPTIM1_IN1" + ], + "12": [ + "SAI1_SD_B" + ], + "13": [ + "HRTIM1_EEV6" + ], + "14": [ + "UART5_CTS" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB6": { + "1": [ + "TIM16_CH1N" + ], + "2": [ + "TIM4_CH1" + ], + "5": [ + "TIM8_CH1" + ], + "6": [ + "TIM8_ETR" + ], + "7": [ + "USART1_TX" + ], + "8": [ + "COMP4_OUT" + ], + "9": [ + "FDCAN2_TX" + ], + "10": [ + "TIM8_BKIN2" + ], + "11": [ + "LPTIM1_ETR" + ], + "12": [ + "HRTIM1_SCIN" + ], + "13": [ + "HRTIM1_EEV4" + ], + "14": [ + "SAI1_FS_B" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB7": { + "1": [ + "TIM17_CH1N" + ], + "2": [ + "TIM4_CH2" + ], + "3": [ + "I2C4_SDA" + ], + "4": [ + "I2C1_SDA" + ], + "5": [ + "TIM8_BKIN" + ], + "7": [ + "USART1_RX" + ], + "8": [ + "COMP3_OUT" + ], + "10": [ + "TIM3_CH4" + ], + "11": [ + "LPTIM1_IN2" + ], + "12": [ + "FMC_NL" + ], + "13": [ + "HRTIM1_EEV3" + ], + "14": [ + "UART4_CTS" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB8": { + "1": [ + "TIM16_CH1" + ], + "2": [ + "TIM4_CH3" + ], + "3": [ + "SAI1_CK1" + ], + "4": [ + "I2C1_SCL" + ], + "7": [ + "USART3_RX" + ], + "8": [ + "COMP1_OUT" + ], + "9": [ + "FDCAN1_RX" + ], + "10": [ + "TIM8_CH2" + ], + "12": [ + "TIM1_BKIN" + ], + "13": [ + "HRTIM1_EEV8" + ], + "14": [ + "SAI1_MCLK_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB9": { + "1": [ + "TIM17_CH1" + ], + "2": [ + "TIM4_CH4" + ], + "3": [ + "SAI1_D2" + ], + "4": [ + "I2C1_SDA" + ], + "6": [ + "IR_OUT" + ], + "7": [ + "USART3_TX" + ], + "8": [ + "COMP2_OUT" + ], + "9": [ + "FDCAN1_TX" + ], + "10": [ + "TIM8_CH3" + ], + "12": [ + "TIM1_CH3N" + ], + "13": [ + "HRTIM1_EEV5" + ], + "14": [ + "SAI1_FS_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB10": { + "1": [ + "TIM2_CH3" + ], + "7": [ + "USART3_TX" + ], + "8": [ + "LPUART1_RX" + ], + "10": [ + "QUADSPI1_CLK" + ], + "12": [ + "TIM1_BKIN" + ], + "13": [ + "HRTIM1_FLT3" + ], + "14": [ + "SAI1_SCK_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB11": { + "1": [ + "TIM2_CH4" + ], + "7": [ + "USART3_RX" + ], + "8": [ + "LPUART1_TX" + ], + "10": [ + "QUADSPI1_BK1_NCS" + ], + "13": [ + "HRTIM1_FLT4" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB12": { + "2": [ + "TIM5_ETR" + ], + "4": [ + "I2C2_SMBA" + ], + "5": [ + "I2S2_WS", + "SPI2_NSS" + ], + "6": [ + "TIM1_BKIN" + ], + "7": [ + "USART3_CK" + ], + "8": [ + "LPUART1_DE", + "LPUART1_RTS" + ], + "9": [ + "FDCAN2_RX" + ], + "13": [ + "HRTIM1_CHC1" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB13": { + "5": [ + "I2S2_CK", + "SPI2_SCK" + ], + "6": [ + "TIM1_CH1N" + ], + "7": [ + "USART3_CTS", + "USART3_NSS" + ], + "8": [ + "LPUART1_CTS" + ], + "9": [ + "FDCAN2_TX" + ], + "13": [ + "HRTIM1_CHC2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB14": { + "1": [ + "TIM15_CH1" + ], + "5": [ + "SPI2_MISO" + ], + "6": [ + "TIM1_CH2N" + ], + "7": [ + "USART3_DE", + "USART3_RTS" + ], + "8": [ + "COMP4_OUT" + ], + "13": [ + "HRTIM1_CHD1" + ], + "15": [ + "EVENTOUT" + ] + }, + "PB15": { + "0": [ + "RTC_REFIN" + ], + "1": [ + "TIM15_CH2" + ], + "2": [ + "TIM15_CH1N" + ], + "3": [ + "COMP3_OUT" + ], + "4": [ + "TIM1_CH3N" + ], + "5": [ + "I2S2_SD", + "SPI2_MOSI" + ], + "13": [ + "HRTIM1_CHD2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC0": { + "1": [ + "LPTIM1_IN1" + ], + "2": [ + "TIM1_CH1" + ], + "8": [ + "LPUART1_RX" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC1": { + "1": [ + "LPTIM1_OUT" + ], + "2": [ + "TIM1_CH2" + ], + "8": [ + "LPUART1_TX" + ], + "10": [ + "QUADSPI1_BK2_IO0" + ], + "13": [ + "SAI1_SD_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC2": { + "1": [ + "LPTIM1_IN2" + ], + "2": [ + "TIM1_CH3" + ], + "3": [ + "COMP3_OUT" + ], + "6": [ + "TIM20_CH2" + ], + "10": [ + "QUADSPI1_BK2_IO1" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC3": { + "0": [ + "SLEEP" + ], + "1": [ + "LPTIM1_ETR" + ], + "2": [ + "TIM1_CH4" + ], + "3": [ + "SAI1_D1" + ], + "6": [ + "TIM1_BKIN2" + ], + "10": [ + "QUADSPI1_BK2_IO2" + ], + "13": [ + "SAI1_SD_A" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC4": { + "2": [ + "TIM1_ETR" + ], + "4": [ + "I2C2_SCL" + ], + "7": [ + "USART1_TX" + ], + "10": [ + "QUADSPI1_BK2_IO3" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC5": { + "2": [ + "TIM15_BKIN" + ], + "3": [ + "SAI1_D3" + ], + "6": [ + "TIM1_CH4N" + ], + "7": [ + "USART1_RX" + ], + "13": [ + "HRTIM1_EEV10" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC6": { + "2": [ + "TIM3_CH1" + ], + "3": [ + "HRTIM1_EEV10" + ], + "4": [ + "TIM8_CH1" + ], + "6": [ + "I2S2_MCK" + ], + "7": [ + "COMP6_OUT" + ], + "8": [ + "I2C4_SCL" + ], + "13": [ + "HRTIM1_CHF1" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC7": { + "2": [ + "TIM3_CH2" + ], + "3": [ + "HRTIM1_FLT5" + ], + "4": [ + "TIM8_CH2" + ], + "6": [ + "I2S3_MCK" + ], + "7": [ + "COMP5_OUT" + ], + "8": [ + "I2C4_SDA" + ], + "13": [ + "HRTIM1_CHF2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC8": { + "2": [ + "TIM3_CH3" + ], + "3": [ + "HRTIM1_CHE1" + ], + "4": [ + "TIM8_CH3" + ], + "6": [ + "TIM20_CH3" + ], + "7": [ + "COMP7_OUT" + ], + "8": [ + "I2C3_SCL" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC9": { + "2": [ + "TIM3_CH4" + ], + "3": [ + "HRTIM1_CHE2" + ], + "4": [ + "TIM8_CH4" + ], + "5": [ + "I2S_CKIN" + ], + "6": [ + "TIM8_BKIN2" + ], + "8": [ + "I2C3_SDA" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC10": { + "4": [ + "TIM8_CH1N" + ], + "5": [ + "UART4_TX" + ], + "6": [ + "I2S3_CK", + "SPI3_SCK" + ], + "7": [ + "USART3_TX" + ], + "13": [ + "HRTIM1_FLT6" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC11": { + "3": [ + "HRTIM1_EEV2" + ], + "4": [ + "TIM8_CH2N" + ], + "5": [ + "UART4_RX" + ], + "6": [ + "SPI3_MISO" + ], + "7": [ + "USART3_RX" + ], + "8": [ + "I2C3_SDA" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC12": { + "1": [ + "TIM5_CH2" + ], + "3": [ + "HRTIM1_EEV1" + ], + "4": [ + "TIM8_CH3N" + ], + "5": [ + "UART5_TX" + ], + "6": [ + "I2S3_SD", + "SPI3_MOSI" + ], + "7": [ + "USART3_CK" + ], + "14": [ + "UCPD1_FRSTX1", + "UCPD1_FRSTX2" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC13": { + "2": [ + "TIM1_BKIN" + ], + "4": [ + "TIM1_CH1N" + ], + "6": [ + "TIM8_CH4N" + ], + "15": [ + "EVENTOUT" + ] + }, + "PC14": { + "15": [ + "EVENTOUT" + ] + }, + "PC15": { + "15": [ + "EVENTOUT" + ] + }, + "PD2": { + "2": [ + "TIM3_ETR" + ], + "4": [ + "TIM8_BKIN" + ], + "5": [ + "UART5_RX" + ], + "15": [ + "EVENTOUT" + ] + }, + "PF0": { + "4": [ + "I2C2_SDA" + ], + "5": [ + "I2S2_WS", + "SPI2_NSS" + ], + "6": [ + "TIM1_CH3N" + ], + "15": [ + "EVENTOUT" + ] + }, + "PF1": { + "5": [ + "I2S2_CK", + "SPI2_SCK" + ], + "15": [ + "EVENTOUT" + ] + }, + "PG10": { + "0": [ + "RCC_MCO" + ], + "15": [ + "EVENTOUT" + ] + } + } + }, + "signals": [ + "VBAT", + "PC13", + "PC14", + "PC15", + "PF0", + "PF1", + "NRST", + "PC0", + "PC1", + "PC2", + "PC3", + "PA0", + "PA1", + "PA2", + "VSS", + "VDD", + "PA3", + "PA4", + "PA5", + "PA6", + "PA7", + "PC4", + "PC5", + "PB0", + "PB1", + "PB2", + "VSSA", + "VREFP", + "VDDA", + "PB10", + "PB11", + "PB12", + "PB13", + "PB14", + "PB15", + "PC6", + "PC7", + "PC8", + "PC9", + "PA8", + "PA9", + "PA10", + "PA11", + "PA12", + "PA13", + "PA14", + "PA15", + "PC10", + "PC11", + "PC12", + "PD2", + "PB3", + "PB4", + "PB5", + "PB6", + "PB7", + "PB8", + "PB9" + ], + "packages": { + "lqfp64": "lqfp64.json" + }, + "console": { + "default": "LPUART1" + }, + "fidelity": { + "functional": { + "claims": "Cortex-M4F instruction execution (Thumb-2 with ARMv7E-M's DSP instructions, FPv4-SP, NVIC with 4 priority bits, SCB, SysTick on HCLK/8, DWT, the MPU with eight regions, lazy floating-point context stacking, semihosting); every register of ST's STM32G474 SVD at its address with its reset value and access type, corrected where RM0440, the CMSIS header or the HAL differ (tools/importers/stm32g474_regs.sh lists the corrections); the memory map (512 KiB of dual-bank flash, SRAM1, SRAM2 and the CCM SRAM at 0x20018000 and its alias at 0x10000000, the system memory, OTP, the engineering bytes with the unique ID, flash size and calibration values, both banks' option bytes, the FDCAN message RAM and the USB packet memory). RCC (rcc_g4.c): HSI16, HSE ready only as the board drives OSC_IN (a crystal without HSEBYP, a clock with it), LSI, LSE and HSI48, each ready its start-up time after it is enabled, LSE kept through every reset but a power-on one; the main PLL from HSI16 or HSE (M, N, P with PLLPDIV, Q, R and their enables), SYSCLK from HSI16, HSE or PLLR switched once ready (SWS), HPRE, PPRE1, PPRE2 and the timers' clock; what the system clock uses cannot be turned off, HSEBYP is kept while HSE is on, BDCR is written only with PWR's DBP and BDRST resets the RTC and TAMP; CIER, CIFR and CICR's ready interrupts; the kernel clocks CCIPR and CCIPR2 select for the U(S)ARTs and LPUART, I2Cs, LPTIM1, SAI1, I2S, FDCAN, the 48 MHz clock, the ADCs and the QUADSPI; MCO's frequency; the peripherals' clock enables (their registers read 0 and ignore writes while off, mcu.clock_gated) and resets; RCC_CSR's reset flags (PINRSTF, BORRSTF, SFTRSTF, IWDGRSTF, WWDGRSTF, LPWRRSTF, OBLRSTF) until RMVF; a VCO, PLL output or SYSCLK outside DS12288's and the voltage range's limits and too few flash wait states for HCLK are reported (mcu.clock_out_of_spec, mcu.flash_wait_states, RM0440 table 9). PWR (pwr_g4.c): the voltage ranges and range 1's boost mode (CR5.R1MODE) bounding SYSCLK, low-power run's REGLPF, the PVD (PVDO against VDD, or PB7 against VREFINT, on EXTI line 16); Stop 0 and Stop 1 (the core's domain's clocks stopped but the RTC's and IWDG's, HSE and the PLL off, an EXTI line's interrupt or event waking the part on HSI16), Standby (RAM lost but SRAM2 with RRS, the pins let go but the pulls CR3.APC keeps from PUCRx/PDCRx and the wake-up pins', a wake-up pin's edge of CR4's polarity, an internal wake-up, NRST or the IWDG ending it with a reset, SR1.SBF), Shutdown (SRAM2 lost too, left through a brownout reset), the option bytes' nRST_STOP, nRST_STDBY and nRST_SHDW. FLASH (flash_g4.c): KEYR's and OPTKEYR's unlock, double-word programming with SIZERR, PGAERR, PGSERR, PROGERR and WRPERR, fast programming of 256-byte rows with MISSERR, page and bank erases, EOP and the error interrupt, BSY for DS12288's typical times, a program running from the bank under operation stalled while the other bank reads on (read-while-write), the option bytes with their complements (OPTVERR on a mismatch) loaded at each reset, OPTSTRT and OBL_LAUNCH's reset, the WRP areas, BOOT0 from PB8 or nBOOT0 with nSWBOOT0 (a system-memory boot reported, mcu.boot_mode), ACR's wait states, prefetch and caches as the fetch timing. GPIO (gpio_f4.c): MODER, OTYPER, OSPEEDR, PUPDR, IDR, ODR, BSRR, BRR, LCKR's lock, AFRL/AFRH choosing among io.alternate's functions, converted from ST's open pin data; SYSCFG's EXTICR, MEMRMP's boot remap and SCSR's CCM SRAM erase; EXTI (exti.c) in two banks: the configurable lines' edges, SWIER, PR, IMR and EMR, their interrupts by line, the direct lines as events. USART1-3, UART4-5 and LPUART1 (usart_v2.c): 7, 8 or 9 bits with parity, the stop bits, MSBFIRST and DATAINV on the line, PRESC and the kernel clock, OVER8, an LPUART's 256 x clock / BRR; TEACK and REACK, the 8-frame FIFOs with their thresholds and flags, TXE/TC, RXNE, ORE (or OVRDIS), PE, FE, IDLE, CMF, RTOF, break and LIN's LBDF, mute mode, nCTS and nRTS, DE for RS-485, SWAP, half-duplex, the synchronous master's CK, wake-up from Stop on HSI16 or LSE, DMA requests, every interrupt; the frames on the TX pin's waveform and decoded from the RX pin. The timers (tim.c, the F4's IP: time base, output compare and PWM, input capture with filters, complementary outputs with dead time and break, the slave modes and encoder, TRGO) with TISEL's internal clocks on TI1 (TIM16 and TIM17: LSI, LSE, HSE/32, MCO; TIM5: LSI, LSE; TIM15: LSE), DBGMCU's freeze bits by name; the programmable CRC (crc.c: POLYSIZE, POL, INIT, REV_IN, REV_OUT); the IWDG with its window (WINR) and the option bytes' hardware start and Stop/Standby freeze, the WWDG with WDGTB's three bits (wdg.c); DMA1 and DMA2 with DMAMUX (dma_g4.c): eight channels each, one item a request or memory to memory, PSIZE and MSIZE packed and unpacked as RM0440's table 89 gives, PINC, MINC, circular mode, HTIF, TCIF, TEIF and GIF with their interrupts, the bits locked while EN is set, a bus error clearing EN until TEIF is cleared; DMAMUX's sixteen channels taking any of the 115 request lines (DMAREQ_ID), synchronisation on an EXTI line or a channel's event (SE, SPOL, SYNC_ID, NBREQ, SOF), event generation (EGE), the four request generators (SIG_ID, GPOL, GNBREQ, OF) and DMAMUX_OVR; SPI1 to SPI4 (spi.c, the FIFO SPI): master and slave in the four modes, 4 to 16-bit frames (DS, 8 bits forced for the values not used), the 32-bit transmit and receive FIFOs (TXE at half, RXNE at FRXTH's threshold, FTLVL, FRLVL, OVR when full), 8-bit and 16-bit (packed) accesses to DR, LDMA_TX and LDMA_RX for an odd DMA count, CRC8 or CRC16 (CRCL, two frames after 8-bit data), the TI mode, NSSP's pulse, simplex and half duplex, MODF, the DMA requests; DBGMCU's IDCODE (0x469) and freeze registers.", + "omissions": [ + "the peripherals coverage.md lists as missing keep their register values and raise mcu.unsupported_access: the ADCs, DACs, comparators, op-amps and VREFBUF, the I2Cs, RTC and TAMP, LPTIM1, RNG, CORDIC, FMAC, CRS, the FDCANs, USB, UCPD, HRTIM, QUADSPI, SAI and FMC", + "the timers' G4 additions: OCxM's fourth bit (retriggerable one-pulse, combined and asymmetric PWM), SMS's fourth bit (combined reset and trigger, the extended encoder modes), the internal trigger inputs ITR4 to ITR10 and TS's fifth bit, MMS's fourth bit, channels 5 and 6, dithering (DITHEN: ARR and CCRx read as their 16 integer bits), UIFREMAP, the encoder index (ECR), the asymmetric dead times (DTR2), break 2, the comparators on TISEL and AF1/AF2's break sources, the G4's ITR interconnection table (the F4's is used)", + "the start-up times, flash times and PVD thresholds are DS12288 Rev 6's typical values (HSI16 0.8 us, an HSE crystal 2 ms, LSI 80 us, LSE 2 s, HSI48 2.5 us, the PLL's lock 15 us; a double word 81.7 us, a fast row 1.91 ms, a page erase 22.02 ms, a bank erase 22.13 ms; the PVD's thresholds), not their spread between parts or their dependence on temperature", + "RCC: the clock security systems (CSSON, LSECSSON: the oscillators never fail), LSEDRV, HSITRIM and HSI48CAL's effect on the frequencies, the CRS's trimming, a peripheral held in reset while its *RSTR bit stays set, the brownout reset (BORRSTF only at power-on), the sleep-mode enables (*SMENR), MCO and LSCO on their pins", + "PWR: the regulator's settling (VOSF never set) and the wake-up times, the supply currents, the PVMs (VDDA is VDD), UCPD's dead-battery bits, VBAT charging", + "FLASH: the option bytes' programming time, the read protection's levels and their mass erase, PCROP and the securable area, ECC, the bank swap (BFB2, FB_MODE), the boot from SRAM, the power-down modes, the caches' real line length", + "USART: noise detection (NE never sets, ONEBIT does nothing), auto baud rate detection, TXINV and RXINV, DE's assertion and deassertion times (DEAT, DEDT), the synchronous slave, smartcard and IrDA modes, TCBGT", + "SYSCFG: SWPR's write protection of the CCM SRAM, its erase time, the parity errors CFGR2 reports; EXTI: the internal lines' sources but PVD's; GPIO: EVENTOUT, the I/O compensation, the 5 V tolerant pins' clamps", + "the I/O thresholds are DS12288's typical characteristics (0.39 x VDD - 0.06 and 0.49 x VDD + 0.26, 200 mV of hysteresis, 40 kOhm pulls), not the guaranteed 0.3 and 0.7 x VDD; the output resistances and edge rates are the F446's", + "SPI: I2S (I2SCFGR keeps its value), the multimaster arbitration a MODF serves beyond the fault", "DMA: the arbitration's delays and the bus matrix's timing (a request is served at once, a memory-to-memory item every two cycles), the DMAMUX inputs' two-cycle filter and the three cycles a CxCR or RGxCR write masks them for, the byte and half-word lanes duplicated for an APB peripheral that ignores the size, LPTIM1_OUT as a trigger and synchronisation input (LPTIM1 is not modelled)", "DBGMCU's REV_ID 0x2001 (revision Z: which revision a board carries varies, UM2505 10.1); a halted core draws its sleep current" + ], + "validation": [ + "repo:tests/unit/test_stm32g4.c", + "repo:tests/vendor/stm32cubeg4" + ] + }, + "timed": { + "claims": "As functional, with the Cortex-M4's cycle counts as the core gives them (estimated tier), the flash's wait states, prefetch and caches charged on fetches, and the peripherals' times at their clocks.", + "omissions": [ + "as functional" + ], + "validation": [ + "repo:tests/unit/test_stm32g4.c", + "repo:tests/vendor/stm32cubeg4" + ] + } + }, + "provenance": { + "author": "EmbSIM", + "license": "Apache-2.0", + "sources": [ + { + "title": "RM0440 Reference manual: STM32G4 Series advanced Arm-based 32-bit MCUs", + "rev": "9" + }, + { + "title": "STM32G474xB/xC/xE datasheet (DS12288)", + "rev": "6" + }, + { + "title": "PM0214 Programming manual: STM32 Cortex-M4 MCUs and MPUs" + }, + { + "title": "STMicroelectronics STM32G474.svd 3.0 (STM32G4 SVD pack), Apache-2.0, as archived by modm-io/cmsis-svd-stm32" + }, + { + "title": "STMicroelectronics STM32_open_pin_data 7d1f151, STM32G474R(B-C-E)Tx.xml and GPIO-STM32G47x_gpio_v1_0_Modes.xml, BSD-3-Clause" + }, + { + "title": "STMicroelectronics STM32CubeG4 (BSD-3-Clause): the HAL's DMA request numbers (stm32g4xx_hal_dma.h) transcribed into dma_requests, its EXTI line types (stm32g4xx_hal_exti.h) and the CMSIS device header stm32g474xx.h, against which the converted register description was checked field by field" + } + ] + }, + "i18n": { + "fr": { + "source": "05964646b243", + "description": "STMicroelectronics STM32G474RE : un Arm Cortex-M4F jusqu'ร  170 MHz avec MPU, 512 Kio de flash ร  double banc, 128 Kio de SRAM (80 Kio de SRAM1, 16 Kio de SRAM2, 32 Kio de CCM SRAM), ses accรฉlรฉrateurs mathรฉmatiques, son timer haute rรฉsolution et sa chaรฎne analogique, en LQFP64 ; le MCU de la NUCLEO-G474RE.", + "fidelity": { + "functional": { + "claims": "Exรฉcution des instructions Cortex-M4F (Thumb-2 avec les instructions DSP de l'ARMv7E-M, FPv4-SP, NVIC ร  4 bits de prioritรฉ, SCB, SysTick sur HCLK/8, DWT, la MPU ร  huit rรฉgions, l'empilement paresseux du contexte flottant, le semihosting) ; chaque registre du SVD STM32G474 de ST ร  son adresse avec sa valeur de reset et son type d'accรจs, corrigรฉ lร  oรน le RM0440, l'en-tรชte CMSIS ou la HAL diffรจrent (tools/importers/stm32g474_regs.sh liste les corrections) ; la carte mรฉmoire (512 Kio de flash ร  double banc, la SRAM1, la SRAM2 et la CCM SRAM ร  0x20018000 et son alias ร  0x10000000, la mรฉmoire systรจme, l'OTP, les octets d'ingรฉnierie avec l'identifiant unique, la taille de la flash et les valeurs d'รฉtalonnage, les octets d'option des deux bancs, la RAM de messages des FDCAN et la mรฉmoire de paquets de l'USB). RCC (rcc_g4.c) : HSI16, HSE prรชt seulement si la carte pilote OSC_IN (un quartz sans HSEBYP, une horloge avec), LSI, LSE et HSI48, chacun prรชt aprรจs son temps de dรฉmarrage une fois activรฉ, LSE conservรฉ ร  travers tout reset sauf la mise sous tension ; la PLL principale depuis HSI16 ou HSE (M, N, P avec PLLPDIV, Q, R et leurs activations), SYSCLK depuis HSI16, HSE ou PLLR, basculรฉ une fois prรชt (SWS), HPRE, PPRE1, PPRE2 et l'horloge des timers ; ce qu'utilise l'horloge systรจme ne peut รชtre รฉteint, HSEBYP est conservรฉ tant que HSE est allumรฉ, BDCR n'est รฉcrit qu'avec le DBP du PWR et BDRST rรฉinitialise le RTC et le TAMP ; les interruptions de disponibilitรฉ de CIER, CIFR et CICR ; les horloges noyau que sรฉlectionnent CCIPR et CCIPR2 pour les U(S)ART et le LPUART, les I2C, le LPTIM1, le SAI1, l'I2S, les FDCAN, l'horloge 48 MHz, les ADC et le QUADSPI ; la frรฉquence du MCO ; les activations d'horloge des pรฉriphรฉriques (leurs registres lisent 0 et ignorent les รฉcritures quand elle est coupรฉe, mcu.clock_gated) et leurs resets ; les indicateurs de reset de RCC_CSR (PINRSTF, BORRSTF, SFTRSTF, IWDGRSTF, WWDGRSTF, LPWRRSTF, OBLRSTF) jusqu'ร  RMVF ; un VCO, une sortie de PLL ou un SYSCLK hors des limites du DS12288 et de la plage de tension, et trop peu d'รฉtats d'attente de la flash pour HCLK, sont signalรฉs (mcu.clock_out_of_spec, mcu.flash_wait_states, table 9 du RM0440). PWR (pwr_g4.c) : les plages de tension et le mode boost de la plage 1 (CR5.R1MODE) qui bornent SYSCLK, le REGLPF du low-power run, le PVD (PVDO face ร  VDD, ou PB7 face ร  VREFINT, sur la ligne EXTI 16) ; Stop 0 et Stop 1 (les horloges du domaine du cล“ur arrรชtรฉes sauf celles du RTC et de l'IWDG, HSE et la PLL รฉteints, l'interruption ou l'รฉvรฉnement d'une ligne EXTI rรฉveillant la puce sur HSI16), Standby (la RAM perdue sauf la SRAM2 avec RRS, les broches relรขchรฉes sauf les tirages que CR3.APC conserve depuis PUCRx/PDCRx et ceux des broches de rรฉveil, un front de broche de rรฉveil de la polaritรฉ de CR4, un rรฉveil interne, NRST ou l'IWDG y mettant fin par un reset, SR1.SBF), Shutdown (la SRAM2 perdue aussi, quittรฉ par un reset de brownout), les nRST_STOP, nRST_STDBY et nRST_SHDW des octets d'option. FLASH (flash_g4.c) : le dรฉverrouillage par KEYR et OPTKEYR, la programmation par double mot avec SIZERR, PGAERR, PGSERR, PROGERR et WRPERR, la programmation rapide de rangรฉes de 256 octets avec MISSERR, les effacements de page et de banc, EOP et l'interruption d'erreur, BSY pendant les temps typiques du DS12288, un programme qui s'exรฉcute depuis le banc en opรฉration bloquรฉ tandis que l'autre banc reste lisible (lecture pendant l'รฉcriture), les octets d'option avec leurs complรฉments (OPTVERR en cas de discordance) chargรฉs ร  chaque reset, OPTSTRT et le reset d'OBL_LAUNCH, les zones WRP, BOOT0 depuis PB8 ou nBOOT0 selon nSWBOOT0 (un dรฉmarrage sur la mรฉmoire systรจme signalรฉ, mcu.boot_mode), les รฉtats d'attente, le prefetch et les caches d'ACR dans le minutage des lectures d'instructions. GPIO (gpio_f4.c) : MODER, OTYPER, OSPEEDR, PUPDR, IDR, ODR, BSRR, BRR, le verrouillage de LCKR, AFRL/AFRH choisissant parmi les fonctions d'io.alternate, converties des donnรฉes de broches ouvertes de ST ; l'EXTICR du SYSCFG, le remappage de dรฉmarrage de MEMRMP et l'effacement de la CCM SRAM par SCSR ; l'EXTI (exti.c) en deux bancs : les fronts des lignes configurables, SWIER, PR, IMR et EMR, leurs interruptions par ligne, les lignes directes comme รฉvรฉnements. USART1-3, UART4-5 et LPUART1 (usart_v2.c) : 7, 8 ou 9 bits avec paritรฉ, les bits de stop, MSBFIRST et DATAINV sur la ligne, PRESC et l'horloge noyau, OVER8, le 256 x horloge / BRR d'un LPUART ; TEACK et REACK, les FIFO de 8 trames avec leurs seuils et indicateurs, TXE/TC, RXNE, ORE (ou OVRDIS), PE, FE, IDLE, CMF, RTOF, le break et le LBDF du LIN, le mode muet, nCTS et nRTS, DE pour le RS-485, SWAP, le half-duplex, le CK du maรฎtre synchrone, le rรฉveil depuis Stop sur HSI16 ou LSE, les requรชtes DMA, toutes les interruptions ; les trames sur la forme d'onde de la broche TX et dรฉcodรฉes depuis la broche RX. Les timers (tim.c, l'IP du F4 : base de temps, comparaison de sortie et PWM, capture d'entrรฉe avec filtres, sorties complรฉmentaires avec temps mort et break, les modes esclaves et le codeur, TRGO) avec les horloges internes de TISEL sur TI1 (TIM16 et TIM17 : LSI, LSE, HSE/32, MCO ; TIM5 : LSI, LSE ; TIM15 : LSE), les bits de gel du DBGMCU trouvรฉs par leur nom ; le CRC programmable (crc.c : POLYSIZE, POL, INIT, REV_IN, REV_OUT) ; l'IWDG avec sa fenรชtre (WINR), le dรฉmarrage matรฉriel et le gel en Stop/Standby des octets d'option, le WWDG avec les trois bits de WDGTB (wdg.c) ; DMA1 et DMA2 avec le DMAMUX (dma_g4.c) : huit canaux chacun, un รฉlรฉment par requรชte ou de mรฉmoire ร  mรฉmoire, PSIZE et MSIZE assemblรฉs et dรฉsassemblรฉs comme le donne la table 89 du RM0440, PINC, MINC, le mode circulaire, HTIF, TCIF, TEIF et GIF avec leurs interruptions, les bits verrouillรฉs tant qu'EN est ร  1, une erreur de bus remettant EN ร  0 jusqu'ร  ce que TEIF soit effacรฉ ; les seize canaux du DMAMUX prenant n'importe laquelle des 115 lignes de requรชte (DMAREQ_ID), la synchronisation sur une ligne EXTI ou l'รฉvรฉnement d'un canal (SE, SPOL, SYNC_ID, NBREQ, SOF), la gรฉnรฉration d'รฉvรฉnements (EGE), les quatre gรฉnรฉrateurs de requรชtes (SIG_ID, GPOL, GNBREQ, OF) et DMAMUX_OVR ; SPI1 ร  SPI4 (spi.c, le SPI ร  FIFO) : maรฎtre et esclave dans les quatre modes, trames de 4 ร  16 bits (DS, 8 bits imposรฉs pour les valeurs inutilisรฉes), les FIFO d'รฉmission et de rรฉception de 32 bits (TXE ร  la moitiรฉ, RXNE au seuil de FRXTH, FTLVL, FRLVL, OVR quand elle est pleine), les accรจs de 8 et 16 bits (empaquetรฉs) ร  DR, LDMA_TX et LDMA_RX pour un nombre impair de transferts DMA, le CRC8 ou CRC16 (CRCL, deux trames aprรจs des donnรฉes de 8 bits), le mode TI, l'impulsion de NSSP, le simplex et le half duplex, MODF, les requรชtes DMA ; l'IDCODE du DBGMCU (0x469) et ses registres de gel.", + "omissions": [ + "les pรฉriphรฉriques que coverage.md indique manquants gardent leurs valeurs de registre et lรจvent mcu.unsupported_access : les ADC, DAC, comparateurs, amplis op et VREFBUF, les I2C, RTC et TAMP, LPTIM1, RNG, CORDIC, FMAC, CRS, les FDCAN, l'USB, l'UCPD, le HRTIM, le QUADSPI, le SAI et le FMC", + "les ajouts G4 des timers : le quatriรจme bit d'OCxM (one-pulse redรฉclenchable, PWM combinรฉe et asymรฉtrique), le quatriรจme bit de SMS (reset et dรฉclenchement combinรฉs, les modes codeur รฉtendus), les entrรฉes de dรฉclenchement internes ITR4 ร  ITR10 et le cinquiรจme bit de TS, le quatriรจme bit de MMS, les canaux 5 et 6, le dithering (DITHEN : ARR et CCRx lus comme leurs 16 bits entiers), UIFREMAP, l'index du codeur (ECR), les temps morts asymรฉtriques (DTR2), le break 2, les comparateurs sur TISEL et les sources de break d'AF1/AF2, la table d'interconnexion ITR du G4 (celle du F4 est utilisรฉe)", + "les temps de dรฉmarrage, les temps de la flash et les seuils du PVD sont les valeurs typiques du DS12288 Rev 6 (HSI16 0,8 ยตs, un quartz HSE 2 ms, LSI 80 ยตs, LSE 2 s, HSI48 2,5 ยตs, le verrouillage de la PLL 15 ยตs ; un double mot 81,7 ยตs, une rangรฉe rapide 1,91 ms, l'effacement d'une page 22,02 ms, celui d'un banc 22,13 ms ; les seuils du PVD), pas leur dispersion d'une puce ร  l'autre ni leur dรฉpendance ร  la tempรฉrature", + "RCC : les systรจmes de sรฉcuritรฉ d'horloge (CSSON, LSECSSON : les oscillateurs ne tombent jamais en panne), LSEDRV, l'effet de HSITRIM et HSI48CAL sur les frรฉquences, l'ajustement par le CRS, un pรฉriphรฉrique maintenu en reset tant que son bit *RSTR reste ร  1, le reset de brownout (BORRSTF seulement ร  la mise sous tension), les activations du mode sommeil (*SMENR), MCO et LSCO sur leurs broches", + "PWR : l'รฉtablissement du rรฉgulateur (VOSF jamais ร  1) et les temps de rรฉveil, les courants d'alimentation, les PVM (VDDA vaut VDD), les bits de batterie morte de l'UCPD, la charge de VBAT", + "FLASH : le temps de programmation des octets d'option, les niveaux de protection en lecture et leur effacement total, le PCROP et la zone sรฉcurisable, l'ECC, l'รฉchange de bancs (BFB2, FB_MODE), le dรฉmarrage depuis la SRAM, les modes basse consommation, la vraie longueur de ligne des caches", + "USART : la dรฉtection de bruit (NE jamais ร  1, ONEBIT sans effet), la dรฉtection automatique du dรฉbit, TXINV et RXINV, les temps d'assertion et de dรฉsassertion de DE (DEAT, DEDT), l'esclave synchrone, les modes carte ร  puce et IrDA, TCBGT", + "SYSCFG : la protection en รฉcriture des pages de la CCM SRAM par SWPR, le temps de son effacement, les erreurs de paritรฉ que signale CFGR2 ; EXTI : les sources des lignes internes sauf celle du PVD ; GPIO : EVENTOUT, la cellule de compensation, les รฉcrรชtages des broches tolรฉrantes au 5 V", + "les seuils des E/S sont les caractรฉristiques typiques du DS12288 (0,39 x VDD - 0,06 et 0,49 x VDD + 0,26, 200 mV d'hystรฉrรฉsis, tirages de 40 kOhm), pas les 0,3 et 0,7 x VDD garantis ; les rรฉsistances de sortie et les vitesses de front sont celles du F446", + "SPI : l'I2S (I2SCFGR garde sa valeur), l'arbitrage multimaรฎtre qu'un MODF sert au-delร  de la faute", + "DMA : les dรฉlais de l'arbitrage et le minutage de la matrice de bus (une requรชte est servie aussitรดt, un รฉlรฉment de mรฉmoire ร  mรฉmoire toutes les deux pรฉriodes), le filtre de deux pรฉriodes des entrรฉes du DMAMUX et les trois pรฉriodes pendant lesquelles une รฉcriture de CxCR ou de RGxCR les masque, les octets et demi-mots dupliquรฉs sur les voies pour un pรฉriphรฉrique APB qui ignore la taille, LPTIM1_OUT comme entrรฉe de dรฉclenchement et de synchronisation (le LPTIM1 n'est pas modรฉlisรฉ)", + "le REV_ID 0x2001 du DBGMCU (rรฉvision Z : la rรฉvision que porte une carte varie, UM2505 10.1) ; un cล“ur arrรชtรฉ consomme son courant de sommeil" + ] + }, + "timed": { + "claims": "Comme le niveau fonctionnel, avec les nombres de cycles du Cortex-M4 tels que le cล“ur les donne (niveau estimรฉ), les รฉtats d'attente, le prefetch et les caches de la flash comptรฉs sur les lectures d'instructions, et les temps des pรฉriphรฉriques ร  leurs horloges.", + "omissions": [ + "comme le niveau fonctionnel" + ] + } + } + } + } +} diff --git a/catalog/mcus/st/stm32g474re/registers.json b/catalog/mcus/st/stm32g474re/registers.json new file mode 100644 index 000000000..5e0c0b122 --- /dev/null +++ b/catalog/mcus/st/stm32g474re/registers.json @@ -0,0 +1,45060 @@ +{ + "schema_version": 1, + "kind": "registers", + "id": "st/stm32g474re/registers", + "version": "1.0.0", + "device": "STM32G474", + "source": "converted from STMicroelectronics STM32G474.svd v3.0 by tools/importers/svd2regs.py; peripherals left out: FDCAN (its address is the FDCAN message RAM's (SRAMCAN, RM0440 2.2.2); FDCAN1 to FDCAN3 keep its registers); register names' peripheral prefixes taken off: TIM2 (22), TIM3 (22), TIM6 (8), FDCAN1 (37), PWR (22), VREFBUF (2), COMP (7), TIM1 (28), TIM16 (20), RCC (30), FLASH (18), DAC1 (23); registers renamed as the reference manual names them: TIM15.CCMR1_Output=CCMR1; fields corrected from the reference manual: PWR.SR2.PVMO1:12:1:r, PWR.SR2.PVMO2:13:1:r, PWR.SR2.PVMO3:14:1:r, PWR.SR2.PVMO4:15:1:r, QUADSPI.CR.FTHRES:8:4, TIM2.CNT.CNT:0:32, DBGMCU.IDCODE.DEV_ID:0:12:r, TIM1.CCMR1.OC1M_3:16:1, TIM1.CCMR1.OC2M_3:24:1, TIM1.CCMR2.OC3M_3:16:1, TIM1.CCMR2.OC4M_3:24:1, TIM2.CCMR1.OC1M_3:16:1, TIM2.CCMR1.OC2M_3:24:1, TIM2.CCMR2.OC3M_3:16:1, TIM2.CCMR2.OC4M_3:24:1, TIM3.CCMR1.OC1M_3:16:1, TIM3.CCMR1.OC2M_3:24:1, TIM3.CCMR2.OC3M_3:16:1, TIM3.CCMR2.OC4M_3:24:1, TIM16.CCMR1.OC1M_3:16:1; reset values corrected from the reference manual: USART1.ISR=0x008000C0, UART4.ISR=0x008000C0, LPUART1.ISR=0x008000C0, FLASH.OPTR=0xFFEFF8AA, RCC.CR=0x00000500, DBGMCU.IDCODE=0x20016469, EXTI.IMR1=0x1F840000, EXTI.IMR2=0x00000C3C; interrupts reassigned from the reference manual: TAMP=RTC_TAMP_CSS_LSE; PWR=PVD_PVM; EXTI=EXTI0,EXTI1,EXTI2,EXTI3,EXTI4,EXTI9_5,EXTI15_10; HRTIM_TIME=HRTIM_TIME_IRQn; HRTIM_TIMF=HRTIM_TIMF_IRQn; TIM15=TIM1_BRK_TIM15; TIM16=TIM1_UP_TIM16; TIM17=TIM1_TRG_COM; ADC2=ADC1_2; DAC1=TIM6_DACUNDER; DAC3=TIM6_DACUNDER; DAC2=TIM7; DAC4=TIM7", + "interrupts": { + "WWDG": 0, + "PVD_PVM": 1, + "RTC_TAMP_CSS_LSE": 2, + "RTC_WKUP": 3, + "FLASH": 4, + "RCC": 5, + "EXTI0": 6, + "EXTI1": 7, + "EXTI2": 8, + "EXTI3": 9, + "EXTI4": 10, + "DMA1_CH1": 11, + "DMA1_CH2": 12, + "DMA1_CH3": 13, + "DMA1_CH4": 14, + "DMA1_CH5": 15, + "DMA1_CH6": 16, + "DMA1_CH7": 17, + "ADC1_2": 18, + "USB_HP": 19, + "USB_LP": 20, + "FDCAN1_IT0": 21, + "FDCAN1_IT1": 22, + "EXTI9_5": 23, + "TIM1_BRK_TIM15": 24, + "TIM1_UP_TIM16": 25, + "TIM1_TRG_COM": 26, + "TIM1_CC": 27, + "TIM2": 28, + "TIM3": 29, + "TIM4": 30, + "I2C1_EV": 31, + "I2C1_ER": 32, + "I2C2_EV": 33, + "I2C2_ER": 34, + "SPI1": 35, + "SPI2": 36, + "USART1": 37, + "USART2": 38, + "USART3": 39, + "EXTI15_10": 40, + "RTC_ALARM": 41, + "USBWakeUP": 42, + "TIM8_BRK": 43, + "TIM8_UP": 44, + "TIM8_TRG_COM": 45, + "TIM8_CC": 46, + "ADC3": 47, + "FMC": 48, + "LPTIM1": 49, + "TIM5": 50, + "SPI3": 51, + "UART4": 52, + "UART5": 53, + "TIM6_DACUNDER": 54, + "TIM7": 55, + "DMA2_CH1": 56, + "DMA2_CH2": 57, + "DMA2_CH3": 58, + "DMA2_CH4": 59, + "DMA2_CH5": 60, + "ADC4": 61, + "ADC5": 62, + "UCPD1": 63, + "COMP1_2_3": 64, + "COMP4_5_6": 65, + "COMP7": 66, + "HRTIM_Master_IRQn": 67, + "HRTIM_TIMA_IRQn": 68, + "HRTIM_TIMB_IRQn": 69, + "HRTIM_TIMC_IRQn": 70, + "HRTIM_TIMD_IRQn": 71, + "HRTIM_TIME_IRQn": 72, + "HRTIM_TIM_FLT_IRQn": 73, + "HRTIM_TIMF_IRQn": 74, + "CRS": 75, + "SAI": 76, + "TIM20_BRK": 77, + "TIM20_UP": 78, + "TIM20_TRG_COM": 79, + "TIM20_CC": 80, + "FPU": 81, + "I2C4_EV": 82, + "I2C4_ER": 83, + "SPI4": 84, + "FDCAN2_IT0": 86, + "FDCAN2_IT1": 87, + "FDCAN3_IT0": 88, + "FDCAN3_IT1": 89, + "RNG": 90, + "LPUART": 91, + "I2C3_EV": 92, + "I2C3_ER": 93, + "DMAMUX_OVR": 94, + "QUADSPI": 95, + "DMA1_CH8": 96, + "DMA2_CH6": 97, + "DMA2_CH7": 98, + "DMA2_CH8": 99, + "Cordic": 100, + "FMAC": 101 + }, + "peripherals": [ + { + "name": "TIM2", + "base": "0x40000000", + "interrupts": [ + "TIM2" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "size": 16, + "fields": [ + [ + "CEN", + 0, + 1 + ], + [ + "UDIS", + 1, + 1 + ], + [ + "URS", + 2, + 1 + ], + [ + "OPM", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CMS", + 5, + 2 + ], + [ + "ARPE", + 7, + 1 + ], + [ + "CKD", + 8, + 2 + ], + [ + "UIFREMAP", + 11, + 1 + ], + [ + "DITHEN", + 12, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "CCDS", + 3, + 1 + ], + [ + "MMS", + 4, + 3 + ], + [ + "TI1S", + 7, + 1 + ], + [ + "MMS_1", + 25, + 1 + ] + ] + }, + { + "name": "SMCR", + "offset": "0x08", + "fields": [ + [ + "SMS", + 0, + 3 + ], + [ + "OCCS", + 3, + 1 + ], + [ + "TS", + 4, + 3 + ], + [ + "MSM", + 7, + 1 + ], + [ + "ETF", + 8, + 4 + ], + [ + "ETPS", + 12, + 2 + ], + [ + "ECE", + 14, + 1 + ], + [ + "ETP", + 15, + 1 + ], + [ + "SMS_1", + 16, + 1 + ], + [ + "TS_1", + 20, + 2 + ], + [ + "SMSPE", + 24, + 1 + ], + [ + "SMSPS", + 25, + 1 + ] + ] + }, + { + "name": "DIER", + "offset": "0x0C", + "fields": [ + [ + "UIE", + 0, + 1 + ], + [ + "CC1IE", + 1, + 1 + ], + [ + "CC2IE", + 2, + 1 + ], + [ + "CC3IE", + 3, + 1 + ], + [ + "CC4IE", + 4, + 1 + ], + [ + "TIE", + 6, + 1 + ], + [ + "UDE", + 8, + 1 + ], + [ + "CC1DE", + 9, + 1 + ], + [ + "CC2DE", + 10, + 1 + ], + [ + "CC3DE", + 11, + 1 + ], + [ + "CC4DE", + 12, + 1 + ], + [ + "TDE", + 14, + 1 + ], + [ + "IDXIE", + 20, + 1 + ], + [ + "DIRIE", + 21, + 1 + ], + [ + "IERRIE", + 22, + 1 + ], + [ + "TERRIE", + 23, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x10", + "fields": [ + [ + "UIF", + 0, + 1 + ], + [ + "CC1IF", + 1, + 1 + ], + [ + "CC2IF", + 2, + 1 + ], + [ + "CC3IF", + 3, + 1 + ], + [ + "CC4IF", + 4, + 1 + ], + [ + "TIF", + 6, + 1 + ], + [ + "CC1OF", + 9, + 1 + ], + [ + "CC2OF", + 10, + 1 + ], + [ + "CC3OF", + 11, + 1 + ], + [ + "CC4OF", + 12, + 1 + ], + [ + "IDXF", + 20, + 1 + ], + [ + "DIRF", + 21, + 1 + ], + [ + "IERRF", + 22, + 1 + ], + [ + "TERRF", + 23, + 1 + ] + ] + }, + { + "name": "EGR", + "offset": "0x14", + "size": 16, + "fields": [ + [ + "UG", + 0, + 1, + "w" + ], + [ + "CC1G", + 1, + 1, + "w" + ], + [ + "CC2G", + 2, + 1, + "w" + ], + [ + "CC3G", + 3, + 1, + "w" + ], + [ + "CC4G", + 4, + 1, + "w" + ], + [ + "TG", + 6, + 1, + "w" + ] + ] + }, + { + "name": "CCMR1", + "offset": "0x18", + "fields": [ + [ + "OC2M_3", + 24, + 1 + ], + [ + "OC1M_3", + 16, + 1 + ], + [ + "IC2F", + 12, + 4 + ], + [ + "IC2PSC", + 10, + 2 + ], + [ + "CC2S", + 8, + 2 + ], + [ + "IC1F", + 4, + 4 + ], + [ + "IC1PSC", + 2, + 2 + ], + [ + "CC1S", + 0, + 2 + ] + ] + }, + { + "name": "CCMR2", + "offset": "0x1C", + "fields": [ + [ + "OC4M_3", + 24, + 1 + ], + [ + "OC3M_3", + 16, + 1 + ], + [ + "IC4F", + 12, + 4 + ], + [ + "IC4PSC", + 10, + 2 + ], + [ + "CC4S", + 8, + 2 + ], + [ + "IC3F", + 4, + 4 + ], + [ + "IC3PSC", + 2, + 2 + ], + [ + "CC3S", + 0, + 2 + ] + ] + }, + { + "name": "CCER", + "offset": "0x20", + "size": 16, + "fields": [ + [ + "CC1E", + 0, + 1 + ], + [ + "CC1P", + 1, + 1 + ], + [ + "CC1NP", + 3, + 1 + ], + [ + "CC2E", + 4, + 1 + ], + [ + "CC2P", + 5, + 1 + ], + [ + "CC2NP", + 7, + 1 + ], + [ + "CC3E", + 8, + 1 + ], + [ + "CC3P", + 9, + 1 + ], + [ + "CC3NP", + 11, + 1 + ], + [ + "CC4E", + 12, + 1 + ], + [ + "CC4P", + 13, + 1 + ], + [ + "CC4NP", + 15, + 1 + ] + ] + }, + { + "name": "CNT", + "offset": "0x24", + "fields": [ + [ + "CNT", + 0, + 32 + ] + ] + }, + { + "name": "PSC", + "offset": "0x28", + "size": 16, + "fields": [ + [ + "PSC", + 0, + 16 + ] + ] + }, + { + "name": "ARR", + "offset": "0x2C", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "ARR", + 0, + 32 + ] + ] + }, + { + "name": "CCR1", + "offset": "0x34", + "fields": [ + [ + "CCR1", + 0, + 32 + ] + ] + }, + { + "name": "CCR2", + "offset": "0x38", + "fields": [ + [ + "CCR2", + 0, + 32 + ] + ] + }, + { + "name": "CCR3", + "offset": "0x3C", + "fields": [ + [ + "CCR3", + 0, + 32 + ] + ] + }, + { + "name": "CCR4", + "offset": "0x40", + "fields": [ + [ + "CCR4", + 0, + 32 + ] + ] + }, + { + "name": "ECR", + "offset": "0x58", + "fields": [ + [ + "IE", + 0, + 1 + ], + [ + "IDIR", + 1, + 2 + ], + [ + "FIDX", + 5, + 1 + ], + [ + "IPOS", + 6, + 2 + ], + [ + "PW", + 16, + 8 + ], + [ + "PWPRSC", + 24, + 3 + ] + ] + }, + { + "name": "TISEL", + "offset": "0x5C", + "fields": [ + [ + "TI1SEL", + 0, + 4 + ], + [ + "TI2SEL", + 8, + 4 + ], + [ + "TI3SEL", + 16, + 4 + ], + [ + "TI4SEL", + 24, + 4 + ] + ] + }, + { + "name": "AF1", + "offset": "0x60", + "fields": [ + [ + "ETRSEL", + 14, + 4 + ] + ] + }, + { + "name": "AF2", + "offset": "0x64", + "fields": [ + [ + "OCRSEL", + 16, + 3 + ] + ] + }, + { + "name": "DCR", + "offset": "0x3DC", + "fields": [ + [ + "DBA", + 0, + 5 + ], + [ + "DBL", + 8, + 5 + ] + ] + }, + { + "name": "DMAR", + "offset": "0x3E0", + "fields": [ + [ + "DMAB", + 0, + 32 + ] + ] + } + ] + }, + { + "name": "TIM3", + "base": "0x40000400", + "interrupts": [ + "TIM3" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "size": 16, + "fields": [ + [ + "CEN", + 0, + 1 + ], + [ + "UDIS", + 1, + 1 + ], + [ + "URS", + 2, + 1 + ], + [ + "OPM", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CMS", + 5, + 2 + ], + [ + "ARPE", + 7, + 1 + ], + [ + "CKD", + 8, + 2 + ], + [ + "UIFREMAP", + 11, + 1 + ], + [ + "DITHEN", + 12, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "CCDS", + 3, + 1 + ], + [ + "MMS", + 4, + 3 + ], + [ + "TI1S", + 7, + 1 + ], + [ + "MMS_1", + 25, + 1 + ] + ] + }, + { + "name": "SMCR", + "offset": "0x08", + "fields": [ + [ + "SMS", + 0, + 3 + ], + [ + "OCCS", + 3, + 1 + ], + [ + "TS", + 4, + 3 + ], + [ + "MSM", + 7, + 1 + ], + [ + "ETF", + 8, + 4 + ], + [ + "ETPS", + 12, + 2 + ], + [ + "ECE", + 14, + 1 + ], + [ + "ETP", + 15, + 1 + ], + [ + "SMS_1", + 16, + 1 + ], + [ + "TS_1", + 20, + 2 + ], + [ + "SMSPE", + 24, + 1 + ], + [ + "SMSPS", + 25, + 1 + ] + ] + }, + { + "name": "DIER", + "offset": "0x0C", + "fields": [ + [ + "UIE", + 0, + 1 + ], + [ + "CC1IE", + 1, + 1 + ], + [ + "CC2IE", + 2, + 1 + ], + [ + "CC3IE", + 3, + 1 + ], + [ + "CC4IE", + 4, + 1 + ], + [ + "TIE", + 6, + 1 + ], + [ + "UDE", + 8, + 1 + ], + [ + "CC1DE", + 9, + 1 + ], + [ + "CC2DE", + 10, + 1 + ], + [ + "CC3DE", + 11, + 1 + ], + [ + "CC4DE", + 12, + 1 + ], + [ + "TDE", + 14, + 1 + ], + [ + "IDXIE", + 20, + 1 + ], + [ + "DIRIE", + 21, + 1 + ], + [ + "IERRIE", + 22, + 1 + ], + [ + "TERRIE", + 23, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x10", + "fields": [ + [ + "UIF", + 0, + 1 + ], + [ + "CC1IF", + 1, + 1 + ], + [ + "CC2IF", + 2, + 1 + ], + [ + "CC3IF", + 3, + 1 + ], + [ + "CC4IF", + 4, + 1 + ], + [ + "TIF", + 6, + 1 + ], + [ + "CC1OF", + 9, + 1 + ], + [ + "CC2OF", + 10, + 1 + ], + [ + "CC3OF", + 11, + 1 + ], + [ + "CC4OF", + 12, + 1 + ], + [ + "IDXF", + 20, + 1 + ], + [ + "DIRF", + 21, + 1 + ], + [ + "IERRF", + 22, + 1 + ], + [ + "TERRF", + 23, + 1 + ] + ] + }, + { + "name": "EGR", + "offset": "0x14", + "size": 16, + "fields": [ + [ + "UG", + 0, + 1, + "w" + ], + [ + "CC1G", + 1, + 1, + "w" + ], + [ + "CC2G", + 2, + 1, + "w" + ], + [ + "CC3G", + 3, + 1, + "w" + ], + [ + "CC4G", + 4, + 1, + "w" + ], + [ + "TG", + 6, + 1, + "w" + ] + ] + }, + { + "name": "CCMR1", + "offset": "0x18", + "fields": [ + [ + "OC2M_3", + 24, + 1 + ], + [ + "OC1M_3", + 16, + 1 + ], + [ + "IC2F", + 12, + 4 + ], + [ + "IC2PSC", + 10, + 2 + ], + [ + "CC2S", + 8, + 2 + ], + [ + "IC1F", + 4, + 4 + ], + [ + "IC1PSC", + 2, + 2 + ], + [ + "CC1S", + 0, + 2 + ] + ] + }, + { + "name": "CCMR2", + "offset": "0x1C", + "fields": [ + [ + "OC4M_3", + 24, + 1 + ], + [ + "OC3M_3", + 16, + 1 + ], + [ + "IC4F", + 12, + 4 + ], + [ + "IC4PSC", + 10, + 2 + ], + [ + "CC4S", + 8, + 2 + ], + [ + "IC3F", + 4, + 4 + ], + [ + "IC3PSC", + 2, + 2 + ], + [ + "CC3S", + 0, + 2 + ] + ] + }, + { + "name": "CCER", + "offset": "0x20", + "size": 16, + "fields": [ + [ + "CC1E", + 0, + 1 + ], + [ + "CC1P", + 1, + 1 + ], + [ + "CC1NP", + 3, + 1 + ], + [ + "CC2E", + 4, + 1 + ], + [ + "CC2P", + 5, + 1 + ], + [ + "CC2NP", + 7, + 1 + ], + [ + "CC3E", + 8, + 1 + ], + [ + "CC3P", + 9, + 1 + ], + [ + "CC3NP", + 11, + 1 + ], + [ + "CC4E", + 12, + 1 + ], + [ + "CC4P", + 13, + 1 + ], + [ + "CC4NP", + 15, + 1 + ] + ] + }, + { + "name": "CNT", + "offset": "0x24", + "fields": [ + [ + "CNT", + 0, + 16 + ], + [ + "UIFCPY", + 31, + 1 + ] + ] + }, + { + "name": "PSC", + "offset": "0x28", + "size": 16, + "fields": [ + [ + "PSC", + 0, + 16 + ] + ] + }, + { + "name": "ARR", + "offset": "0x2C", + "reset": "0x0000FFFF", + "fields": [ + [ + "ARR", + 0, + 20 + ] + ] + }, + { + "name": "CCR1", + "offset": "0x34", + "fields": [ + [ + "CCR1", + 0, + 20 + ] + ] + }, + { + "name": "CCR2", + "offset": "0x38", + "fields": [ + [ + "CCR2", + 0, + 20 + ] + ] + }, + { + "name": "CCR3", + "offset": "0x3C", + "fields": [ + [ + "CCR3", + 0, + 20 + ] + ] + }, + { + "name": "CCR4", + "offset": "0x40", + "fields": [ + [ + "CCR4", + 0, + 20 + ] + ] + }, + { + "name": "ECR", + "offset": "0x58", + "fields": [ + [ + "IE", + 0, + 1 + ], + [ + "IDIR", + 1, + 2 + ], + [ + "FIDX", + 5, + 1 + ], + [ + "IPOS", + 6, + 2 + ], + [ + "PW", + 16, + 8 + ], + [ + "PWPRSC", + 24, + 3 + ] + ] + }, + { + "name": "TISEL", + "offset": "0x5C", + "fields": [ + [ + "TI1SEL", + 0, + 4 + ], + [ + "TI2SEL", + 8, + 4 + ], + [ + "TI3SEL", + 16, + 4 + ], + [ + "TI4SEL", + 24, + 4 + ] + ] + }, + { + "name": "AF1", + "offset": "0x60", + "fields": [ + [ + "ETRSEL", + 14, + 4 + ] + ] + }, + { + "name": "AF2", + "offset": "0x64", + "fields": [ + [ + "OCRSEL", + 16, + 3 + ] + ] + }, + { + "name": "DCR", + "offset": "0x3DC", + "fields": [ + [ + "DBA", + 0, + 5 + ], + [ + "DBL", + 8, + 5 + ] + ] + }, + { + "name": "DMAR", + "offset": "0x3E0", + "fields": [ + [ + "DMAB", + 0, + 32 + ] + ] + } + ] + }, + { + "name": "TIM4", + "base": "0x40000800", + "interrupts": [ + "TIM4" + ], + "derived_from": "TIM3" + }, + { + "name": "TIM5", + "base": "0x40000C00", + "interrupts": [ + "TIM5" + ], + "derived_from": "TIM2" + }, + { + "name": "TIM6", + "base": "0x40001000", + "interrupts": [ + "TIM6_DACUNDER" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "size": 16, + "fields": [ + [ + "CEN", + 0, + 1 + ], + [ + "UDIS", + 1, + 1 + ], + [ + "URS", + 2, + 1 + ], + [ + "OPM", + 3, + 1 + ], + [ + "ARPE", + 7, + 1 + ], + [ + "UIFREMAP", + 11, + 1 + ], + [ + "DITHEN", + 12, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "size": 16, + "fields": [ + [ + "MMS", + 4, + 3 + ] + ] + }, + { + "name": "DIER", + "offset": "0x0C", + "size": 16, + "fields": [ + [ + "UIE", + 0, + 1 + ], + [ + "UDE", + 8, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x10", + "size": 16, + "fields": [ + [ + "UIF", + 0, + 1 + ] + ] + }, + { + "name": "EGR", + "offset": "0x14", + "size": 16, + "fields": [ + [ + "UG", + 0, + 1, + "w" + ] + ] + }, + { + "name": "CNT", + "offset": "0x24", + "fields": [ + [ + "CNT", + 0, + 16 + ], + [ + "UIFCPY", + 31, + 1, + "r" + ] + ] + }, + { + "name": "PSC", + "offset": "0x28", + "size": 16, + "fields": [ + [ + "PSC", + 0, + 16 + ] + ] + }, + { + "name": "ARR", + "offset": "0x2C", + "reset": "0x0000FFFF", + "fields": [ + [ + "ARR", + 0, + 20 + ] + ] + } + ] + }, + { + "name": "TIM7", + "base": "0x40001400", + "interrupts": [ + "TIM7" + ], + "derived_from": "TIM6" + }, + { + "name": "CRS", + "base": "0x40002000", + "interrupts": [ + "CRS" + ], + "registers": [ + { + "name": "CR", + "offset": "0x00", + "reset": "0x00004000", + "fields": [ + [ + "SYNCOKIE", + 0, + 1 + ], + [ + "SYNCWARNIE", + 1, + 1 + ], + [ + "ERRIE", + 2, + 1 + ], + [ + "ESYNCIE", + 3, + 1 + ], + [ + "CEN", + 5, + 1 + ], + [ + "AUTOTRIMEN", + 6, + 1 + ], + [ + "SWSYNC", + 7, + 1 + ], + [ + "TRIM", + 8, + 7 + ] + ] + }, + { + "name": "CFGR", + "offset": "0x04", + "reset": "0x2022BB7F", + "fields": [ + [ + "RELOAD", + 0, + 16 + ], + [ + "FELIM", + 16, + 8 + ], + [ + "SYNCDIV", + 24, + 3 + ], + [ + "SYNCSRC", + 28, + 2 + ], + [ + "SYNCPOL", + 31, + 1 + ] + ] + }, + { + "name": "ISR", + "offset": "0x08", + "fields": [ + [ + "SYNCOKF", + 0, + 1, + "r" + ], + [ + "SYNCWARNF", + 1, + 1, + "r" + ], + [ + "ERRF", + 2, + 1, + "r" + ], + [ + "ESYNCF", + 3, + 1, + "r" + ], + [ + "SYNCERR", + 8, + 1, + "r" + ], + [ + "SYNCMISS", + 9, + 1, + "r" + ], + [ + "TRIMOVF", + 10, + 1, + "r" + ], + [ + "FEDIR", + 15, + 1, + "r" + ], + [ + "FECAP", + 16, + 16, + "r" + ] + ] + }, + { + "name": "ICR", + "offset": "0x0C", + "fields": [ + [ + "SYNCOKC", + 0, + 1 + ], + [ + "SYNCWARNC", + 1, + 1 + ], + [ + "ERRC", + 2, + 1 + ], + [ + "ESYNCC", + 3, + 1 + ] + ] + } + ] + }, + { + "name": "TAMP", + "base": "0x40002400", + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "reset": "0xFFFF0000", + "fields": [ + [ + "TAMP1E", + 0, + 1 + ], + [ + "TAMP2E", + 1, + 1 + ], + [ + "TAMP3E", + 2, + 1 + ], + [ + "ITAMP3E", + 18, + 1 + ], + [ + "ITAMP4E", + 19, + 1 + ], + [ + "ITAMP5E", + 20, + 1 + ], + [ + "ITAMP6E", + 21, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "TAMP1NOER", + 0, + 1 + ], + [ + "TAMP2NOER", + 1, + 1 + ], + [ + "TAMP3NOER", + 2, + 1 + ], + [ + "TAMP1MSK", + 16, + 1 + ], + [ + "TAMP2MSK", + 17, + 1 + ], + [ + "TAMP3MSK", + 18, + 1 + ], + [ + "TAMP1TRG", + 24, + 1 + ], + [ + "TAMP2TRG", + 25, + 1 + ], + [ + "TAMP3TRG", + 26, + 1 + ] + ] + }, + { + "name": "FLTCR", + "offset": "0x0C", + "fields": [ + [ + "TAMPFREQ", + 0, + 3 + ], + [ + "TAMPFLT", + 3, + 2 + ], + [ + "TAMPPRCH", + 5, + 2 + ], + [ + "TAMPPUDIS", + 7, + 1 + ] + ] + }, + { + "name": "IER", + "offset": "0x2C", + "fields": [ + [ + "TAMP1IE", + 0, + 1 + ], + [ + "TAMP2IE", + 1, + 1 + ], + [ + "TAMP3IE", + 2, + 1 + ], + [ + "ITAMP3IE", + 18, + 1 + ], + [ + "ITAMP4IE", + 19, + 1 + ], + [ + "ITAMP5IE", + 20, + 1 + ], + [ + "ITAMP6IE", + 21, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x30", + "fields": [ + [ + "TAMP1F", + 0, + 1, + "r" + ], + [ + "TAMP2F", + 1, + 1, + "r" + ], + [ + "TAMP3F", + 2, + 1, + "r" + ], + [ + "ITAMP3F", + 18, + 1, + "r" + ], + [ + "ITAMP4F", + 19, + 1, + "r" + ], + [ + "ITAMP5F", + 20, + 1, + "r" + ], + [ + "ITAMP6F", + 21, + 1, + "r" + ] + ] + }, + { + "name": "MISR", + "offset": "0x34", + "fields": [ + [ + "TAMP1MF", + 0, + 1, + "r" + ], + [ + "TAMP2MF", + 1, + 1, + "r" + ], + [ + "TAMP3MF", + 2, + 1, + "r" + ], + [ + "ITAMP3MF", + 18, + 1, + "r" + ], + [ + "ITAMP4MF", + 19, + 1, + "r" + ], + [ + "ITAMP5MF", + 20, + 1, + "r" + ], + [ + "ITAMP6MF", + 21, + 1, + "r" + ] + ] + }, + { + "name": "SCR", + "offset": "0x3C", + "fields": [ + [ + "CTAMP1F", + 0, + 1 + ], + [ + "CTAMP2F", + 1, + 1 + ], + [ + "CTAMP3F", + 2, + 1 + ], + [ + "CITAMP3F", + 18, + 1 + ], + [ + "CITAMP4F", + 19, + 1 + ], + [ + "CITAMP5F", + 20, + 1 + ], + [ + "CITAMP6F", + 21, + 1 + ] + ] + }, + { + "name": "BKP0R", + "offset": "0x100", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP1R", + "offset": "0x104", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP2R", + "offset": "0x108", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP3R", + "offset": "0x10C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP4R", + "offset": "0x110", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP5R", + "offset": "0x114", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP6R", + "offset": "0x118", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP7R", + "offset": "0x11C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP8R", + "offset": "0x120", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP9R", + "offset": "0x124", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP10R", + "offset": "0x128", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP11R", + "offset": "0x12C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP12R", + "offset": "0x130", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP13R", + "offset": "0x134", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP14R", + "offset": "0x138", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP15R", + "offset": "0x13C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP16R", + "offset": "0x140", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP17R", + "offset": "0x144", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP18R", + "offset": "0x148", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP19R", + "offset": "0x14C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP20R", + "offset": "0x150", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP21R", + "offset": "0x154", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP22R", + "offset": "0x158", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP23R", + "offset": "0x15C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP24R", + "offset": "0x160", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP25R", + "offset": "0x164", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP26R", + "offset": "0x168", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP27R", + "offset": "0x16C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP28R", + "offset": "0x170", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP29R", + "offset": "0x174", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP30R", + "offset": "0x178", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + }, + { + "name": "BKP31R", + "offset": "0x17C", + "fields": [ + [ + "BKP", + 0, + 32 + ] + ] + } + ], + "interrupts": [ + "RTC_TAMP_CSS_LSE" + ] + }, + { + "name": "RTC", + "base": "0x40002800", + "interrupts": [ + "RTC_TAMP_CSS_LSE", + "RTC_WKUP", + "RTC_ALARM" + ], + "registers": [ + { + "name": "TR", + "offset": "0x00", + "fields": [ + [ + "PM", + 22, + 1 + ], + [ + "HT", + 20, + 2 + ], + [ + "HU", + 16, + 4 + ], + [ + "MNT", + 12, + 3 + ], + [ + "MNU", + 8, + 4 + ], + [ + "ST", + 4, + 3 + ], + [ + "SU", + 0, + 4 + ] + ] + }, + { + "name": "DR", + "offset": "0x04", + "reset": "0x00002101", + "fields": [ + [ + "YT", + 20, + 4 + ], + [ + "YU", + 16, + 4 + ], + [ + "WDU", + 13, + 3 + ], + [ + "MT", + 12, + 1 + ], + [ + "MU", + 8, + 4 + ], + [ + "DT", + 4, + 2 + ], + [ + "DU", + 0, + 4 + ] + ] + }, + { + "name": "SSR", + "offset": "0x08", + "fields": [ + [ + "SS", + 0, + 16, + "r" + ] + ] + }, + { + "name": "ICSR", + "offset": "0x0C", + "reset": "0x00000007", + "fields": [ + [ + "ALRAWF", + 0, + 1, + "r" + ], + [ + "ALRBWF", + 1, + 1, + "r" + ], + [ + "WUTWF", + 2, + 1, + "r" + ], + [ + "SHPF", + 3, + 1 + ], + [ + "INITS", + 4, + 1, + "r" + ], + [ + "RSF", + 5, + 1 + ], + [ + "INITF", + 6, + 1, + "r" + ], + [ + "INIT", + 7, + 1 + ], + [ + "RECALPF", + 16, + 1, + "r" + ] + ] + }, + { + "name": "PRER", + "offset": "0x10", + "reset": "0x007F00FF", + "fields": [ + [ + "PREDIV_A", + 16, + 7 + ], + [ + "PREDIV_S", + 0, + 15 + ] + ] + }, + { + "name": "WUTR", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "WUT", + 0, + 16 + ] + ] + }, + { + "name": "CR", + "offset": "0x18", + "fields": [ + [ + "WCKSEL", + 0, + 3 + ], + [ + "TSEDGE", + 3, + 1 + ], + [ + "REFCKON", + 4, + 1 + ], + [ + "BYPSHAD", + 5, + 1 + ], + [ + "FMT", + 6, + 1 + ], + [ + "ALRAE", + 8, + 1 + ], + [ + "ALRBE", + 9, + 1 + ], + [ + "WUTE", + 10, + 1 + ], + [ + "TSE", + 11, + 1 + ], + [ + "ALRAIE", + 12, + 1 + ], + [ + "ALRBIE", + 13, + 1 + ], + [ + "WUTIE", + 14, + 1 + ], + [ + "TSIE", + 15, + 1 + ], + [ + "ADD1H", + 16, + 1 + ], + [ + "SUB1H", + 17, + 1 + ], + [ + "BKP", + 18, + 1 + ], + [ + "COSEL", + 19, + 1 + ], + [ + "POL", + 20, + 1 + ], + [ + "OSEL", + 21, + 2 + ], + [ + "COE", + 23, + 1 + ], + [ + "ITSE", + 24, + 1 + ], + [ + "TAMPTS", + 25, + 1 + ], + [ + "TAMPOE", + 26, + 1 + ], + [ + "TAMPALRM_PU", + 29, + 1 + ], + [ + "TAMPALRM_TYPE", + 30, + 1 + ], + [ + "OUT2EN", + 31, + 1 + ] + ] + }, + { + "name": "WPR", + "offset": "0x24", + "fields": [ + [ + "KEY", + 0, + 8, + "w" + ] + ] + }, + { + "name": "CALR", + "offset": "0x28", + "fields": [ + [ + "CALP", + 15, + 1 + ], + [ + "CALW8", + 14, + 1 + ], + [ + "CALW16", + 13, + 1 + ], + [ + "CALM", + 0, + 9 + ] + ] + }, + { + "name": "SHIFTR", + "offset": "0x2C", + "fields": [ + [ + "ADD1S", + 31, + 1, + "w" + ], + [ + "SUBFS", + 0, + 15, + "w" + ] + ] + }, + { + "name": "TSTR", + "offset": "0x30", + "fields": [ + [ + "SU", + 0, + 4, + "r" + ], + [ + "ST", + 4, + 3, + "r" + ], + [ + "MNU", + 8, + 4, + "r" + ], + [ + "MNT", + 12, + 3, + "r" + ], + [ + "HU", + 16, + 4, + "r" + ], + [ + "HT", + 20, + 2, + "r" + ], + [ + "PM", + 22, + 1, + "r" + ] + ] + }, + { + "name": "TSDR", + "offset": "0x34", + "fields": [ + [ + "WDU", + 13, + 3, + "r" + ], + [ + "MT", + 12, + 1, + "r" + ], + [ + "MU", + 8, + 4, + "r" + ], + [ + "DT", + 4, + 2, + "r" + ], + [ + "DU", + 0, + 4, + "r" + ] + ] + }, + { + "name": "TSSSR", + "offset": "0x38", + "fields": [ + [ + "SS", + 0, + 16, + "r" + ] + ] + }, + { + "name": "ALRMAR", + "offset": "0x40", + "fields": [ + [ + "MSK4", + 31, + 1 + ], + [ + "WDSEL", + 30, + 1 + ], + [ + "DT", + 28, + 2 + ], + [ + "DU", + 24, + 4 + ], + [ + "MSK3", + 23, + 1 + ], + [ + "PM", + 22, + 1 + ], + [ + "HT", + 20, + 2 + ], + [ + "HU", + 16, + 4 + ], + [ + "MSK2", + 15, + 1 + ], + [ + "MNT", + 12, + 3 + ], + [ + "MNU", + 8, + 4 + ], + [ + "MSK1", + 7, + 1 + ], + [ + "ST", + 4, + 3 + ], + [ + "SU", + 0, + 4 + ] + ] + }, + { + "name": "ALRMASSR", + "offset": "0x44", + "fields": [ + [ + "MASKSS", + 24, + 4 + ], + [ + "SS", + 0, + 15 + ] + ] + }, + { + "name": "ALRMBR", + "offset": "0x48", + "fields": [ + [ + "MSK4", + 31, + 1 + ], + [ + "WDSEL", + 30, + 1 + ], + [ + "DT", + 28, + 2 + ], + [ + "DU", + 24, + 4 + ], + [ + "MSK3", + 23, + 1 + ], + [ + "PM", + 22, + 1 + ], + [ + "HT", + 20, + 2 + ], + [ + "HU", + 16, + 4 + ], + [ + "MSK2", + 15, + 1 + ], + [ + "MNT", + 12, + 3 + ], + [ + "MNU", + 8, + 4 + ], + [ + "MSK1", + 7, + 1 + ], + [ + "ST", + 4, + 3 + ], + [ + "SU", + 0, + 4 + ] + ] + }, + { + "name": "ALRMBSSR", + "offset": "0x4C", + "fields": [ + [ + "MASKSS", + 24, + 4 + ], + [ + "SS", + 0, + 15 + ] + ] + }, + { + "name": "SR", + "offset": "0x50", + "fields": [ + [ + "ALRAF", + 0, + 1, + "r" + ], + [ + "ALRBF", + 1, + 1, + "r" + ], + [ + "WUTF", + 2, + 1, + "r" + ], + [ + "TSF", + 3, + 1, + "r" + ], + [ + "TSOVF", + 4, + 1, + "r" + ], + [ + "ITSF", + 5, + 1, + "r" + ] + ] + }, + { + "name": "MISR", + "offset": "0x54", + "fields": [ + [ + "ALRAMF", + 0, + 1, + "r" + ], + [ + "ALRBMF", + 1, + 1, + "r" + ], + [ + "WUTMF", + 2, + 1, + "r" + ], + [ + "TSMF", + 3, + 1, + "r" + ], + [ + "TSOVMF", + 4, + 1, + "r" + ], + [ + "ITSMF", + 5, + 1, + "r" + ] + ] + }, + { + "name": "SCR", + "offset": "0x5C", + "fields": [ + [ + "CALRAF", + 0, + 1, + "w" + ], + [ + "CALRBF", + 1, + 1, + "w" + ], + [ + "CWUTF", + 2, + 1, + "w" + ], + [ + "CTSF", + 3, + 1, + "w" + ], + [ + "CTSOVF", + 4, + 1, + "w" + ], + [ + "CITSF", + 5, + 1, + "w" + ] + ] + } + ] + }, + { + "name": "WWDG", + "base": "0x40002C00", + "interrupts": [ + "WWDG" + ], + "registers": [ + { + "name": "CR", + "offset": "0x00", + "reset": "0x0000007F", + "fields": [ + [ + "WDGA", + 7, + 1 + ], + [ + "T", + 0, + 7 + ] + ] + }, + { + "name": "CFR", + "offset": "0x04", + "reset": "0x0000007F", + "fields": [ + [ + "WDGTB", + 11, + 3 + ], + [ + "EWI", + 9, + 1 + ], + [ + "W", + 0, + 7 + ] + ] + }, + { + "name": "SR", + "offset": "0x08", + "fields": [ + [ + "EWIF", + 0, + 1 + ] + ] + } + ] + }, + { + "name": "IWDG", + "base": "0x40003000", + "registers": [ + { + "name": "KR", + "offset": "0x00", + "fields": [ + [ + "KEY", + 0, + 16, + "w" + ] + ] + }, + { + "name": "PR", + "offset": "0x04", + "fields": [ + [ + "PR", + 0, + 3 + ] + ] + }, + { + "name": "RLR", + "offset": "0x08", + "reset": "0x00000FFF", + "fields": [ + [ + "RL", + 0, + 12 + ] + ] + }, + { + "name": "SR", + "offset": "0x0C", + "fields": [ + [ + "WVU", + 2, + 1, + "r" + ], + [ + "RVU", + 1, + 1, + "r" + ], + [ + "PVU", + 0, + 1, + "r" + ] + ] + }, + { + "name": "WINR", + "offset": "0x10", + "reset": "0x00000FFF", + "fields": [ + [ + "WIN", + 0, + 12 + ] + ] + } + ] + }, + { + "name": "SPI2", + "base": "0x40003800", + "interrupts": [ + "SPI2" + ], + "derived_from": "SPI4" + }, + { + "name": "SPI3", + "base": "0x40003C00", + "interrupts": [ + "SPI3" + ], + "derived_from": "SPI4" + }, + { + "name": "USART2", + "base": "0x40004400", + "interrupts": [ + "USART2" + ], + "derived_from": "USART1" + }, + { + "name": "USART3", + "base": "0x40004800", + "interrupts": [ + "USART3" + ], + "derived_from": "USART1" + }, + { + "name": "UART4", + "base": "0x40004C00", + "interrupts": [ + "UART4" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "fields": [ + [ + "RXFFIE", + 31, + 1 + ], + [ + "TXFEIE", + 30, + 1 + ], + [ + "FIFOEN", + 29, + 1 + ], + [ + "M1", + 28, + 1 + ], + [ + "EOBIE", + 27, + 1 + ], + [ + "RTOIE", + 26, + 1 + ], + [ + "DEAT4", + 25, + 1 + ], + [ + "DEAT3", + 24, + 1 + ], + [ + "DEAT2", + 23, + 1 + ], + [ + "DEAT1", + 22, + 1 + ], + [ + "DEAT0", + 21, + 1 + ], + [ + "DEDT4", + 20, + 1 + ], + [ + "DEDT3", + 19, + 1 + ], + [ + "DEDT2", + 18, + 1 + ], + [ + "DEDT1", + 17, + 1 + ], + [ + "DEDT0", + 16, + 1 + ], + [ + "OVER8", + 15, + 1 + ], + [ + "CMIE", + 14, + 1 + ], + [ + "MME", + 13, + 1 + ], + [ + "M0", + 12, + 1 + ], + [ + "WAKE", + 11, + 1 + ], + [ + "PCE", + 10, + 1 + ], + [ + "PS", + 9, + 1 + ], + [ + "PEIE", + 8, + 1 + ], + [ + "TXEIE", + 7, + 1 + ], + [ + "TCIE", + 6, + 1 + ], + [ + "RXNEIE", + 5, + 1 + ], + [ + "IDLEIE", + 4, + 1 + ], + [ + "TE", + 3, + 1 + ], + [ + "RE", + 2, + 1 + ], + [ + "UESM", + 1, + 1 + ], + [ + "UE", + 0, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "ADD4_7", + 28, + 4 + ], + [ + "ADD0_3", + 24, + 4 + ], + [ + "RTOEN", + 23, + 1 + ], + [ + "ABRMOD1", + 22, + 1 + ], + [ + "ABRMOD0", + 21, + 1 + ], + [ + "ABREN", + 20, + 1 + ], + [ + "MSBFIRST", + 19, + 1 + ], + [ + "TAINV", + 18, + 1 + ], + [ + "TXINV", + 17, + 1 + ], + [ + "RXINV", + 16, + 1 + ], + [ + "SWAP", + 15, + 1 + ], + [ + "LINEN", + 14, + 1 + ], + [ + "STOP", + 12, + 2 + ], + [ + "CLKEN", + 11, + 1 + ], + [ + "CPOL", + 10, + 1 + ], + [ + "CPHA", + 9, + 1 + ], + [ + "LBCL", + 8, + 1 + ], + [ + "LBDIE", + 6, + 1 + ], + [ + "LBDL", + 5, + 1 + ], + [ + "ADDM7", + 4, + 1 + ], + [ + "DIS_NSS", + 3, + 1 + ], + [ + "SLVEN", + 0, + 1 + ] + ] + }, + { + "name": "CR3", + "offset": "0x08", + "fields": [ + [ + "TXFTCFG", + 29, + 3 + ], + [ + "RXFTIE", + 28, + 1 + ], + [ + "RXFTCFG", + 25, + 3 + ], + [ + "TCBGTIE", + 24, + 1 + ], + [ + "TXFTIE", + 23, + 1 + ], + [ + "WUFIE", + 22, + 1 + ], + [ + "WUS", + 20, + 2 + ], + [ + "SCARCNT", + 17, + 3 + ], + [ + "DEP", + 15, + 1 + ], + [ + "DEM", + 14, + 1 + ], + [ + "DDRE", + 13, + 1 + ], + [ + "OVRDIS", + 12, + 1 + ], + [ + "ONEBIT", + 11, + 1 + ], + [ + "CTSIE", + 10, + 1 + ], + [ + "CTSE", + 9, + 1 + ], + [ + "RTSE", + 8, + 1 + ], + [ + "DMAT", + 7, + 1 + ], + [ + "DMAR", + 6, + 1 + ], + [ + "SCEN", + 5, + 1 + ], + [ + "NACK", + 4, + 1 + ], + [ + "HDSEL", + 3, + 1 + ], + [ + "IRLP", + 2, + 1 + ], + [ + "IREN", + 1, + 1 + ], + [ + "EIE", + 0, + 1 + ] + ] + }, + { + "name": "BRR", + "offset": "0x0C", + "fields": [ + [ + "DIV_Mantissa", + 4, + 12 + ], + [ + "DIV_Fraction", + 0, + 4 + ] + ] + }, + { + "name": "GTPR", + "offset": "0x10", + "fields": [ + [ + "GT", + 8, + 8 + ], + [ + "PSC", + 0, + 8 + ] + ] + }, + { + "name": "RTOR", + "offset": "0x14", + "fields": [ + [ + "BLEN", + 24, + 8 + ], + [ + "RTO", + 0, + 24 + ] + ] + }, + { + "name": "RQR", + "offset": "0x18", + "fields": [ + [ + "TXFRQ", + 4, + 1, + "w" + ], + [ + "RXFRQ", + 3, + 1, + "w" + ], + [ + "MMRQ", + 2, + 1, + "w" + ], + [ + "SBKRQ", + 1, + 1, + "w" + ], + [ + "ABRRQ", + 0, + 1, + "w" + ] + ] + }, + { + "name": "ISR", + "offset": "0x1C", + "reset": "0x008000C0", + "fields": [ + [ + "TXFT", + 27, + 1, + "r" + ], + [ + "RXFT", + 26, + 1, + "r" + ], + [ + "TCBGT", + 25, + 1, + "r" + ], + [ + "RXFF", + 24, + 1, + "r" + ], + [ + "TXFE", + 23, + 1, + "r" + ], + [ + "REACK", + 22, + 1, + "r" + ], + [ + "TEACK", + 21, + 1, + "r" + ], + [ + "WUF", + 20, + 1, + "r" + ], + [ + "RWU", + 19, + 1, + "r" + ], + [ + "SBKF", + 18, + 1, + "r" + ], + [ + "CMF", + 17, + 1, + "r" + ], + [ + "BUSY", + 16, + 1, + "r" + ], + [ + "ABRF", + 15, + 1, + "r" + ], + [ + "ABRE", + 14, + 1, + "r" + ], + [ + "UDR", + 13, + 1, + "r" + ], + [ + "EOBF", + 12, + 1, + "r" + ], + [ + "RTOF", + 11, + 1, + "r" + ], + [ + "CTS", + 10, + 1, + "r" + ], + [ + "CTSIF", + 9, + 1, + "r" + ], + [ + "LBDF", + 8, + 1, + "r" + ], + [ + "TXE", + 7, + 1, + "r" + ], + [ + "TC", + 6, + 1, + "r" + ], + [ + "RXNE", + 5, + 1, + "r" + ], + [ + "IDLE", + 4, + 1, + "r" + ], + [ + "ORE", + 3, + 1, + "r" + ], + [ + "NF", + 2, + 1, + "r" + ], + [ + "FE", + 1, + 1, + "r" + ], + [ + "PE", + 0, + 1, + "r" + ] + ] + }, + { + "name": "ICR", + "offset": "0x20", + "fields": [ + [ + "WUCF", + 20, + 1, + "w" + ], + [ + "CMCF", + 17, + 1, + "w" + ], + [ + "UDRCF", + 13, + 1, + "w" + ], + [ + "EOBCF", + 12, + 1, + "w" + ], + [ + "RTOCF", + 11, + 1, + "w" + ], + [ + "CTSCF", + 9, + 1, + "w" + ], + [ + "LBDCF", + 8, + 1, + "w" + ], + [ + "TCBGTCF", + 7, + 1, + "w" + ], + [ + "TCCF", + 6, + 1, + "w" + ], + [ + "TXFECF", + 5, + 1, + "w" + ], + [ + "IDLECF", + 4, + 1, + "w" + ], + [ + "ORECF", + 3, + 1, + "w" + ], + [ + "NCF", + 2, + 1, + "w" + ], + [ + "FECF", + 1, + 1, + "w" + ], + [ + "PECF", + 0, + 1, + "w" + ] + ] + }, + { + "name": "RDR", + "offset": "0x24", + "fields": [ + [ + "RDR", + 0, + 9, + "r" + ] + ] + }, + { + "name": "TDR", + "offset": "0x28", + "fields": [ + [ + "TDR", + 0, + 9 + ] + ] + }, + { + "name": "PRESC", + "offset": "0x2C", + "fields": [ + [ + "PRESCALER", + 0, + 4 + ] + ] + } + ] + }, + { + "name": "UART5", + "base": "0x40005000", + "interrupts": [ + "UART5" + ], + "derived_from": "UART4" + }, + { + "name": "I2C1", + "base": "0x40005400", + "interrupts": [ + "I2C1_EV", + "I2C1_ER" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "fields": [ + [ + "PE", + 0, + 1 + ], + [ + "TXIE", + 1, + 1 + ], + [ + "RXIE", + 2, + 1 + ], + [ + "ADDRIE", + 3, + 1 + ], + [ + "NACKIE", + 4, + 1 + ], + [ + "STOPIE", + 5, + 1 + ], + [ + "TCIE", + 6, + 1 + ], + [ + "ERRIE", + 7, + 1 + ], + [ + "DNF", + 8, + 4 + ], + [ + "ANFOFF", + 12, + 1 + ], + [ + "TXDMAEN", + 14, + 1 + ], + [ + "RXDMAEN", + 15, + 1 + ], + [ + "SBC", + 16, + 1 + ], + [ + "NOSTRETCH", + 17, + 1 + ], + [ + "WUPEN", + 18, + 1 + ], + [ + "GCEN", + 19, + 1 + ], + [ + "SMBHEN", + 20, + 1 + ], + [ + "SMBDEN", + 21, + 1 + ], + [ + "ALERTEN", + 22, + 1 + ], + [ + "PECEN", + 23, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "PECBYTE", + 26, + 1 + ], + [ + "AUTOEND", + 25, + 1 + ], + [ + "RELOAD", + 24, + 1 + ], + [ + "NBYTES", + 16, + 8 + ], + [ + "NACK", + 15, + 1 + ], + [ + "STOP", + 14, + 1 + ], + [ + "START", + 13, + 1 + ], + [ + "HEAD10R", + 12, + 1 + ], + [ + "ADD10", + 11, + 1 + ], + [ + "RD_WRN", + 10, + 1 + ], + [ + "SADD", + 0, + 10 + ] + ] + }, + { + "name": "OAR1", + "offset": "0x08", + "fields": [ + [ + "OA1", + 0, + 10 + ], + [ + "OA1MODE", + 10, + 1 + ], + [ + "OA1EN", + 15, + 1 + ] + ] + }, + { + "name": "OAR2", + "offset": "0x0C", + "fields": [ + [ + "OA2", + 1, + 7 + ], + [ + "OA2MSK", + 8, + 3 + ], + [ + "OA2EN", + 15, + 1 + ] + ] + }, + { + "name": "TIMINGR", + "offset": "0x10", + "fields": [ + [ + "SCLL", + 0, + 8 + ], + [ + "SCLH", + 8, + 8 + ], + [ + "SDADEL", + 16, + 4 + ], + [ + "SCLDEL", + 20, + 4 + ], + [ + "PRESC", + 28, + 4 + ] + ] + }, + { + "name": "TIMEOUTR", + "offset": "0x14", + "fields": [ + [ + "TIMEOUTA", + 0, + 12 + ], + [ + "TIDLE", + 12, + 1 + ], + [ + "TIMOUTEN", + 15, + 1 + ], + [ + "TIMEOUTB", + 16, + 12 + ], + [ + "TEXTEN", + 31, + 1 + ] + ] + }, + { + "name": "ISR", + "offset": "0x18", + "reset": "0x00000001", + "fields": [ + [ + "ADDCODE", + 17, + 7, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ], + [ + "BUSY", + 15, + 1, + "r" + ], + [ + "ALERT", + 13, + 1, + "r" + ], + [ + "TIMEOUT", + 12, + 1, + "r" + ], + [ + "PECERR", + 11, + 1, + "r" + ], + [ + "OVR", + 10, + 1, + "r" + ], + [ + "ARLO", + 9, + 1, + "r" + ], + [ + "BERR", + 8, + 1, + "r" + ], + [ + "TCR", + 7, + 1, + "r" + ], + [ + "TC", + 6, + 1, + "r" + ], + [ + "STOPF", + 5, + 1, + "r" + ], + [ + "NACKF", + 4, + 1, + "r" + ], + [ + "ADDR", + 3, + 1, + "r" + ], + [ + "RXNE", + 2, + 1, + "r" + ], + [ + "TXIS", + 1, + 1 + ], + [ + "TXE", + 0, + 1 + ] + ] + }, + { + "name": "ICR", + "offset": "0x1C", + "fields": [ + [ + "ALERTCF", + 13, + 1, + "w" + ], + [ + "TIMOUTCF", + 12, + 1, + "w" + ], + [ + "PECCF", + 11, + 1, + "w" + ], + [ + "OVRCF", + 10, + 1, + "w" + ], + [ + "ARLOCF", + 9, + 1, + "w" + ], + [ + "BERRCF", + 8, + 1, + "w" + ], + [ + "STOPCF", + 5, + 1, + "w" + ], + [ + "NACKCF", + 4, + 1, + "w" + ], + [ + "ADDRCF", + 3, + 1, + "w" + ] + ] + }, + { + "name": "PECR", + "offset": "0x20", + "fields": [ + [ + "PEC", + 0, + 8, + "r" + ] + ] + }, + { + "name": "RXDR", + "offset": "0x24", + "fields": [ + [ + "RXDATA", + 0, + 8, + "r" + ] + ] + }, + { + "name": "TXDR", + "offset": "0x28", + "fields": [ + [ + "TXDATA", + 0, + 8 + ] + ] + } + ] + }, + { + "name": "I2C2", + "base": "0x40005800", + "interrupts": [ + "I2C2_EV", + "I2C2_ER" + ], + "derived_from": "I2C1" + }, + { + "name": "USB_FS_device", + "base": "0x40005C00", + "interrupts": [ + "USB_HP", + "USB_LP", + "USBWakeUP" + ], + "registers": [ + { + "name": "EP0R", + "offset": "0x00", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "EP1R", + "offset": "0x04", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "EP2R", + "offset": "0x08", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "EP3R", + "offset": "0x0C", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "EP4R", + "offset": "0x10", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "EP5R", + "offset": "0x14", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "EP6R", + "offset": "0x18", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "EP7R", + "offset": "0x1C", + "fields": [ + [ + "EA", + 0, + 4 + ], + [ + "STAT_TX", + 4, + 2 + ], + [ + "DTOG_TX", + 6, + 1 + ], + [ + "CTR_TX", + 7, + 1 + ], + [ + "EP_KIND", + 8, + 1 + ], + [ + "EP_TYPE", + 9, + 2 + ], + [ + "SETUP", + 11, + 1 + ], + [ + "STAT_RX", + 12, + 2 + ], + [ + "DTOG_RX", + 14, + 1 + ], + [ + "CTR_RX", + 15, + 1 + ] + ] + }, + { + "name": "CNTR", + "offset": "0x40", + "fields": [ + [ + "FRES", + 0, + 1 + ], + [ + "PDWN", + 1, + 1 + ], + [ + "LP_MODE", + 2, + 1 + ], + [ + "FSUSP", + 3, + 1 + ], + [ + "RESUME", + 4, + 1 + ], + [ + "L1RESUME", + 5, + 1 + ], + [ + "L1REQM", + 7, + 1 + ], + [ + "ESOFM", + 8, + 1 + ], + [ + "SOFM", + 9, + 1 + ], + [ + "RESETM", + 10, + 1 + ], + [ + "SUSPM", + 11, + 1 + ], + [ + "WKUPM", + 12, + 1 + ], + [ + "ERRM", + 13, + 1 + ], + [ + "PMAOVRM", + 14, + 1 + ], + [ + "CTRM", + 15, + 1 + ] + ] + }, + { + "name": "ISTR", + "offset": "0x44", + "fields": [ + [ + "EP_ID", + 0, + 4 + ], + [ + "DIR", + 4, + 1 + ], + [ + "L1REQ", + 7, + 1 + ], + [ + "ESOF", + 8, + 1 + ], + [ + "SOF", + 9, + 1 + ], + [ + "RESET", + 10, + 1 + ], + [ + "SUSP", + 11, + 1 + ], + [ + "WKUP", + 12, + 1 + ], + [ + "ERR", + 13, + 1 + ], + [ + "PMAOVR", + 14, + 1 + ], + [ + "CTR", + 15, + 1 + ] + ] + }, + { + "name": "FNR", + "offset": "0x48", + "fields": [ + [ + "FN", + 0, + 11, + "r" + ], + [ + "LSOF", + 11, + 2, + "r" + ], + [ + "LCK", + 13, + 1, + "r" + ], + [ + "RXDM", + 14, + 1, + "r" + ], + [ + "RXDP", + 15, + 1, + "r" + ] + ] + }, + { + "name": "DADDR", + "offset": "0x4C", + "fields": [ + [ + "ADD", + 0, + 7 + ], + [ + "EF", + 7, + 1 + ] + ] + }, + { + "name": "BTABLE", + "offset": "0x50", + "fields": [ + [ + "BTABLE", + 3, + 13 + ] + ] + } + ] + }, + { + "name": "FDCAN1", + "base": "0x40006400", + "interrupts": [ + "FDCAN1_IT0", + "FDCAN1_IT1" + ], + "registers": [ + { + "name": "CREL", + "offset": "0x00", + "reset": "0x32141218", + "fields": [ + [ + "DAY", + 0, + 8, + "r" + ], + [ + "MON", + 8, + 8, + "r" + ], + [ + "YEAR", + 16, + 4, + "r" + ], + [ + "SUBSTEP", + 20, + 4, + "r" + ], + [ + "STEP", + 24, + 4, + "r" + ], + [ + "REL", + 28, + 4, + "r" + ] + ] + }, + { + "name": "ENDN", + "offset": "0x04", + "reset": "0x87654321", + "fields": [ + [ + "ETV", + 0, + 32, + "r" + ] + ] + }, + { + "name": "DBTP", + "offset": "0x0C", + "reset": "0x00000A33", + "fields": [ + [ + "DSJW", + 0, + 4 + ], + [ + "DTSEG2", + 4, + 4 + ], + [ + "DTSEG1", + 8, + 5 + ], + [ + "DBRP", + 16, + 5 + ], + [ + "TDC", + 23, + 1 + ] + ] + }, + { + "name": "TEST", + "offset": "0x10", + "fields": [ + [ + "LBCK", + 4, + 1 + ], + [ + "TX", + 5, + 2 + ], + [ + "RX", + 7, + 1, + "r" + ] + ] + }, + { + "name": "RWD", + "offset": "0x14", + "fields": [ + [ + "WDC", + 0, + 8 + ], + [ + "WDV", + 8, + 8, + "r" + ] + ] + }, + { + "name": "CCCR", + "offset": "0x18", + "reset": "0x00000001", + "fields": [ + [ + "INIT", + 0, + 1 + ], + [ + "CCE", + 1, + 1 + ], + [ + "ASM", + 2, + 1 + ], + [ + "CSA", + 3, + 1, + "r" + ], + [ + "CSR", + 4, + 1 + ], + [ + "MON", + 5, + 1 + ], + [ + "DAR", + 6, + 1 + ], + [ + "TEST", + 7, + 1 + ], + [ + "FDOE", + 8, + 1 + ], + [ + "BRSE", + 9, + 1 + ], + [ + "PXHD", + 12, + 1 + ], + [ + "EFBI", + 13, + 1 + ], + [ + "TXP", + 14, + 1 + ], + [ + "NISO", + 15, + 1 + ] + ] + }, + { + "name": "NBTP", + "offset": "0x1C", + "reset": "0x06000A03", + "fields": [ + [ + "NTSEG2", + 0, + 7 + ], + [ + "NTSEG1", + 8, + 8 + ], + [ + "NBRP", + 16, + 9 + ], + [ + "NSJW", + 25, + 7 + ] + ] + }, + { + "name": "TSCC", + "offset": "0x20", + "fields": [ + [ + "TSS", + 0, + 2 + ], + [ + "TCP", + 16, + 4 + ] + ] + }, + { + "name": "TSCV", + "offset": "0x24", + "fields": [ + [ + "TSC", + 0, + 16 + ] + ] + }, + { + "name": "TOCC", + "offset": "0x28", + "reset": "0xFFFF0000", + "fields": [ + [ + "ETOC", + 0, + 1 + ], + [ + "TOS", + 1, + 2 + ], + [ + "TOP", + 16, + 16 + ] + ] + }, + { + "name": "TOCV", + "offset": "0x2C", + "reset": "0x0000FFFF", + "fields": [ + [ + "TOC", + 0, + 16 + ] + ] + }, + { + "name": "ECR", + "offset": "0x40", + "fields": [ + [ + "TEC", + 0, + 8, + "r" + ], + [ + "REC", + 8, + 7, + "r" + ], + [ + "RP", + 15, + 1, + "r" + ], + [ + "CEL", + 16, + 8 + ] + ] + }, + { + "name": "PSR", + "offset": "0x44", + "reset": "0x00000707", + "fields": [ + [ + "LEC", + 0, + 3 + ], + [ + "ACT", + 3, + 2, + "r" + ], + [ + "EP", + 5, + 1, + "r" + ], + [ + "EW", + 6, + 1, + "r" + ], + [ + "BO", + 7, + 1, + "r" + ], + [ + "DLEC", + 8, + 3 + ], + [ + "RESI", + 11, + 1 + ], + [ + "RBRS", + 12, + 1 + ], + [ + "REDL", + 13, + 1 + ], + [ + "PXE", + 14, + 1 + ], + [ + "TDCV", + 16, + 7, + "r" + ] + ] + }, + { + "name": "TDCR", + "offset": "0x48", + "fields": [ + [ + "TDCF", + 0, + 7 + ], + [ + "TDCO", + 8, + 7 + ] + ] + }, + { + "name": "IR", + "offset": "0x50", + "fields": [ + [ + "RF0N", + 0, + 1 + ], + [ + "RF0F", + 1, + 1 + ], + [ + "RF0L", + 2, + 1 + ], + [ + "RF1N", + 3, + 1 + ], + [ + "RF1F", + 4, + 1 + ], + [ + "RF1L", + 5, + 1 + ], + [ + "HPM", + 6, + 1 + ], + [ + "TC", + 7, + 1 + ], + [ + "TCF", + 8, + 1 + ], + [ + "TFE", + 9, + 1 + ], + [ + "TEFN", + 10, + 1 + ], + [ + "TEFF", + 11, + 1 + ], + [ + "TEFL", + 12, + 1 + ], + [ + "TSW", + 13, + 1 + ], + [ + "MRAF", + 14, + 1 + ], + [ + "TOO", + 15, + 1 + ], + [ + "ELO", + 16, + 1 + ], + [ + "EP", + 17, + 1 + ], + [ + "EW", + 18, + 1 + ], + [ + "BO", + 19, + 1 + ], + [ + "WDI", + 20, + 1 + ], + [ + "PEA", + 21, + 1 + ], + [ + "PED", + 22, + 1 + ], + [ + "ARA", + 23, + 1 + ] + ] + }, + { + "name": "IE", + "offset": "0x54", + "fields": [ + [ + "RF0NE", + 0, + 1 + ], + [ + "RF0FE", + 1, + 1 + ], + [ + "RF0LE", + 2, + 1 + ], + [ + "RF1NE", + 3, + 1 + ], + [ + "RF1FE", + 4, + 1 + ], + [ + "RF1LE", + 5, + 1 + ], + [ + "HPME", + 6, + 1 + ], + [ + "TCE", + 7, + 1 + ], + [ + "TCFE", + 8, + 1 + ], + [ + "TFEE", + 9, + 1 + ], + [ + "TEFNE", + 10, + 1 + ], + [ + "TEFFE", + 11, + 1 + ], + [ + "TEFLE", + 12, + 1 + ], + [ + "TSWE", + 13, + 1 + ], + [ + "MRAFE", + 14, + 1 + ], + [ + "TOOE", + 15, + 1 + ], + [ + "ELOE", + 16, + 1 + ], + [ + "EPE", + 17, + 1 + ], + [ + "EWE", + 18, + 1 + ], + [ + "BOE", + 19, + 1 + ], + [ + "WDIE", + 20, + 1 + ], + [ + "PEAE", + 21, + 1 + ], + [ + "PEDE", + 22, + 1 + ], + [ + "ARAE", + 23, + 1 + ] + ] + }, + { + "name": "ILS", + "offset": "0x58", + "fields": [ + [ + "RXFIFO0", + 0, + 1 + ], + [ + "RXFIFO1", + 1, + 1 + ], + [ + "SMSG", + 2, + 1 + ], + [ + "TFERR", + 3, + 1 + ], + [ + "MISC", + 4, + 1 + ], + [ + "BERR", + 5, + 1 + ], + [ + "PERR", + 6, + 1 + ] + ] + }, + { + "name": "ILE", + "offset": "0x5C", + "fields": [ + [ + "EINT0", + 0, + 1 + ], + [ + "EINT1", + 1, + 1 + ] + ] + }, + { + "name": "RXGFC", + "offset": "0x80", + "fields": [ + [ + "RRFE", + 0, + 1 + ], + [ + "RRFS", + 1, + 1 + ], + [ + "ANFE", + 2, + 2 + ], + [ + "ANFS", + 4, + 2 + ], + [ + "F1OM", + 8, + 1 + ], + [ + "F0OM", + 9, + 1 + ], + [ + "LSS", + 16, + 5 + ], + [ + "LSE", + 24, + 4 + ] + ] + }, + { + "name": "XIDAM", + "offset": "0x84", + "reset": "0x1FFFFFFF", + "fields": [ + [ + "EIDM", + 0, + 29 + ] + ] + }, + { + "name": "HPMS", + "offset": "0x88", + "fields": [ + [ + "BIDX", + 0, + 3, + "r" + ], + [ + "MSI", + 6, + 2, + "r" + ], + [ + "FIDX", + 8, + 5, + "r" + ], + [ + "FLST", + 15, + 1, + "r" + ] + ] + }, + { + "name": "RXF0S", + "offset": "0x90", + "fields": [ + [ + "F0FL", + 0, + 4, + "r" + ], + [ + "F0GI", + 8, + 2, + "r" + ], + [ + "F0PI", + 16, + 2, + "r" + ], + [ + "F0F", + 24, + 1, + "r" + ], + [ + "RF0L", + 25, + 1, + "r" + ] + ] + }, + { + "name": "RXF0A", + "offset": "0x94", + "fields": [ + [ + "F0AI", + 0, + 3 + ] + ] + }, + { + "name": "RXF1S", + "offset": "0x98", + "fields": [ + [ + "F1FL", + 0, + 4, + "r" + ], + [ + "F1GI", + 8, + 2, + "r" + ], + [ + "F1PI", + 16, + 2, + "r" + ], + [ + "F1F", + 24, + 1, + "r" + ], + [ + "RF1L", + 25, + 1, + "r" + ] + ] + }, + { + "name": "RXF1A", + "offset": "0x9C", + "fields": [ + [ + "F1AI", + 0, + 3 + ] + ] + }, + { + "name": "TXBC", + "offset": "0xC0", + "fields": [ + [ + "TFQM", + 24, + 1 + ] + ] + }, + { + "name": "TXFQS", + "offset": "0xC4", + "reset": "0x00000003", + "fields": [ + [ + "TFFL", + 0, + 3, + "r" + ], + [ + "TFGI", + 8, + 2, + "r" + ], + [ + "TFQPI", + 16, + 2, + "r" + ], + [ + "TFQF", + 21, + 1, + "r" + ] + ] + }, + { + "name": "TXBRP", + "offset": "0xC8", + "fields": [ + [ + "TRP", + 0, + 3, + "r" + ] + ] + }, + { + "name": "TXBAR", + "offset": "0xCC", + "fields": [ + [ + "AR", + 0, + 3 + ] + ] + }, + { + "name": "TXBCR", + "offset": "0xD0", + "fields": [ + [ + "CR", + 0, + 3 + ] + ] + }, + { + "name": "TXBTO", + "offset": "0xD4", + "fields": [ + [ + "TO", + 0, + 3, + "r" + ] + ] + }, + { + "name": "TXBCF", + "offset": "0xD8", + "fields": [ + [ + "CF", + 0, + 3, + "r" + ] + ] + }, + { + "name": "TXBTIE", + "offset": "0xDC", + "fields": [ + [ + "TIE", + 0, + 3 + ] + ] + }, + { + "name": "TXBCIE", + "offset": "0xE0", + "fields": [ + [ + "CFIE", + 0, + 3 + ] + ] + }, + { + "name": "TXEFS", + "offset": "0xE4", + "fields": [ + [ + "EFFL", + 0, + 3, + "r" + ], + [ + "EFGI", + 8, + 2, + "r" + ], + [ + "EFPI", + 16, + 2, + "r" + ], + [ + "EFF", + 24, + 1, + "r" + ], + [ + "TEFL", + 25, + 1, + "r" + ] + ] + }, + { + "name": "TXEFA", + "offset": "0xE8", + "fields": [ + [ + "EFAI", + 0, + 2 + ] + ] + }, + { + "name": "CKDIV", + "offset": "0x100", + "fields": [ + [ + "PDIV", + 0, + 4 + ] + ] + } + ] + }, + { + "name": "FDCAN2", + "base": "0x40006800", + "interrupts": [ + "FDCAN2_IT0", + "FDCAN2_IT1" + ], + "derived_from": "FDCAN1" + }, + { + "name": "FDCAN3", + "base": "0x40006C00", + "interrupts": [ + "FDCAN3_IT0", + "FDCAN3_IT1" + ], + "derived_from": "FDCAN1" + }, + { + "name": "PWR", + "base": "0x40007000", + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "reset": "0x00000200", + "fields": [ + [ + "LPMS", + 0, + 3 + ], + [ + "FPD_STOP", + 3, + 1 + ], + [ + "DBP", + 8, + 1 + ], + [ + "VOS", + 9, + 2 + ], + [ + "LPR", + 14, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "PVDE", + 0, + 1 + ], + [ + "PVDLS", + 1, + 3 + ], + [ + "PVMEN1", + 6, + 1 + ], + [ + "PVMEN2", + 7, + 1 + ] + ] + }, + { + "name": "CR3", + "offset": "0x08", + "reset": "0x00008000", + "fields": [ + [ + "EWUP1", + 0, + 1 + ], + [ + "EWUP2", + 1, + 1 + ], + [ + "EWUP3", + 2, + 1 + ], + [ + "EWUP4", + 3, + 1 + ], + [ + "EWUP5", + 4, + 1 + ], + [ + "RRS", + 8, + 1 + ], + [ + "APC", + 10, + 1 + ], + [ + "UCPD1_STDBY", + 13, + 1 + ], + [ + "UCPD1_DBDIS", + 14, + 1 + ], + [ + "EIWUL", + 15, + 1 + ] + ] + }, + { + "name": "CR4", + "offset": "0x0C", + "fields": [ + [ + "WP1", + 0, + 1 + ], + [ + "WP2", + 1, + 1 + ], + [ + "WP3", + 2, + 1 + ], + [ + "WP4", + 3, + 1 + ], + [ + "WP5", + 4, + 1 + ], + [ + "VBE", + 8, + 1 + ], + [ + "VBRS", + 9, + 1 + ] + ] + }, + { + "name": "SR1", + "offset": "0x10", + "fields": [ + [ + "WUF1", + 0, + 1, + "r" + ], + [ + "WUF2", + 1, + 1, + "r" + ], + [ + "WUF3", + 2, + 1, + "r" + ], + [ + "WUF4", + 3, + 1, + "r" + ], + [ + "WUF5", + 4, + 1, + "r" + ], + [ + "SBF", + 8, + 1, + "r" + ], + [ + "WUFI", + 15, + 1, + "r" + ] + ] + }, + { + "name": "SR2", + "offset": "0x14", + "fields": [ + [ + "PVMO4", + 15, + 1, + "r" + ], + [ + "PVMO3", + 14, + 1, + "r" + ], + [ + "PVMO2", + 13, + 1, + "r" + ], + [ + "PVMO1", + 12, + 1, + "r" + ], + [ + "PVDO", + 11, + 1, + "r" + ], + [ + "VOSF", + 10, + 1, + "r" + ], + [ + "REGLPF", + 9, + 1, + "r" + ], + [ + "REGLPS", + 8, + 1, + "r" + ] + ] + }, + { + "name": "SCR", + "offset": "0x18", + "fields": [ + [ + "CWUF1", + 0, + 1, + "w" + ], + [ + "CWUF2", + 1, + 1, + "w" + ], + [ + "CWUF3", + 2, + 1, + "w" + ], + [ + "CWUF4", + 3, + 1, + "w" + ], + [ + "CWUF5", + 4, + 1, + "w" + ], + [ + "CSBF", + 8, + 1, + "w" + ] + ] + }, + { + "name": "PUCRA", + "offset": "0x20", + "fields": [ + [ + "PU0", + 0, + 1 + ], + [ + "PU1", + 1, + 1 + ], + [ + "PU2", + 2, + 1 + ], + [ + "PU3", + 3, + 1 + ], + [ + "PU4", + 4, + 1 + ], + [ + "PU5", + 5, + 1 + ], + [ + "PU6", + 6, + 1 + ], + [ + "PU7", + 7, + 1 + ], + [ + "PU8", + 8, + 1 + ], + [ + "PU9", + 9, + 1 + ], + [ + "PU10", + 10, + 1 + ], + [ + "PU11", + 11, + 1 + ], + [ + "PU12", + 12, + 1 + ], + [ + "PU13", + 13, + 1 + ], + [ + "PU15", + 15, + 1 + ] + ] + }, + { + "name": "PDCRA", + "offset": "0x24", + "fields": [ + [ + "PD0", + 0, + 1 + ], + [ + "PD1", + 1, + 1 + ], + [ + "PD2", + 2, + 1 + ], + [ + "PD3", + 3, + 1 + ], + [ + "PD4", + 4, + 1 + ], + [ + "PD5", + 5, + 1 + ], + [ + "PD6", + 6, + 1 + ], + [ + "PD7", + 7, + 1 + ], + [ + "PD8", + 8, + 1 + ], + [ + "PD9", + 9, + 1 + ], + [ + "PD10", + 10, + 1 + ], + [ + "PD11", + 11, + 1 + ], + [ + "PD12", + 12, + 1 + ], + [ + "PD14", + 14, + 1 + ] + ] + }, + { + "name": "PUCRB", + "offset": "0x28", + "fields": [ + [ + "PU0", + 0, + 1 + ], + [ + "PU1", + 1, + 1 + ], + [ + "PU2", + 2, + 1 + ], + [ + "PU3", + 3, + 1 + ], + [ + "PU4", + 4, + 1 + ], + [ + "PU5", + 5, + 1 + ], + [ + "PU6", + 6, + 1 + ], + [ + "PU7", + 7, + 1 + ], + [ + "PU8", + 8, + 1 + ], + [ + "PU9", + 9, + 1 + ], + [ + "PU10", + 10, + 1 + ], + [ + "PU11", + 11, + 1 + ], + [ + "PU12", + 12, + 1 + ], + [ + "PU13", + 13, + 1 + ], + [ + "PU14", + 14, + 1 + ], + [ + "PU15", + 15, + 1 + ] + ] + }, + { + "name": "PDCRB", + "offset": "0x2C", + "fields": [ + [ + "PD0", + 0, + 1 + ], + [ + "PD1", + 1, + 1 + ], + [ + "PD2", + 2, + 1 + ], + [ + "PD3", + 3, + 1 + ], + [ + "PD5", + 5, + 1 + ], + [ + "PD6", + 6, + 1 + ], + [ + "PD7", + 7, + 1 + ], + [ + "PD8", + 8, + 1 + ], + [ + "PD9", + 9, + 1 + ], + [ + "PD10", + 10, + 1 + ], + [ + "PD11", + 11, + 1 + ], + [ + "PD12", + 12, + 1 + ], + [ + "PD13", + 13, + 1 + ], + [ + "PD14", + 14, + 1 + ], + [ + "PD15", + 15, + 1 + ] + ] + }, + { + "name": "PUCRC", + "offset": "0x30", + "fields": [ + [ + "PU0", + 0, + 1 + ], + [ + "PU1", + 1, + 1 + ], + [ + "PU2", + 2, + 1 + ], + [ + "PU3", + 3, + 1 + ], + [ + "PU4", + 4, + 1 + ], + [ + "PU5", + 5, + 1 + ], + [ + "PU6", + 6, + 1 + ], + [ + "PU7", + 7, + 1 + ], + [ + "PU8", + 8, + 1 + ], + [ + "PU9", + 9, + 1 + ], + [ + "PU10", + 10, + 1 + ], + [ + "PU11", + 11, + 1 + ], + [ + "PU12", + 12, + 1 + ], + [ + "PU13", + 13, + 1 + ], + [ + "PU14", + 14, + 1 + ], + [ + "PU15", + 15, + 1 + ] + ] + }, + { + "name": "PDCRC", + "offset": "0x34", + "fields": [ + [ + "PD0", + 0, + 1 + ], + [ + "PD1", + 1, + 1 + ], + [ + "PD2", + 2, + 1 + ], + [ + "PD3", + 3, + 1 + ], + [ + "PD4", + 4, + 1 + ], + [ + "PD5", + 5, + 1 + ], + [ + "PD6", + 6, + 1 + ], + [ + "PD7", + 7, + 1 + ], + [ + "PD8", + 8, + 1 + ], + [ + "PD9", + 9, + 1 + ], + [ + "PD10", + 10, + 1 + ], + [ + "PD11", + 11, + 1 + ], + [ + "PD12", + 12, + 1 + ], + [ + "PD13", + 13, + 1 + ], + [ + "PD14", + 14, + 1 + ], + [ + "PD15", + 15, + 1 + ] + ] + }, + { + "name": "PUCRD", + "offset": "0x38", + "fields": [ + [ + "PU0", + 0, + 1 + ], + [ + "PU1", + 1, + 1 + ], + [ + "PU2", + 2, + 1 + ], + [ + "PU3", + 3, + 1 + ], + [ + "PU4", + 4, + 1 + ], + [ + "PU5", + 5, + 1 + ], + [ + "PU6", + 6, + 1 + ], + [ + "PU7", + 7, + 1 + ], + [ + "PU8", + 8, + 1 + ], + [ + "PU9", + 9, + 1 + ], + [ + "PU10", + 10, + 1 + ], + [ + "PU11", + 11, + 1 + ], + [ + "PU12", + 12, + 1 + ], + [ + "PU13", + 13, + 1 + ], + [ + "PU14", + 14, + 1 + ], + [ + "PU15", + 15, + 1 + ] + ] + }, + { + "name": "PDCRD", + "offset": "0x3C", + "fields": [ + [ + "PD0", + 0, + 1 + ], + [ + "PD1", + 1, + 1 + ], + [ + "PD2", + 2, + 1 + ], + [ + "PD3", + 3, + 1 + ], + [ + "PD4", + 4, + 1 + ], + [ + "PD5", + 5, + 1 + ], + [ + "PD6", + 6, + 1 + ], + [ + "PD7", + 7, + 1 + ], + [ + "PD8", + 8, + 1 + ], + [ + "PD9", + 9, + 1 + ], + [ + "PD10", + 10, + 1 + ], + [ + "PD11", + 11, + 1 + ], + [ + "PD12", + 12, + 1 + ], + [ + "PD13", + 13, + 1 + ], + [ + "PD14", + 14, + 1 + ], + [ + "PD15", + 15, + 1 + ] + ] + }, + { + "name": "PUCRE", + "offset": "0x40", + "fields": [ + [ + "PU0", + 0, + 1 + ], + [ + "PU1", + 1, + 1 + ], + [ + "PU2", + 2, + 1 + ], + [ + "PU3", + 3, + 1 + ], + [ + "PU4", + 4, + 1 + ], + [ + "PU5", + 5, + 1 + ], + [ + "PU6", + 6, + 1 + ], + [ + "PU7", + 7, + 1 + ], + [ + "PU8", + 8, + 1 + ], + [ + "PU9", + 9, + 1 + ], + [ + "PU10", + 10, + 1 + ], + [ + "PU11", + 11, + 1 + ], + [ + "PU12", + 12, + 1 + ], + [ + "PU13", + 13, + 1 + ], + [ + "PU14", + 14, + 1 + ], + [ + "PU15", + 15, + 1 + ] + ] + }, + { + "name": "PDCRE", + "offset": "0x44", + "fields": [ + [ + "PD0", + 0, + 1 + ], + [ + "PD1", + 1, + 1 + ], + [ + "PD2", + 2, + 1 + ], + [ + "PD3", + 3, + 1 + ], + [ + "PD4", + 4, + 1 + ], + [ + "PD5", + 5, + 1 + ], + [ + "PD6", + 6, + 1 + ], + [ + "PD7", + 7, + 1 + ], + [ + "PD8", + 8, + 1 + ], + [ + "PD9", + 9, + 1 + ], + [ + "PD10", + 10, + 1 + ], + [ + "PD11", + 11, + 1 + ], + [ + "PD12", + 12, + 1 + ], + [ + "PD13", + 13, + 1 + ], + [ + "PD14", + 14, + 1 + ], + [ + "PD15", + 15, + 1 + ] + ] + }, + { + "name": "PUCRF", + "offset": "0x48", + "fields": [ + [ + "PU0", + 0, + 1 + ], + [ + "PU1", + 1, + 1 + ], + [ + "PU2", + 2, + 1 + ], + [ + "PU3", + 3, + 1 + ], + [ + "PU4", + 4, + 1 + ], + [ + "PU5", + 5, + 1 + ], + [ + "PU6", + 6, + 1 + ], + [ + "PU7", + 7, + 1 + ], + [ + "PU8", + 8, + 1 + ], + [ + "PU9", + 9, + 1 + ], + [ + "PU10", + 10, + 1 + ], + [ + "PU11", + 11, + 1 + ], + [ + "PU12", + 12, + 1 + ], + [ + "PU13", + 13, + 1 + ], + [ + "PU14", + 14, + 1 + ], + [ + "PU15", + 15, + 1 + ] + ] + }, + { + "name": "PDCRF", + "offset": "0x4C", + "fields": [ + [ + "PD0", + 0, + 1 + ], + [ + "PD1", + 1, + 1 + ], + [ + "PD2", + 2, + 1 + ], + [ + "PD3", + 3, + 1 + ], + [ + "PD4", + 4, + 1 + ], + [ + "PD5", + 5, + 1 + ], + [ + "PD6", + 6, + 1 + ], + [ + "PD7", + 7, + 1 + ], + [ + "PD8", + 8, + 1 + ], + [ + "PD9", + 9, + 1 + ], + [ + "PD10", + 10, + 1 + ], + [ + "PD11", + 11, + 1 + ], + [ + "PD12", + 12, + 1 + ], + [ + "PD13", + 13, + 1 + ], + [ + "PD14", + 14, + 1 + ], + [ + "PD15", + 15, + 1 + ] + ] + }, + { + "name": "PUCRG", + "offset": "0x50", + "fields": [ + [ + "PU0", + 0, + 1 + ], + [ + "PU1", + 1, + 1 + ], + [ + "PU2", + 2, + 1 + ], + [ + "PU3", + 3, + 1 + ], + [ + "PU4", + 4, + 1 + ], + [ + "PU5", + 5, + 1 + ], + [ + "PU6", + 6, + 1 + ], + [ + "PU7", + 7, + 1 + ], + [ + "PU8", + 8, + 1 + ], + [ + "PU9", + 9, + 1 + ], + [ + "PU10", + 10, + 1 + ] + ] + }, + { + "name": "PDCRG", + "offset": "0x54", + "fields": [ + [ + "PD0", + 0, + 1 + ], + [ + "PD1", + 1, + 1 + ], + [ + "PD2", + 2, + 1 + ], + [ + "PD3", + 3, + 1 + ], + [ + "PD4", + 4, + 1 + ], + [ + "PD5", + 5, + 1 + ], + [ + "PD6", + 6, + 1 + ], + [ + "PD7", + 7, + 1 + ], + [ + "PD8", + 8, + 1 + ], + [ + "PD9", + 9, + 1 + ], + [ + "PD10", + 10, + 1 + ] + ] + }, + { + "name": "CR5", + "offset": "0x80", + "reset": "0x00000100", + "fields": [ + [ + "R1MODE", + 8, + 1 + ] + ] + } + ], + "interrupts": [ + "PVD_PVM" + ] + }, + { + "name": "I2C3", + "base": "0x40007800", + "interrupts": [ + "I2C3_EV", + "I2C3_ER" + ], + "derived_from": "I2C1" + }, + { + "name": "LPTIM1", + "base": "0x40007C00", + "interrupts": [ + "LPTIM1" + ], + "registers": [ + { + "name": "ISR", + "offset": "0x00", + "fields": [ + [ + "DOWN", + 6, + 1, + "r" + ], + [ + "UP", + 5, + 1, + "r" + ], + [ + "ARROK", + 4, + 1, + "r" + ], + [ + "CMPOK", + 3, + 1, + "r" + ], + [ + "EXTTRIG", + 2, + 1, + "r" + ], + [ + "ARRM", + 1, + 1, + "r" + ], + [ + "CMPM", + 0, + 1, + "r" + ] + ] + }, + { + "name": "ICR", + "offset": "0x04", + "fields": [ + [ + "DOWNCF", + 6, + 1, + "w" + ], + [ + "UPCF", + 5, + 1, + "w" + ], + [ + "ARROKCF", + 4, + 1, + "w" + ], + [ + "CMPOKCF", + 3, + 1, + "w" + ], + [ + "EXTTRIGCF", + 2, + 1, + "w" + ], + [ + "ARRMCF", + 1, + 1, + "w" + ], + [ + "CMPMCF", + 0, + 1, + "w" + ] + ] + }, + { + "name": "IER", + "offset": "0x08", + "fields": [ + [ + "DOWNIE", + 6, + 1 + ], + [ + "UPIE", + 5, + 1 + ], + [ + "ARROKIE", + 4, + 1 + ], + [ + "CMPOKIE", + 3, + 1 + ], + [ + "EXTTRIGIE", + 2, + 1 + ], + [ + "ARRMIE", + 1, + 1 + ], + [ + "CMPMIE", + 0, + 1 + ] + ] + }, + { + "name": "CFGR", + "offset": "0x0C", + "fields": [ + [ + "ENC", + 24, + 1 + ], + [ + "COUNTMODE", + 23, + 1 + ], + [ + "PRELOAD", + 22, + 1 + ], + [ + "WAVPOL", + 21, + 1 + ], + [ + "WAVE", + 20, + 1 + ], + [ + "TIMOUT", + 19, + 1 + ], + [ + "TRIGEN", + 17, + 2 + ], + [ + "TRIGSEL", + 13, + 4 + ], + [ + "PRESC", + 9, + 3 + ], + [ + "TRGFLT", + 6, + 2 + ], + [ + "CKFLT", + 3, + 2 + ], + [ + "CKPOL", + 1, + 2 + ], + [ + "CKSEL", + 0, + 1 + ] + ] + }, + { + "name": "CR", + "offset": "0x10", + "fields": [ + [ + "RSTARE", + 4, + 1 + ], + [ + "COUNTRST", + 3, + 1 + ], + [ + "CNTSTRT", + 2, + 1 + ], + [ + "SNGSTRT", + 1, + 1 + ], + [ + "ENABLE", + 0, + 1 + ] + ] + }, + { + "name": "CMP", + "offset": "0x14", + "fields": [ + [ + "CMP", + 0, + 16 + ] + ] + }, + { + "name": "ARR", + "offset": "0x18", + "reset": "0x00000001", + "fields": [ + [ + "ARR", + 0, + 16 + ] + ] + }, + { + "name": "CNT", + "offset": "0x1C", + "fields": [ + [ + "CNT", + 0, + 16, + "r" + ] + ] + }, + { + "name": "OR", + "offset": "0x20", + "fields": [ + [ + "IN1", + 0, + 1 + ], + [ + "IN2", + 1, + 1 + ], + [ + "IN1_2_1", + 2, + 2 + ], + [ + "IN2_2_1", + 4, + 2 + ] + ] + } + ] + }, + { + "name": "LPUART1", + "base": "0x40008000", + "interrupts": [ + "LPUART" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "fields": [ + [ + "RXFFIE", + 31, + 1 + ], + [ + "TXFEIE", + 30, + 1 + ], + [ + "FIFOEN", + 29, + 1 + ], + [ + "M1", + 28, + 1 + ], + [ + "DEAT4", + 25, + 1 + ], + [ + "DEAT3", + 24, + 1 + ], + [ + "DEAT2", + 23, + 1 + ], + [ + "DEAT1", + 22, + 1 + ], + [ + "DEAT0", + 21, + 1 + ], + [ + "DEDT4", + 20, + 1 + ], + [ + "DEDT3", + 19, + 1 + ], + [ + "DEDT2", + 18, + 1 + ], + [ + "DEDT1", + 17, + 1 + ], + [ + "DEDT0", + 16, + 1 + ], + [ + "CMIE", + 14, + 1 + ], + [ + "MME", + 13, + 1 + ], + [ + "M0", + 12, + 1 + ], + [ + "WAKE", + 11, + 1 + ], + [ + "PCE", + 10, + 1 + ], + [ + "PS", + 9, + 1 + ], + [ + "PEIE", + 8, + 1 + ], + [ + "TXEIE", + 7, + 1 + ], + [ + "TCIE", + 6, + 1 + ], + [ + "RXNEIE", + 5, + 1 + ], + [ + "IDLEIE", + 4, + 1 + ], + [ + "TE", + 3, + 1 + ], + [ + "RE", + 2, + 1 + ], + [ + "UESM", + 1, + 1 + ], + [ + "UE", + 0, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "ADD4_7", + 28, + 4 + ], + [ + "ADD0_3", + 24, + 4 + ], + [ + "MSBFIRST", + 19, + 1 + ], + [ + "TAINV", + 18, + 1 + ], + [ + "TXINV", + 17, + 1 + ], + [ + "RXINV", + 16, + 1 + ], + [ + "SWAP", + 15, + 1 + ], + [ + "STOP", + 12, + 2 + ], + [ + "ADDM7", + 4, + 1 + ] + ] + }, + { + "name": "CR3", + "offset": "0x08", + "fields": [ + [ + "TXFTCFG", + 29, + 3 + ], + [ + "RXFTIE", + 28, + 1 + ], + [ + "RXFTCFG", + 25, + 3 + ], + [ + "TXFTIE", + 23, + 1 + ], + [ + "WUFIE", + 22, + 1 + ], + [ + "WUS", + 20, + 2 + ], + [ + "DEP", + 15, + 1 + ], + [ + "DEM", + 14, + 1 + ], + [ + "DDRE", + 13, + 1 + ], + [ + "OVRDIS", + 12, + 1 + ], + [ + "CTSIE", + 10, + 1 + ], + [ + "CTSE", + 9, + 1 + ], + [ + "RTSE", + 8, + 1 + ], + [ + "DMAT", + 7, + 1 + ], + [ + "DMAR", + 6, + 1 + ], + [ + "HDSEL", + 3, + 1 + ], + [ + "EIE", + 0, + 1 + ] + ] + }, + { + "name": "BRR", + "offset": "0x0C", + "fields": [ + [ + "BRR", + 0, + 20 + ] + ] + }, + { + "name": "RQR", + "offset": "0x18", + "fields": [ + [ + "TXFRQ", + 4, + 1, + "w" + ], + [ + "RXFRQ", + 3, + 1, + "w" + ], + [ + "MMRQ", + 2, + 1, + "w" + ], + [ + "SBKRQ", + 1, + 1, + "w" + ] + ] + }, + { + "name": "ISR", + "offset": "0x1C", + "reset": "0x008000C0", + "fields": [ + [ + "TXFT", + 27, + 1, + "r" + ], + [ + "RXFT", + 26, + 1, + "r" + ], + [ + "RXFF", + 24, + 1, + "r" + ], + [ + "TXFE", + 23, + 1, + "r" + ], + [ + "REACK", + 22, + 1, + "r" + ], + [ + "TEACK", + 21, + 1, + "r" + ], + [ + "WUF", + 20, + 1, + "r" + ], + [ + "RWU", + 19, + 1, + "r" + ], + [ + "SBKF", + 18, + 1, + "r" + ], + [ + "CMF", + 17, + 1, + "r" + ], + [ + "BUSY", + 16, + 1, + "r" + ], + [ + "CTS", + 10, + 1, + "r" + ], + [ + "CTSIF", + 9, + 1, + "r" + ], + [ + "TXE", + 7, + 1, + "r" + ], + [ + "TC", + 6, + 1, + "r" + ], + [ + "RXNE", + 5, + 1, + "r" + ], + [ + "IDLE", + 4, + 1, + "r" + ], + [ + "ORE", + 3, + 1, + "r" + ], + [ + "NF", + 2, + 1, + "r" + ], + [ + "FE", + 1, + 1, + "r" + ], + [ + "PE", + 0, + 1, + "r" + ] + ] + }, + { + "name": "ICR", + "offset": "0x20", + "fields": [ + [ + "WUCF", + 20, + 1, + "w" + ], + [ + "CMCF", + 17, + 1, + "w" + ], + [ + "CTSCF", + 9, + 1, + "w" + ], + [ + "TCCF", + 6, + 1, + "w" + ], + [ + "IDLECF", + 4, + 1, + "w" + ], + [ + "ORECF", + 3, + 1, + "w" + ], + [ + "NCF", + 2, + 1, + "w" + ], + [ + "FECF", + 1, + 1, + "w" + ], + [ + "PECF", + 0, + 1, + "w" + ] + ] + }, + { + "name": "RDR", + "offset": "0x24", + "fields": [ + [ + "RDR", + 0, + 9, + "r" + ] + ] + }, + { + "name": "TDR", + "offset": "0x28", + "fields": [ + [ + "TDR", + 0, + 9 + ] + ] + }, + { + "name": "PRESC", + "offset": "0x2C", + "fields": [ + [ + "PRESCALER", + 0, + 4 + ] + ] + } + ] + }, + { + "name": "I2C4", + "base": "0x40008400", + "interrupts": [ + "I2C4_EV", + "I2C4_ER" + ], + "derived_from": "I2C1" + }, + { + "name": "UCPD1", + "base": "0x4000A000", + "interrupts": [ + "UCPD1" + ], + "registers": [ + { + "name": "CFG1", + "offset": "0x00", + "fields": [ + [ + "HBITCLKDIV", + 0, + 6 + ], + [ + "IFRGAP", + 6, + 5 + ], + [ + "TRANSWIN", + 11, + 5 + ], + [ + "PSC_USBPDCLK", + 17, + 3 + ], + [ + "RXORDSETEN", + 20, + 9 + ], + [ + "TXDMAEN", + 29, + 1 + ], + [ + "RXDMAEN", + 30, + 1 + ], + [ + "UCPDEN", + 31, + 1 + ] + ] + }, + { + "name": "CFG2", + "offset": "0x04", + "fields": [ + [ + "RXFILTDIS", + 0, + 1 + ], + [ + "RXFILT2N3", + 1, + 1 + ], + [ + "FORCECLK", + 2, + 1 + ], + [ + "WUPEN", + 3, + 1 + ] + ] + }, + { + "name": "CR", + "offset": "0x0C", + "fields": [ + [ + "TXMODE", + 0, + 2 + ], + [ + "TXSEND", + 2, + 1 + ], + [ + "TXHRST", + 3, + 1 + ], + [ + "RXMODE", + 4, + 1 + ], + [ + "PHYRXEN", + 5, + 1 + ], + [ + "PHYCCSEL", + 6, + 1 + ], + [ + "ANASUBMODE", + 7, + 2 + ], + [ + "ANAMODE", + 9, + 1 + ], + [ + "CCENABLE", + 10, + 2 + ], + [ + "FRSRXEN", + 16, + 1 + ], + [ + "FRSTX", + 17, + 1 + ], + [ + "RDCH", + 18, + 1 + ], + [ + "CC1TCDIS", + 20, + 1 + ], + [ + "CC2TCDIS", + 21, + 1 + ] + ] + }, + { + "name": "IMR", + "offset": "0x10", + "fields": [ + [ + "TXISIE", + 0, + 1 + ], + [ + "TXMSGDISCIE", + 1, + 1 + ], + [ + "TXMSGSENTIE", + 2, + 1 + ], + [ + "TXMSGABTIE", + 3, + 1 + ], + [ + "HRSTDISCIE", + 4, + 1 + ], + [ + "HRSTSENTIE", + 5, + 1 + ], + [ + "TXUNDIE", + 6, + 1 + ], + [ + "RXNEIE", + 8, + 1 + ], + [ + "RXORDDETIE", + 9, + 1 + ], + [ + "RXHRSTDETIE", + 10, + 1 + ], + [ + "RXOVRIE", + 11, + 1 + ], + [ + "RXMSGENDIE", + 12, + 1 + ], + [ + "TYPECEVT1IE", + 14, + 1 + ], + [ + "TYPECEVT2IE", + 15, + 1 + ], + [ + "FRSEVTIE", + 20, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x14", + "fields": [ + [ + "TXIS", + 0, + 1 + ], + [ + "TXMSGDISC", + 1, + 1 + ], + [ + "TXMSGSENT", + 2, + 1 + ], + [ + "TXMSGABT", + 3, + 1 + ], + [ + "HRSTDISC", + 4, + 1 + ], + [ + "HRSTSENT", + 5, + 1 + ], + [ + "TXUND", + 6, + 1 + ], + [ + "RXNE", + 8, + 1 + ], + [ + "RXORDDET", + 9, + 1 + ], + [ + "RXHRSTDET", + 10, + 1 + ], + [ + "RXOVR", + 11, + 1 + ], + [ + "RXMSGEND", + 12, + 1 + ], + [ + "RXERR", + 13, + 1 + ], + [ + "TYPECEVT1", + 14, + 1 + ], + [ + "TYPECEVT2", + 15, + 1 + ], + [ + "TYPEC_VSTATE_CC1", + 16, + 2 + ], + [ + "TYPEC_VSTATE_CC2", + 18, + 2 + ], + [ + "FRSEVT", + 20, + 1 + ] + ] + }, + { + "name": "ICR", + "offset": "0x18", + "fields": [ + [ + "TXMSGDISCCF", + 1, + 1 + ], + [ + "TXMSGSENTCF", + 2, + 1 + ], + [ + "TXMSGABTCF", + 3, + 1 + ], + [ + "HRSTDISCCF", + 4, + 1 + ], + [ + "HRSTSENTCF", + 5, + 1 + ], + [ + "TXUNDCF", + 6, + 1 + ], + [ + "RXORDDETCF", + 9, + 1 + ], + [ + "RXHRSTDETCF", + 10, + 1 + ], + [ + "RXOVRCF", + 11, + 1 + ], + [ + "RXMSGENDCF", + 12, + 1 + ], + [ + "TYPECEVT1CF", + 14, + 1 + ], + [ + "TYPECEVT2CF", + 15, + 1 + ], + [ + "FRSEVTCF", + 20, + 1 + ] + ] + }, + { + "name": "TX_ORDSET", + "offset": "0x1C", + "fields": [ + [ + "TXORDSET", + 0, + 20 + ] + ] + }, + { + "name": "TX_PAYSZ", + "offset": "0x20", + "fields": [ + [ + "TXPAYSZ", + 0, + 10 + ] + ] + }, + { + "name": "TXDR", + "offset": "0x24", + "fields": [ + [ + "TXDATA", + 0, + 8 + ] + ] + }, + { + "name": "RX_ORDSET", + "offset": "0x28", + "fields": [ + [ + "RXORDSET", + 0, + 3, + "r" + ], + [ + "RXSOP3OF4", + 3, + 1, + "r" + ], + [ + "RXSOPKINVALID", + 4, + 3, + "r" + ] + ] + }, + { + "name": "RX_PAYSZ", + "offset": "0x2C", + "fields": [ + [ + "RXPAYSZ", + 0, + 10, + "r" + ] + ] + }, + { + "name": "RXDR", + "offset": "0x30", + "fields": [ + [ + "RXDATA", + 0, + 8, + "r" + ] + ] + }, + { + "name": "RX_ORDEXT1", + "offset": "0x34", + "fields": [ + [ + "RXSOPX1", + 0, + 20 + ] + ] + }, + { + "name": "RX_ORDEXT2", + "offset": "0x38", + "fields": [ + [ + "RXSOPX2", + 0, + 20 + ] + ] + } + ] + }, + { + "name": "SYSCFG", + "base": "0x40010000", + "registers": [ + { + "name": "MEMRMP", + "offset": "0x00", + "fields": [ + [ + "MEM_MODE", + 0, + 3 + ], + [ + "FB_mode", + 8, + 1 + ] + ] + }, + { + "name": "CFGR1", + "offset": "0x04", + "reset": "0x7C000001", + "fields": [ + [ + "BOOSTEN", + 8, + 1 + ], + [ + "ANASWVDD", + 9, + 1 + ], + [ + "I2C_PB6_FMP", + 16, + 1 + ], + [ + "I2C_PB7_FMP", + 17, + 1 + ], + [ + "I2C_PB8_FMP", + 18, + 1 + ], + [ + "I2C_PB9_FMP", + 19, + 1 + ], + [ + "I2C1_FMP", + 20, + 1 + ], + [ + "I2C2_FMP", + 21, + 1 + ], + [ + "I2C3_FMP", + 22, + 1 + ], + [ + "I2C4_FMP", + 23, + 1 + ], + [ + "FPU_IE", + 26, + 6 + ] + ] + }, + { + "name": "EXTICR1", + "offset": "0x08", + "fields": [ + [ + "EXTI3", + 12, + 4 + ], + [ + "EXTI2", + 8, + 4 + ], + [ + "EXTI1", + 4, + 4 + ], + [ + "EXTI0", + 0, + 4 + ] + ] + }, + { + "name": "EXTICR2", + "offset": "0x0C", + "fields": [ + [ + "EXTI7", + 12, + 4 + ], + [ + "EXTI6", + 8, + 4 + ], + [ + "EXTI5", + 4, + 4 + ], + [ + "EXTI4", + 0, + 4 + ] + ] + }, + { + "name": "EXTICR3", + "offset": "0x10", + "fields": [ + [ + "EXTI11", + 12, + 4 + ], + [ + "EXTI10", + 8, + 4 + ], + [ + "EXTI9", + 4, + 4 + ], + [ + "EXTI8", + 0, + 4 + ] + ] + }, + { + "name": "EXTICR4", + "offset": "0x14", + "fields": [ + [ + "EXTI15", + 12, + 4 + ], + [ + "EXTI14", + 8, + 4 + ], + [ + "EXTI13", + 4, + 4 + ], + [ + "EXTI12", + 0, + 4 + ] + ] + }, + { + "name": "SCSR", + "offset": "0x18", + "fields": [ + [ + "CCMER", + 0, + 1 + ], + [ + "CCMBSY", + 1, + 1, + "r" + ] + ] + }, + { + "name": "CFGR2", + "offset": "0x1C", + "fields": [ + [ + "CLL", + 0, + 1 + ], + [ + "SPL", + 1, + 1 + ], + [ + "PVDL", + 2, + 1 + ], + [ + "ECCL", + 3, + 1 + ], + [ + "SPF", + 8, + 1 + ] + ] + }, + { + "name": "SWPR", + "offset": "0x20", + "fields": [ + [ + "Page0_WP", + 0, + 1 + ], + [ + "Page1_WP", + 1, + 1 + ], + [ + "Page2_WP", + 2, + 1 + ], + [ + "Page3_WP", + 3, + 1 + ], + [ + "Page4_WP", + 4, + 1 + ], + [ + "Page5_WP", + 5, + 1 + ], + [ + "Page6_WP", + 6, + 1 + ], + [ + "Page7_WP", + 7, + 1 + ], + [ + "Page8_WP", + 8, + 1 + ], + [ + "Page9_WP", + 9, + 1 + ], + [ + "Page10_WP", + 10, + 1 + ], + [ + "Page11_WP", + 11, + 1 + ], + [ + "Page12_WP", + 12, + 1 + ], + [ + "Page13_WP", + 13, + 1 + ], + [ + "Page14_WP", + 14, + 1 + ], + [ + "Page15_WP", + 15, + 1 + ], + [ + "Page16_WP", + 16, + 1 + ], + [ + "Page17_WP", + 17, + 1 + ], + [ + "Page18_WP", + 18, + 1 + ], + [ + "Page19_WP", + 19, + 1 + ], + [ + "Page20_WP", + 20, + 1 + ], + [ + "Page21_WP", + 21, + 1 + ], + [ + "Page22_WP", + 22, + 1 + ], + [ + "Page23_WP", + 23, + 1 + ], + [ + "Page24_WP", + 24, + 1 + ], + [ + "Page25_WP", + 25, + 1 + ], + [ + "Page26_WP", + 26, + 1 + ], + [ + "Page27_WP", + 27, + 1 + ], + [ + "Page28_WP", + 28, + 1 + ], + [ + "Page29_WP", + 29, + 1 + ], + [ + "Page30_WP", + 30, + 1 + ], + [ + "Page31_WP", + 31, + 1 + ] + ] + }, + { + "name": "SKR", + "offset": "0x24", + "fields": [ + [ + "KEY", + 0, + 8, + "w" + ] + ] + } + ] + }, + { + "name": "VREFBUF", + "base": "0x40010030", + "registers": [ + { + "name": "CSR", + "offset": "0x00", + "reset": "0x00000002", + "fields": [ + [ + "ENVR", + 0, + 1 + ], + [ + "HIZ", + 1, + 1 + ], + [ + "VRR", + 3, + 1, + "r" + ], + [ + "VRS", + 4, + 2 + ] + ] + }, + { + "name": "CCR", + "offset": "0x04", + "fields": [ + [ + "TRIM", + 0, + 6 + ] + ] + } + ] + }, + { + "name": "COMP", + "base": "0x40010200", + "interrupts": [ + "COMP1_2_3", + "COMP4_5_6", + "COMP7" + ], + "registers": [ + { + "name": "C1CSR", + "offset": "0x00", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "INMSEL", + 4, + 3 + ], + [ + "INPSEL", + 8, + 1 + ], + [ + "POL", + 15, + 1 + ], + [ + "HYST", + 16, + 3 + ], + [ + "BLANKSEL", + 19, + 3 + ], + [ + "BRGEN", + 22, + 1 + ], + [ + "SCALEN", + 23, + 1 + ], + [ + "VALUE", + 30, + 1, + "r" + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "C2CSR", + "offset": "0x04", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "INMSEL", + 4, + 3 + ], + [ + "INPSEL", + 8, + 1 + ], + [ + "POL", + 15, + 1 + ], + [ + "HYST", + 16, + 3 + ], + [ + "BLANKSEL", + 19, + 3 + ], + [ + "BRGEN", + 22, + 1 + ], + [ + "SCALEN", + 23, + 1 + ], + [ + "VALUE", + 30, + 1, + "r" + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "C3CSR", + "offset": "0x08", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "INMSEL", + 4, + 3 + ], + [ + "INPSEL", + 8, + 1 + ], + [ + "POL", + 15, + 1 + ], + [ + "HYST", + 16, + 3 + ], + [ + "BLANKSEL", + 19, + 3 + ], + [ + "BRGEN", + 22, + 1 + ], + [ + "SCALEN", + 23, + 1 + ], + [ + "VALUE", + 30, + 1, + "r" + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "C4CSR", + "offset": "0x0C", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "INMSEL", + 4, + 3 + ], + [ + "INPSEL", + 8, + 1 + ], + [ + "POL", + 15, + 1 + ], + [ + "HYST", + 16, + 3 + ], + [ + "BLANKSEL", + 19, + 3 + ], + [ + "BRGEN", + 22, + 1 + ], + [ + "SCALEN", + 23, + 1 + ], + [ + "VALUE", + 30, + 1, + "r" + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "C5CSR", + "offset": "0x10", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "INMSEL", + 4, + 3 + ], + [ + "INPSEL", + 8, + 1 + ], + [ + "POL", + 15, + 1 + ], + [ + "HYST", + 16, + 3 + ], + [ + "BLANKSEL", + 19, + 3 + ], + [ + "BRGEN", + 22, + 1 + ], + [ + "SCALEN", + 23, + 1 + ], + [ + "VALUE", + 30, + 1, + "r" + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "C6CSR", + "offset": "0x14", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "INMSEL", + 4, + 3 + ], + [ + "INPSEL", + 8, + 1 + ], + [ + "POL", + 15, + 1 + ], + [ + "HYST", + 16, + 3 + ], + [ + "BLANKSEL", + 19, + 3 + ], + [ + "BRGEN", + 22, + 1 + ], + [ + "SCALEN", + 23, + 1 + ], + [ + "VALUE", + 30, + 1, + "r" + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "C7CSR", + "offset": "0x18", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "INMSEL", + 4, + 3 + ], + [ + "INPSEL", + 8, + 1 + ], + [ + "POL", + 15, + 1 + ], + [ + "HYST", + 16, + 3 + ], + [ + "BLANKSEL", + 19, + 3 + ], + [ + "BRGEN", + 22, + 1 + ], + [ + "SCALEN", + 23, + 1 + ], + [ + "VALUE", + 30, + 1, + "r" + ], + [ + "LOCK", + 31, + 1 + ] + ] + } + ] + }, + { + "name": "OPAMP", + "base": "0x40010300", + "registers": [ + { + "name": "OPAMP1_CSR", + "offset": "0x00", + "fields": [ + [ + "OPAEN", + 0, + 1 + ], + [ + "FORCE_VP", + 1, + 1 + ], + [ + "VP_SEL", + 2, + 2 + ], + [ + "USERTRIM", + 4, + 1 + ], + [ + "VM_SEL", + 5, + 2 + ], + [ + "OPAHSM", + 7, + 1 + ], + [ + "OPAINTOEN", + 8, + 1 + ], + [ + "CALON", + 11, + 1 + ], + [ + "CALSEL", + 12, + 2 + ], + [ + "PGA_GAIN", + 14, + 5 + ], + [ + "TRIMOFFSETP", + 19, + 5 + ], + [ + "TRIMOFFSETN", + 24, + 5 + ], + [ + "CALOUT", + 30, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP2_CSR", + "offset": "0x04", + "fields": [ + [ + "OPAEN", + 0, + 1 + ], + [ + "FORCE_VP", + 1, + 1 + ], + [ + "VP_SEL", + 2, + 2 + ], + [ + "USERTRIM", + 4, + 1 + ], + [ + "VM_SEL", + 5, + 2 + ], + [ + "OPAHSM", + 7, + 1 + ], + [ + "OPAINTOEN", + 8, + 1 + ], + [ + "CALON", + 11, + 1 + ], + [ + "CALSEL", + 12, + 2 + ], + [ + "PGA_GAIN", + 14, + 5 + ], + [ + "TRIMOFFSETP", + 19, + 5 + ], + [ + "TRIMOFFSETN", + 24, + 5 + ], + [ + "CALOUT", + 30, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP3_CSR", + "offset": "0x08", + "fields": [ + [ + "OPAEN", + 0, + 1 + ], + [ + "FORCE_VP", + 1, + 1 + ], + [ + "VP_SEL", + 2, + 2 + ], + [ + "USERTRIM", + 4, + 1 + ], + [ + "VM_SEL", + 5, + 2 + ], + [ + "OPAHSM", + 7, + 1 + ], + [ + "OPAINTOEN", + 8, + 1 + ], + [ + "CALON", + 11, + 1 + ], + [ + "CALSEL", + 12, + 2 + ], + [ + "PGA_GAIN", + 14, + 5 + ], + [ + "TRIMOFFSETP", + 19, + 5 + ], + [ + "TRIMOFFSETN", + 24, + 5 + ], + [ + "CALOUT", + 30, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP4_CSR", + "offset": "0x0C", + "fields": [ + [ + "OPAEN", + 0, + 1 + ], + [ + "FORCE_VP", + 1, + 1 + ], + [ + "VP_SEL", + 2, + 2 + ], + [ + "USERTRIM", + 4, + 1 + ], + [ + "VM_SEL", + 5, + 2 + ], + [ + "OPAHSM", + 7, + 1 + ], + [ + "OPAINTOEN", + 8, + 1 + ], + [ + "CALON", + 11, + 1 + ], + [ + "CALSEL", + 12, + 2 + ], + [ + "PGA_GAIN", + 14, + 5 + ], + [ + "TRIMOFFSETP", + 19, + 5 + ], + [ + "TRIMOFFSETN", + 24, + 5 + ], + [ + "CALOUT", + 30, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP5_CSR", + "offset": "0x10", + "fields": [ + [ + "OPAEN", + 0, + 1 + ], + [ + "FORCE_VP", + 1, + 1 + ], + [ + "VP_SEL", + 2, + 2 + ], + [ + "USERTRIM", + 4, + 1 + ], + [ + "VM_SEL", + 5, + 2 + ], + [ + "OPAHSM", + 7, + 1 + ], + [ + "OPAINTOEN", + 8, + 1 + ], + [ + "CALON", + 11, + 1 + ], + [ + "CALSEL", + 12, + 2 + ], + [ + "PGA_GAIN", + 14, + 5 + ], + [ + "TRIMOFFSETP", + 19, + 5 + ], + [ + "TRIMOFFSETN", + 24, + 5 + ], + [ + "CALOUT", + 30, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP6_CSR", + "offset": "0x14", + "fields": [ + [ + "OPAEN", + 0, + 1 + ], + [ + "FORCE_VP", + 1, + 1 + ], + [ + "VP_SEL", + 2, + 2 + ], + [ + "USERTRIM", + 4, + 1 + ], + [ + "VM_SEL", + 5, + 2 + ], + [ + "OPAHSM", + 7, + 1 + ], + [ + "OPAINTOEN", + 8, + 1 + ], + [ + "CALON", + 11, + 1 + ], + [ + "CALSEL", + 12, + 2 + ], + [ + "PGA_GAIN", + 14, + 5 + ], + [ + "TRIMOFFSETP", + 19, + 5 + ], + [ + "TRIMOFFSETN", + 24, + 5 + ], + [ + "CALOUT", + 30, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP1_TCMR", + "offset": "0x18", + "fields": [ + [ + "VMS_SEL", + 0, + 1 + ], + [ + "VPS_SEL", + 1, + 2 + ], + [ + "T1CM_EN", + 3, + 1 + ], + [ + "T8CM_EN", + 4, + 1 + ], + [ + "T20CM_EN", + 5, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP2_TCMR", + "offset": "0x1C", + "fields": [ + [ + "VMS_SEL", + 0, + 1 + ], + [ + "VPS_SEL", + 1, + 2 + ], + [ + "T1CM_EN", + 3, + 1 + ], + [ + "T8CM_EN", + 4, + 1 + ], + [ + "T20CM_EN", + 5, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP3_TCMR", + "offset": "0x20", + "fields": [ + [ + "VMS_SEL", + 0, + 1 + ], + [ + "VPS_SEL", + 1, + 2 + ], + [ + "T1CM_EN", + 3, + 1 + ], + [ + "T8CM_EN", + 4, + 1 + ], + [ + "T20CM_EN", + 5, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP4_TCMR", + "offset": "0x24", + "fields": [ + [ + "VMS_SEL", + 0, + 1 + ], + [ + "VPS_SEL", + 1, + 2 + ], + [ + "T1CM_EN", + 3, + 1 + ], + [ + "T8CM_EN", + 4, + 1 + ], + [ + "T20CM_EN", + 5, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP5_TCMR", + "offset": "0x28", + "fields": [ + [ + "VMS_SEL", + 0, + 1 + ], + [ + "VPS_SEL", + 1, + 2 + ], + [ + "T1CM_EN", + 3, + 1 + ], + [ + "T8CM_EN", + 4, + 1 + ], + [ + "T20CM_EN", + 5, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "OPAMP6_TCMR", + "offset": "0x2C", + "fields": [ + [ + "VMS_SEL", + 0, + 1 + ], + [ + "VPS_SEL", + 1, + 2 + ], + [ + "T1CM_EN", + 3, + 1 + ], + [ + "T8CM_EN", + 4, + 1 + ], + [ + "T20CM_EN", + 5, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + } + ] + }, + { + "name": "EXTI", + "base": "0x40010400", + "interrupts": [ + "EXTI0", + "EXTI1", + "EXTI2", + "EXTI3", + "EXTI4", + "EXTI9_5", + "EXTI15_10" + ], + "registers": [ + { + "name": "IMR1", + "offset": "0x00", + "reset": "0x1F840000", + "fields": [ + [ + "IM0", + 0, + 1 + ], + [ + "IM1", + 1, + 1 + ], + [ + "IM2", + 2, + 1 + ], + [ + "IM3", + 3, + 1 + ], + [ + "IM4", + 4, + 1 + ], + [ + "IM5", + 5, + 1 + ], + [ + "IM6", + 6, + 1 + ], + [ + "IM7", + 7, + 1 + ], + [ + "IM8", + 8, + 1 + ], + [ + "IM9", + 9, + 1 + ], + [ + "IM10", + 10, + 1 + ], + [ + "IM11", + 11, + 1 + ], + [ + "IM12", + 12, + 1 + ], + [ + "IM13", + 13, + 1 + ], + [ + "IM14", + 14, + 1 + ], + [ + "IM15", + 15, + 1 + ], + [ + "IM16", + 16, + 1 + ], + [ + "IM17", + 17, + 1 + ], + [ + "IM18", + 18, + 1 + ], + [ + "IM19", + 19, + 1 + ], + [ + "IM20", + 20, + 1 + ], + [ + "IM21", + 21, + 1 + ], + [ + "IM22", + 22, + 1 + ], + [ + "IM23", + 23, + 1 + ], + [ + "IM24", + 24, + 1 + ], + [ + "IM25", + 25, + 1 + ], + [ + "IM26", + 26, + 1 + ], + [ + "IM27", + 27, + 1 + ], + [ + "IM28", + 28, + 1 + ], + [ + "IM29", + 29, + 1 + ], + [ + "IM30", + 30, + 1 + ], + [ + "IM31", + 31, + 1 + ] + ] + }, + { + "name": "EMR1", + "offset": "0x04", + "fields": [ + [ + "EM0", + 0, + 1 + ], + [ + "EM1", + 1, + 1 + ], + [ + "EM2", + 2, + 1 + ], + [ + "EM3", + 3, + 1 + ], + [ + "EM4", + 4, + 1 + ], + [ + "EM5", + 5, + 1 + ], + [ + "EM6", + 6, + 1 + ], + [ + "EM7", + 7, + 1 + ], + [ + "EM8", + 8, + 1 + ], + [ + "EM9", + 9, + 1 + ], + [ + "EM10", + 10, + 1 + ], + [ + "EM11", + 11, + 1 + ], + [ + "EM12", + 12, + 1 + ], + [ + "EM13", + 13, + 1 + ], + [ + "EM14", + 14, + 1 + ], + [ + "EM15", + 15, + 1 + ], + [ + "EM16", + 16, + 1 + ], + [ + "EM17", + 17, + 1 + ], + [ + "EM18", + 18, + 1 + ], + [ + "EM19", + 19, + 1 + ], + [ + "EM20", + 20, + 1 + ], + [ + "EM21", + 21, + 1 + ], + [ + "EM22", + 22, + 1 + ], + [ + "EM23", + 23, + 1 + ], + [ + "EM24", + 24, + 1 + ], + [ + "EM25", + 25, + 1 + ], + [ + "EM26", + 26, + 1 + ], + [ + "EM27", + 27, + 1 + ], + [ + "EM28", + 28, + 1 + ], + [ + "EM29", + 29, + 1 + ], + [ + "EM30", + 30, + 1 + ], + [ + "EM31", + 31, + 1 + ] + ] + }, + { + "name": "RTSR1", + "offset": "0x08", + "fields": [ + [ + "RT0", + 0, + 1 + ], + [ + "RT1", + 1, + 1 + ], + [ + "RT2", + 2, + 1 + ], + [ + "RT3", + 3, + 1 + ], + [ + "RT4", + 4, + 1 + ], + [ + "RT5", + 5, + 1 + ], + [ + "RT6", + 6, + 1 + ], + [ + "RT7", + 7, + 1 + ], + [ + "RT8", + 8, + 1 + ], + [ + "RT9", + 9, + 1 + ], + [ + "RT10", + 10, + 1 + ], + [ + "RT11", + 11, + 1 + ], + [ + "RT12", + 12, + 1 + ], + [ + "RT13", + 13, + 1 + ], + [ + "RT14", + 14, + 1 + ], + [ + "RT15", + 15, + 1 + ], + [ + "RT16", + 16, + 1 + ], + [ + "RT18", + 18, + 1 + ], + [ + "RT19", + 19, + 1 + ], + [ + "RT20", + 20, + 1 + ], + [ + "RT21", + 21, + 1 + ], + [ + "RT22", + 22, + 1 + ], + [ + "RT", + 29, + 3 + ] + ] + }, + { + "name": "FTSR1", + "offset": "0x0C", + "fields": [ + [ + "FT0", + 0, + 1 + ], + [ + "FT1", + 1, + 1 + ], + [ + "FT2", + 2, + 1 + ], + [ + "FT3", + 3, + 1 + ], + [ + "FT4", + 4, + 1 + ], + [ + "FT5", + 5, + 1 + ], + [ + "FT6", + 6, + 1 + ], + [ + "FT7", + 7, + 1 + ], + [ + "FT8", + 8, + 1 + ], + [ + "FT9", + 9, + 1 + ], + [ + "FT10", + 10, + 1 + ], + [ + "FT11", + 11, + 1 + ], + [ + "FT12", + 12, + 1 + ], + [ + "FT13", + 13, + 1 + ], + [ + "FT14", + 14, + 1 + ], + [ + "FT15", + 15, + 1 + ], + [ + "FT16", + 16, + 1 + ], + [ + "FT18", + 18, + 1 + ], + [ + "FT19", + 19, + 1 + ], + [ + "FT20", + 20, + 1 + ], + [ + "FT21", + 21, + 1 + ], + [ + "FT22", + 22, + 1 + ] + ] + }, + { + "name": "SWIER1", + "offset": "0x10", + "fields": [ + [ + "SWI0", + 0, + 1 + ], + [ + "SWI1", + 1, + 1 + ], + [ + "SWI2", + 2, + 1 + ], + [ + "SWI3", + 3, + 1 + ], + [ + "SWI4", + 4, + 1 + ], + [ + "SWI5", + 5, + 1 + ], + [ + "SWI6", + 6, + 1 + ], + [ + "SWI7", + 7, + 1 + ], + [ + "SWI8", + 8, + 1 + ], + [ + "SWI9", + 9, + 1 + ], + [ + "SWI10", + 10, + 1 + ], + [ + "SWI11", + 11, + 1 + ], + [ + "SWI12", + 12, + 1 + ], + [ + "SWI13", + 13, + 1 + ], + [ + "SWI14", + 14, + 1 + ], + [ + "SWI15", + 15, + 1 + ], + [ + "SWI16", + 16, + 1 + ], + [ + "SWI18", + 18, + 1 + ], + [ + "SWI19", + 19, + 1 + ], + [ + "SWI20", + 20, + 1 + ], + [ + "SWI21", + 21, + 1 + ], + [ + "SWI22", + 22, + 1 + ] + ] + }, + { + "name": "PR1", + "offset": "0x14", + "fields": [ + [ + "PIF0", + 0, + 1 + ], + [ + "PIF1", + 1, + 1 + ], + [ + "PIF2", + 2, + 1 + ], + [ + "PIF3", + 3, + 1 + ], + [ + "PIF4", + 4, + 1 + ], + [ + "PIF5", + 5, + 1 + ], + [ + "PIF6", + 6, + 1 + ], + [ + "PIF7", + 7, + 1 + ], + [ + "PIF8", + 8, + 1 + ], + [ + "PIF9", + 9, + 1 + ], + [ + "PIF10", + 10, + 1 + ], + [ + "PIF11", + 11, + 1 + ], + [ + "PIF12", + 12, + 1 + ], + [ + "PIF13", + 13, + 1 + ], + [ + "PIF14", + 14, + 1 + ], + [ + "PIF15", + 15, + 1 + ], + [ + "PIF16", + 16, + 1 + ], + [ + "PIF17", + 17, + 1 + ], + [ + "PIF18", + 18, + 1 + ], + [ + "PIF19", + 19, + 1 + ], + [ + "PIF20", + 20, + 1 + ], + [ + "PIF21", + 21, + 1 + ], + [ + "PIF22", + 22, + 1 + ], + [ + "PIF29", + 29, + 1 + ], + [ + "PIF30", + 30, + 1 + ], + [ + "PIF31", + 31, + 1 + ] + ] + }, + { + "name": "IMR2", + "offset": "0x20", + "reset": "0x00000C3C", + "fields": [ + [ + "IM32", + 0, + 1 + ], + [ + "IM33", + 1, + 1 + ], + [ + "IM34", + 2, + 1 + ], + [ + "IM35", + 3, + 1 + ], + [ + "IM36", + 4, + 1 + ], + [ + "IM37", + 5, + 1 + ], + [ + "IM38", + 6, + 1 + ], + [ + "IM39", + 7, + 1 + ], + [ + "IM40", + 8, + 1 + ], + [ + "IM41", + 9, + 1 + ], + [ + "IM42", + 10, + 1 + ], + [ + "IM43", + 11, + 1 + ] + ] + }, + { + "name": "EMR2", + "offset": "0x24", + "fields": [ + [ + "EM32", + 0, + 1 + ], + [ + "EM33", + 1, + 1 + ], + [ + "EM34", + 2, + 1 + ], + [ + "EM35", + 3, + 1 + ], + [ + "EM36", + 4, + 1 + ], + [ + "EM37", + 5, + 1 + ], + [ + "EM38", + 6, + 1 + ], + [ + "EM39", + 7, + 1 + ], + [ + "EM40", + 8, + 1 + ] + ] + }, + { + "name": "RTSR2", + "offset": "0x28", + "fields": [ + [ + "RT32", + 0, + 1 + ], + [ + "RT33", + 1, + 1 + ], + [ + "RT38", + 6, + 1 + ], + [ + "RT39", + 7, + 1 + ], + [ + "RT40", + 8, + 1 + ], + [ + "RT41", + 9, + 1 + ] + ] + }, + { + "name": "FTSR2", + "offset": "0x2C", + "fields": [ + [ + "FT35", + 3, + 1 + ], + [ + "FT36", + 4, + 1 + ], + [ + "FT37", + 5, + 1 + ], + [ + "FT38", + 6, + 1 + ] + ] + }, + { + "name": "SWIER2", + "offset": "0x30", + "fields": [ + [ + "SWI35", + 3, + 1 + ], + [ + "SWI36", + 4, + 1 + ], + [ + "SWI37", + 5, + 1 + ], + [ + "SWI38", + 6, + 1 + ] + ] + }, + { + "name": "PR2", + "offset": "0x34", + "fields": [ + [ + "PIF35", + 3, + 1 + ], + [ + "PIF36", + 4, + 1 + ], + [ + "PIF37", + 5, + 1 + ], + [ + "PIF38", + 6, + 1 + ] + ] + } + ] + }, + { + "name": "TIM1", + "base": "0x40012C00", + "interrupts": [ + "TIM1_BRK_TIM15", + "TIM1_UP_TIM16", + "TIM1_TRG_COM", + "TIM1_CC" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "size": 16, + "fields": [ + [ + "CEN", + 0, + 1 + ], + [ + "UDIS", + 1, + 1 + ], + [ + "URS", + 2, + 1 + ], + [ + "OPM", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CMS", + 5, + 2 + ], + [ + "ARPE", + 7, + 1 + ], + [ + "CKD", + 8, + 2 + ], + [ + "UIFREMAP", + 11, + 1 + ], + [ + "DITHEN", + 12, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "CCPC", + 0, + 1 + ], + [ + "CCUS", + 2, + 1 + ], + [ + "CCDS", + 3, + 1 + ], + [ + "MMS", + 4, + 3 + ], + [ + "TI1S", + 7, + 1 + ], + [ + "OIS1", + 8, + 1 + ], + [ + "OIS1N", + 9, + 1 + ], + [ + "OIS2", + 10, + 1 + ], + [ + "OIS2N", + 11, + 1 + ], + [ + "OIS3", + 12, + 1 + ], + [ + "OIS3N", + 13, + 1 + ], + [ + "OIS4", + 14, + 1 + ], + [ + "OIS4N", + 15, + 1 + ], + [ + "OIS5", + 16, + 1 + ], + [ + "OIS6", + 18, + 1 + ], + [ + "MMS2", + 20, + 4 + ], + [ + "MMS_1", + 25, + 1 + ] + ] + }, + { + "name": "SMCR", + "offset": "0x08", + "fields": [ + [ + "SMS", + 0, + 3 + ], + [ + "OCCS", + 3, + 1 + ], + [ + "TS", + 4, + 3 + ], + [ + "MSM", + 7, + 1 + ], + [ + "ETF", + 8, + 4 + ], + [ + "ETPS", + 12, + 2 + ], + [ + "ECE", + 14, + 1 + ], + [ + "ETP", + 15, + 1 + ], + [ + "SMS_1", + 16, + 1 + ], + [ + "TS_1", + 20, + 2 + ], + [ + "SMSPE", + 24, + 1 + ], + [ + "SMSPS", + 25, + 1 + ] + ] + }, + { + "name": "DIER", + "offset": "0x0C", + "fields": [ + [ + "UIE", + 0, + 1 + ], + [ + "CC1IE", + 1, + 1 + ], + [ + "CC2IE", + 2, + 1 + ], + [ + "CC3IE", + 3, + 1 + ], + [ + "CC4IE", + 4, + 1 + ], + [ + "COMIE", + 5, + 1 + ], + [ + "TIE", + 6, + 1 + ], + [ + "BIE", + 7, + 1 + ], + [ + "UDE", + 8, + 1 + ], + [ + "CC1DE", + 9, + 1 + ], + [ + "CC2DE", + 10, + 1 + ], + [ + "CC3DE", + 11, + 1 + ], + [ + "CC4DE", + 12, + 1 + ], + [ + "COMDE", + 13, + 1 + ], + [ + "TDE", + 14, + 1 + ], + [ + "IDXIE", + 20, + 1 + ], + [ + "DIRIE", + 21, + 1 + ], + [ + "IERRIE", + 22, + 1 + ], + [ + "TERRIE", + 23, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x10", + "fields": [ + [ + "UIF", + 0, + 1 + ], + [ + "CC1IF", + 1, + 1 + ], + [ + "CC2IF", + 2, + 1 + ], + [ + "CC3IF", + 3, + 1 + ], + [ + "CC4IF", + 4, + 1 + ], + [ + "COMIF", + 5, + 1 + ], + [ + "TIF", + 6, + 1 + ], + [ + "BIF", + 7, + 1 + ], + [ + "B2IF", + 8, + 1 + ], + [ + "CC1OF", + 9, + 1 + ], + [ + "CC2OF", + 10, + 1 + ], + [ + "CC3OF", + 11, + 1 + ], + [ + "CC4OF", + 12, + 1 + ], + [ + "SBIF", + 13, + 1 + ], + [ + "CC5IF", + 16, + 1 + ], + [ + "CC6IF", + 17, + 1 + ], + [ + "IDXF", + 20, + 1 + ], + [ + "DIRF", + 21, + 1 + ], + [ + "IERRF", + 22, + 1 + ], + [ + "TERRF", + 23, + 1 + ] + ] + }, + { + "name": "EGR", + "offset": "0x14", + "size": 16, + "fields": [ + [ + "UG", + 0, + 1, + "w" + ], + [ + "CC1G", + 1, + 1, + "w" + ], + [ + "CC2G", + 2, + 1, + "w" + ], + [ + "CC3G", + 3, + 1, + "w" + ], + [ + "CC4G", + 4, + 1, + "w" + ], + [ + "COMG", + 5, + 1, + "w" + ], + [ + "TG", + 6, + 1, + "w" + ], + [ + "BG", + 7, + 1, + "w" + ], + [ + "B2G", + 8, + 1, + "w" + ] + ] + }, + { + "name": "CCMR1", + "offset": "0x18", + "fields": [ + [ + "OC2M_3", + 24, + 1 + ], + [ + "OC1M_3", + 16, + 1 + ], + [ + "IC2F", + 12, + 4 + ], + [ + "IC2PSC", + 10, + 2 + ], + [ + "CC2S", + 8, + 2 + ], + [ + "IC1F", + 4, + 4 + ], + [ + "IC1PSC", + 2, + 2 + ], + [ + "CC1S", + 0, + 2 + ] + ] + }, + { + "name": "CCMR2", + "offset": "0x1C", + "fields": [ + [ + "OC4M_3", + 24, + 1 + ], + [ + "OC3M_3", + 16, + 1 + ], + [ + "IC4F", + 12, + 4 + ], + [ + "IC4PSC", + 10, + 2 + ], + [ + "CC4S", + 8, + 2 + ], + [ + "IC3F", + 4, + 4 + ], + [ + "IC3PSC", + 2, + 2 + ], + [ + "CC3S", + 0, + 2 + ] + ] + }, + { + "name": "CCER", + "offset": "0x20", + "fields": [ + [ + "CC1E", + 0, + 1 + ], + [ + "CC1P", + 1, + 1 + ], + [ + "CC1NE", + 2, + 1 + ], + [ + "CC1NP", + 3, + 1 + ], + [ + "CC2E", + 4, + 1 + ], + [ + "CC2P", + 5, + 1 + ], + [ + "CC2NE", + 6, + 1 + ], + [ + "CC2NP", + 7, + 1 + ], + [ + "CC3E", + 8, + 1 + ], + [ + "CC3P", + 9, + 1 + ], + [ + "CC3NE", + 10, + 1 + ], + [ + "CC3NP", + 11, + 1 + ], + [ + "CC4E", + 12, + 1 + ], + [ + "CC4P", + 13, + 1 + ], + [ + "CC4NE", + 14, + 1 + ], + [ + "CC4NP", + 15, + 1 + ], + [ + "CC5E", + 16, + 1 + ], + [ + "CC5P", + 17, + 1 + ], + [ + "CC6E", + 20, + 1 + ], + [ + "CC6P", + 21, + 1 + ] + ] + }, + { + "name": "CNT", + "offset": "0x24", + "fields": [ + [ + "CNT", + 0, + 16 + ], + [ + "UIFCPY", + 31, + 1, + "r" + ] + ] + }, + { + "name": "PSC", + "offset": "0x28", + "size": 16, + "fields": [ + [ + "PSC", + 0, + 16 + ] + ] + }, + { + "name": "ARR", + "offset": "0x2C", + "reset": "0x0000FFFF", + "fields": [ + [ + "ARR", + 0, + 20 + ] + ] + }, + { + "name": "RCR", + "offset": "0x30", + "size": 16, + "fields": [ + [ + "REP", + 0, + 16 + ] + ] + }, + { + "name": "CCR1", + "offset": "0x34", + "fields": [ + [ + "CCR1", + 0, + 20 + ] + ] + }, + { + "name": "CCR2", + "offset": "0x38", + "fields": [ + [ + "CCR2", + 0, + 20 + ] + ] + }, + { + "name": "CCR3", + "offset": "0x3C", + "fields": [ + [ + "CCR3", + 0, + 20 + ] + ] + }, + { + "name": "CCR4", + "offset": "0x40", + "fields": [ + [ + "CCR4", + 0, + 20 + ] + ] + }, + { + "name": "BDTR", + "offset": "0x44", + "fields": [ + [ + "DTG", + 0, + 8 + ], + [ + "LOCK", + 8, + 2 + ], + [ + "OSSI", + 10, + 1 + ], + [ + "OSSR", + 11, + 1 + ], + [ + "BKE", + 12, + 1 + ], + [ + "BKP", + 13, + 1 + ], + [ + "AOE", + 14, + 1 + ], + [ + "MOE", + 15, + 1 + ], + [ + "BKF", + 16, + 4 + ], + [ + "BK2F", + 20, + 4 + ], + [ + "BK2E", + 24, + 1 + ], + [ + "BK2P", + 25, + 1 + ], + [ + "BKDSRM", + 26, + 1 + ], + [ + "BK2DSRM", + 27, + 1 + ], + [ + "BKBID", + 28, + 1 + ], + [ + "BK2BID", + 29, + 1 + ] + ] + }, + { + "name": "CCR5", + "offset": "0x48", + "fields": [ + [ + "CCR5", + 0, + 20 + ], + [ + "GC5C1", + 29, + 1 + ], + [ + "GC5C2", + 30, + 1 + ], + [ + "GC5C3", + 31, + 1 + ] + ] + }, + { + "name": "CCR6", + "offset": "0x4C", + "fields": [ + [ + "CCR6", + 0, + 20 + ] + ] + }, + { + "name": "CCMR3", + "offset": "0x50", + "fields": [ + [ + "OC5FE", + 2, + 1 + ], + [ + "OC5PE", + 3, + 1 + ], + [ + "OC5M", + 4, + 3 + ], + [ + "OC5CE", + 7, + 1 + ], + [ + "OC6FE", + 10, + 1 + ], + [ + "OC6PE", + 11, + 1 + ], + [ + "OC6M", + 12, + 3 + ], + [ + "OC6CE", + 15, + 1 + ], + [ + "OC5M_1", + 16, + 1 + ], + [ + "OC6M_1", + 24, + 1 + ] + ] + }, + { + "name": "DTR2", + "offset": "0x54", + "fields": [ + [ + "DTGF", + 0, + 8 + ], + [ + "DTAE", + 16, + 1 + ], + [ + "DTPE", + 17, + 1 + ] + ] + }, + { + "name": "ECR", + "offset": "0x58", + "fields": [ + [ + "IE", + 0, + 1 + ], + [ + "IDIR", + 1, + 2 + ], + [ + "FIDX", + 5, + 1 + ], + [ + "IPOS", + 6, + 2 + ], + [ + "PW", + 16, + 8 + ], + [ + "PWPRSC", + 24, + 3 + ] + ] + }, + { + "name": "TISEL", + "offset": "0x5C", + "fields": [ + [ + "TI1SEL", + 0, + 4 + ], + [ + "TI2SEL", + 8, + 4 + ], + [ + "TI3SEL", + 16, + 4 + ], + [ + "TI4SEL", + 24, + 4 + ] + ] + }, + { + "name": "AF1", + "offset": "0x60", + "reset": "0x00000001", + "fields": [ + [ + "BKINE", + 0, + 1 + ], + [ + "BKCMP1E", + 1, + 1 + ], + [ + "BKCMP2E", + 2, + 1 + ], + [ + "BKCMP3E", + 3, + 1 + ], + [ + "BKCMP4E", + 4, + 1 + ], + [ + "BKCMP5E", + 5, + 1 + ], + [ + "BKCMP6E", + 6, + 1 + ], + [ + "BKCMP7E", + 7, + 1 + ], + [ + "BKCMP8E", + 8, + 1 + ], + [ + "BKINP", + 9, + 1 + ], + [ + "BKCMP1P", + 10, + 1 + ], + [ + "BKCMP2P", + 11, + 1 + ], + [ + "BKCMP3P", + 12, + 1 + ], + [ + "BKCMP4P", + 13, + 1 + ], + [ + "ETRSEL", + 14, + 4 + ] + ] + }, + { + "name": "AF2", + "offset": "0x64", + "reset": "0x00000001", + "fields": [ + [ + "BK2INE", + 0, + 1 + ], + [ + "BK2CMP1E", + 1, + 1 + ], + [ + "BK2CMP2E", + 2, + 1 + ], + [ + "BK2CMP3E", + 3, + 1 + ], + [ + "BK2CMP4E", + 4, + 1 + ], + [ + "BK2CMP5E", + 5, + 1 + ], + [ + "BK2CMP6E", + 6, + 1 + ], + [ + "BK2CMP7E", + 7, + 1 + ], + [ + "BK2CMP8E", + 8, + 1 + ], + [ + "BK2INP", + 9, + 1 + ], + [ + "BK2CMP1P", + 10, + 1 + ], + [ + "BK2CMP2P", + 11, + 1 + ], + [ + "BK2CMP3P", + 12, + 1 + ], + [ + "BK2CMP4P", + 13, + 1 + ], + [ + "OCRSEL", + 16, + 3 + ] + ] + }, + { + "name": "DCR", + "offset": "0x3DC", + "fields": [ + [ + "DBA", + 0, + 5 + ], + [ + "DBL", + 8, + 5 + ] + ] + }, + { + "name": "DMAR", + "offset": "0x3E0", + "fields": [ + [ + "DMAB", + 0, + 32 + ] + ] + } + ] + }, + { + "name": "SPI1", + "base": "0x40013000", + "interrupts": [ + "SPI1" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "fields": [ + [ + "BIDIMODE", + 15, + 1 + ], + [ + "BIDIOE", + 14, + 1 + ], + [ + "CRCEN", + 13, + 1 + ], + [ + "CRCNEXT", + 12, + 1 + ], + [ + "DFF", + 11, + 1 + ], + [ + "RXONLY", + 10, + 1 + ], + [ + "SSM", + 9, + 1 + ], + [ + "SSI", + 8, + 1 + ], + [ + "LSBFIRST", + 7, + 1 + ], + [ + "SPE", + 6, + 1 + ], + [ + "BR", + 3, + 3 + ], + [ + "MSTR", + 2, + 1 + ], + [ + "CPOL", + 1, + 1 + ], + [ + "CPHA", + 0, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "reset": "0x00000700", + "fields": [ + [ + "RXDMAEN", + 0, + 1 + ], + [ + "TXDMAEN", + 1, + 1 + ], + [ + "SSOE", + 2, + 1 + ], + [ + "NSSP", + 3, + 1 + ], + [ + "FRF", + 4, + 1 + ], + [ + "ERRIE", + 5, + 1 + ], + [ + "RXNEIE", + 6, + 1 + ], + [ + "TXEIE", + 7, + 1 + ], + [ + "DS", + 8, + 4 + ], + [ + "FRXTH", + 12, + 1 + ], + [ + "LDMA_RX", + 13, + 1 + ], + [ + "LDMA_TX", + 14, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x08", + "reset": "0x00000002", + "fields": [ + [ + "RXNE", + 0, + 1, + "r" + ], + [ + "TXE", + 1, + 1, + "r" + ], + [ + "CRCERR", + 4, + 1 + ], + [ + "MODF", + 5, + 1, + "r" + ], + [ + "OVR", + 6, + 1, + "r" + ], + [ + "BSY", + 7, + 1, + "r" + ], + [ + "TIFRFE", + 8, + 1, + "r" + ], + [ + "FRLVL", + 9, + 2, + "r" + ], + [ + "FTLVL", + 11, + 2, + "r" + ] + ] + }, + { + "name": "DR", + "offset": "0x0C", + "fields": [ + [ + "DR", + 0, + 16 + ] + ] + }, + { + "name": "CRCPR", + "offset": "0x10", + "reset": "0x00000007", + "fields": [ + [ + "CRCPOLY", + 0, + 16 + ] + ] + }, + { + "name": "RXCRCR", + "offset": "0x14", + "fields": [ + [ + "RxCRC", + 0, + 16, + "r" + ] + ] + }, + { + "name": "TXCRCR", + "offset": "0x18", + "fields": [ + [ + "TxCRC", + 0, + 16, + "r" + ] + ] + }, + { + "name": "I2SCFGR", + "offset": "0x1C", + "fields": [ + [ + "CHLEN", + 0, + 1 + ], + [ + "DATLEN", + 1, + 2 + ], + [ + "CKPOL", + 3, + 1 + ], + [ + "I2SSTD", + 4, + 2 + ], + [ + "PCMSYNC", + 7, + 1 + ], + [ + "I2SCFG", + 8, + 2 + ], + [ + "I2SE", + 10, + 1 + ], + [ + "I2SMOD", + 11, + 1 + ] + ] + }, + { + "name": "I2SPR", + "offset": "0x20", + "reset": "0x00000002", + "fields": [ + [ + "I2SDIV", + 0, + 8 + ], + [ + "ODD", + 8, + 1 + ], + [ + "MCKOE", + 9, + 1 + ] + ] + } + ] + }, + { + "name": "TIM8", + "base": "0x40013400", + "interrupts": [ + "TIM8_BRK", + "TIM8_UP", + "TIM8_TRG_COM", + "TIM8_CC" + ], + "derived_from": "TIM1" + }, + { + "name": "USART1", + "base": "0x40013800", + "interrupts": [ + "USART1" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "fields": [ + [ + "RXFFIE", + 31, + 1 + ], + [ + "TXFEIE", + 30, + 1 + ], + [ + "FIFOEN", + 29, + 1 + ], + [ + "M1", + 28, + 1 + ], + [ + "EOBIE", + 27, + 1 + ], + [ + "RTOIE", + 26, + 1 + ], + [ + "DEAT4", + 25, + 1 + ], + [ + "DEAT3", + 24, + 1 + ], + [ + "DEAT2", + 23, + 1 + ], + [ + "DEAT1", + 22, + 1 + ], + [ + "DEAT0", + 21, + 1 + ], + [ + "DEDT4", + 20, + 1 + ], + [ + "DEDT3", + 19, + 1 + ], + [ + "DEDT2", + 18, + 1 + ], + [ + "DEDT1", + 17, + 1 + ], + [ + "DEDT0", + 16, + 1 + ], + [ + "OVER8", + 15, + 1 + ], + [ + "CMIE", + 14, + 1 + ], + [ + "MME", + 13, + 1 + ], + [ + "M0", + 12, + 1 + ], + [ + "WAKE", + 11, + 1 + ], + [ + "PCE", + 10, + 1 + ], + [ + "PS", + 9, + 1 + ], + [ + "PEIE", + 8, + 1 + ], + [ + "TXEIE", + 7, + 1 + ], + [ + "TCIE", + 6, + 1 + ], + [ + "RXNEIE", + 5, + 1 + ], + [ + "IDLEIE", + 4, + 1 + ], + [ + "TE", + 3, + 1 + ], + [ + "RE", + 2, + 1 + ], + [ + "UESM", + 1, + 1 + ], + [ + "UE", + 0, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "ADD4_7", + 28, + 4 + ], + [ + "ADD0_3", + 24, + 4 + ], + [ + "RTOEN", + 23, + 1 + ], + [ + "ABRMOD1", + 22, + 1 + ], + [ + "ABRMOD0", + 21, + 1 + ], + [ + "ABREN", + 20, + 1 + ], + [ + "MSBFIRST", + 19, + 1 + ], + [ + "TAINV", + 18, + 1 + ], + [ + "TXINV", + 17, + 1 + ], + [ + "RXINV", + 16, + 1 + ], + [ + "SWAP", + 15, + 1 + ], + [ + "LINEN", + 14, + 1 + ], + [ + "STOP", + 12, + 2 + ], + [ + "CLKEN", + 11, + 1 + ], + [ + "CPOL", + 10, + 1 + ], + [ + "CPHA", + 9, + 1 + ], + [ + "LBCL", + 8, + 1 + ], + [ + "LBDIE", + 6, + 1 + ], + [ + "LBDL", + 5, + 1 + ], + [ + "ADDM7", + 4, + 1 + ], + [ + "DIS_NSS", + 3, + 1 + ], + [ + "SLVEN", + 0, + 1 + ] + ] + }, + { + "name": "CR3", + "offset": "0x08", + "fields": [ + [ + "TXFTCFG", + 29, + 3 + ], + [ + "RXFTIE", + 28, + 1 + ], + [ + "RXFTCFG", + 25, + 3 + ], + [ + "TCBGTIE", + 24, + 1 + ], + [ + "TXFTIE", + 23, + 1 + ], + [ + "WUFIE", + 22, + 1 + ], + [ + "WUS", + 20, + 2 + ], + [ + "SCARCNT", + 17, + 3 + ], + [ + "DEP", + 15, + 1 + ], + [ + "DEM", + 14, + 1 + ], + [ + "DDRE", + 13, + 1 + ], + [ + "OVRDIS", + 12, + 1 + ], + [ + "ONEBIT", + 11, + 1 + ], + [ + "CTSIE", + 10, + 1 + ], + [ + "CTSE", + 9, + 1 + ], + [ + "RTSE", + 8, + 1 + ], + [ + "DMAT", + 7, + 1 + ], + [ + "DMAR", + 6, + 1 + ], + [ + "SCEN", + 5, + 1 + ], + [ + "NACK", + 4, + 1 + ], + [ + "HDSEL", + 3, + 1 + ], + [ + "IRLP", + 2, + 1 + ], + [ + "IREN", + 1, + 1 + ], + [ + "EIE", + 0, + 1 + ] + ] + }, + { + "name": "BRR", + "offset": "0x0C", + "fields": [ + [ + "DIV_Mantissa", + 4, + 12 + ], + [ + "DIV_Fraction", + 0, + 4 + ] + ] + }, + { + "name": "GTPR", + "offset": "0x10", + "fields": [ + [ + "GT", + 8, + 8 + ], + [ + "PSC", + 0, + 8 + ] + ] + }, + { + "name": "RTOR", + "offset": "0x14", + "fields": [ + [ + "BLEN", + 24, + 8 + ], + [ + "RTO", + 0, + 24 + ] + ] + }, + { + "name": "RQR", + "offset": "0x18", + "fields": [ + [ + "TXFRQ", + 4, + 1, + "w" + ], + [ + "RXFRQ", + 3, + 1, + "w" + ], + [ + "MMRQ", + 2, + 1, + "w" + ], + [ + "SBKRQ", + 1, + 1, + "w" + ], + [ + "ABRRQ", + 0, + 1, + "w" + ] + ] + }, + { + "name": "ISR", + "offset": "0x1C", + "fields": [ + [ + "TXFT", + 27, + 1, + "r" + ], + [ + "RXFT", + 26, + 1, + "r" + ], + [ + "TCBGT", + 25, + 1, + "r" + ], + [ + "RXFF", + 24, + 1, + "r" + ], + [ + "TXFE", + 23, + 1, + "r" + ], + [ + "REACK", + 22, + 1, + "r" + ], + [ + "TEACK", + 21, + 1, + "r" + ], + [ + "WUF", + 20, + 1, + "r" + ], + [ + "RWU", + 19, + 1, + "r" + ], + [ + "SBKF", + 18, + 1, + "r" + ], + [ + "CMF", + 17, + 1, + "r" + ], + [ + "BUSY", + 16, + 1, + "r" + ], + [ + "ABRF", + 15, + 1, + "r" + ], + [ + "ABRE", + 14, + 1, + "r" + ], + [ + "UDR", + 13, + 1, + "r" + ], + [ + "EOBF", + 12, + 1, + "r" + ], + [ + "RTOF", + 11, + 1, + "r" + ], + [ + "CTS", + 10, + 1, + "r" + ], + [ + "CTSIF", + 9, + 1, + "r" + ], + [ + "LBDF", + 8, + 1, + "r" + ], + [ + "TXE", + 7, + 1, + "r" + ], + [ + "TC", + 6, + 1, + "r" + ], + [ + "RXNE", + 5, + 1, + "r" + ], + [ + "IDLE", + 4, + 1, + "r" + ], + [ + "ORE", + 3, + 1, + "r" + ], + [ + "NF", + 2, + 1, + "r" + ], + [ + "FE", + 1, + 1, + "r" + ], + [ + "PE", + 0, + 1, + "r" + ] + ], + "reset": "0x008000C0" + }, + { + "name": "ICR", + "offset": "0x20", + "fields": [ + [ + "WUCF", + 20, + 1, + "w" + ], + [ + "CMCF", + 17, + 1, + "w" + ], + [ + "UDRCF", + 13, + 1, + "w" + ], + [ + "EOBCF", + 12, + 1, + "w" + ], + [ + "RTOCF", + 11, + 1, + "w" + ], + [ + "CTSCF", + 9, + 1, + "w" + ], + [ + "LBDCF", + 8, + 1, + "w" + ], + [ + "TCBGTCF", + 7, + 1, + "w" + ], + [ + "TCCF", + 6, + 1, + "w" + ], + [ + "TXFECF", + 5, + 1, + "w" + ], + [ + "IDLECF", + 4, + 1, + "w" + ], + [ + "ORECF", + 3, + 1, + "w" + ], + [ + "NCF", + 2, + 1, + "w" + ], + [ + "FECF", + 1, + 1, + "w" + ], + [ + "PECF", + 0, + 1, + "w" + ] + ] + }, + { + "name": "RDR", + "offset": "0x24", + "fields": [ + [ + "RDR", + 0, + 9, + "r" + ] + ] + }, + { + "name": "TDR", + "offset": "0x28", + "fields": [ + [ + "TDR", + 0, + 9 + ] + ] + }, + { + "name": "PRESC", + "offset": "0x2C", + "fields": [ + [ + "PRESCALER", + 0, + 4 + ] + ] + } + ] + }, + { + "name": "SPI4", + "base": "0x40013C00", + "interrupts": [ + "SPI4" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "reset": "0x00000700", + "fields": [ + [ + "BIDIMODE", + 15, + 1 + ], + [ + "BIDIOE", + 14, + 1 + ], + [ + "CRCEN", + 13, + 1 + ], + [ + "CRCNEXT", + 12, + 1 + ], + [ + "DFF", + 11, + 1 + ], + [ + "RXONLY", + 10, + 1 + ], + [ + "SSM", + 9, + 1 + ], + [ + "SSI", + 8, + 1 + ], + [ + "LSBFIRST", + 7, + 1 + ], + [ + "SPE", + 6, + 1 + ], + [ + "BR", + 3, + 3 + ], + [ + "MSTR", + 2, + 1 + ], + [ + "CPOL", + 1, + 1 + ], + [ + "CPHA", + 0, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "RXDMAEN", + 0, + 1 + ], + [ + "TXDMAEN", + 1, + 1 + ], + [ + "SSOE", + 2, + 1 + ], + [ + "NSSP", + 3, + 1 + ], + [ + "FRF", + 4, + 1 + ], + [ + "ERRIE", + 5, + 1 + ], + [ + "RXNEIE", + 6, + 1 + ], + [ + "TXEIE", + 7, + 1 + ], + [ + "DS", + 8, + 4 + ], + [ + "FRXTH", + 12, + 1 + ], + [ + "LDMA_RX", + 13, + 1 + ], + [ + "LDMA_TX", + 14, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x08", + "reset": "0x00000002", + "fields": [ + [ + "RXNE", + 0, + 1, + "r" + ], + [ + "TXE", + 1, + 1, + "r" + ], + [ + "CRCERR", + 4, + 1 + ], + [ + "MODF", + 5, + 1, + "r" + ], + [ + "OVR", + 6, + 1, + "r" + ], + [ + "BSY", + 7, + 1, + "r" + ], + [ + "TIFRFE", + 8, + 1, + "r" + ], + [ + "FRLVL", + 9, + 2, + "r" + ], + [ + "FTLVL", + 11, + 2, + "r" + ] + ] + }, + { + "name": "DR", + "offset": "0x0C", + "fields": [ + [ + "DR", + 0, + 16 + ] + ] + }, + { + "name": "CRCPR", + "offset": "0x10", + "reset": "0x00000007", + "fields": [ + [ + "CRCPOLY", + 0, + 16 + ] + ] + }, + { + "name": "RXCRCR", + "offset": "0x14", + "fields": [ + [ + "RxCRC", + 0, + 16, + "r" + ] + ] + }, + { + "name": "TXCRCR", + "offset": "0x18", + "fields": [ + [ + "TxCRC", + 0, + 16, + "r" + ] + ] + }, + { + "name": "I2SCFGR", + "offset": "0x1C", + "fields": [ + [ + "CHLEN", + 0, + 1 + ], + [ + "DATLEN", + 1, + 2 + ], + [ + "CKPOL", + 3, + 1 + ], + [ + "I2SSTD", + 4, + 2 + ], + [ + "PCMSYNC", + 7, + 1 + ], + [ + "I2SCFG", + 8, + 2 + ], + [ + "I2SE", + 10, + 1 + ], + [ + "I2SMOD", + 11, + 1 + ] + ] + }, + { + "name": "I2SPR", + "offset": "0x20", + "reset": "0x00000002", + "fields": [ + [ + "I2SDIV", + 0, + 8 + ], + [ + "ODD", + 8, + 1 + ], + [ + "MCKOE", + 9, + 1 + ] + ] + } + ] + }, + { + "name": "TIM15", + "base": "0x40014000", + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "fields": [ + [ + "CEN", + 0, + 1 + ], + [ + "UDIS", + 1, + 1 + ], + [ + "URS", + 2, + 1 + ], + [ + "OPM", + 3, + 1 + ], + [ + "ARPE", + 7, + 1 + ], + [ + "CKD", + 8, + 2 + ], + [ + "UIFREMAP", + 11, + 1 + ], + [ + "DITHEN", + 12, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "OIS2", + 10, + 1 + ], + [ + "OIS1N", + 9, + 1 + ], + [ + "OIS1", + 8, + 1 + ], + [ + "TI1S", + 7, + 1 + ], + [ + "MMS", + 4, + 3 + ], + [ + "CCDS", + 3, + 1 + ], + [ + "CCUS", + 2, + 1 + ], + [ + "CCPC", + 0, + 1 + ] + ] + }, + { + "name": "SMCR", + "offset": "0x08", + "fields": [ + [ + "TS_4_3", + 20, + 2 + ], + [ + "SMS_3", + 16, + 1 + ], + [ + "MSM", + 7, + 1 + ], + [ + "TS", + 4, + 3 + ], + [ + "SMS", + 0, + 3 + ] + ] + }, + { + "name": "DIER", + "offset": "0x0C", + "fields": [ + [ + "TDE", + 14, + 1 + ], + [ + "COMDE", + 13, + 1 + ], + [ + "CC2DE", + 10, + 1 + ], + [ + "CC1DE", + 9, + 1 + ], + [ + "UDE", + 8, + 1 + ], + [ + "BIE", + 7, + 1 + ], + [ + "TIE", + 6, + 1 + ], + [ + "COMIE", + 5, + 1 + ], + [ + "CC2IE", + 2, + 1 + ], + [ + "CC1IE", + 1, + 1 + ], + [ + "UIE", + 0, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x10", + "fields": [ + [ + "CC2OF", + 10, + 1 + ], + [ + "CC1OF", + 9, + 1 + ], + [ + "BIF", + 7, + 1 + ], + [ + "TIF", + 6, + 1 + ], + [ + "COMIF", + 5, + 1 + ], + [ + "CC2IF", + 2, + 1 + ], + [ + "CC1IF", + 1, + 1 + ], + [ + "UIF", + 0, + 1 + ] + ] + }, + { + "name": "EGR", + "offset": "0x14", + "fields": [ + [ + "BG", + 7, + 1, + "w" + ], + [ + "TG", + 6, + 1, + "w" + ], + [ + "COMG", + 5, + 1, + "w" + ], + [ + "CC2G", + 2, + 1, + "w" + ], + [ + "CC1G", + 1, + 1, + "w" + ], + [ + "UG", + 0, + 1, + "w" + ] + ] + }, + { + "name": "CCMR1", + "offset": "0x18", + "fields": [ + [ + "OC2M_3", + 24, + 1 + ], + [ + "OC1M_3", + 16, + 1 + ], + [ + "OC2M", + 12, + 3 + ], + [ + "OC2PE", + 11, + 1 + ], + [ + "OC2FE", + 10, + 1 + ], + [ + "CC2S", + 8, + 2 + ], + [ + "OC1CE", + 7, + 1 + ], + [ + "OC1M", + 4, + 3 + ], + [ + "OC1PE", + 3, + 1 + ], + [ + "OC1FE", + 2, + 1 + ], + [ + "CC1S", + 0, + 2 + ] + ] + }, + { + "name": "CCER", + "offset": "0x20", + "fields": [ + [ + "CC2NP", + 7, + 1 + ], + [ + "CC2P", + 5, + 1 + ], + [ + "CC2E", + 4, + 1 + ], + [ + "CC1NP", + 3, + 1 + ], + [ + "CC1NE", + 2, + 1 + ], + [ + "CC1P", + 1, + 1 + ], + [ + "CC1E", + 0, + 1 + ] + ] + }, + { + "name": "CNT", + "offset": "0x24", + "fields": [ + [ + "CNT", + 0, + 16 + ], + [ + "UIFCPY", + 31, + 1, + "r" + ] + ] + }, + { + "name": "PSC", + "offset": "0x28", + "fields": [ + [ + "PSC", + 0, + 16 + ] + ] + }, + { + "name": "ARR", + "offset": "0x2C", + "reset": "0x0000FFFF", + "fields": [ + [ + "ARR", + 0, + 16 + ] + ] + }, + { + "name": "RCR", + "offset": "0x30", + "fields": [ + [ + "REP", + 0, + 8 + ] + ] + }, + { + "name": "CCR1", + "offset": "0x34", + "fields": [ + [ + "CCR1", + 0, + 16 + ] + ] + }, + { + "name": "CCR2", + "offset": "0x38", + "fields": [ + [ + "CCR2", + 0, + 16 + ] + ] + }, + { + "name": "BDTR", + "offset": "0x44", + "fields": [ + [ + "DTG", + 0, + 8 + ], + [ + "LOCK", + 8, + 2 + ], + [ + "OSSI", + 10, + 1 + ], + [ + "OSSR", + 11, + 1 + ], + [ + "BKE", + 12, + 1 + ], + [ + "BKP", + 13, + 1 + ], + [ + "AOE", + 14, + 1 + ], + [ + "MOE", + 15, + 1 + ], + [ + "BKF", + 16, + 4 + ], + [ + "BKDSRM", + 26, + 1 + ], + [ + "BKBID", + 28, + 1 + ] + ] + }, + { + "name": "DTR2", + "offset": "0x54", + "fields": [ + [ + "DTGF", + 0, + 8 + ], + [ + "DTAE", + 16, + 1 + ], + [ + "DTPE", + 17, + 1 + ] + ] + }, + { + "name": "TISEL", + "offset": "0x5C", + "fields": [ + [ + "TI1SEL", + 0, + 4 + ], + [ + "TI2SEL", + 8, + 4 + ] + ] + }, + { + "name": "AF1", + "offset": "0x60", + "fields": [ + [ + "BKCMP4P", + 13, + 1 + ], + [ + "BKCMP3P", + 12, + 1 + ], + [ + "BKCMP2P", + 11, + 1 + ], + [ + "BKCMP1P", + 10, + 1 + ], + [ + "BKINP", + 9, + 1 + ], + [ + "BKCMP7E", + 7, + 1 + ], + [ + "BKCMP6E", + 6, + 1 + ], + [ + "BKCMP5E", + 5, + 1 + ], + [ + "BKCMP4E", + 4, + 1 + ], + [ + "BKCMP3E", + 3, + 1 + ], + [ + "BKCMP2E", + 2, + 1 + ], + [ + "BKCMP1E", + 1, + 1 + ], + [ + "BKINE", + 0, + 1 + ] + ] + }, + { + "name": "AF2", + "offset": "0x64", + "fields": [ + [ + "OCRSEL", + 16, + 3 + ] + ] + }, + { + "name": "DCR", + "offset": "0x3DC", + "fields": [ + [ + "DBL", + 8, + 5 + ], + [ + "DBA", + 0, + 5 + ] + ] + }, + { + "name": "DMAR", + "offset": "0x3E0", + "fields": [ + [ + "DMAB", + 0, + 32 + ] + ] + } + ], + "interrupts": [ + "TIM1_BRK_TIM15" + ] + }, + { + "name": "TIM16", + "base": "0x40014400", + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "size": 16, + "fields": [ + [ + "CEN", + 0, + 1 + ], + [ + "UDIS", + 1, + 1 + ], + [ + "URS", + 2, + 1 + ], + [ + "OPM", + 3, + 1 + ], + [ + "ARPE", + 7, + 1 + ], + [ + "CKD", + 8, + 2 + ], + [ + "UIFREMAP", + 11, + 1 + ], + [ + "DITHEN", + 12, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "size": 16, + "fields": [ + [ + "CCPC", + 0, + 1 + ], + [ + "CCUS", + 2, + 1 + ], + [ + "CCDS", + 3, + 1 + ], + [ + "OIS1", + 8, + 1 + ], + [ + "OIS1N", + 9, + 1 + ] + ] + }, + { + "name": "DIER", + "offset": "0x0C", + "size": 16, + "fields": [ + [ + "UIE", + 0, + 1 + ], + [ + "CC1IE", + 1, + 1 + ], + [ + "COMIE", + 5, + 1 + ], + [ + "BIE", + 7, + 1 + ], + [ + "UDE", + 8, + 1 + ], + [ + "CC1DE", + 9, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x10", + "size": 16, + "fields": [ + [ + "UIF", + 0, + 1 + ], + [ + "CC1IF", + 1, + 1 + ], + [ + "COMIF", + 5, + 1 + ], + [ + "BIF", + 7, + 1 + ], + [ + "CC1OF", + 9, + 1 + ] + ] + }, + { + "name": "EGR", + "offset": "0x14", + "size": 16, + "fields": [ + [ + "UG", + 0, + 1, + "w" + ], + [ + "CC1G", + 1, + 1, + "w" + ], + [ + "COMG", + 5, + 1, + "w" + ], + [ + "BG", + 7, + 1, + "w" + ] + ] + }, + { + "name": "CCMR1", + "offset": "0x18", + "fields": [ + [ + "OC1M_3", + 16, + 1 + ], + [ + "IC1F", + 4, + 4 + ], + [ + "IC1PSC", + 2, + 2 + ], + [ + "CC1S", + 0, + 2 + ] + ] + }, + { + "name": "CCER", + "offset": "0x20", + "size": 16, + "fields": [ + [ + "CC1E", + 0, + 1 + ], + [ + "CC1P", + 1, + 1 + ], + [ + "CC1NE", + 2, + 1 + ], + [ + "CC1NP", + 3, + 1 + ] + ] + }, + { + "name": "CNT", + "offset": "0x24", + "fields": [ + [ + "CNT", + 0, + 16 + ], + [ + "UIFCPY", + 31, + 1, + "r" + ] + ] + }, + { + "name": "PSC", + "offset": "0x28", + "size": 16, + "fields": [ + [ + "PSC", + 0, + 16 + ] + ] + }, + { + "name": "ARR", + "offset": "0x2C", + "reset": "0x0000FFFF", + "fields": [ + [ + "ARR", + 0, + 20 + ] + ] + }, + { + "name": "RCR", + "offset": "0x30", + "size": 16, + "fields": [ + [ + "REP", + 0, + 8 + ] + ] + }, + { + "name": "CCR1", + "offset": "0x34", + "fields": [ + [ + "CCR1", + 0, + 20 + ] + ] + }, + { + "name": "BDTR", + "offset": "0x44", + "fields": [ + [ + "DTG", + 0, + 8 + ], + [ + "LOCK", + 8, + 2 + ], + [ + "OSSI", + 10, + 1 + ], + [ + "OSSR", + 11, + 1 + ], + [ + "BKE", + 12, + 1 + ], + [ + "BKP", + 13, + 1 + ], + [ + "AOE", + 14, + 1 + ], + [ + "MOE", + 15, + 1 + ], + [ + "BKF", + 16, + 4 + ], + [ + "BKDSRM", + 26, + 1 + ], + [ + "BKBID", + 28, + 1 + ] + ] + }, + { + "name": "DTR2", + "offset": "0x54", + "fields": [ + [ + "DTGF", + 0, + 8 + ], + [ + "DTAE", + 16, + 1 + ], + [ + "DTPE", + 17, + 1 + ] + ] + }, + { + "name": "TISEL", + "offset": "0x5C", + "fields": [ + [ + "TI1SEL", + 0, + 4 + ] + ] + }, + { + "name": "AF1", + "offset": "0x60", + "reset": "0x00000001", + "fields": [ + [ + "BKINE", + 0, + 1 + ], + [ + "BKCMP1E", + 1, + 1 + ], + [ + "BKCMP2E", + 2, + 1 + ], + [ + "BKCMP3E", + 3, + 1 + ], + [ + "BKCMP4E", + 4, + 1 + ], + [ + "BKCMP5E", + 5, + 1 + ], + [ + "BKCMP6E", + 6, + 1 + ], + [ + "BKCMP7E", + 7, + 1 + ], + [ + "BKCMP8E", + 8, + 1 + ], + [ + "BKINP", + 9, + 1 + ], + [ + "BKCMP1P", + 10, + 1 + ], + [ + "BKCMP2P", + 11, + 1 + ], + [ + "BKCMP3P", + 12, + 1 + ], + [ + "BKCMP4P", + 13, + 1 + ] + ] + }, + { + "name": "AF2", + "offset": "0x64", + "fields": [ + [ + "OCRSEL", + 16, + 3 + ] + ] + }, + { + "name": "OR1", + "offset": "0x68", + "fields": [ + [ + "HSE32EN", + 0, + 1 + ] + ] + }, + { + "name": "DCR", + "offset": "0x3DC", + "fields": [ + [ + "DBA", + 0, + 5 + ], + [ + "DBL", + 8, + 5 + ] + ] + }, + { + "name": "DMAR", + "offset": "0x3E0", + "fields": [ + [ + "DMAB", + 0, + 32 + ] + ] + } + ], + "interrupts": [ + "TIM1_UP_TIM16" + ] + }, + { + "name": "TIM17", + "base": "0x40014800", + "derived_from": "TIM16", + "interrupts": [ + "TIM1_TRG_COM" + ] + }, + { + "name": "TIM20", + "base": "0x40015000", + "interrupts": [ + "TIM20_BRK", + "TIM20_UP", + "TIM20_TRG_COM", + "TIM20_CC" + ], + "derived_from": "TIM1" + }, + { + "name": "SAI", + "base": "0x40015400", + "interrupts": [ + "SAI" + ], + "registers": [ + { + "name": "BCR1", + "offset": "0x24", + "reset": "0x00000040", + "fields": [ + [ + "MCKEN", + 27, + 1 + ], + [ + "OSR", + 26, + 1 + ], + [ + "MCJDIV", + 20, + 6 + ], + [ + "NODIV", + 19, + 1 + ], + [ + "DMAEN", + 17, + 1 + ], + [ + "SAIBEN", + 16, + 1 + ], + [ + "OutDri", + 13, + 1 + ], + [ + "MONO", + 12, + 1 + ], + [ + "SYNCEN", + 10, + 2 + ], + [ + "CKSTR", + 9, + 1 + ], + [ + "LSBFIRST", + 8, + 1 + ], + [ + "DS", + 5, + 3 + ], + [ + "PRTCFG", + 2, + 2 + ], + [ + "MODE", + 0, + 2 + ] + ] + }, + { + "name": "BCR2", + "offset": "0x28", + "fields": [ + [ + "COMP", + 14, + 2 + ], + [ + "CPL", + 13, + 1 + ], + [ + "MUTECN", + 7, + 6 + ], + [ + "MUTEVAL", + 6, + 1 + ], + [ + "MUTE", + 5, + 1 + ], + [ + "TRIS", + 4, + 1 + ], + [ + "FFLUS", + 3, + 1 + ], + [ + "FTH", + 0, + 3 + ] + ] + }, + { + "name": "BFRCR", + "offset": "0x2C", + "reset": "0x00000007", + "fields": [ + [ + "FSOFF", + 18, + 1 + ], + [ + "FSPOL", + 17, + 1 + ], + [ + "FSDEF", + 16, + 1 + ], + [ + "FSALL", + 8, + 7 + ], + [ + "FRL", + 0, + 8 + ] + ] + }, + { + "name": "BSLOTR", + "offset": "0x30", + "fields": [ + [ + "SLOTEN", + 16, + 16 + ], + [ + "NBSLOT", + 8, + 4 + ], + [ + "SLOTSZ", + 6, + 2 + ], + [ + "FBOFF", + 0, + 5 + ] + ] + }, + { + "name": "BIM", + "offset": "0x34", + "fields": [ + [ + "LFSDETIE", + 6, + 1 + ], + [ + "AFSDETIE", + 5, + 1 + ], + [ + "CNRDYIE", + 4, + 1 + ], + [ + "FREQIE", + 3, + 1 + ], + [ + "WCKCFG", + 2, + 1 + ], + [ + "MUTEDET", + 1, + 1 + ], + [ + "OVRUDRIE", + 0, + 1 + ] + ] + }, + { + "name": "BSR", + "offset": "0x38", + "fields": [ + [ + "FLVL", + 16, + 3, + "r" + ], + [ + "LFSDET", + 6, + 1, + "r" + ], + [ + "AFSDET", + 5, + 1, + "r" + ], + [ + "CNRDY", + 4, + 1, + "r" + ], + [ + "FREQ", + 3, + 1, + "r" + ], + [ + "WCKCFG", + 2, + 1, + "r" + ], + [ + "MUTEDET", + 1, + 1, + "r" + ], + [ + "OVRUDR", + 0, + 1, + "r" + ] + ] + }, + { + "name": "BCLRFR", + "offset": "0x3C", + "fields": [ + [ + "LFSDET", + 6, + 1, + "w" + ], + [ + "CAFSDET", + 5, + 1, + "w" + ], + [ + "CNRDY", + 4, + 1, + "w" + ], + [ + "WCKCFG", + 2, + 1, + "w" + ], + [ + "MUTEDET", + 1, + 1, + "w" + ], + [ + "OVRUDR", + 0, + 1, + "w" + ] + ] + }, + { + "name": "BDR", + "offset": "0x40", + "fields": [ + [ + "DATA", + 0, + 32 + ] + ] + }, + { + "name": "ACR1", + "offset": "0x04", + "reset": "0x00000040", + "fields": [ + [ + "MCKEN", + 27, + 1 + ], + [ + "OSR", + 26, + 1 + ], + [ + "MCJDIV", + 20, + 6 + ], + [ + "NODIV", + 19, + 1 + ], + [ + "DMAEN", + 17, + 1 + ], + [ + "SAIAEN", + 16, + 1 + ], + [ + "OutDri", + 13, + 1 + ], + [ + "MONO", + 12, + 1 + ], + [ + "SYNCEN", + 10, + 2 + ], + [ + "CKSTR", + 9, + 1 + ], + [ + "LSBFIRST", + 8, + 1 + ], + [ + "DS", + 5, + 3 + ], + [ + "PRTCFG", + 2, + 2 + ], + [ + "MODE", + 0, + 2 + ] + ] + }, + { + "name": "ACR2", + "offset": "0x08", + "fields": [ + [ + "COMP", + 14, + 2 + ], + [ + "CPL", + 13, + 1 + ], + [ + "MUTECN", + 7, + 6 + ], + [ + "MUTEVAL", + 6, + 1 + ], + [ + "MUTE", + 5, + 1 + ], + [ + "TRIS", + 4, + 1 + ], + [ + "FFLUS", + 3, + 1 + ], + [ + "FTH", + 0, + 3 + ] + ] + }, + { + "name": "AFRCR", + "offset": "0x0C", + "reset": "0x00000007", + "fields": [ + [ + "FSOFF", + 18, + 1 + ], + [ + "FSPOL", + 17, + 1 + ], + [ + "FSDEF", + 16, + 1 + ], + [ + "FSALL", + 8, + 7 + ], + [ + "FRL", + 0, + 8 + ] + ] + }, + { + "name": "ASLOTR", + "offset": "0x10", + "fields": [ + [ + "SLOTEN", + 16, + 16 + ], + [ + "NBSLOT", + 8, + 4 + ], + [ + "SLOTSZ", + 6, + 2 + ], + [ + "FBOFF", + 0, + 5 + ] + ] + }, + { + "name": "AIM", + "offset": "0x14", + "fields": [ + [ + "LFSDET", + 6, + 1 + ], + [ + "AFSDETIE", + 5, + 1 + ], + [ + "CNRDYIE", + 4, + 1 + ], + [ + "FREQIE", + 3, + 1 + ], + [ + "WCKCFG", + 2, + 1 + ], + [ + "MUTEDET", + 1, + 1 + ], + [ + "OVRUDRIE", + 0, + 1 + ] + ] + }, + { + "name": "ASR", + "offset": "0x18", + "fields": [ + [ + "FLVL", + 16, + 3 + ], + [ + "LFSDET", + 6, + 1 + ], + [ + "AFSDET", + 5, + 1 + ], + [ + "CNRDY", + 4, + 1 + ], + [ + "FREQ", + 3, + 1 + ], + [ + "WCKCFG", + 2, + 1 + ], + [ + "MUTEDET", + 1, + 1 + ], + [ + "OVRUDR", + 0, + 1 + ] + ] + }, + { + "name": "ACLRFR", + "offset": "0x1C", + "fields": [ + [ + "LFSDET", + 6, + 1 + ], + [ + "CAFSDET", + 5, + 1 + ], + [ + "CNRDY", + 4, + 1 + ], + [ + "WCKCFG", + 2, + 1 + ], + [ + "MUTEDET", + 1, + 1 + ], + [ + "OVRUDR", + 0, + 1 + ] + ] + }, + { + "name": "ADR", + "offset": "0x20", + "fields": [ + [ + "DATA", + 0, + 32 + ] + ] + }, + { + "name": "PDMCR", + "offset": "0x44", + "fields": [ + [ + "PDMEN", + 0, + 1 + ], + [ + "MICNBR", + 4, + 2 + ], + [ + "CKEN1", + 8, + 1 + ], + [ + "CKEN2", + 9, + 1 + ], + [ + "CKEN3", + 10, + 1 + ], + [ + "CKEN4", + 11, + 1 + ] + ] + }, + { + "name": "PDMDLY", + "offset": "0x48", + "fields": [ + [ + "DLYM1L", + 0, + 3 + ], + [ + "DLYM1R", + 4, + 3 + ], + [ + "DLYM2L", + 8, + 3 + ], + [ + "DLYM2R", + 12, + 3 + ], + [ + "DLYM3L", + 16, + 3 + ], + [ + "DLYM3R", + 20, + 3 + ], + [ + "DLYM4L", + 24, + 3 + ], + [ + "DLYM4R", + 28, + 3 + ] + ] + } + ] + }, + { + "name": "HRTIM_Master", + "base": "0x40016800", + "interrupts": [ + "HRTIM_Master_IRQn" + ], + "registers": [ + { + "name": "MCR", + "offset": "0x00", + "fields": [ + [ + "BRSTDMA", + 30, + 2 + ], + [ + "MREPU", + 29, + 1 + ], + [ + "PREEN", + 27, + 1 + ], + [ + "DACSYNC", + 25, + 2 + ], + [ + "TFCEN", + 22, + 1 + ], + [ + "TECEN", + 21, + 1 + ], + [ + "TDCEN", + 20, + 1 + ], + [ + "TCCEN", + 19, + 1 + ], + [ + "TBCEN", + 18, + 1 + ], + [ + "TACEN", + 17, + 1 + ], + [ + "MCEN", + 16, + 1 + ], + [ + "SYNC_SRC", + 14, + 2 + ], + [ + "SYNC_OUT", + 12, + 2 + ], + [ + "SYNCSTRTM", + 11, + 1 + ], + [ + "SYNCRSTM", + 10, + 1 + ], + [ + "SYNC_IN", + 8, + 2 + ], + [ + "INTLVD", + 6, + 2 + ], + [ + "HALF", + 5, + 1 + ], + [ + "RETRIG", + 4, + 1 + ], + [ + "CONT", + 3, + 1 + ], + [ + "CK_PSC", + 0, + 3 + ] + ] + }, + { + "name": "MISR", + "offset": "0x04", + "fields": [ + [ + "MUPD", + 6, + 1, + "r" + ], + [ + "SYNC", + 5, + 1, + "r" + ], + [ + "MREP", + 4, + 1, + "r" + ], + [ + "MCMP4", + 3, + 1, + "r" + ], + [ + "MCMP3", + 2, + 1, + "r" + ], + [ + "MCMP2", + 1, + 1, + "r" + ], + [ + "MCMP1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "MICR", + "offset": "0x08", + "fields": [ + [ + "MUPDC", + 6, + 1, + "w" + ], + [ + "SYNCC", + 5, + 1, + "w" + ], + [ + "MREPC", + 4, + 1, + "w" + ], + [ + "MCMP4C", + 3, + 1, + "w" + ], + [ + "MCMP3C", + 2, + 1, + "w" + ], + [ + "MCMP2C", + 1, + 1, + "w" + ], + [ + "MCMP1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "MDIER", + "offset": "0x0C", + "fields": [ + [ + "MUPDDE", + 22, + 1 + ], + [ + "SYNCDE", + 21, + 1 + ], + [ + "MREPDE", + 20, + 1 + ], + [ + "MCMP4DE", + 19, + 1 + ], + [ + "MCMP3DE", + 18, + 1 + ], + [ + "MCMP2DE", + 17, + 1 + ], + [ + "MCMP1DE", + 16, + 1 + ], + [ + "MUPDIE", + 6, + 1 + ], + [ + "SYNCIE", + 5, + 1 + ], + [ + "MREPIE", + 4, + 1 + ], + [ + "MCMP4IE", + 3, + 1 + ], + [ + "MCMP3IE", + 2, + 1 + ], + [ + "MCMP2IE", + 1, + 1 + ], + [ + "MCMP1IE", + 0, + 1 + ] + ] + }, + { + "name": "MCNTR", + "offset": "0x10", + "fields": [ + [ + "MCNT", + 0, + 16 + ] + ] + }, + { + "name": "MPER", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "MPER", + 0, + 16 + ] + ] + }, + { + "name": "MREP", + "offset": "0x18", + "fields": [ + [ + "MREP", + 0, + 8 + ] + ] + }, + { + "name": "MCMP1R", + "offset": "0x1C", + "fields": [ + [ + "MCMP1", + 0, + 16 + ] + ] + }, + { + "name": "MCMP2R", + "offset": "0x24", + "fields": [ + [ + "MCMP2", + 0, + 16 + ] + ] + }, + { + "name": "MCMP3R", + "offset": "0x28", + "fields": [ + [ + "MCMP3", + 0, + 16 + ] + ] + }, + { + "name": "MCMP4R", + "offset": "0x2C", + "fields": [ + [ + "MCMP4", + 0, + 16 + ] + ] + } + ] + }, + { + "name": "HRTIM_TIMA", + "base": "0x40016880", + "interrupts": [ + "HRTIM_TIMA_IRQn" + ], + "registers": [ + { + "name": "TIMACR", + "offset": "0x00", + "fields": [ + [ + "UPDGAT", + 28, + 4 + ], + [ + "PREEN", + 27, + 1 + ], + [ + "DACSYNC", + 25, + 2 + ], + [ + "MSTU", + 24, + 1 + ], + [ + "TEU", + 23, + 1 + ], + [ + "TDU", + 22, + 1 + ], + [ + "TCU", + 21, + 1 + ], + [ + "TBU", + 20, + 1 + ], + [ + "TxRSTU", + 18, + 1 + ], + [ + "TxREPU", + 17, + 1 + ], + [ + "TFU", + 16, + 1 + ], + [ + "DELCMP4", + 14, + 2 + ], + [ + "DELCMP2", + 12, + 2 + ], + [ + "SYNCSTRTx", + 11, + 1 + ], + [ + "SYNCRSTx", + 10, + 1 + ], + [ + "RSYNCU", + 9, + 1 + ], + [ + "INTLVD", + 7, + 2 + ], + [ + "PSHPLL", + 6, + 1 + ], + [ + "HALF", + 5, + 1 + ], + [ + "RETRIG", + 4, + 1 + ], + [ + "CONT", + 3, + 1 + ], + [ + "CK_PSCx", + 0, + 3 + ] + ] + }, + { + "name": "TIMAISR", + "offset": "0x04", + "fields": [ + [ + "O2CPY", + 21, + 1, + "r" + ], + [ + "O1CPY", + 20, + 1, + "r" + ], + [ + "O2STAT", + 19, + 1, + "r" + ], + [ + "O1STAT", + 18, + 1, + "r" + ], + [ + "IPPSTAT", + 17, + 1, + "r" + ], + [ + "CPPSTAT", + 16, + 1, + "r" + ], + [ + "DLYPRT", + 14, + 1, + "r" + ], + [ + "RST", + 13, + 1, + "r" + ], + [ + "RSTx2", + 12, + 1, + "r" + ], + [ + "SETx2", + 11, + 1, + "r" + ], + [ + "RSTx1", + 10, + 1, + "r" + ], + [ + "SETx1", + 9, + 1, + "r" + ], + [ + "CPT2", + 8, + 1, + "r" + ], + [ + "CPT1", + 7, + 1, + "r" + ], + [ + "UPD", + 6, + 1, + "r" + ], + [ + "REP", + 4, + 1, + "r" + ], + [ + "CMP4", + 3, + 1, + "r" + ], + [ + "CMP3", + 2, + 1, + "r" + ], + [ + "CMP2", + 1, + 1, + "r" + ], + [ + "CMP1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "TIMAICR", + "offset": "0x08", + "fields": [ + [ + "DLYPRTC", + 14, + 1, + "w" + ], + [ + "RSTC", + 13, + 1, + "w" + ], + [ + "RSTx2C", + 12, + 1, + "w" + ], + [ + "SET2xC", + 11, + 1, + "w" + ], + [ + "RSTx1C", + 10, + 1, + "w" + ], + [ + "SET1xC", + 9, + 1, + "w" + ], + [ + "CPT2C", + 8, + 1, + "w" + ], + [ + "CPT1C", + 7, + 1, + "w" + ], + [ + "UPDC", + 6, + 1, + "w" + ], + [ + "REPC", + 4, + 1, + "w" + ], + [ + "CMP4C", + 3, + 1, + "w" + ], + [ + "CMP3C", + 2, + 1, + "w" + ], + [ + "CMP2C", + 1, + 1, + "w" + ], + [ + "CMP1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "TIMADIER", + "offset": "0x0C", + "fields": [ + [ + "DLYPRTDE", + 30, + 1 + ], + [ + "RSTDE", + 29, + 1 + ], + [ + "RSTx2DE", + 28, + 1 + ], + [ + "SETx2DE", + 27, + 1 + ], + [ + "RSTx1DE", + 26, + 1 + ], + [ + "SET1xDE", + 25, + 1 + ], + [ + "CPT2DE", + 24, + 1 + ], + [ + "CPT1DE", + 23, + 1 + ], + [ + "UPDDE", + 22, + 1 + ], + [ + "REPDE", + 20, + 1 + ], + [ + "CMP4DE", + 19, + 1 + ], + [ + "CMP3DE", + 18, + 1 + ], + [ + "CMP2DE", + 17, + 1 + ], + [ + "CMP1DE", + 16, + 1 + ], + [ + "DLYPRTIE", + 14, + 1 + ], + [ + "RSTIE", + 13, + 1 + ], + [ + "RSTx2IE", + 12, + 1 + ], + [ + "SETx2IE", + 11, + 1 + ], + [ + "RSTx1IE", + 10, + 1 + ], + [ + "SET1xIE", + 9, + 1 + ], + [ + "CPT2IE", + 8, + 1 + ], + [ + "CPT1IE", + 7, + 1 + ], + [ + "UPDIE", + 6, + 1 + ], + [ + "REPIE", + 4, + 1 + ], + [ + "CMP4IE", + 3, + 1 + ], + [ + "CMP3IE", + 2, + 1 + ], + [ + "CMP2IE", + 1, + 1 + ], + [ + "CMP1IE", + 0, + 1 + ] + ] + }, + { + "name": "CNTAR", + "offset": "0x10", + "fields": [ + [ + "CNTx", + 0, + 16 + ] + ] + }, + { + "name": "PERAR", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "PERx", + 0, + 16 + ] + ] + }, + { + "name": "REPAR", + "offset": "0x18", + "fields": [ + [ + "REPx", + 0, + 8 + ] + ] + }, + { + "name": "CMP1AR", + "offset": "0x1C", + "fields": [ + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP1CAR", + "offset": "0x20", + "fields": [ + [ + "REPx", + 16, + 8 + ], + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP2AR", + "offset": "0x24", + "fields": [ + [ + "CMP2x", + 0, + 16 + ] + ] + }, + { + "name": "CMP3AR", + "offset": "0x28", + "fields": [ + [ + "CMP3x", + 0, + 16 + ] + ] + }, + { + "name": "CMP4AR", + "offset": "0x2C", + "fields": [ + [ + "CMP4x", + 0, + 16 + ] + ] + }, + { + "name": "CPT1AR", + "offset": "0x30", + "fields": [ + [ + "CPT1x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "CPT2AR", + "offset": "0x34", + "fields": [ + [ + "DIR", + 16, + 1, + "r" + ], + [ + "CPT2x", + 0, + 16, + "r" + ] + ] + }, + { + "name": "DTAR", + "offset": "0x38", + "fields": [ + [ + "DTFLKx", + 31, + 1 + ], + [ + "DTFSLKx", + 30, + 1 + ], + [ + "SDTFx", + 25, + 1 + ], + [ + "DTFx", + 16, + 9 + ], + [ + "DTRLKx", + 15, + 1 + ], + [ + "DTRSLKx", + 14, + 1 + ], + [ + "DTPRSC", + 10, + 3 + ], + [ + "SDTRx", + 9, + 1 + ], + [ + "DTRx", + 0, + 9 + ] + ] + }, + { + "name": "SETA1R", + "offset": "0x3C", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTA1R", + "offset": "0x40", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "SETA2R", + "offset": "0x44", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTA2R", + "offset": "0x48", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "EEFAR1", + "offset": "0x4C", + "fields": [ + [ + "EE5FLTR", + 25, + 4 + ], + [ + "EE5LTCH", + 24, + 1 + ], + [ + "EE4FLTR", + 19, + 4 + ], + [ + "EE4LTCH", + 18, + 1 + ], + [ + "EE3FLTR", + 13, + 4 + ], + [ + "EE3LTCH", + 12, + 1 + ], + [ + "EE2FLTR", + 7, + 4 + ], + [ + "EE2LTCH", + 6, + 1 + ], + [ + "EE1FLTR", + 1, + 4 + ], + [ + "EE1LTCH", + 0, + 1 + ] + ] + }, + { + "name": "EEFAR2", + "offset": "0x50", + "fields": [ + [ + "EE10FLTR", + 25, + 4 + ], + [ + "EE10LTCH", + 24, + 1 + ], + [ + "EE9FLTR", + 19, + 4 + ], + [ + "EE9LTCH", + 18, + 1 + ], + [ + "EE8FLTR", + 13, + 4 + ], + [ + "EE8LTCH", + 12, + 1 + ], + [ + "EE7FLTR", + 7, + 4 + ], + [ + "EE7LTCH", + 6, + 1 + ], + [ + "EE6FLTR", + 1, + 4 + ], + [ + "EE6LTCH", + 0, + 1 + ] + ] + }, + { + "name": "RSTAR", + "offset": "0x54", + "fields": [ + [ + "TIMFCPM2", + 31, + 1 + ], + [ + "TIMECMP4", + 30, + 1 + ], + [ + "TIMECMP2", + 29, + 1 + ], + [ + "TIMECMP1", + 28, + 1 + ], + [ + "TIMDCMP4", + 27, + 1 + ], + [ + "TIMDCMP2", + 26, + 1 + ], + [ + "TIMDCMP1", + 25, + 1 + ], + [ + "TIMCCMP4", + 24, + 1 + ], + [ + "TIMCCMP2", + 23, + 1 + ], + [ + "TIMCCMP1", + 22, + 1 + ], + [ + "TIMBCMP4", + 21, + 1 + ], + [ + "TIMBCMP2", + 20, + 1 + ], + [ + "TIMBCMP1", + 19, + 1 + ], + [ + "EXTEVNT10", + 18, + 1 + ], + [ + "EXTEVNT9", + 17, + 1 + ], + [ + "EXTEVNT8", + 16, + 1 + ], + [ + "EXTEVNT7", + 15, + 1 + ], + [ + "EXTEVNT6", + 14, + 1 + ], + [ + "EXTEVNT5", + 13, + 1 + ], + [ + "EXTEVNT4", + 12, + 1 + ], + [ + "EXTEVNT3", + 11, + 1 + ], + [ + "EXTEVNT2", + 10, + 1 + ], + [ + "EXTEVNT1", + 9, + 1 + ], + [ + "MSTCMP4", + 8, + 1 + ], + [ + "MSTCMP3", + 7, + 1 + ], + [ + "MSTCMP2", + 6, + 1 + ], + [ + "MSTCMP1", + 5, + 1 + ], + [ + "MSTPER", + 4, + 1 + ], + [ + "CMP4", + 3, + 1 + ], + [ + "CMP2", + 2, + 1 + ], + [ + "UPDT", + 1, + 1 + ], + [ + "TIMFCMP1", + 0, + 1 + ] + ] + }, + { + "name": "CHPAR", + "offset": "0x58", + "fields": [ + [ + "STRTPW", + 7, + 4 + ], + [ + "CHPDTY", + 4, + 3 + ], + [ + "CHPFRQ", + 0, + 4 + ] + ] + }, + { + "name": "CPT1ACR", + "offset": "0x5C", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TFCMP2", + 15, + 1 + ], + [ + "TFCMP1", + 14, + 1 + ], + [ + "TF1RST", + 13, + 1 + ], + [ + "TF1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "CPT2ACR", + "offset": "0x60", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TFCMP2", + 15, + 1 + ], + [ + "TFCMP1", + 14, + 1 + ], + [ + "TF1RST", + 13, + 1 + ], + [ + "TF1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "OUTAR", + "offset": "0x64", + "fields": [ + [ + "DIDL2", + 23, + 1 + ], + [ + "CHP2", + 22, + 1 + ], + [ + "FAULT2", + 20, + 2 + ], + [ + "IDLES2", + 19, + 1 + ], + [ + "IDLEM2", + 18, + 1 + ], + [ + "POL2", + 17, + 1 + ], + [ + "BIAR", + 14, + 1 + ], + [ + "DLYPRT", + 10, + 3 + ], + [ + "DLYPRTEN", + 9, + 1 + ], + [ + "DTEN", + 8, + 1 + ], + [ + "DIDL1", + 7, + 1 + ], + [ + "CHP1", + 6, + 1 + ], + [ + "FAULT1", + 4, + 2 + ], + [ + "IDLES1", + 3, + 1 + ], + [ + "IDLEM1", + 2, + 1 + ], + [ + "POL1", + 1, + 1 + ] + ] + }, + { + "name": "FLTAR", + "offset": "0x68", + "fields": [ + [ + "FLTLCK", + 31, + 1 + ], + [ + "FLT6EN", + 5, + 1 + ], + [ + "FLT5EN", + 4, + 1 + ], + [ + "FLT4EN", + 3, + 1 + ], + [ + "FLT3EN", + 2, + 1 + ], + [ + "FLT2EN", + 1, + 1 + ], + [ + "FLT1EN", + 0, + 1 + ] + ] + }, + { + "name": "TIMACR2", + "offset": "0x6C", + "fields": [ + [ + "TRGHLF", + 20, + 1 + ], + [ + "GTCMP3", + 17, + 1 + ], + [ + "GTCMP1", + 16, + 1 + ], + [ + "FEROM", + 14, + 2 + ], + [ + "BMROM", + 12, + 2 + ], + [ + "ADROM", + 10, + 2 + ], + [ + "OUTROM", + 8, + 2 + ], + [ + "ROM", + 6, + 2 + ], + [ + "UDM", + 4, + 1 + ], + [ + "DCDR", + 2, + 1 + ], + [ + "DCDS", + 1, + 1 + ], + [ + "DCDE", + 0, + 1 + ] + ] + }, + { + "name": "AEEFR3", + "offset": "0x70", + "fields": [ + [ + "EEVACNT", + 8, + 6 + ], + [ + "EEVASEL", + 4, + 4 + ], + [ + "EEVARSTM", + 2, + 1 + ], + [ + "EEVACRES", + 1, + 1 + ], + [ + "EEVACE", + 0, + 1 + ] + ] + } + ] + }, + { + "name": "HRTIM_TIMB", + "base": "0x40016900", + "interrupts": [ + "HRTIM_TIMB_IRQn" + ], + "registers": [ + { + "name": "TIMBCR", + "offset": "0x00", + "fields": [ + [ + "UPDGAT", + 28, + 4 + ], + [ + "PREEN", + 27, + 1 + ], + [ + "DACSYNC", + 25, + 2 + ], + [ + "MSTU", + 24, + 1 + ], + [ + "TEU", + 23, + 1 + ], + [ + "TDU", + 22, + 1 + ], + [ + "TCU", + 21, + 1 + ], + [ + "TAU", + 19, + 1 + ], + [ + "TxRSTU", + 18, + 1 + ], + [ + "TxREPU", + 17, + 1 + ], + [ + "TFU", + 16, + 1 + ], + [ + "DELCMP4", + 14, + 2 + ], + [ + "DELCMP2", + 12, + 2 + ], + [ + "SYNCSTRTx", + 11, + 1 + ], + [ + "SYNCRSTx", + 10, + 1 + ], + [ + "RSYNCU", + 9, + 1 + ], + [ + "INTLVD", + 7, + 2 + ], + [ + "PSHPLL", + 6, + 1 + ], + [ + "HALF", + 5, + 1 + ], + [ + "RETRIG", + 4, + 1 + ], + [ + "CONT", + 3, + 1 + ], + [ + "CK_PSCx", + 0, + 3 + ] + ] + }, + { + "name": "TIMBISR", + "offset": "0x04", + "fields": [ + [ + "O2CPY", + 21, + 1, + "r" + ], + [ + "O1CPY", + 20, + 1, + "r" + ], + [ + "O2STAT", + 19, + 1, + "r" + ], + [ + "O1STAT", + 18, + 1, + "r" + ], + [ + "IPPSTAT", + 17, + 1, + "r" + ], + [ + "CPPSTAT", + 16, + 1, + "r" + ], + [ + "DLYPRT", + 14, + 1, + "r" + ], + [ + "RST", + 13, + 1, + "r" + ], + [ + "RSTx2", + 12, + 1, + "r" + ], + [ + "SETx2", + 11, + 1, + "r" + ], + [ + "RSTx1", + 10, + 1, + "r" + ], + [ + "SETx1", + 9, + 1, + "r" + ], + [ + "CPT2", + 8, + 1, + "r" + ], + [ + "CPT1", + 7, + 1, + "r" + ], + [ + "UPD", + 6, + 1, + "r" + ], + [ + "REP", + 4, + 1, + "r" + ], + [ + "CMP4", + 3, + 1, + "r" + ], + [ + "CMP3", + 2, + 1, + "r" + ], + [ + "CMP2", + 1, + 1, + "r" + ], + [ + "CMP1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "TIMBICR", + "offset": "0x08", + "fields": [ + [ + "DLYPRTC", + 14, + 1, + "w" + ], + [ + "RSTC", + 13, + 1, + "w" + ], + [ + "RSTx2C", + 12, + 1, + "w" + ], + [ + "SET2xC", + 11, + 1, + "w" + ], + [ + "RSTx1C", + 10, + 1, + "w" + ], + [ + "SET1xC", + 9, + 1, + "w" + ], + [ + "CPT2C", + 8, + 1, + "w" + ], + [ + "CPT1C", + 7, + 1, + "w" + ], + [ + "UPDC", + 6, + 1, + "w" + ], + [ + "REPC", + 4, + 1, + "w" + ], + [ + "CMP4C", + 3, + 1, + "w" + ], + [ + "CMP3C", + 2, + 1, + "w" + ], + [ + "CMP2C", + 1, + 1, + "w" + ], + [ + "CMP1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "TIMBDIER", + "offset": "0x0C", + "fields": [ + [ + "DLYPRTDE", + 30, + 1 + ], + [ + "RSTDE", + 29, + 1 + ], + [ + "RSTx2DE", + 28, + 1 + ], + [ + "SETx2DE", + 27, + 1 + ], + [ + "RSTx1DE", + 26, + 1 + ], + [ + "SET1xDE", + 25, + 1 + ], + [ + "CPT2DE", + 24, + 1 + ], + [ + "CPT1DE", + 23, + 1 + ], + [ + "UPDDE", + 22, + 1 + ], + [ + "REPDE", + 20, + 1 + ], + [ + "CMP4DE", + 19, + 1 + ], + [ + "CMP3DE", + 18, + 1 + ], + [ + "CMP2DE", + 17, + 1 + ], + [ + "CMP1DE", + 16, + 1 + ], + [ + "DLYPRTIE", + 14, + 1 + ], + [ + "RSTIE", + 13, + 1 + ], + [ + "RSTx2IE", + 12, + 1 + ], + [ + "SETx2IE", + 11, + 1 + ], + [ + "RSTx1IE", + 10, + 1 + ], + [ + "SET1xIE", + 9, + 1 + ], + [ + "CPT2IE", + 8, + 1 + ], + [ + "CPT1IE", + 7, + 1 + ], + [ + "UPDIE", + 6, + 1 + ], + [ + "REPIE", + 4, + 1 + ], + [ + "CMP4IE", + 3, + 1 + ], + [ + "CMP3IE", + 2, + 1 + ], + [ + "CMP2IE", + 1, + 1 + ], + [ + "CMP1IE", + 0, + 1 + ] + ] + }, + { + "name": "CNTR", + "offset": "0x10", + "fields": [ + [ + "CNTx", + 0, + 16 + ] + ] + }, + { + "name": "PERBR", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "PERx", + 0, + 16 + ] + ] + }, + { + "name": "REPBR", + "offset": "0x18", + "fields": [ + [ + "REPx", + 0, + 8 + ] + ] + }, + { + "name": "CMP1BR", + "offset": "0x1C", + "fields": [ + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP1CBR", + "offset": "0x20", + "fields": [ + [ + "REPx", + 16, + 8 + ], + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP2BR", + "offset": "0x24", + "fields": [ + [ + "CMP2x", + 0, + 16 + ] + ] + }, + { + "name": "CMP3BR", + "offset": "0x28", + "fields": [ + [ + "CMP3x", + 0, + 16 + ] + ] + }, + { + "name": "CMP4BR", + "offset": "0x2C", + "fields": [ + [ + "CMP4x", + 0, + 16 + ] + ] + }, + { + "name": "CPT1BR", + "offset": "0x30", + "fields": [ + [ + "CPT1x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "CPT2BR", + "offset": "0x34", + "fields": [ + [ + "CPT2x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "DTBR", + "offset": "0x38", + "fields": [ + [ + "DTFLKx", + 31, + 1 + ], + [ + "DTFSLKx", + 30, + 1 + ], + [ + "SDTFx", + 25, + 1 + ], + [ + "DTFx", + 16, + 9 + ], + [ + "DTRLKx", + 15, + 1 + ], + [ + "DTRSLKx", + 14, + 1 + ], + [ + "DTPRSC", + 10, + 3 + ], + [ + "SDTRx", + 9, + 1 + ], + [ + "DTRx", + 0, + 9 + ] + ] + }, + { + "name": "SETB1R", + "offset": "0x3C", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTB1R", + "offset": "0x40", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "SETB2R", + "offset": "0x44", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTB2R", + "offset": "0x48", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "EEFBR1", + "offset": "0x4C", + "fields": [ + [ + "EE5FLTR", + 25, + 4 + ], + [ + "EE5LTCH", + 24, + 1 + ], + [ + "EE4FLTR", + 19, + 4 + ], + [ + "EE4LTCH", + 18, + 1 + ], + [ + "EE3FLTR", + 13, + 4 + ], + [ + "EE3LTCH", + 12, + 1 + ], + [ + "EE2FLTR", + 7, + 4 + ], + [ + "EE2LTCH", + 6, + 1 + ], + [ + "EE1FLTR", + 1, + 4 + ], + [ + "EE1LTCH", + 0, + 1 + ] + ] + }, + { + "name": "EEFBR2", + "offset": "0x50", + "fields": [ + [ + "EE10FLTR", + 25, + 4 + ], + [ + "EE10LTCH", + 24, + 1 + ], + [ + "EE9FLTR", + 19, + 4 + ], + [ + "EE9LTCH", + 18, + 1 + ], + [ + "EE8FLTR", + 13, + 4 + ], + [ + "EE8LTCH", + 12, + 1 + ], + [ + "EE7FLTR", + 7, + 4 + ], + [ + "EE7LTCH", + 6, + 1 + ], + [ + "EE6FLTR", + 1, + 4 + ], + [ + "EE6LTCH", + 0, + 1 + ] + ] + }, + { + "name": "RSTBR", + "offset": "0x54", + "fields": [ + [ + "TIMFCPM2", + 31, + 1 + ], + [ + "TIMECMP4", + 30, + 1 + ], + [ + "TIMECMP2", + 29, + 1 + ], + [ + "TIMECMP1", + 28, + 1 + ], + [ + "TIMDCMP4", + 27, + 1 + ], + [ + "TIMDCMP2", + 26, + 1 + ], + [ + "TIMDCMP1", + 25, + 1 + ], + [ + "TIMCCMP4", + 24, + 1 + ], + [ + "TIMCCMP2", + 23, + 1 + ], + [ + "TIMCCMP1", + 22, + 1 + ], + [ + "TIMACMP4", + 21, + 1 + ], + [ + "TIMACMP2", + 20, + 1 + ], + [ + "TIMACMP1", + 19, + 1 + ], + [ + "EXTEVNT10", + 18, + 1 + ], + [ + "EXTEVNT9", + 17, + 1 + ], + [ + "EXTEVNT8", + 16, + 1 + ], + [ + "EXTEVNT7", + 15, + 1 + ], + [ + "EXTEVNT6", + 14, + 1 + ], + [ + "EXTEVNT5", + 13, + 1 + ], + [ + "EXTEVNT4", + 12, + 1 + ], + [ + "EXTEVNT3", + 11, + 1 + ], + [ + "EXTEVNT2", + 10, + 1 + ], + [ + "EXTEVNT1", + 9, + 1 + ], + [ + "MSTCMP4", + 8, + 1 + ], + [ + "MSTCMP3", + 7, + 1 + ], + [ + "MSTCMP2", + 6, + 1 + ], + [ + "MSTCMP1", + 5, + 1 + ], + [ + "MSTPER", + 4, + 1 + ], + [ + "CMP4", + 3, + 1 + ], + [ + "CMP2", + 2, + 1 + ], + [ + "UPDT", + 1, + 1 + ], + [ + "TIMFCMP1", + 0, + 1 + ] + ] + }, + { + "name": "CHPBR", + "offset": "0x58", + "fields": [ + [ + "STRTPW", + 7, + 4 + ], + [ + "CHPDTY", + 4, + 3 + ], + [ + "CHPFRQ", + 0, + 4 + ] + ] + }, + { + "name": "CPT1BCR", + "offset": "0x5C", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TFCMP2", + 19, + 1 + ], + [ + "TFCMP1", + 18, + 1 + ], + [ + "TF1RST", + 17, + 1 + ], + [ + "TF1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "CPT2BCR", + "offset": "0x60", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TFCMP2", + 19, + 1 + ], + [ + "TFCMP1", + 18, + 1 + ], + [ + "TF1RST", + 17, + 1 + ], + [ + "TF1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "OUTBR", + "offset": "0x64", + "fields": [ + [ + "DIDL2", + 23, + 1 + ], + [ + "CHP2", + 22, + 1 + ], + [ + "FAULT2", + 20, + 2 + ], + [ + "IDLES2", + 19, + 1 + ], + [ + "IDLEM2", + 18, + 1 + ], + [ + "POL2", + 17, + 1 + ], + [ + "BIAR", + 14, + 1 + ], + [ + "DLYPRT", + 10, + 3 + ], + [ + "DLYPRTEN", + 9, + 1 + ], + [ + "DTEN", + 8, + 1 + ], + [ + "DIDL1", + 7, + 1 + ], + [ + "CHP1", + 6, + 1 + ], + [ + "FAULT1", + 4, + 2 + ], + [ + "IDLES1", + 3, + 1 + ], + [ + "IDLEM1", + 2, + 1 + ], + [ + "POL1", + 1, + 1 + ] + ] + }, + { + "name": "FLTBR", + "offset": "0x68", + "fields": [ + [ + "FLTLCK", + 31, + 1 + ], + [ + "FLT6EN", + 5, + 1 + ], + [ + "FLT5EN", + 4, + 1 + ], + [ + "FLT4EN", + 3, + 1 + ], + [ + "FLT3EN", + 2, + 1 + ], + [ + "FLT2EN", + 1, + 1 + ], + [ + "FLT1EN", + 0, + 1 + ] + ] + }, + { + "name": "TIMBCR2", + "offset": "0x6C", + "fields": [ + [ + "TRGHLF", + 20, + 1 + ], + [ + "GTCMP3", + 17, + 1 + ], + [ + "GTCMP1", + 16, + 1 + ], + [ + "FEROM", + 14, + 2 + ], + [ + "BMROM", + 12, + 2 + ], + [ + "ADROM", + 10, + 2 + ], + [ + "OUTROM", + 8, + 2 + ], + [ + "ROM", + 6, + 2 + ], + [ + "UDM", + 4, + 1 + ], + [ + "DCDR", + 2, + 1 + ], + [ + "DCDS", + 1, + 1 + ], + [ + "DCDE", + 0, + 1 + ] + ] + }, + { + "name": "BEEFR3", + "offset": "0x70", + "fields": [ + [ + "EEVACNT", + 8, + 6 + ], + [ + "EEVASEL", + 4, + 4 + ], + [ + "EEVARSTM", + 2, + 1 + ], + [ + "EEVACRES", + 1, + 1 + ], + [ + "EEVACE", + 0, + 1 + ] + ] + } + ] + }, + { + "name": "HRTIM_TIMC", + "base": "0x40016980", + "interrupts": [ + "HRTIM_TIMC_IRQn" + ], + "registers": [ + { + "name": "TIMCCR", + "offset": "0x00", + "fields": [ + [ + "UPDGAT", + 28, + 4 + ], + [ + "PREEN", + 27, + 1 + ], + [ + "DACSYNC", + 25, + 2 + ], + [ + "MSTU", + 24, + 1 + ], + [ + "TEU", + 23, + 1 + ], + [ + "TDU", + 22, + 1 + ], + [ + "TBU", + 20, + 1 + ], + [ + "TAU", + 19, + 1 + ], + [ + "TxRSTU", + 18, + 1 + ], + [ + "TxREPU", + 17, + 1 + ], + [ + "TFU", + 16, + 1 + ], + [ + "DELCMP4", + 14, + 2 + ], + [ + "DELCMP2", + 12, + 2 + ], + [ + "SYNCSTRTx", + 11, + 1 + ], + [ + "SYNCRSTx", + 10, + 1 + ], + [ + "RSYNCU", + 9, + 1 + ], + [ + "INTLVD", + 7, + 2 + ], + [ + "PSHPLL", + 6, + 1 + ], + [ + "HALF", + 5, + 1 + ], + [ + "RETRIG", + 4, + 1 + ], + [ + "CONT", + 3, + 1 + ], + [ + "CK_PSCx", + 0, + 3 + ] + ] + }, + { + "name": "TIMCISR", + "offset": "0x04", + "fields": [ + [ + "O2CPY", + 21, + 1, + "r" + ], + [ + "O1CPY", + 20, + 1, + "r" + ], + [ + "O2STAT", + 19, + 1, + "r" + ], + [ + "O1STAT", + 18, + 1, + "r" + ], + [ + "IPPSTAT", + 17, + 1, + "r" + ], + [ + "CPPSTAT", + 16, + 1, + "r" + ], + [ + "DLYPRT", + 14, + 1, + "r" + ], + [ + "RST", + 13, + 1, + "r" + ], + [ + "RSTx2", + 12, + 1, + "r" + ], + [ + "SETx2", + 11, + 1, + "r" + ], + [ + "RSTx1", + 10, + 1, + "r" + ], + [ + "SETx1", + 9, + 1, + "r" + ], + [ + "CPT2", + 8, + 1, + "r" + ], + [ + "CPT1", + 7, + 1, + "r" + ], + [ + "UPD", + 6, + 1, + "r" + ], + [ + "REP", + 4, + 1, + "r" + ], + [ + "CMP4", + 3, + 1, + "r" + ], + [ + "CMP3", + 2, + 1, + "r" + ], + [ + "CMP2", + 1, + 1, + "r" + ], + [ + "CMP1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "TIMCICR", + "offset": "0x08", + "fields": [ + [ + "DLYPRTC", + 14, + 1, + "w" + ], + [ + "RSTC", + 13, + 1, + "w" + ], + [ + "RSTx2C", + 12, + 1, + "w" + ], + [ + "SET2xC", + 11, + 1, + "w" + ], + [ + "RSTx1C", + 10, + 1, + "w" + ], + [ + "SET1xC", + 9, + 1, + "w" + ], + [ + "CPT2C", + 8, + 1, + "w" + ], + [ + "CPT1C", + 7, + 1, + "w" + ], + [ + "UPDC", + 6, + 1, + "w" + ], + [ + "REPC", + 4, + 1, + "w" + ], + [ + "CMP4C", + 3, + 1, + "w" + ], + [ + "CMP3C", + 2, + 1, + "w" + ], + [ + "CMP2C", + 1, + 1, + "w" + ], + [ + "CMP1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "TIMCDIER", + "offset": "0x0C", + "fields": [ + [ + "DLYPRTDE", + 30, + 1 + ], + [ + "RSTDE", + 29, + 1 + ], + [ + "RSTx2DE", + 28, + 1 + ], + [ + "SETx2DE", + 27, + 1 + ], + [ + "RSTx1DE", + 26, + 1 + ], + [ + "SET1xDE", + 25, + 1 + ], + [ + "CPT2DE", + 24, + 1 + ], + [ + "CPT1DE", + 23, + 1 + ], + [ + "UPDDE", + 22, + 1 + ], + [ + "REPDE", + 20, + 1 + ], + [ + "CMP4DE", + 19, + 1 + ], + [ + "CMP3DE", + 18, + 1 + ], + [ + "CMP2DE", + 17, + 1 + ], + [ + "CMP1DE", + 16, + 1 + ], + [ + "DLYPRTIE", + 14, + 1 + ], + [ + "RSTIE", + 13, + 1 + ], + [ + "RSTx2IE", + 12, + 1 + ], + [ + "SETx2IE", + 11, + 1 + ], + [ + "RSTx1IE", + 10, + 1 + ], + [ + "SET1xIE", + 9, + 1 + ], + [ + "CPT2IE", + 8, + 1 + ], + [ + "CPT1IE", + 7, + 1 + ], + [ + "UPDIE", + 6, + 1 + ], + [ + "REPIE", + 4, + 1 + ], + [ + "CMP4IE", + 3, + 1 + ], + [ + "CMP3IE", + 2, + 1 + ], + [ + "CMP2IE", + 1, + 1 + ], + [ + "CMP1IE", + 0, + 1 + ] + ] + }, + { + "name": "CNTCR", + "offset": "0x10", + "fields": [ + [ + "CNTx", + 0, + 16 + ] + ] + }, + { + "name": "PERCR", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "PERx", + 0, + 16 + ] + ] + }, + { + "name": "REPCR", + "offset": "0x18", + "fields": [ + [ + "REPx", + 0, + 8 + ] + ] + }, + { + "name": "CMP1CR", + "offset": "0x1C", + "fields": [ + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP1CCR", + "offset": "0x20", + "fields": [ + [ + "REPx", + 16, + 8 + ], + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP2CR", + "offset": "0x24", + "fields": [ + [ + "CMP2x", + 0, + 16 + ] + ] + }, + { + "name": "CMP3CR", + "offset": "0x28", + "fields": [ + [ + "CMP3x", + 0, + 16 + ] + ] + }, + { + "name": "CMP4CR", + "offset": "0x2C", + "fields": [ + [ + "CMP4x", + 0, + 16 + ] + ] + }, + { + "name": "CPT1CR", + "offset": "0x30", + "fields": [ + [ + "CPT1x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "CPT2CR", + "offset": "0x34", + "fields": [ + [ + "CPT2x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "DTCR", + "offset": "0x38", + "fields": [ + [ + "DTFLKx", + 31, + 1 + ], + [ + "DTFSLKx", + 30, + 1 + ], + [ + "SDTFx", + 25, + 1 + ], + [ + "DTFx", + 16, + 9 + ], + [ + "DTRLKx", + 15, + 1 + ], + [ + "DTRSLKx", + 14, + 1 + ], + [ + "DTPRSC", + 10, + 3 + ], + [ + "SDTRx", + 9, + 1 + ], + [ + "DTRx", + 0, + 9 + ] + ] + }, + { + "name": "SETC1R", + "offset": "0x3C", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTC1R", + "offset": "0x40", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "SETC2R", + "offset": "0x44", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTC2R", + "offset": "0x48", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "EEFCR1", + "offset": "0x4C", + "fields": [ + [ + "EE5FLTR", + 25, + 4 + ], + [ + "EE5LTCH", + 24, + 1 + ], + [ + "EE4FLTR", + 19, + 4 + ], + [ + "EE4LTCH", + 18, + 1 + ], + [ + "EE3FLTR", + 13, + 4 + ], + [ + "EE3LTCH", + 12, + 1 + ], + [ + "EE2FLTR", + 7, + 4 + ], + [ + "EE2LTCH", + 6, + 1 + ], + [ + "EE1FLTR", + 1, + 4 + ], + [ + "EE1LTCH", + 0, + 1 + ] + ] + }, + { + "name": "EEFCR2", + "offset": "0x50", + "fields": [ + [ + "EE10FLTR", + 25, + 4 + ], + [ + "EE10LTCH", + 24, + 1 + ], + [ + "EE9FLTR", + 19, + 4 + ], + [ + "EE9LTCH", + 18, + 1 + ], + [ + "EE8FLTR", + 13, + 4 + ], + [ + "EE8LTCH", + 12, + 1 + ], + [ + "EE7FLTR", + 7, + 4 + ], + [ + "EE7LTCH", + 6, + 1 + ], + [ + "EE6FLTR", + 1, + 4 + ], + [ + "EE6LTCH", + 0, + 1 + ] + ] + }, + { + "name": "RSTCR", + "offset": "0x54", + "fields": [ + [ + "TIMFCPM2", + 31, + 1 + ], + [ + "TIMECMP4", + 30, + 1 + ], + [ + "TIMECMP2", + 29, + 1 + ], + [ + "TIMECMP1", + 28, + 1 + ], + [ + "TIMDCMP4", + 27, + 1 + ], + [ + "TIMDCMP2", + 26, + 1 + ], + [ + "TIMDCMP1", + 25, + 1 + ], + [ + "TIMBCMP4", + 24, + 1 + ], + [ + "TIMBCMP2", + 23, + 1 + ], + [ + "TIMBCMP1", + 22, + 1 + ], + [ + "TIMACMP4", + 21, + 1 + ], + [ + "TIMACMP2", + 20, + 1 + ], + [ + "TIMACMP1", + 19, + 1 + ], + [ + "EXTEVNT10", + 18, + 1 + ], + [ + "EXTEVNT9", + 17, + 1 + ], + [ + "EXTEVNT8", + 16, + 1 + ], + [ + "EXTEVNT7", + 15, + 1 + ], + [ + "EXTEVNT6", + 14, + 1 + ], + [ + "EXTEVNT5", + 13, + 1 + ], + [ + "EXTEVNT4", + 12, + 1 + ], + [ + "EXTEVNT3", + 11, + 1 + ], + [ + "EXTEVNT2", + 10, + 1 + ], + [ + "EXTEVNT1", + 9, + 1 + ], + [ + "MSTCMP4", + 8, + 1 + ], + [ + "MSTCMP3", + 7, + 1 + ], + [ + "MSTCMP2", + 6, + 1 + ], + [ + "MSTCMP1", + 5, + 1 + ], + [ + "MSTPER", + 4, + 1 + ], + [ + "CMP4", + 3, + 1 + ], + [ + "CMP2", + 2, + 1 + ], + [ + "UPDT", + 1, + 1 + ], + [ + "TIMFCMP1", + 0, + 1 + ] + ] + }, + { + "name": "CHPCR", + "offset": "0x58", + "fields": [ + [ + "STRTPW", + 7, + 4 + ], + [ + "CHPDTY", + 4, + 3 + ], + [ + "CHPFRQ", + 0, + 4 + ] + ] + }, + { + "name": "CPT1CCR", + "offset": "0x5C", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TFCMP2", + 23, + 1 + ], + [ + "TFCMP1", + 22, + 1 + ], + [ + "TF1RST", + 21, + 1 + ], + [ + "TF1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "CPT2CCR", + "offset": "0x60", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TF1CMP2", + 23, + 1 + ], + [ + "TF1CMP1", + 22, + 1 + ], + [ + "TF1RST", + 21, + 1 + ], + [ + "TF1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "OUTCR", + "offset": "0x64", + "fields": [ + [ + "DIDL2", + 23, + 1 + ], + [ + "CHP2", + 22, + 1 + ], + [ + "FAULT2", + 20, + 2 + ], + [ + "IDLES2", + 19, + 1 + ], + [ + "IDLEM2", + 18, + 1 + ], + [ + "POL2", + 17, + 1 + ], + [ + "BIAR", + 14, + 1 + ], + [ + "DLYPRT", + 10, + 3 + ], + [ + "DLYPRTEN", + 9, + 1 + ], + [ + "DTEN", + 8, + 1 + ], + [ + "DIDL1", + 7, + 1 + ], + [ + "CHP1", + 6, + 1 + ], + [ + "FAULT1", + 4, + 2 + ], + [ + "IDLES1", + 3, + 1 + ], + [ + "IDLEM1", + 2, + 1 + ], + [ + "POL1", + 1, + 1 + ] + ] + }, + { + "name": "FLTCR", + "offset": "0x68", + "fields": [ + [ + "FLTLCK", + 31, + 1 + ], + [ + "FLT6EN", + 5, + 1 + ], + [ + "FLT5EN", + 4, + 1 + ], + [ + "FLT4EN", + 3, + 1 + ], + [ + "FLT3EN", + 2, + 1 + ], + [ + "FLT2EN", + 1, + 1 + ], + [ + "FLT1EN", + 0, + 1 + ] + ] + }, + { + "name": "TIMCCR2", + "offset": "0x6C", + "fields": [ + [ + "TRGHLF", + 20, + 1 + ], + [ + "GTCMP3", + 17, + 1 + ], + [ + "GTCMP1", + 16, + 1 + ], + [ + "FEROM", + 14, + 2 + ], + [ + "BMROM", + 12, + 2 + ], + [ + "ADROM", + 10, + 2 + ], + [ + "OUTROM", + 8, + 2 + ], + [ + "ROM", + 6, + 2 + ], + [ + "UDM", + 4, + 1 + ], + [ + "DCDR", + 2, + 1 + ], + [ + "DCDS", + 1, + 1 + ], + [ + "DCDE", + 0, + 1 + ] + ] + }, + { + "name": "CEEFR3", + "offset": "0x70", + "fields": [ + [ + "EEVACNT", + 8, + 6 + ], + [ + "EEVASEL", + 4, + 4 + ], + [ + "EEVARSTM", + 2, + 1 + ], + [ + "EEVACRES", + 1, + 1 + ], + [ + "EEVACE", + 0, + 1 + ] + ] + } + ] + }, + { + "name": "HRTIM_TIMD", + "base": "0x40016A00", + "interrupts": [ + "HRTIM_TIMD_IRQn" + ], + "registers": [ + { + "name": "TIMDCR", + "offset": "0x00", + "fields": [ + [ + "UPDGAT", + 28, + 4 + ], + [ + "PREEN", + 27, + 1 + ], + [ + "DACSYNC", + 25, + 2 + ], + [ + "MSTU", + 24, + 1 + ], + [ + "TEU", + 23, + 1 + ], + [ + "TCU", + 21, + 1 + ], + [ + "TBU", + 20, + 1 + ], + [ + "TAU", + 19, + 1 + ], + [ + "TxRSTU", + 18, + 1 + ], + [ + "TxREPU", + 17, + 1 + ], + [ + "TFU", + 16, + 1 + ], + [ + "DELCMP4", + 14, + 2 + ], + [ + "DELCMP2", + 12, + 2 + ], + [ + "SYNCSTRTx", + 11, + 1 + ], + [ + "SYNCRSTx", + 10, + 1 + ], + [ + "RSYNCU", + 9, + 1 + ], + [ + "INTLVD", + 7, + 2 + ], + [ + "PSHPLL", + 6, + 1 + ], + [ + "HALF", + 5, + 1 + ], + [ + "RETRIG", + 4, + 1 + ], + [ + "CONT", + 3, + 1 + ], + [ + "CK_PSCx", + 0, + 3 + ] + ] + }, + { + "name": "TIMDISR", + "offset": "0x04", + "fields": [ + [ + "O2CPY", + 21, + 1, + "r" + ], + [ + "O1CPY", + 20, + 1, + "r" + ], + [ + "O2STAT", + 19, + 1, + "r" + ], + [ + "O1STAT", + 18, + 1, + "r" + ], + [ + "IPPSTAT", + 17, + 1, + "r" + ], + [ + "CPPSTAT", + 16, + 1, + "r" + ], + [ + "DLYPRT", + 14, + 1, + "r" + ], + [ + "RST", + 13, + 1, + "r" + ], + [ + "RSTx2", + 12, + 1, + "r" + ], + [ + "SETx2", + 11, + 1, + "r" + ], + [ + "RSTx1", + 10, + 1, + "r" + ], + [ + "SETx1", + 9, + 1, + "r" + ], + [ + "CPT2", + 8, + 1, + "r" + ], + [ + "CPT1", + 7, + 1, + "r" + ], + [ + "UPD", + 6, + 1, + "r" + ], + [ + "REP", + 4, + 1, + "r" + ], + [ + "CMP4", + 3, + 1, + "r" + ], + [ + "CMP3", + 2, + 1, + "r" + ], + [ + "CMP2", + 1, + 1, + "r" + ], + [ + "CMP1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "TIMDICR", + "offset": "0x08", + "fields": [ + [ + "DLYPRTC", + 14, + 1, + "w" + ], + [ + "RSTC", + 13, + 1, + "w" + ], + [ + "RSTx2C", + 12, + 1, + "w" + ], + [ + "SET2xC", + 11, + 1, + "w" + ], + [ + "RSTx1C", + 10, + 1, + "w" + ], + [ + "SET1xC", + 9, + 1, + "w" + ], + [ + "CPT2C", + 8, + 1, + "w" + ], + [ + "CPT1C", + 7, + 1, + "w" + ], + [ + "UPDC", + 6, + 1, + "w" + ], + [ + "REPC", + 4, + 1, + "w" + ], + [ + "CMP4C", + 3, + 1, + "w" + ], + [ + "CMP3C", + 2, + 1, + "w" + ], + [ + "CMP2C", + 1, + 1, + "w" + ], + [ + "CMP1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "TIMDDIER", + "offset": "0x0C", + "fields": [ + [ + "DLYPRTDE", + 30, + 1 + ], + [ + "RSTDE", + 29, + 1 + ], + [ + "RSTx2DE", + 28, + 1 + ], + [ + "SETx2DE", + 27, + 1 + ], + [ + "RSTx1DE", + 26, + 1 + ], + [ + "SET1xDE", + 25, + 1 + ], + [ + "CPT2DE", + 24, + 1 + ], + [ + "CPT1DE", + 23, + 1 + ], + [ + "UPDDE", + 22, + 1 + ], + [ + "REPDE", + 20, + 1 + ], + [ + "CMP4DE", + 19, + 1 + ], + [ + "CMP3DE", + 18, + 1 + ], + [ + "CMP2DE", + 17, + 1 + ], + [ + "CMP1DE", + 16, + 1 + ], + [ + "DLYPRTIE", + 14, + 1 + ], + [ + "RSTIE", + 13, + 1 + ], + [ + "RSTx2IE", + 12, + 1 + ], + [ + "SETx2IE", + 11, + 1 + ], + [ + "RSTx1IE", + 10, + 1 + ], + [ + "SET1xIE", + 9, + 1 + ], + [ + "CPT2IE", + 8, + 1 + ], + [ + "CPT1IE", + 7, + 1 + ], + [ + "UPDIE", + 6, + 1 + ], + [ + "REPIE", + 4, + 1 + ], + [ + "CMP4IE", + 3, + 1 + ], + [ + "CMP3IE", + 2, + 1 + ], + [ + "CMP2IE", + 1, + 1 + ], + [ + "CMP1IE", + 0, + 1 + ] + ] + }, + { + "name": "CNTDR", + "offset": "0x10", + "fields": [ + [ + "CNTx", + 0, + 16 + ] + ] + }, + { + "name": "PERDR", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "PERx", + 0, + 16 + ] + ] + }, + { + "name": "REPDR", + "offset": "0x18", + "fields": [ + [ + "REPx", + 0, + 8 + ] + ] + }, + { + "name": "CMP1DR", + "offset": "0x1C", + "fields": [ + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP1CDR", + "offset": "0x20", + "fields": [ + [ + "REPx", + 16, + 8 + ], + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP2DR", + "offset": "0x24", + "fields": [ + [ + "CMP2x", + 0, + 16 + ] + ] + }, + { + "name": "CMP3DR", + "offset": "0x28", + "fields": [ + [ + "CMP3x", + 0, + 16 + ] + ] + }, + { + "name": "CMP4DR", + "offset": "0x2C", + "fields": [ + [ + "CMP4x", + 0, + 16 + ] + ] + }, + { + "name": "CPT1DR", + "offset": "0x30", + "fields": [ + [ + "CPT1x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "CPT2DR", + "offset": "0x34", + "fields": [ + [ + "CPT2x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "DTDR", + "offset": "0x38", + "fields": [ + [ + "DTFLKx", + 31, + 1 + ], + [ + "DTFSLKx", + 30, + 1 + ], + [ + "SDTFx", + 25, + 1 + ], + [ + "DTFx", + 16, + 9 + ], + [ + "DTRLKx", + 15, + 1 + ], + [ + "DTRSLKx", + 14, + 1 + ], + [ + "DTPRSC", + 10, + 3 + ], + [ + "SDTRx", + 9, + 1 + ], + [ + "DTRx", + 0, + 9 + ] + ] + }, + { + "name": "SETD1R", + "offset": "0x3C", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTD1R", + "offset": "0x40", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "SETD2R", + "offset": "0x44", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTD2R", + "offset": "0x48", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "EEFDR1", + "offset": "0x4C", + "fields": [ + [ + "EE5FLTR", + 25, + 4 + ], + [ + "EE5LTCH", + 24, + 1 + ], + [ + "EE4FLTR", + 19, + 4 + ], + [ + "EE4LTCH", + 18, + 1 + ], + [ + "EE3FLTR", + 13, + 4 + ], + [ + "EE3LTCH", + 12, + 1 + ], + [ + "EE2FLTR", + 7, + 4 + ], + [ + "EE2LTCH", + 6, + 1 + ], + [ + "EE1FLTR", + 1, + 4 + ], + [ + "EE1LTCH", + 0, + 1 + ] + ] + }, + { + "name": "EEFDR2", + "offset": "0x50", + "fields": [ + [ + "EE10FLTR", + 25, + 4 + ], + [ + "EE10LTCH", + 24, + 1 + ], + [ + "EE9FLTR", + 19, + 4 + ], + [ + "EE9LTCH", + 18, + 1 + ], + [ + "EE8FLTR", + 13, + 4 + ], + [ + "EE8LTCH", + 12, + 1 + ], + [ + "EE7FLTR", + 7, + 4 + ], + [ + "EE7LTCH", + 6, + 1 + ], + [ + "EE6FLTR", + 1, + 4 + ], + [ + "EE6LTCH", + 0, + 1 + ] + ] + }, + { + "name": "RSTDR", + "offset": "0x54", + "fields": [ + [ + "TIMFCPM2", + 31, + 1 + ], + [ + "TIMECMP4", + 30, + 1 + ], + [ + "TIMECMP2", + 29, + 1 + ], + [ + "TIMECMP1", + 28, + 1 + ], + [ + "TIMCCMP4", + 27, + 1 + ], + [ + "TIMCCMP2", + 26, + 1 + ], + [ + "TIMCCMP1", + 25, + 1 + ], + [ + "TIMBCMP4", + 24, + 1 + ], + [ + "TIMBCMP2", + 23, + 1 + ], + [ + "TIMBCMP1", + 22, + 1 + ], + [ + "TIMACMP4", + 21, + 1 + ], + [ + "TIMACMP2", + 20, + 1 + ], + [ + "TIMACMP1", + 19, + 1 + ], + [ + "EXTEVNT10", + 18, + 1 + ], + [ + "EXTEVNT9", + 17, + 1 + ], + [ + "EXTEVNT8", + 16, + 1 + ], + [ + "EXTEVNT7", + 15, + 1 + ], + [ + "EXTEVNT6", + 14, + 1 + ], + [ + "EXTEVNT5", + 13, + 1 + ], + [ + "EXTEVNT4", + 12, + 1 + ], + [ + "EXTEVNT3", + 11, + 1 + ], + [ + "EXTEVNT2", + 10, + 1 + ], + [ + "EXTEVNT1", + 9, + 1 + ], + [ + "MSTCMP4", + 8, + 1 + ], + [ + "MSTCMP3", + 7, + 1 + ], + [ + "MSTCMP2", + 6, + 1 + ], + [ + "MSTCMP1", + 5, + 1 + ], + [ + "MSTPER", + 4, + 1 + ], + [ + "CMP4", + 3, + 1 + ], + [ + "CMP2", + 2, + 1 + ], + [ + "UPDT", + 1, + 1 + ], + [ + "TIMFCMP1", + 0, + 1 + ] + ] + }, + { + "name": "CHPDR", + "offset": "0x58", + "fields": [ + [ + "STRTPW", + 7, + 4 + ], + [ + "CHPDTY", + 4, + 3 + ], + [ + "CHPFRQ", + 0, + 4 + ] + ] + }, + { + "name": "CPT1DCR", + "offset": "0x5C", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TFCMP2", + 27, + 1 + ], + [ + "TFCMP1", + 26, + 1 + ], + [ + "TF1RST", + 25, + 1 + ], + [ + "TF1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "CPT2DCR", + "offset": "0x60", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TFCMP2", + 27, + 1 + ], + [ + "TFCMP1", + 26, + 1 + ], + [ + "TF1RST", + 25, + 1 + ], + [ + "TF1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "OUTDR", + "offset": "0x64", + "fields": [ + [ + "DIDL2", + 23, + 1 + ], + [ + "CHP2", + 22, + 1 + ], + [ + "FAULT2", + 20, + 2 + ], + [ + "IDLES2", + 19, + 1 + ], + [ + "IDLEM2", + 18, + 1 + ], + [ + "POL2", + 17, + 1 + ], + [ + "BIAR", + 14, + 1 + ], + [ + "DLYPRT", + 10, + 3 + ], + [ + "DLYPRTEN", + 9, + 1 + ], + [ + "DTEN", + 8, + 1 + ], + [ + "DIDL1", + 7, + 1 + ], + [ + "CHP1", + 6, + 1 + ], + [ + "FAULT1", + 4, + 2 + ], + [ + "IDLES1", + 3, + 1 + ], + [ + "IDLEM1", + 2, + 1 + ], + [ + "POL1", + 1, + 1 + ] + ] + }, + { + "name": "FLTDR", + "offset": "0x68", + "fields": [ + [ + "FLTLCK", + 31, + 1 + ], + [ + "FLT6EN", + 5, + 1 + ], + [ + "FLT5EN", + 4, + 1 + ], + [ + "FLT4EN", + 3, + 1 + ], + [ + "FLT3EN", + 2, + 1 + ], + [ + "FLT2EN", + 1, + 1 + ], + [ + "FLT1EN", + 0, + 1 + ] + ] + }, + { + "name": "TIMDCR2", + "offset": "0x6C", + "fields": [ + [ + "TRGHLF", + 20, + 1 + ], + [ + "GTCMP3", + 17, + 1 + ], + [ + "GTCMP1", + 16, + 1 + ], + [ + "FEROM", + 14, + 2 + ], + [ + "BMROM", + 12, + 2 + ], + [ + "ADROM", + 10, + 2 + ], + [ + "OUTROM", + 8, + 2 + ], + [ + "ROM", + 6, + 2 + ], + [ + "UDM", + 4, + 1 + ], + [ + "DCDR", + 2, + 1 + ], + [ + "DCDS", + 1, + 1 + ], + [ + "DCDE", + 0, + 1 + ] + ] + }, + { + "name": "DEEFR3", + "offset": "0x70", + "fields": [ + [ + "EEVACNT", + 8, + 6 + ], + [ + "EEVASEL", + 4, + 4 + ], + [ + "EEVARSTM", + 2, + 1 + ], + [ + "EEVACRES", + 1, + 1 + ], + [ + "EEVACE", + 0, + 1 + ] + ] + } + ] + }, + { + "name": "HRTIM_TIME", + "base": "0x40016A80", + "registers": [ + { + "name": "TIMECR", + "offset": "0x00", + "fields": [ + [ + "UPDGAT", + 28, + 4 + ], + [ + "PREEN", + 27, + 1 + ], + [ + "DACSYNC", + 25, + 2 + ], + [ + "MSTU", + 24, + 1 + ], + [ + "TDU", + 22, + 1 + ], + [ + "TCU", + 21, + 1 + ], + [ + "TBU", + 20, + 1 + ], + [ + "TAU", + 19, + 1 + ], + [ + "TxRSTU", + 18, + 1 + ], + [ + "TxREPU", + 17, + 1 + ], + [ + "TFU", + 16, + 1 + ], + [ + "DELCMP4", + 14, + 2 + ], + [ + "DELCMP2", + 12, + 2 + ], + [ + "SYNCSTRTx", + 11, + 1 + ], + [ + "SYNCRSTx", + 10, + 1 + ], + [ + "RSYNCU", + 9, + 1 + ], + [ + "INTLVD", + 7, + 2 + ], + [ + "PSHPLL", + 6, + 1 + ], + [ + "HALF", + 5, + 1 + ], + [ + "RETRIG", + 4, + 1 + ], + [ + "CONT", + 3, + 1 + ], + [ + "CK_PSCx", + 0, + 3 + ] + ] + }, + { + "name": "TIMEISR", + "offset": "0x04", + "fields": [ + [ + "O2CPY", + 21, + 1, + "r" + ], + [ + "O1CPY", + 20, + 1, + "r" + ], + [ + "O2STAT", + 19, + 1, + "r" + ], + [ + "O1STAT", + 18, + 1, + "r" + ], + [ + "IPPSTAT", + 17, + 1, + "r" + ], + [ + "CPPSTAT", + 16, + 1, + "r" + ], + [ + "DLYPRT", + 14, + 1, + "r" + ], + [ + "RST", + 13, + 1, + "r" + ], + [ + "RSTx2", + 12, + 1, + "r" + ], + [ + "SETx2", + 11, + 1, + "r" + ], + [ + "RSTx1", + 10, + 1, + "r" + ], + [ + "SETx1", + 9, + 1, + "r" + ], + [ + "CPT2", + 8, + 1, + "r" + ], + [ + "CPT1", + 7, + 1, + "r" + ], + [ + "UPD", + 6, + 1, + "r" + ], + [ + "REP", + 4, + 1, + "r" + ], + [ + "CMP4", + 3, + 1, + "r" + ], + [ + "CMP3", + 2, + 1, + "r" + ], + [ + "CMP2", + 1, + 1, + "r" + ], + [ + "CMP1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "TIMEICR", + "offset": "0x08", + "fields": [ + [ + "DLYPRTC", + 14, + 1, + "w" + ], + [ + "RSTC", + 13, + 1, + "w" + ], + [ + "RSTx2C", + 12, + 1, + "w" + ], + [ + "SET2xC", + 11, + 1, + "w" + ], + [ + "RSTx1C", + 10, + 1, + "w" + ], + [ + "SET1xC", + 9, + 1, + "w" + ], + [ + "CPT2C", + 8, + 1, + "w" + ], + [ + "CPT1C", + 7, + 1, + "w" + ], + [ + "UPDC", + 6, + 1, + "w" + ], + [ + "REPC", + 4, + 1, + "w" + ], + [ + "CMP4C", + 3, + 1, + "w" + ], + [ + "CMP3C", + 2, + 1, + "w" + ], + [ + "CMP2C", + 1, + 1, + "w" + ], + [ + "CMP1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "TIMEDIER", + "offset": "0x0C", + "fields": [ + [ + "DLYPRTDE", + 30, + 1 + ], + [ + "RSTDE", + 29, + 1 + ], + [ + "RSTx2DE", + 28, + 1 + ], + [ + "SETx2DE", + 27, + 1 + ], + [ + "RSTx1DE", + 26, + 1 + ], + [ + "SET1xDE", + 25, + 1 + ], + [ + "CPT2DE", + 24, + 1 + ], + [ + "CPT1DE", + 23, + 1 + ], + [ + "UPDDE", + 22, + 1 + ], + [ + "REPDE", + 20, + 1 + ], + [ + "CMP4DE", + 19, + 1 + ], + [ + "CMP3DE", + 18, + 1 + ], + [ + "CMP2DE", + 17, + 1 + ], + [ + "CMP1DE", + 16, + 1 + ], + [ + "DLYPRTIE", + 14, + 1 + ], + [ + "RSTIE", + 13, + 1 + ], + [ + "RSTx2IE", + 12, + 1 + ], + [ + "SETx2IE", + 11, + 1 + ], + [ + "RSTx1IE", + 10, + 1 + ], + [ + "SET1xIE", + 9, + 1 + ], + [ + "CPT2IE", + 8, + 1 + ], + [ + "CPT1IE", + 7, + 1 + ], + [ + "UPDIE", + 6, + 1 + ], + [ + "REPIE", + 4, + 1 + ], + [ + "CMP4IE", + 3, + 1 + ], + [ + "CMP3IE", + 2, + 1 + ], + [ + "CMP2IE", + 1, + 1 + ], + [ + "CMP1IE", + 0, + 1 + ] + ] + }, + { + "name": "CNTER", + "offset": "0x10", + "fields": [ + [ + "CNTx", + 0, + 16 + ] + ] + }, + { + "name": "PERER", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "PERx", + 0, + 16 + ] + ] + }, + { + "name": "REPER", + "offset": "0x18", + "fields": [ + [ + "REPx", + 0, + 8 + ] + ] + }, + { + "name": "CMP1ER", + "offset": "0x1C", + "fields": [ + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP1CER", + "offset": "0x20", + "fields": [ + [ + "REPx", + 16, + 8 + ], + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP2ER", + "offset": "0x24", + "fields": [ + [ + "CMP2x", + 0, + 16 + ] + ] + }, + { + "name": "CMP3ER", + "offset": "0x28", + "fields": [ + [ + "CMP3x", + 0, + 16 + ] + ] + }, + { + "name": "CMP4ER", + "offset": "0x2C", + "fields": [ + [ + "CMP4x", + 0, + 16 + ] + ] + }, + { + "name": "CPT1ER", + "offset": "0x30", + "fields": [ + [ + "CPT1x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "CPT2ER", + "offset": "0x34", + "fields": [ + [ + "CPT2x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "DTER", + "offset": "0x38", + "fields": [ + [ + "DTFLKx", + 31, + 1 + ], + [ + "DTFSLKx", + 30, + 1 + ], + [ + "SDTFx", + 25, + 1 + ], + [ + "DTFx", + 16, + 9 + ], + [ + "DTRLKx", + 15, + 1 + ], + [ + "DTRSLKx", + 14, + 1 + ], + [ + "DTPRSC", + 10, + 3 + ], + [ + "SDTRx", + 9, + 1 + ], + [ + "DTRx", + 0, + 9 + ] + ] + }, + { + "name": "SETE1R", + "offset": "0x3C", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTE1R", + "offset": "0x40", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "SETE2R", + "offset": "0x44", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTE2R", + "offset": "0x48", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "EEFER1", + "offset": "0x4C", + "fields": [ + [ + "EE5FLTR", + 25, + 4 + ], + [ + "EE5LTCH", + 24, + 1 + ], + [ + "EE4FLTR", + 19, + 4 + ], + [ + "EE4LTCH", + 18, + 1 + ], + [ + "EE3FLTR", + 13, + 4 + ], + [ + "EE3LTCH", + 12, + 1 + ], + [ + "EE2FLTR", + 7, + 4 + ], + [ + "EE2LTCH", + 6, + 1 + ], + [ + "EE1FLTR", + 1, + 4 + ], + [ + "EE1LTCH", + 0, + 1 + ] + ] + }, + { + "name": "EEFER2", + "offset": "0x50", + "fields": [ + [ + "EE10FLTR", + 25, + 4 + ], + [ + "EE10LTCH", + 24, + 1 + ], + [ + "EE9FLTR", + 19, + 4 + ], + [ + "EE9LTCH", + 18, + 1 + ], + [ + "EE8FLTR", + 13, + 4 + ], + [ + "EE8LTCH", + 12, + 1 + ], + [ + "EE7FLTR", + 7, + 4 + ], + [ + "EE7LTCH", + 6, + 1 + ], + [ + "EE6FLTR", + 1, + 4 + ], + [ + "EE6LTCH", + 0, + 1 + ] + ] + }, + { + "name": "RSTER", + "offset": "0x54", + "fields": [ + [ + "TIMFCPM2", + 31, + 1 + ], + [ + "TIMDCMP4", + 30, + 1 + ], + [ + "TIMDCMP2", + 29, + 1 + ], + [ + "TIMDCMP1", + 28, + 1 + ], + [ + "TIMCCMP4", + 27, + 1 + ], + [ + "TIMCCMP2", + 26, + 1 + ], + [ + "TIMCCMP1", + 25, + 1 + ], + [ + "TIMBCMP4", + 24, + 1 + ], + [ + "TIMBCMP2", + 23, + 1 + ], + [ + "TIMBCMP1", + 22, + 1 + ], + [ + "TIMACMP4", + 21, + 1 + ], + [ + "TIMACMP2", + 20, + 1 + ], + [ + "TIMACMP1", + 19, + 1 + ], + [ + "EXTEVNT10", + 18, + 1 + ], + [ + "EXTEVNT9", + 17, + 1 + ], + [ + "EXTEVNT8", + 16, + 1 + ], + [ + "EXTEVNT7", + 15, + 1 + ], + [ + "EXTEVNT6", + 14, + 1 + ], + [ + "EXTEVNT5", + 13, + 1 + ], + [ + "EXTEVNT4", + 12, + 1 + ], + [ + "EXTEVNT3", + 11, + 1 + ], + [ + "EXTEVNT2", + 10, + 1 + ], + [ + "EXTEVNT1", + 9, + 1 + ], + [ + "MSTCMP4", + 8, + 1 + ], + [ + "MSTCMP3", + 7, + 1 + ], + [ + "MSTCMP2", + 6, + 1 + ], + [ + "MSTCMP1", + 5, + 1 + ], + [ + "MSTPER", + 4, + 1 + ], + [ + "CMP4", + 3, + 1 + ], + [ + "CMP2", + 2, + 1 + ], + [ + "UPDT", + 1, + 1 + ], + [ + "TIMFCMP1", + 0, + 1 + ] + ] + }, + { + "name": "CHPER", + "offset": "0x58", + "fields": [ + [ + "STRTPW", + 7, + 4 + ], + [ + "CHPDTY", + 4, + 3 + ], + [ + "CHPFRQ", + 0, + 4 + ] + ] + }, + { + "name": "CPT1ECR", + "offset": "0x5C", + "fields": [ + [ + "TFCMP2", + 31, + 1 + ], + [ + "TFCMP1", + 30, + 1 + ], + [ + "TF1RST", + 29, + 1 + ], + [ + "TF1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "CPT2ECR", + "offset": "0x60", + "fields": [ + [ + "TFCMP2", + 31, + 1 + ], + [ + "TFCMP1", + 30, + 1 + ], + [ + "TF1RST", + 29, + 1 + ], + [ + "TF1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "OUTER", + "offset": "0x64", + "fields": [ + [ + "DIDL2", + 23, + 1 + ], + [ + "CHP2", + 22, + 1 + ], + [ + "FAULT2", + 20, + 2 + ], + [ + "IDLES2", + 19, + 1 + ], + [ + "IDLEM2", + 18, + 1 + ], + [ + "POL2", + 17, + 1 + ], + [ + "BIAR", + 14, + 1 + ], + [ + "DLYPRT", + 10, + 3 + ], + [ + "DLYPRTEN", + 9, + 1 + ], + [ + "DTEN", + 8, + 1 + ], + [ + "DIDL1", + 7, + 1 + ], + [ + "CHP1", + 6, + 1 + ], + [ + "FAULT1", + 4, + 2 + ], + [ + "IDLES1", + 3, + 1 + ], + [ + "IDLEM1", + 2, + 1 + ], + [ + "POL1", + 1, + 1 + ] + ] + }, + { + "name": "FLTER", + "offset": "0x68", + "fields": [ + [ + "FLTLCK", + 31, + 1 + ], + [ + "FLT6EN", + 5, + 1 + ], + [ + "FLT5EN", + 4, + 1 + ], + [ + "FLT4EN", + 3, + 1 + ], + [ + "FLT3EN", + 2, + 1 + ], + [ + "FLT2EN", + 1, + 1 + ], + [ + "FLT1EN", + 0, + 1 + ] + ] + }, + { + "name": "TIMECR2", + "offset": "0x6C", + "fields": [ + [ + "TRGHLF", + 20, + 1 + ], + [ + "GTCMP3", + 17, + 1 + ], + [ + "GTCMP1", + 16, + 1 + ], + [ + "FEROM", + 14, + 2 + ], + [ + "BMROM", + 12, + 2 + ], + [ + "ADROM", + 10, + 2 + ], + [ + "OUTROM", + 8, + 2 + ], + [ + "ROM", + 6, + 2 + ], + [ + "UDM", + 4, + 1 + ], + [ + "DCDR", + 2, + 1 + ], + [ + "DCDS", + 1, + 1 + ], + [ + "DCDE", + 0, + 1 + ] + ] + }, + { + "name": "EEEFR3", + "offset": "0x70", + "fields": [ + [ + "EEVACNT", + 8, + 6 + ], + [ + "EEVASEL", + 4, + 4 + ], + [ + "EEVARSTM", + 2, + 1 + ], + [ + "EEVACRES", + 1, + 1 + ], + [ + "EEVACE", + 0, + 1 + ] + ] + } + ], + "interrupts": [ + "HRTIM_TIME_IRQn" + ] + }, + { + "name": "HRTIM_TIMF", + "base": "0x40016B00", + "interrupts": [ + "HRTIM_TIMF_IRQn" + ], + "registers": [ + { + "name": "TIMFCR", + "offset": "0x00", + "fields": [ + [ + "UPDGAT", + 28, + 4 + ], + [ + "PREEN", + 27, + 1 + ], + [ + "DACSYNC", + 25, + 2 + ], + [ + "MSTU", + 24, + 1 + ], + [ + "TDU", + 22, + 1 + ], + [ + "TCU", + 21, + 1 + ], + [ + "TBU", + 20, + 1 + ], + [ + "TAU", + 19, + 1 + ], + [ + "TxRSTU", + 18, + 1 + ], + [ + "TxREPU", + 17, + 1 + ], + [ + "DELCMP4", + 14, + 2 + ], + [ + "DELCMP2", + 12, + 2 + ], + [ + "SYNCSTRTx", + 11, + 1 + ], + [ + "SYNCRSTx", + 10, + 1 + ], + [ + "RSYNCU", + 9, + 1 + ], + [ + "INTLVD", + 7, + 2 + ], + [ + "PSHPLL", + 6, + 1 + ], + [ + "HALF", + 5, + 1 + ], + [ + "RETRIG", + 4, + 1 + ], + [ + "CONT", + 3, + 1 + ], + [ + "CK_PSCx", + 0, + 3 + ] + ] + }, + { + "name": "TIMFISR", + "offset": "0x04", + "fields": [ + [ + "O2CPY", + 21, + 1, + "r" + ], + [ + "O1CPY", + 20, + 1, + "r" + ], + [ + "O2STAT", + 19, + 1, + "r" + ], + [ + "O1STAT", + 18, + 1, + "r" + ], + [ + "IPPSTAT", + 17, + 1, + "r" + ], + [ + "CPPSTAT", + 16, + 1, + "r" + ], + [ + "DLYPRT", + 14, + 1, + "r" + ], + [ + "RST", + 13, + 1, + "r" + ], + [ + "RSTx2", + 12, + 1, + "r" + ], + [ + "SETx2", + 11, + 1, + "r" + ], + [ + "RSTx1", + 10, + 1, + "r" + ], + [ + "SETx1", + 9, + 1, + "r" + ], + [ + "CPT2", + 8, + 1, + "r" + ], + [ + "CPT1", + 7, + 1, + "r" + ], + [ + "UPD", + 6, + 1, + "r" + ], + [ + "REP", + 4, + 1, + "r" + ], + [ + "CMP4", + 3, + 1, + "r" + ], + [ + "CMP3", + 2, + 1, + "r" + ], + [ + "CMP2", + 1, + 1, + "r" + ], + [ + "CMP1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "TIMFICR", + "offset": "0x08", + "fields": [ + [ + "DLYPRTC", + 14, + 1, + "w" + ], + [ + "RSTC", + 13, + 1, + "w" + ], + [ + "RSTx2C", + 12, + 1, + "w" + ], + [ + "SET2xC", + 11, + 1, + "w" + ], + [ + "RSTx1C", + 10, + 1, + "w" + ], + [ + "SET1xC", + 9, + 1, + "w" + ], + [ + "CPT2C", + 8, + 1, + "w" + ], + [ + "CPT1C", + 7, + 1, + "w" + ], + [ + "UPDC", + 6, + 1, + "w" + ], + [ + "REPC", + 4, + 1, + "w" + ], + [ + "CMP4C", + 3, + 1, + "w" + ], + [ + "CMP3C", + 2, + 1, + "w" + ], + [ + "CMP2C", + 1, + 1, + "w" + ], + [ + "CMP1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "TIMFDIER", + "offset": "0x0C", + "fields": [ + [ + "DLYPRTDE", + 30, + 1 + ], + [ + "RSTDE", + 29, + 1 + ], + [ + "RSTx2DE", + 28, + 1 + ], + [ + "SETx2DE", + 27, + 1 + ], + [ + "RSTx1DE", + 26, + 1 + ], + [ + "SET1xDE", + 25, + 1 + ], + [ + "CPT2DE", + 24, + 1 + ], + [ + "CPT1DE", + 23, + 1 + ], + [ + "UPDDE", + 22, + 1 + ], + [ + "REPDE", + 20, + 1 + ], + [ + "CMP4DE", + 19, + 1 + ], + [ + "CMP3DE", + 18, + 1 + ], + [ + "CMP2DE", + 17, + 1 + ], + [ + "CMP1DE", + 16, + 1 + ], + [ + "DLYPRTIE", + 14, + 1 + ], + [ + "RSTIE", + 13, + 1 + ], + [ + "RSTx2IE", + 12, + 1 + ], + [ + "SETx2IE", + 11, + 1 + ], + [ + "RSTx1IE", + 10, + 1 + ], + [ + "SET1xIE", + 9, + 1 + ], + [ + "CPT2IE", + 8, + 1 + ], + [ + "CPT1IE", + 7, + 1 + ], + [ + "UPDIE", + 6, + 1 + ], + [ + "REPIE", + 4, + 1 + ], + [ + "CMP4IE", + 3, + 1 + ], + [ + "CMP3IE", + 2, + 1 + ], + [ + "CMP2IE", + 1, + 1 + ], + [ + "CMP1IE", + 0, + 1 + ] + ] + }, + { + "name": "CNTFR", + "offset": "0x10", + "fields": [ + [ + "CNTx", + 0, + 16 + ] + ] + }, + { + "name": "PERFR", + "offset": "0x14", + "reset": "0x0000FFFF", + "fields": [ + [ + "PERx", + 0, + 16 + ] + ] + }, + { + "name": "REPFR", + "offset": "0x18", + "fields": [ + [ + "REPx", + 0, + 8 + ] + ] + }, + { + "name": "CMP1FR", + "offset": "0x1C", + "fields": [ + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP1CFR", + "offset": "0x20", + "fields": [ + [ + "REPx", + 16, + 8 + ], + [ + "CMP1x", + 0, + 16 + ] + ] + }, + { + "name": "CMP2FR", + "offset": "0x24", + "fields": [ + [ + "CMP2x", + 0, + 16 + ] + ] + }, + { + "name": "CMP3FR", + "offset": "0x28", + "fields": [ + [ + "CMP3x", + 0, + 16 + ] + ] + }, + { + "name": "CMP4FR", + "offset": "0x2C", + "fields": [ + [ + "CMP4x", + 0, + 16 + ] + ] + }, + { + "name": "CPT1FR", + "offset": "0x30", + "fields": [ + [ + "CPT1x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "CPT2FR", + "offset": "0x34", + "fields": [ + [ + "CPT2x", + 0, + 16, + "r" + ], + [ + "DIR", + 16, + 1, + "r" + ] + ] + }, + { + "name": "DTFR", + "offset": "0x38", + "fields": [ + [ + "DTFLKx", + 31, + 1 + ], + [ + "DTFSLKx", + 30, + 1 + ], + [ + "SDTFx", + 25, + 1 + ], + [ + "DTFx", + 16, + 9 + ], + [ + "DTRLKx", + 15, + 1 + ], + [ + "DTRSLKx", + 14, + 1 + ], + [ + "DTPRSC", + 10, + 3 + ], + [ + "SDTRx", + 9, + 1 + ], + [ + "DTRx", + 0, + 9 + ] + ] + }, + { + "name": "SETF1R", + "offset": "0x3C", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTE1R", + "offset": "0x40", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "SETF2R", + "offset": "0x44", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SST", + 0, + 1 + ] + ] + }, + { + "name": "RSTF2R", + "offset": "0x48", + "fields": [ + [ + "UPDATE", + 31, + 1 + ], + [ + "EXTEVNT10", + 30, + 1 + ], + [ + "EXTEVNT9", + 29, + 1 + ], + [ + "EXTEVNT8", + 28, + 1 + ], + [ + "EXTEVNT7", + 27, + 1 + ], + [ + "EXTEVNT6", + 26, + 1 + ], + [ + "EXTEVNT5", + 25, + 1 + ], + [ + "EXTEVNT4", + 24, + 1 + ], + [ + "EXTEVNT3", + 23, + 1 + ], + [ + "EXTEVNT2", + 22, + 1 + ], + [ + "EXTEVNT1", + 21, + 1 + ], + [ + "TIMEVNT9", + 20, + 1 + ], + [ + "TIMEVNT8", + 19, + 1 + ], + [ + "TIMEVNT7", + 18, + 1 + ], + [ + "TIMEVNT6", + 17, + 1 + ], + [ + "TIMEVNT5", + 16, + 1 + ], + [ + "TIMEVNT4", + 15, + 1 + ], + [ + "TIMEVNT3", + 14, + 1 + ], + [ + "TIMEVNT2", + 13, + 1 + ], + [ + "TIMEVNT1", + 12, + 1 + ], + [ + "MSTCMP4", + 11, + 1 + ], + [ + "MSTCMP3", + 10, + 1 + ], + [ + "MSTCMP2", + 9, + 1 + ], + [ + "MSTCMP1", + 8, + 1 + ], + [ + "MSTPER", + 7, + 1 + ], + [ + "CMP4", + 6, + 1 + ], + [ + "CMP3", + 5, + 1 + ], + [ + "CMP2", + 4, + 1 + ], + [ + "CMP1", + 3, + 1 + ], + [ + "PER", + 2, + 1 + ], + [ + "RESYNC", + 1, + 1 + ], + [ + "SRT", + 0, + 1 + ] + ] + }, + { + "name": "EEFFR1", + "offset": "0x4C", + "fields": [ + [ + "EE5FLTR", + 25, + 4 + ], + [ + "EE5LTCH", + 24, + 1 + ], + [ + "EE4FLTR", + 19, + 4 + ], + [ + "EE4LTCH", + 18, + 1 + ], + [ + "EE3FLTR", + 13, + 4 + ], + [ + "EE3LTCH", + 12, + 1 + ], + [ + "EE2FLTR", + 7, + 4 + ], + [ + "EE2LTCH", + 6, + 1 + ], + [ + "EE1FLTR", + 1, + 4 + ], + [ + "EE1LTCH", + 0, + 1 + ] + ] + }, + { + "name": "EEFFR2", + "offset": "0x50", + "fields": [ + [ + "EE10FLTR", + 25, + 4 + ], + [ + "EE10LTCH", + 24, + 1 + ], + [ + "EE9FLTR", + 19, + 4 + ], + [ + "EE9LTCH", + 18, + 1 + ], + [ + "EE8FLTR", + 13, + 4 + ], + [ + "EE8LTCH", + 12, + 1 + ], + [ + "EE7FLTR", + 7, + 4 + ], + [ + "EE7LTCH", + 6, + 1 + ], + [ + "EE6FLTR", + 1, + 4 + ], + [ + "EE6LTCH", + 0, + 1 + ] + ] + }, + { + "name": "RSTFR", + "offset": "0x54", + "fields": [ + [ + "TIMFCPM2", + 31, + 1 + ], + [ + "TIMDCMP4", + 30, + 1 + ], + [ + "TIMDCMP2", + 29, + 1 + ], + [ + "TIMDCMP1", + 28, + 1 + ], + [ + "TIMCCMP4", + 27, + 1 + ], + [ + "TIMCCMP2", + 26, + 1 + ], + [ + "TIMCCMP1", + 25, + 1 + ], + [ + "TIMBCMP4", + 24, + 1 + ], + [ + "TIMBCMP2", + 23, + 1 + ], + [ + "TIMBCMP1", + 22, + 1 + ], + [ + "TIMACMP4", + 21, + 1 + ], + [ + "TIMACMP2", + 20, + 1 + ], + [ + "TIMACMP1", + 19, + 1 + ], + [ + "EXTEVNT10", + 18, + 1 + ], + [ + "EXTEVNT9", + 17, + 1 + ], + [ + "EXTEVNT8", + 16, + 1 + ], + [ + "EXTEVNT7", + 15, + 1 + ], + [ + "EXTEVNT6", + 14, + 1 + ], + [ + "EXTEVNT5", + 13, + 1 + ], + [ + "EXTEVNT4", + 12, + 1 + ], + [ + "EXTEVNT3", + 11, + 1 + ], + [ + "EXTEVNT2", + 10, + 1 + ], + [ + "EXTEVNT1", + 9, + 1 + ], + [ + "MSTCMP4", + 8, + 1 + ], + [ + "MSTCMP3", + 7, + 1 + ], + [ + "MSTCMP2", + 6, + 1 + ], + [ + "MSTCMP1", + 5, + 1 + ], + [ + "MSTPER", + 4, + 1 + ], + [ + "CMP4", + 3, + 1 + ], + [ + "CMP2", + 2, + 1 + ], + [ + "UPDT", + 1, + 1 + ], + [ + "TIMFCMP1", + 0, + 1 + ] + ] + }, + { + "name": "CHPFR", + "offset": "0x58", + "fields": [ + [ + "STRTPW", + 7, + 4 + ], + [ + "CHPDTY", + 4, + 3 + ], + [ + "CHPFRQ", + 0, + 4 + ] + ] + }, + { + "name": "CPT1FCR", + "offset": "0x5C", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "CPT2FCR", + "offset": "0x60", + "fields": [ + [ + "TECMP2", + 31, + 1 + ], + [ + "TECMP1", + 30, + 1 + ], + [ + "TE1RST", + 29, + 1 + ], + [ + "TE1SET", + 28, + 1 + ], + [ + "TDCMP2", + 27, + 1 + ], + [ + "TDCMP1", + 26, + 1 + ], + [ + "TD1RST", + 25, + 1 + ], + [ + "TD1SET", + 24, + 1 + ], + [ + "TCCMP2", + 23, + 1 + ], + [ + "TCCMP1", + 22, + 1 + ], + [ + "TC1RST", + 21, + 1 + ], + [ + "TC1SET", + 20, + 1 + ], + [ + "TBCMP2", + 19, + 1 + ], + [ + "TBCMP1", + 18, + 1 + ], + [ + "TB1RST", + 17, + 1 + ], + [ + "TB1SET", + 16, + 1 + ], + [ + "TACMP2", + 15, + 1 + ], + [ + "TACMP1", + 14, + 1 + ], + [ + "TA1RST", + 13, + 1 + ], + [ + "TA1SET", + 12, + 1 + ], + [ + "EXEV10CPT", + 11, + 1 + ], + [ + "EXEV9CPT", + 10, + 1 + ], + [ + "EXEV8CPT", + 9, + 1 + ], + [ + "EXEV7CPT", + 8, + 1 + ], + [ + "EXEV6CPT", + 7, + 1 + ], + [ + "EXEV5CPT", + 6, + 1 + ], + [ + "EXEV4CPT", + 5, + 1 + ], + [ + "EXEV3CPT", + 4, + 1 + ], + [ + "EXEV2CPT", + 3, + 1 + ], + [ + "EXEV1CPT", + 2, + 1 + ], + [ + "UDPCPT", + 1, + 1 + ], + [ + "SWCPT", + 0, + 1 + ] + ] + }, + { + "name": "OUTFR", + "offset": "0x64", + "fields": [ + [ + "DIDL2", + 23, + 1 + ], + [ + "CHP2", + 22, + 1 + ], + [ + "FAULT2", + 20, + 2 + ], + [ + "IDLES2", + 19, + 1 + ], + [ + "IDLEM2", + 18, + 1 + ], + [ + "POL2", + 17, + 1 + ], + [ + "BIAR", + 14, + 1 + ], + [ + "DLYPRT", + 10, + 3 + ], + [ + "DLYPRTEN", + 9, + 1 + ], + [ + "DTEN", + 8, + 1 + ], + [ + "DIDL1", + 7, + 1 + ], + [ + "CHP1", + 6, + 1 + ], + [ + "FAULT1", + 4, + 2 + ], + [ + "IDLES1", + 3, + 1 + ], + [ + "IDLEM1", + 2, + 1 + ], + [ + "POL1", + 1, + 1 + ] + ] + }, + { + "name": "FLTFR", + "offset": "0x68", + "fields": [ + [ + "FLTLCK", + 31, + 1 + ], + [ + "FLT6EN", + 5, + 1 + ], + [ + "FLT5EN", + 4, + 1 + ], + [ + "FLT4EN", + 3, + 1 + ], + [ + "FLT3EN", + 2, + 1 + ], + [ + "FLT2EN", + 1, + 1 + ], + [ + "FLT1EN", + 0, + 1 + ] + ] + }, + { + "name": "TIMFCR2", + "offset": "0x6C", + "fields": [ + [ + "TRGHLF", + 20, + 1 + ], + [ + "GTCMP3", + 17, + 1 + ], + [ + "GTCMP1", + 16, + 1 + ], + [ + "FEROM", + 14, + 2 + ], + [ + "BMROM", + 12, + 2 + ], + [ + "ADROM", + 10, + 2 + ], + [ + "OUTROM", + 8, + 2 + ], + [ + "ROM", + 6, + 2 + ], + [ + "UDM", + 4, + 1 + ], + [ + "DCDR", + 2, + 1 + ], + [ + "DCDS", + 1, + 1 + ], + [ + "DCDE", + 0, + 1 + ] + ] + }, + { + "name": "FEEFR3", + "offset": "0x70", + "fields": [ + [ + "EEVACNT", + 8, + 6 + ], + [ + "EEVASEL", + 4, + 4 + ], + [ + "EEVARSTM", + 2, + 1 + ], + [ + "EEVACRES", + 1, + 1 + ], + [ + "EEVACE", + 0, + 1 + ] + ] + } + ] + }, + { + "name": "HRTIM_Common", + "base": "0x40016B80", + "interrupts": [ + "HRTIM_TIM_FLT_IRQn" + ], + "registers": [ + { + "name": "CR1", + "offset": "0x00", + "fields": [ + [ + "AD4USRC", + 25, + 3 + ], + [ + "AD3USRC", + 22, + 3 + ], + [ + "AD2USRC", + 19, + 3 + ], + [ + "AD1USRC", + 16, + 3 + ], + [ + "TFUDIS", + 6, + 1 + ], + [ + "TEUDIS", + 5, + 1 + ], + [ + "TDUDIS", + 4, + 1 + ], + [ + "TCUDIS", + 3, + 1 + ], + [ + "TBUDIS", + 2, + 1 + ], + [ + "TAUDIS", + 1, + 1 + ], + [ + "MUDIS", + 0, + 1 + ] + ] + }, + { + "name": "CR2", + "offset": "0x04", + "fields": [ + [ + "SWPF", + 21, + 1 + ], + [ + "SWPE", + 20, + 1 + ], + [ + "SWPD", + 19, + 1 + ], + [ + "SWPC", + 18, + 1 + ], + [ + "SWPB", + 17, + 1 + ], + [ + "SWPA", + 16, + 1 + ], + [ + "TFRST", + 14, + 1 + ], + [ + "TERST", + 13, + 1 + ], + [ + "TDRST", + 12, + 1 + ], + [ + "TCRST", + 11, + 1 + ], + [ + "TBRST", + 10, + 1 + ], + [ + "TARST", + 9, + 1 + ], + [ + "MRST", + 8, + 1 + ], + [ + "TFSWU", + 6, + 1 + ], + [ + "TESWU", + 5, + 1 + ], + [ + "TDSWU", + 4, + 1 + ], + [ + "TCSWU", + 3, + 1 + ], + [ + "TBSWU", + 2, + 1 + ], + [ + "TASWU", + 1, + 1 + ], + [ + "MSWU", + 0, + 1 + ] + ] + }, + { + "name": "ISR", + "offset": "0x08", + "fields": [ + [ + "BMPER", + 17, + 1, + "r" + ], + [ + "DLLRDY", + 16, + 1, + "r" + ], + [ + "FLT6", + 6, + 1, + "r" + ], + [ + "SYSFLT", + 5, + 1, + "r" + ], + [ + "FLT5", + 4, + 1, + "r" + ], + [ + "FLT4", + 3, + 1, + "r" + ], + [ + "FLT3", + 2, + 1, + "r" + ], + [ + "FLT2", + 1, + 1, + "r" + ], + [ + "FLT1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "ICR", + "offset": "0x0C", + "fields": [ + [ + "BMPERC", + 17, + 1, + "w" + ], + [ + "DLLRDYC", + 16, + 1, + "w" + ], + [ + "FLT6C", + 6, + 1, + "w" + ], + [ + "SYSFLTC", + 5, + 1, + "w" + ], + [ + "FLT5C", + 4, + 1, + "w" + ], + [ + "FLT4C", + 3, + 1, + "w" + ], + [ + "FLT3C", + 2, + 1, + "w" + ], + [ + "FLT2C", + 1, + 1, + "w" + ], + [ + "FLT1C", + 0, + 1, + "w" + ] + ] + }, + { + "name": "IER", + "offset": "0x10", + "fields": [ + [ + "BMPERIE", + 17, + 1 + ], + [ + "DLLRDYIE", + 16, + 1 + ], + [ + "FLT6IE", + 6, + 1 + ], + [ + "SYSFLTE", + 5, + 1 + ], + [ + "FLT5IE", + 4, + 1 + ], + [ + "FLT4IE", + 3, + 1 + ], + [ + "FLT3IE", + 2, + 1 + ], + [ + "FLT2IE", + 1, + 1 + ], + [ + "FLT1IE", + 0, + 1 + ] + ] + }, + { + "name": "OENR", + "offset": "0x14", + "fields": [ + [ + "TF2OEN", + 11, + 1 + ], + [ + "TF1OEN", + 10, + 1 + ], + [ + "TE2OEN", + 9, + 1 + ], + [ + "TE1OEN", + 8, + 1 + ], + [ + "TD2OEN", + 7, + 1 + ], + [ + "TD1OEN", + 6, + 1 + ], + [ + "TC2OEN", + 5, + 1 + ], + [ + "TC1OEN", + 4, + 1 + ], + [ + "TB2OEN", + 3, + 1 + ], + [ + "TB1OEN", + 2, + 1 + ], + [ + "TA2OEN", + 1, + 1 + ], + [ + "TA1OEN", + 0, + 1 + ] + ] + }, + { + "name": "ODISR", + "offset": "0x18", + "fields": [ + [ + "TF2ODIS", + 11, + 1, + "w" + ], + [ + "TF1ODIS", + 10, + 1, + "w" + ], + [ + "TE2ODIS", + 9, + 1, + "w" + ], + [ + "TE1ODIS", + 8, + 1, + "w" + ], + [ + "TD2ODIS", + 7, + 1, + "w" + ], + [ + "TD1ODIS", + 6, + 1, + "w" + ], + [ + "TC2ODIS", + 5, + 1, + "w" + ], + [ + "TC1ODIS", + 4, + 1, + "w" + ], + [ + "TB2ODIS", + 3, + 1, + "w" + ], + [ + "TB1ODIS", + 2, + 1, + "w" + ], + [ + "TA2ODIS", + 1, + 1, + "w" + ], + [ + "TA1ODIS", + 0, + 1, + "w" + ] + ] + }, + { + "name": "ODSR", + "offset": "0x1C", + "fields": [ + [ + "TF2ODS", + 11, + 1, + "r" + ], + [ + "TF1ODS", + 10, + 1, + "r" + ], + [ + "TE2ODS", + 9, + 1, + "r" + ], + [ + "TE1ODS", + 8, + 1, + "r" + ], + [ + "TD2ODS", + 7, + 1, + "r" + ], + [ + "TD1ODS", + 6, + 1, + "r" + ], + [ + "TC2ODS", + 5, + 1, + "r" + ], + [ + "TC1ODS", + 4, + 1, + "r" + ], + [ + "TB2ODS", + 3, + 1, + "r" + ], + [ + "TB1ODS", + 2, + 1, + "r" + ], + [ + "TA2ODS", + 1, + 1, + "r" + ], + [ + "TA1ODS", + 0, + 1, + "r" + ] + ] + }, + { + "name": "BMCR", + "offset": "0x20", + "fields": [ + [ + "BMSTAT", + 31, + 1 + ], + [ + "TFBM", + 22, + 1 + ], + [ + "TEBM", + 21, + 1 + ], + [ + "TDBM", + 20, + 1 + ], + [ + "TCBM", + 19, + 1 + ], + [ + "TBBM", + 18, + 1 + ], + [ + "TABM", + 17, + 1 + ], + [ + "MTBM", + 16, + 1 + ], + [ + "BMPREN", + 10, + 1 + ], + [ + "BMPRSC", + 6, + 4 + ], + [ + "BMCLK", + 2, + 4 + ], + [ + "BMOM", + 1, + 1 + ], + [ + "BME", + 0, + 1 + ] + ] + }, + { + "name": "BMTRG", + "offset": "0x24", + "fields": [ + [ + "OCHPEV", + 31, + 1 + ], + [ + "EEV8", + 30, + 1 + ], + [ + "EEV7", + 29, + 1 + ], + [ + "TDEEV8", + 28, + 1 + ], + [ + "TDEEV7", + 27, + 1 + ], + [ + "TECMP2", + 26, + 1 + ], + [ + "TECMP1", + 25, + 1 + ], + [ + "TEREP", + 24, + 1 + ], + [ + "TERST", + 23, + 1 + ], + [ + "TDCMP2", + 22, + 1 + ], + [ + "TDCMP1", + 21, + 1 + ], + [ + "TDREP", + 20, + 1 + ], + [ + "TDRST", + 19, + 1 + ], + [ + "TCCMP2", + 18, + 1 + ], + [ + "TCCMP1", + 17, + 1 + ], + [ + "TCREP", + 16, + 1 + ], + [ + "TCRST", + 15, + 1 + ], + [ + "TBCMP2", + 14, + 1 + ], + [ + "TBCMP1", + 13, + 1 + ], + [ + "TBREP", + 12, + 1 + ], + [ + "TBRST", + 11, + 1 + ], + [ + "TACMP2", + 10, + 1 + ], + [ + "TACMP1", + 9, + 1 + ], + [ + "TAREP", + 8, + 1 + ], + [ + "TARST", + 7, + 1 + ], + [ + "MSTCMP4", + 6, + 1 + ], + [ + "MSTCMP3", + 5, + 1 + ], + [ + "MSTCMP2", + 4, + 1 + ], + [ + "MSTCMP1", + 3, + 1 + ], + [ + "MSTREP", + 2, + 1 + ], + [ + "MSTRST", + 1, + 1 + ], + [ + "SW", + 0, + 1 + ] + ] + }, + { + "name": "BMCMPR", + "offset": "0x28", + "fields": [ + [ + "BMCMP", + 0, + 16 + ] + ] + }, + { + "name": "BMPER", + "offset": "0x2C", + "fields": [ + [ + "BMPER", + 0, + 16 + ] + ] + }, + { + "name": "EECR1", + "offset": "0x30", + "fields": [ + [ + "EE5FAST", + 29, + 1 + ], + [ + "EE5SNS", + 27, + 2 + ], + [ + "EE5POL", + 26, + 1 + ], + [ + "EE5SRC", + 24, + 2 + ], + [ + "EE4FAST", + 23, + 1 + ], + [ + "EE4SNS", + 21, + 2 + ], + [ + "EE4POL", + 20, + 1 + ], + [ + "EE4SRC", + 18, + 2 + ], + [ + "EE3FAST", + 17, + 1 + ], + [ + "EE3SNS", + 15, + 2 + ], + [ + "EE3POL", + 14, + 1 + ], + [ + "EE3SRC", + 12, + 2 + ], + [ + "EE2FAST", + 11, + 1 + ], + [ + "EE2SNS", + 9, + 2 + ], + [ + "EE2POL", + 8, + 1 + ], + [ + "EE2SRC", + 6, + 2 + ], + [ + "EE1FAST", + 5, + 1 + ], + [ + "EE1SNS", + 3, + 2 + ], + [ + "EE1POL", + 2, + 1 + ], + [ + "EE1SRC", + 0, + 2 + ] + ] + }, + { + "name": "EECR2", + "offset": "0x34", + "fields": [ + [ + "EE6SRC", + 0, + 2 + ], + [ + "EE6POL", + 2, + 1 + ], + [ + "EE6SNS", + 3, + 2 + ], + [ + "EE7SRC", + 6, + 2 + ], + [ + "EE7POL", + 8, + 1 + ], + [ + "EE7SNS", + 9, + 2 + ], + [ + "EE8SRC", + 12, + 2 + ], + [ + "EE8POL", + 14, + 1 + ], + [ + "EE8SNS", + 15, + 2 + ], + [ + "EE9SRC", + 18, + 2 + ], + [ + "EE9POL", + 20, + 1 + ], + [ + "EE9SNS", + 21, + 2 + ], + [ + "EE10SRC", + 24, + 2 + ], + [ + "EE10POL", + 26, + 1 + ], + [ + "EE10SNS", + 27, + 2 + ] + ] + }, + { + "name": "EECR3", + "offset": "0x38", + "fields": [ + [ + "EE6F", + 0, + 4 + ], + [ + "EE7F", + 6, + 4 + ], + [ + "EE8F", + 12, + 4 + ], + [ + "EE9F", + 18, + 4 + ], + [ + "EE10F", + 24, + 4 + ], + [ + "EEVSD", + 30, + 2 + ] + ] + }, + { + "name": "ADC1R", + "offset": "0x3C", + "fields": [ + [ + "AD1TEPER", + 31, + 1 + ], + [ + "AD1TEC4", + 30, + 1 + ], + [ + "AD1TEC3", + 29, + 1 + ], + [ + "AD1TEC2", + 28, + 1 + ], + [ + "AD1TDPER", + 27, + 1 + ], + [ + "AD1TDC4", + 26, + 1 + ], + [ + "AD1TDC3", + 25, + 1 + ], + [ + "AD1TDC2", + 24, + 1 + ], + [ + "AD1TCPER", + 23, + 1 + ], + [ + "AD1TCC4", + 22, + 1 + ], + [ + "AD1TCC3", + 21, + 1 + ], + [ + "AD1TCC2", + 20, + 1 + ], + [ + "AD1TBRST", + 19, + 1 + ], + [ + "AD1TBPER", + 18, + 1 + ], + [ + "AD1TBC4", + 17, + 1 + ], + [ + "AD1TBC3", + 16, + 1 + ], + [ + "AD1TBC2", + 15, + 1 + ], + [ + "AD1TARST", + 14, + 1 + ], + [ + "AD1TAPER", + 13, + 1 + ], + [ + "AD1TAC4", + 12, + 1 + ], + [ + "AD1TAC3", + 11, + 1 + ], + [ + "AD1TAC2", + 10, + 1 + ], + [ + "AD1EEV5", + 9, + 1 + ], + [ + "AD1EEV4", + 8, + 1 + ], + [ + "AD1EEV3", + 7, + 1 + ], + [ + "AD1EEV2", + 6, + 1 + ], + [ + "AD1EEV1", + 5, + 1 + ], + [ + "AD1MPER", + 4, + 1 + ], + [ + "AD1MC4", + 3, + 1 + ], + [ + "AD1MC3", + 2, + 1 + ], + [ + "AD1MC2", + 1, + 1 + ], + [ + "AD1MC1", + 0, + 1 + ] + ] + }, + { + "name": "ADC2R", + "offset": "0x40", + "fields": [ + [ + "AD2TERST", + 31, + 1 + ], + [ + "AD2TEC4", + 30, + 1 + ], + [ + "AD2TEC3", + 29, + 1 + ], + [ + "AD2TEC2", + 28, + 1 + ], + [ + "AD2TDRST", + 27, + 1 + ], + [ + "AD2TDPER", + 26, + 1 + ], + [ + "AD2TDC4", + 25, + 1 + ], + [ + "AD2TDC3", + 24, + 1 + ], + [ + "AD2TDC2", + 23, + 1 + ], + [ + "AD2TCRST", + 22, + 1 + ], + [ + "AD2TCPER", + 21, + 1 + ], + [ + "AD2TCC4", + 20, + 1 + ], + [ + "AD2TCC3", + 19, + 1 + ], + [ + "AD2TCC2", + 18, + 1 + ], + [ + "AD2TBPER", + 17, + 1 + ], + [ + "AD2TBC4", + 16, + 1 + ], + [ + "AD2TBC3", + 15, + 1 + ], + [ + "AD2TBC2", + 14, + 1 + ], + [ + "AD2TAPER", + 13, + 1 + ], + [ + "AD2TAC4", + 12, + 1 + ], + [ + "AD2TAC3", + 11, + 1 + ], + [ + "AD2TAC2", + 10, + 1 + ], + [ + "AD2EEV10", + 9, + 1 + ], + [ + "AD2EEV9", + 8, + 1 + ], + [ + "AD2EEV8", + 7, + 1 + ], + [ + "AD2EEV7", + 6, + 1 + ], + [ + "AD2EEV6", + 5, + 1 + ], + [ + "AD2MPER", + 4, + 1 + ], + [ + "AD2MC4", + 3, + 1 + ], + [ + "AD2MC3", + 2, + 1 + ], + [ + "AD2MC2", + 1, + 1 + ], + [ + "AD2MC1", + 0, + 1 + ] + ] + }, + { + "name": "ADC3R", + "offset": "0x44", + "fields": [ + [ + "AD1TEPER", + 31, + 1 + ], + [ + "AD1TEC4", + 30, + 1 + ], + [ + "AD1TEC3", + 29, + 1 + ], + [ + "AD1TEC2", + 28, + 1 + ], + [ + "AD1TDPER", + 27, + 1 + ], + [ + "AD1TDC4", + 26, + 1 + ], + [ + "AD1TDC3", + 25, + 1 + ], + [ + "AD1TDC2", + 24, + 1 + ], + [ + "AD1TCPER", + 23, + 1 + ], + [ + "AD1TCC4", + 22, + 1 + ], + [ + "AD1TCC3", + 21, + 1 + ], + [ + "AD1TCC2", + 20, + 1 + ], + [ + "AD1TBRST", + 19, + 1 + ], + [ + "AD1TBPER", + 18, + 1 + ], + [ + "AD1TBC4", + 17, + 1 + ], + [ + "AD1TBC3", + 16, + 1 + ], + [ + "AD1TBC2", + 15, + 1 + ], + [ + "AD1TARST", + 14, + 1 + ], + [ + "AD1TAPER", + 13, + 1 + ], + [ + "AD1TAC4", + 12, + 1 + ], + [ + "AD1TAC3", + 11, + 1 + ], + [ + "AD1TAC2", + 10, + 1 + ], + [ + "AD1EEV5", + 9, + 1 + ], + [ + "AD1EEV4", + 8, + 1 + ], + [ + "AD1EEV3", + 7, + 1 + ], + [ + "AD1EEV2", + 6, + 1 + ], + [ + "AD1EEV1", + 5, + 1 + ], + [ + "AD1MPER", + 4, + 1 + ], + [ + "AD1MC4", + 3, + 1 + ], + [ + "AD1MC3", + 2, + 1 + ], + [ + "AD1MC2", + 1, + 1 + ], + [ + "AD1MC1", + 0, + 1 + ] + ] + }, + { + "name": "ADC4R", + "offset": "0x48", + "fields": [ + [ + "AD2TERST", + 31, + 1 + ], + [ + "AD2TEC4", + 30, + 1 + ], + [ + "AD2TEC3", + 29, + 1 + ], + [ + "AD2TEC2", + 28, + 1 + ], + [ + "AD2TDRST", + 27, + 1 + ], + [ + "AD2TDPER", + 26, + 1 + ], + [ + "AD2TDC4", + 25, + 1 + ], + [ + "AD2TDC3", + 24, + 1 + ], + [ + "AD2TDC2", + 23, + 1 + ], + [ + "AD2TCRST", + 22, + 1 + ], + [ + "AD2TCPER", + 21, + 1 + ], + [ + "AD2TCC4", + 20, + 1 + ], + [ + "AD2TCC3", + 19, + 1 + ], + [ + "AD2TCC2", + 18, + 1 + ], + [ + "AD2TBPER", + 17, + 1 + ], + [ + "AD2TBC4", + 16, + 1 + ], + [ + "AD2TBC3", + 15, + 1 + ], + [ + "AD2TBC2", + 14, + 1 + ], + [ + "AD2TAPER", + 13, + 1 + ], + [ + "AD2TAC4", + 12, + 1 + ], + [ + "AD2TAC3", + 11, + 1 + ], + [ + "AD2TAC2", + 10, + 1 + ], + [ + "AD2EEV10", + 9, + 1 + ], + [ + "AD2EEV9", + 8, + 1 + ], + [ + "AD2EEV8", + 7, + 1 + ], + [ + "AD2EEV7", + 6, + 1 + ], + [ + "AD2EEV6", + 5, + 1 + ], + [ + "AD2MPER", + 4, + 1 + ], + [ + "AD2MC4", + 3, + 1 + ], + [ + "AD2MC3", + 2, + 1 + ], + [ + "AD2MC2", + 1, + 1 + ], + [ + "AD2MC1", + 0, + 1 + ] + ] + }, + { + "name": "DLLCR", + "offset": "0x4C", + "fields": [ + [ + "CALRTE", + 2, + 2 + ], + [ + "CALEN", + 1, + 1 + ], + [ + "CAL", + 0, + 1 + ] + ] + }, + { + "name": "FLTINR1", + "offset": "0x50", + "fields": [ + [ + "FLT4LCK", + 31, + 1 + ], + [ + "FLT4F", + 27, + 4 + ], + [ + "FLT4SRC", + 26, + 1 + ], + [ + "FLT4P", + 25, + 1 + ], + [ + "FLT4E", + 24, + 1 + ], + [ + "FLT3LCK", + 23, + 1 + ], + [ + "FLT3F", + 19, + 4 + ], + [ + "FLT3SRC", + 18, + 1 + ], + [ + "FLT3P", + 17, + 1 + ], + [ + "FLT3E", + 16, + 1 + ], + [ + "FLT2LCK", + 15, + 1 + ], + [ + "FLT2F", + 11, + 4 + ], + [ + "FLT2SRC", + 10, + 1 + ], + [ + "FLT2P", + 9, + 1 + ], + [ + "FLT2E", + 8, + 1 + ], + [ + "FLT1LCK", + 7, + 1 + ], + [ + "FLT1F", + 3, + 4 + ], + [ + "FLT1SRC", + 2, + 1 + ], + [ + "FLT1P", + 1, + 1 + ], + [ + "FLT1E", + 0, + 1 + ] + ] + }, + { + "name": "FLTINR2", + "offset": "0x54", + "fields": [ + [ + "FLTSD", + 24, + 2 + ], + [ + "FLT6SRC_1", + 21, + 1 + ], + [ + "FLT5SRC_1", + 20, + 1 + ], + [ + "FLT4SRC_1", + 19, + 1 + ], + [ + "FLT3SRC_1", + 18, + 1 + ], + [ + "FLT2SRC_1", + 17, + 1 + ], + [ + "FLT1SRC_1", + 16, + 1 + ], + [ + "FLT6LCK", + 15, + 1 + ], + [ + "FLT6F", + 11, + 4 + ], + [ + "FLT6SRC_0", + 10, + 1 + ], + [ + "FLT6P", + 9, + 1 + ], + [ + "FLT6E", + 8, + 1 + ], + [ + "FLT5LCK", + 7, + 1 + ], + [ + "FLT5F", + 3, + 4 + ], + [ + "FLT5SRC", + 2, + 1 + ], + [ + "FLT5P", + 1, + 1 + ], + [ + "FLT5E", + 0, + 1 + ] + ] + }, + { + "name": "BDMUPDR", + "offset": "0x58", + "fields": [ + [ + "MCMP4", + 9, + 1 + ], + [ + "MCMP3", + 8, + 1 + ], + [ + "MCMP2", + 7, + 1 + ], + [ + "MCMP1", + 6, + 1 + ], + [ + "MREP", + 5, + 1 + ], + [ + "MPER", + 4, + 1 + ], + [ + "MCNT", + 3, + 1 + ], + [ + "MDIER", + 2, + 1 + ], + [ + "MICR", + 1, + 1 + ], + [ + "MCR", + 0, + 1 + ] + ] + }, + { + "name": "BDTAUPR", + "offset": "0x5C", + "fields": [ + [ + "TIMxEEFR3", + 22, + 1 + ], + [ + "TIMxCR2", + 21, + 1 + ], + [ + "TIMxFLTR", + 20, + 1 + ], + [ + "TIMxOUTR", + 19, + 1 + ], + [ + "TIMxCHPR", + 18, + 1 + ], + [ + "TIMxRSTR", + 17, + 1 + ], + [ + "TIMxEEFR2", + 16, + 1 + ], + [ + "TIMxEEFR1", + 15, + 1 + ], + [ + "TIMxRST2R", + 14, + 1 + ], + [ + "TIMxSET2R", + 13, + 1 + ], + [ + "TIMxRST1R", + 12, + 1 + ], + [ + "TIMxSET1R", + 11, + 1 + ], + [ + "TIMx_DTxR", + 10, + 1 + ], + [ + "TIMxCMP4", + 9, + 1 + ], + [ + "TIMxCMP3", + 8, + 1 + ], + [ + "TIMxCMP2", + 7, + 1 + ], + [ + "TIMxCMP1", + 6, + 1 + ], + [ + "TIMxREP", + 5, + 1 + ], + [ + "TIMxPER", + 4, + 1 + ], + [ + "TIMxCNT", + 3, + 1 + ], + [ + "TIMxDIER", + 2, + 1 + ], + [ + "TIMxICR", + 1, + 1 + ], + [ + "TIMxCR", + 0, + 1 + ] + ] + }, + { + "name": "BDTBUPR", + "offset": "0x60", + "fields": [ + [ + "TIMxEEFR3", + 22, + 1 + ], + [ + "TIMxCR2", + 21, + 1 + ], + [ + "TIMxFLTR", + 20, + 1 + ], + [ + "TIMxOUTR", + 19, + 1 + ], + [ + "TIMxCHPR", + 18, + 1 + ], + [ + "TIMxRSTR", + 17, + 1 + ], + [ + "TIMxEEFR2", + 16, + 1 + ], + [ + "TIMxEEFR1", + 15, + 1 + ], + [ + "TIMxRST2R", + 14, + 1 + ], + [ + "TIMxSET2R", + 13, + 1 + ], + [ + "TIMxRST1R", + 12, + 1 + ], + [ + "TIMxSET1R", + 11, + 1 + ], + [ + "TIMx_DTxR", + 10, + 1 + ], + [ + "TIMxCMP4", + 9, + 1 + ], + [ + "TIMxCMP3", + 8, + 1 + ], + [ + "TIMxCMP2", + 7, + 1 + ], + [ + "TIMxCMP1", + 6, + 1 + ], + [ + "TIMxREP", + 5, + 1 + ], + [ + "TIMxPER", + 4, + 1 + ], + [ + "TIMxCNT", + 3, + 1 + ], + [ + "TIMxDIER", + 2, + 1 + ], + [ + "TIMxICR", + 1, + 1 + ], + [ + "TIMxCR", + 0, + 1 + ] + ] + }, + { + "name": "BDTCUPR", + "offset": "0x64", + "fields": [ + [ + "TIMxEEFR3", + 22, + 1 + ], + [ + "TIMxCR2", + 21, + 1 + ], + [ + "TIMxFLTR", + 20, + 1 + ], + [ + "TIMxOUTR", + 19, + 1 + ], + [ + "TIMxCHPR", + 18, + 1 + ], + [ + "TIMxRSTR", + 17, + 1 + ], + [ + "TIMxEEFR2", + 16, + 1 + ], + [ + "TIMxEEFR1", + 15, + 1 + ], + [ + "TIMxRST2R", + 14, + 1 + ], + [ + "TIMxSET2R", + 13, + 1 + ], + [ + "TIMxRST1R", + 12, + 1 + ], + [ + "TIMxSET1R", + 11, + 1 + ], + [ + "TIMx_DTxR", + 10, + 1 + ], + [ + "TIMxCMP4", + 9, + 1 + ], + [ + "TIMxCMP3", + 8, + 1 + ], + [ + "TIMxCMP2", + 7, + 1 + ], + [ + "TIMxCMP1", + 6, + 1 + ], + [ + "TIMxREP", + 5, + 1 + ], + [ + "TIMxPER", + 4, + 1 + ], + [ + "TIMxCNT", + 3, + 1 + ], + [ + "TIMxDIER", + 2, + 1 + ], + [ + "TIMxICR", + 1, + 1 + ], + [ + "TIMxCR", + 0, + 1 + ] + ] + }, + { + "name": "BDTDUPR", + "offset": "0x68", + "fields": [ + [ + "TIMxEEFR3", + 22, + 1 + ], + [ + "TIMxCR2", + 21, + 1 + ], + [ + "TIMxFLTR", + 20, + 1 + ], + [ + "TIMxOUTR", + 19, + 1 + ], + [ + "TIMxCHPR", + 18, + 1 + ], + [ + "TIMxRSTR", + 17, + 1 + ], + [ + "TIMxEEFR2", + 16, + 1 + ], + [ + "TIMxEEFR1", + 15, + 1 + ], + [ + "TIMxRST2R", + 14, + 1 + ], + [ + "TIMxSET2R", + 13, + 1 + ], + [ + "TIMxRST1R", + 12, + 1 + ], + [ + "TIMxSET1R", + 11, + 1 + ], + [ + "TIMx_DTxR", + 10, + 1 + ], + [ + "TIMxCMP4", + 9, + 1 + ], + [ + "TIMxCMP3", + 8, + 1 + ], + [ + "TIMxCMP2", + 7, + 1 + ], + [ + "TIMxCMP1", + 6, + 1 + ], + [ + "TIMxREP", + 5, + 1 + ], + [ + "TIMxPER", + 4, + 1 + ], + [ + "TIMxCNT", + 3, + 1 + ], + [ + "TIMxDIER", + 2, + 1 + ], + [ + "TIMxICR", + 1, + 1 + ], + [ + "TIMxCR", + 0, + 1 + ] + ] + }, + { + "name": "BDTEUPR", + "offset": "0x6C", + "fields": [ + [ + "TIMxEEFR3", + 22, + 1 + ], + [ + "TIMxCR2", + 21, + 1 + ], + [ + "TIMxFLTR", + 20, + 1 + ], + [ + "TIMxOUTR", + 19, + 1 + ], + [ + "TIMxCHPR", + 18, + 1 + ], + [ + "TIMxRSTR", + 17, + 1 + ], + [ + "TIMxEEFR2", + 16, + 1 + ], + [ + "TIMxEEFR1", + 15, + 1 + ], + [ + "TIMxRST2R", + 14, + 1 + ], + [ + "TIMxSET2R", + 13, + 1 + ], + [ + "TIMxRST1R", + 12, + 1 + ], + [ + "TIMxSET1R", + 11, + 1 + ], + [ + "TIMx_DTxR", + 10, + 1 + ], + [ + "TIMxCMP4", + 9, + 1 + ], + [ + "TIMxCMP3", + 8, + 1 + ], + [ + "TIMxCMP2", + 7, + 1 + ], + [ + "TIMxCMP1", + 6, + 1 + ], + [ + "TIMxREP", + 5, + 1 + ], + [ + "TIMxPER", + 4, + 1 + ], + [ + "TIMxCNT", + 3, + 1 + ], + [ + "TIMxDIER", + 2, + 1 + ], + [ + "TIMxICR", + 1, + 1 + ], + [ + "TIMxCR", + 0, + 1 + ] + ] + }, + { + "name": "BDTFUPR", + "offset": "0x74", + "fields": [ + [ + "TIMxEEFR3", + 22, + 1 + ], + [ + "TIMxCR2", + 21, + 1 + ], + [ + "TIMxFLTR", + 20, + 1 + ], + [ + "TIMxOUTR", + 19, + 1 + ], + [ + "TIMxCHPR", + 18, + 1 + ], + [ + "TIMxRSTR", + 17, + 1 + ], + [ + "TIMxEEFR2", + 16, + 1 + ], + [ + "TIMxEEFR1", + 15, + 1 + ], + [ + "TIMxRST2R", + 14, + 1 + ], + [ + "TIMxSET2R", + 13, + 1 + ], + [ + "TIMxRST1R", + 12, + 1 + ], + [ + "TIMxSET1R", + 11, + 1 + ], + [ + "TIMx_DTxR", + 10, + 1 + ], + [ + "TIMxCMP4", + 9, + 1 + ], + [ + "TIMxCMP3", + 8, + 1 + ], + [ + "TIMxCMP2", + 7, + 1 + ], + [ + "TIMxCMP1", + 6, + 1 + ], + [ + "TIMxREP", + 5, + 1 + ], + [ + "TIMxPER", + 4, + 1 + ], + [ + "TIMxCNT", + 3, + 1 + ], + [ + "TIMxDIER", + 2, + 1 + ], + [ + "TIMxICR", + 1, + 1 + ], + [ + "TIMxCR", + 0, + 1 + ] + ] + }, + { + "name": "BDMADR", + "offset": "0x70", + "fields": [ + [ + "BDMADR", + 0, + 32, + "w" + ] + ] + }, + { + "name": "ADCER", + "offset": "0x78", + "fields": [ + [ + "ADC10TRG", + 26, + 5 + ], + [ + "ADC9TRG", + 21, + 5 + ], + [ + "ADC8TRG", + 16, + 5 + ], + [ + "ADC7TRG", + 10, + 5 + ], + [ + "ADC6TRG", + 5, + 5 + ], + [ + "ADC5TRG", + 0, + 5 + ] + ] + }, + { + "name": "ADCUR", + "offset": "0x7C", + "fields": [ + [ + "AD10USRC", + 20, + 3 + ], + [ + "AD9USRC", + 16, + 3 + ], + [ + "AD8USRC", + 12, + 3 + ], + [ + "AD7USRC", + 8, + 3 + ], + [ + "AD6USRC", + 4, + 3 + ], + [ + "AD5USRC", + 0, + 3 + ] + ] + }, + { + "name": "ADCPS1", + "offset": "0x80", + "fields": [ + [ + "ADC5PSC", + 24, + 5 + ], + [ + "ADC4PSC", + 18, + 5 + ], + [ + "ADC3PSC", + 12, + 5 + ], + [ + "ADC2PSC", + 6, + 5 + ], + [ + "ADC1PSC", + 0, + 5 + ] + ] + }, + { + "name": "ADCPS2", + "offset": "0x84", + "fields": [ + [ + "ADC10PSC", + 24, + 5 + ], + [ + "ADC9PSC", + 18, + 5 + ], + [ + "ADC8PSC", + 12, + 5 + ], + [ + "ADC7PSC", + 6, + 5 + ], + [ + "ADC6PSC", + 0, + 5 + ] + ] + }, + { + "name": "FLTINR3", + "offset": "0x88", + "fields": [ + [ + "FLT4RSTM", + 31, + 1 + ], + [ + "FLT4CRES", + 30, + 1 + ], + [ + "FLT4CNT", + 26, + 4 + ], + [ + "FLT4BLKS", + 25, + 1 + ], + [ + "FLT4BLKE", + 24, + 1 + ], + [ + "FLT3RSTM", + 23, + 1 + ], + [ + "FLT3CRES", + 22, + 1 + ], + [ + "FLT3CNT", + 18, + 4 + ], + [ + "FLT3BLKS", + 17, + 1 + ], + [ + "FLT3BLKE", + 16, + 1 + ], + [ + "FLT2RSTM", + 15, + 1 + ], + [ + "FLT2CRES", + 14, + 1 + ], + [ + "FLT2CNT", + 10, + 4 + ], + [ + "FLT2BLKS", + 9, + 1 + ], + [ + "FLT2BLKE", + 8, + 1 + ], + [ + "FLT1RSTM", + 7, + 1 + ], + [ + "FLT1CRES", + 6, + 1 + ], + [ + "FLT1CNT", + 2, + 4 + ], + [ + "FLT1BLKS", + 1, + 1 + ], + [ + "FLT1BLKE", + 0, + 1 + ] + ] + }, + { + "name": "FLTINR4", + "offset": "0x8C", + "fields": [ + [ + "FLT6RSTM", + 15, + 1 + ], + [ + "FLT6CRES", + 14, + 1 + ], + [ + "FLT6CNT", + 10, + 4 + ], + [ + "FLT6BLKS", + 9, + 1 + ], + [ + "FLT6BLKE", + 8, + 1 + ], + [ + "FLT5RSTM", + 7, + 1 + ], + [ + "FLT5CRES", + 6, + 1 + ], + [ + "FLT5CNT", + 2, + 4 + ], + [ + "FLT5BLKS", + 1, + 1 + ], + [ + "FLT5BLKE", + 0, + 1 + ] + ] + } + ] + }, + { + "name": "DMA1", + "base": "0x40020000", + "interrupts": [ + "DMA1_CH1", + "DMA1_CH2", + "DMA1_CH3", + "DMA1_CH4", + "DMA1_CH5", + "DMA1_CH6", + "DMA1_CH7", + "DMA1_CH8" + ], + "registers": [ + { + "name": "ISR", + "offset": "0x00", + "fields": [ + [ + "TEIF8", + 31, + 1, + "r" + ], + [ + "HTIF8", + 30, + 1, + "r" + ], + [ + "TCIF8", + 29, + 1, + "r" + ], + [ + "GIF8", + 28, + 1, + "r" + ], + [ + "TEIF7", + 27, + 1, + "r" + ], + [ + "HTIF7", + 26, + 1, + "r" + ], + [ + "TCIF7", + 25, + 1, + "r" + ], + [ + "GIF7", + 24, + 1, + "r" + ], + [ + "TEIF6", + 23, + 1, + "r" + ], + [ + "HTIF6", + 22, + 1, + "r" + ], + [ + "TCIF6", + 21, + 1, + "r" + ], + [ + "GIF6", + 20, + 1, + "r" + ], + [ + "TEIF5", + 19, + 1, + "r" + ], + [ + "HTIF5", + 18, + 1, + "r" + ], + [ + "TCIF5", + 17, + 1, + "r" + ], + [ + "GIF5", + 16, + 1, + "r" + ], + [ + "TEIF4", + 15, + 1, + "r" + ], + [ + "HTIF4", + 14, + 1, + "r" + ], + [ + "TCIF4", + 13, + 1, + "r" + ], + [ + "GIF4", + 12, + 1, + "r" + ], + [ + "TEIF3", + 11, + 1, + "r" + ], + [ + "HTIF3", + 10, + 1, + "r" + ], + [ + "TCIF3", + 9, + 1, + "r" + ], + [ + "GIF3", + 8, + 1, + "r" + ], + [ + "TEIF2", + 7, + 1, + "r" + ], + [ + "HTIF2", + 6, + 1, + "r" + ], + [ + "TCIF2", + 5, + 1, + "r" + ], + [ + "GIF2", + 4, + 1, + "r" + ], + [ + "TEIF1", + 3, + 1, + "r" + ], + [ + "HTIF1", + 2, + 1, + "r" + ], + [ + "TCIF1", + 1, + 1, + "r" + ], + [ + "GIF1", + 0, + 1, + "r" + ] + ] + }, + { + "name": "IFCR", + "offset": "0x04", + "fields": [ + [ + "TEIF8", + 31, + 1, + "w" + ], + [ + "HTIF8", + 30, + 1, + "w" + ], + [ + "TCIF8", + 29, + 1, + "w" + ], + [ + "GIF8", + 28, + 1, + "w" + ], + [ + "TEIF7", + 27, + 1, + "w" + ], + [ + "HTIF7", + 26, + 1, + "w" + ], + [ + "TCIF7", + 25, + 1, + "w" + ], + [ + "GIF7", + 24, + 1, + "w" + ], + [ + "TEIF6", + 23, + 1, + "w" + ], + [ + "HTIF6", + 22, + 1, + "w" + ], + [ + "TCIF6", + 21, + 1, + "w" + ], + [ + "GIF6", + 20, + 1, + "w" + ], + [ + "TEIF5", + 19, + 1, + "w" + ], + [ + "HTIF5", + 18, + 1, + "w" + ], + [ + "TCIF5", + 17, + 1, + "w" + ], + [ + "GIF5", + 16, + 1, + "w" + ], + [ + "TEIF4", + 15, + 1, + "w" + ], + [ + "HTIF4", + 14, + 1, + "w" + ], + [ + "TCIF4", + 13, + 1, + "w" + ], + [ + "GIF4", + 12, + 1, + "w" + ], + [ + "TEIF3", + 11, + 1, + "w" + ], + [ + "HTIF3", + 10, + 1, + "w" + ], + [ + "TCIF3", + 9, + 1, + "w" + ], + [ + "GIF3", + 8, + 1, + "w" + ], + [ + "TEIF2", + 7, + 1, + "w" + ], + [ + "HTIF2", + 6, + 1, + "w" + ], + [ + "TCIF2", + 5, + 1, + "w" + ], + [ + "GIF2", + 4, + 1, + "w" + ], + [ + "TEIF1", + 3, + 1, + "w" + ], + [ + "HTIF1", + 2, + 1, + "w" + ], + [ + "TCIF1", + 1, + 1, + "w" + ], + [ + "GIF1", + 0, + 1, + "w" + ] + ] + }, + { + "name": "CCR1", + "offset": "0x08", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CCR2", + "offset": "0x1C", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CCR3", + "offset": "0x30", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CCR4", + "offset": "0x44", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CCR5", + "offset": "0x58", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CCR6", + "offset": "0x6C", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CCR7", + "offset": "0x80", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CCR8", + "offset": "0x94", + "fields": [ + [ + "EN", + 0, + 1 + ], + [ + "TCIE", + 1, + 1 + ], + [ + "HTIE", + 2, + 1 + ], + [ + "TEIE", + 3, + 1 + ], + [ + "DIR", + 4, + 1 + ], + [ + "CIRC", + 5, + 1 + ], + [ + "PINC", + 6, + 1 + ], + [ + "MINC", + 7, + 1 + ], + [ + "PSIZE", + 8, + 2 + ], + [ + "MSIZE", + 10, + 2 + ], + [ + "PL", + 12, + 2 + ], + [ + "MEM2MEM", + 14, + 1 + ] + ] + }, + { + "name": "CNDTR1", + "offset": "0x0C", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CNDTR2", + "offset": "0x20", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CNDTR3", + "offset": "0x34", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CNDTR4", + "offset": "0x48", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CNDTR5", + "offset": "0x5C", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CNDTR6", + "offset": "0x70", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CNDTR7", + "offset": "0x84", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CNDTR8", + "offset": "0x98", + "fields": [ + [ + "NDT", + 0, + 16 + ] + ] + }, + { + "name": "CPAR1", + "offset": "0x10", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CPAR2", + "offset": "0x24", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CPAR3", + "offset": "0x38", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CPAR4", + "offset": "0x4C", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CPAR5", + "offset": "0x60", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CPAR6", + "offset": "0x74", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CPAR7", + "offset": "0x88", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CPAR8", + "offset": "0x9C", + "fields": [ + [ + "PA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR1", + "offset": "0x14", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR2", + "offset": "0x28", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR3", + "offset": "0x3C", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR4", + "offset": "0x50", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR5", + "offset": "0x64", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR6", + "offset": "0x78", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR7", + "offset": "0x8C", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + }, + { + "name": "CMAR8", + "offset": "0xA0", + "fields": [ + [ + "MA", + 0, + 32 + ] + ] + } + ] + }, + { + "name": "DMA2", + "base": "0x40020400", + "interrupts": [ + "DMA2_CH1", + "DMA2_CH2", + "DMA2_CH3", + "DMA2_CH4", + "DMA2_CH5", + "DMA2_CH6", + "DMA2_CH7", + "DMA2_CH8" + ], + "derived_from": "DMA1" + }, + { + "name": "DMAMUX", + "base": "0x40020800", + "interrupts": [ + "DMAMUX_OVR" + ], + "registers": [ + { + "name": "C0CR", + "offset": "0x00", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C1CR", + "offset": "0x04", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C2CR", + "offset": "0x08", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C3CR", + "offset": "0x0C", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C4CR", + "offset": "0x10", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C5CR", + "offset": "0x14", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C6CR", + "offset": "0x18", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C7CR", + "offset": "0x1C", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C8CR", + "offset": "0x20", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C9CR", + "offset": "0x24", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C10CR", + "offset": "0x28", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C11CR", + "offset": "0x2C", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C12CR", + "offset": "0x30", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C13CR", + "offset": "0x34", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C14CR", + "offset": "0x38", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "C15CR", + "offset": "0x3C", + "fields": [ + [ + "DMAREQ_ID", + 0, + 7 + ], + [ + "SOIE", + 8, + 1 + ], + [ + "EGE", + 9, + 1 + ], + [ + "SE", + 16, + 1 + ], + [ + "SPOL", + 17, + 2 + ], + [ + "NBREQ", + 19, + 5 + ], + [ + "SYNC_ID", + 24, + 5 + ] + ] + }, + { + "name": "RG0CR", + "offset": "0x100", + "fields": [ + [ + "SIG_ID", + 0, + 5 + ], + [ + "OIE", + 8, + 1 + ], + [ + "GE", + 16, + 1 + ], + [ + "GPOL", + 17, + 2 + ], + [ + "GNBREQ", + 19, + 5 + ] + ] + }, + { + "name": "RG1CR", + "offset": "0x104", + "fields": [ + [ + "SIG_ID", + 0, + 5 + ], + [ + "OIE", + 8, + 1 + ], + [ + "GE", + 16, + 1 + ], + [ + "GPOL", + 17, + 2 + ], + [ + "GNBREQ", + 19, + 5 + ] + ] + }, + { + "name": "RG2CR", + "offset": "0x108", + "fields": [ + [ + "SIG_ID", + 0, + 5 + ], + [ + "OIE", + 8, + 1 + ], + [ + "GE", + 16, + 1 + ], + [ + "GPOL", + 17, + 2 + ], + [ + "GNBREQ", + 19, + 5 + ] + ] + }, + { + "name": "RG3CR", + "offset": "0x10C", + "fields": [ + [ + "SIG_ID", + 0, + 5 + ], + [ + "OIE", + 8, + 1 + ], + [ + "GE", + 16, + 1 + ], + [ + "GPOL", + 17, + 2 + ], + [ + "GNBREQ", + 19, + 5 + ] + ] + }, + { + "name": "RGSR", + "offset": "0x140", + "fields": [ + [ + "OF", + 0, + 4, + "r" + ] + ] + }, + { + "name": "RGCFR", + "offset": "0x144", + "fields": [ + [ + "COF", + 0, + 4, + "w" + ] + ] + }, + { + "name": "CSR", + "offset": "0x80", + "fields": [ + [ + "SOF", + 0, + 16, + "r" + ] + ] + }, + { + "name": "CFR", + "offset": "0x84", + "fields": [ + [ + "CSOF", + 0, + 16, + "w" + ] + ] + } + ] + }, + { + "name": "CORDIC", + "base": "0x40020C00", + "interrupts": [ + "Cordic" + ], + "registers": [ + { + "name": "CSR", + "offset": "0x00", + "fields": [ + [ + "FUNC", + 0, + 4 + ], + [ + "PRECISION", + 4, + 4 + ], + [ + "SCALE", + 8, + 3 + ], + [ + "IEN", + 16, + 1 + ], + [ + "DMAREN", + 17, + 1 + ], + [ + "DMAWEN", + 18, + 1 + ], + [ + "NRES", + 19, + 1 + ], + [ + "NARGS", + 20, + 1 + ], + [ + "RESSIZE", + 21, + 1 + ], + [ + "ARGSIZE", + 22, + 1 + ], + [ + "RRDY", + 31, + 1 + ] + ] + }, + { + "name": "WDATA", + "offset": "0x04", + "fields": [ + [ + "ARG", + 0, + 32 + ] + ] + }, + { + "name": "RDATA", + "offset": "0x08", + "fields": [ + [ + "RES", + 0, + 32, + "r" + ] + ] + } + ] + }, + { + "name": "RCC", + "base": "0x40021000", + "interrupts": [ + "RCC" + ], + "registers": [ + { + "name": "CR", + "offset": "0x00", + "reset": "0x00000500", + "fields": [ + [ + "HSION", + 8, + 1 + ], + [ + "HSIKERON", + 9, + 1 + ], + [ + "HSIRDY", + 10, + 1, + "r" + ], + [ + "HSEON", + 16, + 1 + ], + [ + "HSERDY", + 17, + 1, + "r" + ], + [ + "HSEBYP", + 18, + 1 + ], + [ + "CSSON", + 19, + 1 + ], + [ + "PLLON", + 24, + 1 + ], + [ + "PLLRDY", + 25, + 1, + "r" + ] + ] + }, + { + "name": "ICSCR", + "offset": "0x04", + "reset": "0x40000000", + "fields": [ + [ + "HSICAL", + 16, + 8, + "r" + ], + [ + "HSITRIM", + 24, + 7 + ] + ] + }, + { + "name": "CFGR", + "offset": "0x08", + "reset": "0x00000005", + "fields": [ + [ + "SW", + 0, + 2 + ], + [ + "SWS", + 2, + 2, + "r" + ], + [ + "HPRE", + 4, + 4 + ], + [ + "PPRE1", + 8, + 3 + ], + [ + "PPRE2", + 11, + 3 + ], + [ + "MCOSEL", + 24, + 4 + ], + [ + "MCOPRE", + 28, + 3 + ] + ] + }, + { + "name": "PLLCFGR", + "offset": "0x0C", + "reset": "0x00001000", + "fields": [ + [ + "PLLSRC", + 0, + 2 + ], + [ + "PLLM", + 4, + 4 + ], + [ + "PLLN", + 8, + 7 + ], + [ + "PLLPEN", + 16, + 1 + ], + [ + "PLLP", + 17, + 1 + ], + [ + "PLLQEN", + 20, + 1 + ], + [ + "PLLQ", + 21, + 2 + ], + [ + "PLLREN", + 24, + 1 + ], + [ + "PLLR", + 25, + 2 + ], + [ + "PLLPDIV", + 27, + 5 + ] + ] + }, + { + "name": "CIER", + "offset": "0x18", + "fields": [ + [ + "LSIRDYIE", + 0, + 1 + ], + [ + "LSERDYIE", + 1, + 1 + ], + [ + "HSIRDYIE", + 3, + 1 + ], + [ + "HSERDYIE", + 4, + 1 + ], + [ + "PLLRDYIE", + 5, + 1 + ], + [ + "LSECSSIE", + 9, + 1 + ], + [ + "HSI48RDYIE", + 10, + 1 + ] + ] + }, + { + "name": "CIFR", + "offset": "0x1C", + "fields": [ + [ + "LSIRDYF", + 0, + 1, + "r" + ], + [ + "LSERDYF", + 1, + 1, + "r" + ], + [ + "HSIRDYF", + 3, + 1, + "r" + ], + [ + "HSERDYF", + 4, + 1, + "r" + ], + [ + "PLLRDYF", + 5, + 1, + "r" + ], + [ + "CSSF", + 8, + 1, + "r" + ], + [ + "LSECSSF", + 9, + 1, + "r" + ], + [ + "HSI48RDYF", + 10, + 1, + "r" + ] + ] + }, + { + "name": "CICR", + "offset": "0x20", + "fields": [ + [ + "LSIRDYC", + 0, + 1, + "w" + ], + [ + "LSERDYC", + 1, + 1, + "w" + ], + [ + "HSIRDYC", + 3, + 1, + "w" + ], + [ + "HSERDYC", + 4, + 1, + "w" + ], + [ + "PLLRDYC", + 5, + 1, + "w" + ], + [ + "CSSC", + 8, + 1, + "w" + ], + [ + "LSECSSC", + 9, + 1, + "w" + ], + [ + "HSI48RDYC", + 10, + 1, + "w" + ] + ] + }, + { + "name": "AHB1RSTR", + "offset": "0x28", + "fields": [ + [ + "DMA1RST", + 0, + 1 + ], + [ + "DMA2RST", + 1, + 1 + ], + [ + "DMAMUX1RST", + 2, + 1 + ], + [ + "CORDICRST", + 3, + 1 + ], + [ + "FMACRST", + 4, + 1 + ], + [ + "FLASHRST", + 8, + 1 + ], + [ + "CRCRST", + 12, + 1 + ] + ] + }, + { + "name": "AHB2RSTR", + "offset": "0x2C", + "fields": [ + [ + "GPIOARST", + 0, + 1 + ], + [ + "GPIOBRST", + 1, + 1 + ], + [ + "GPIOCRST", + 2, + 1 + ], + [ + "GPIODRST", + 3, + 1 + ], + [ + "GPIOERST", + 4, + 1 + ], + [ + "GPIOFRST", + 5, + 1 + ], + [ + "GPIOGRST", + 6, + 1 + ], + [ + "ADC12RST", + 13, + 1 + ], + [ + "ADC345RST", + 14, + 1 + ], + [ + "DAC1RST", + 16, + 1 + ], + [ + "DAC2RST", + 17, + 1 + ], + [ + "DAC3RST", + 18, + 1 + ], + [ + "DAC4RST", + 19, + 1 + ], + [ + "AESRST", + 24, + 1 + ], + [ + "RNGRST", + 26, + 1 + ] + ] + }, + { + "name": "AHB3RSTR", + "offset": "0x30", + "fields": [ + [ + "FMCRST", + 0, + 1 + ], + [ + "QSPIRST", + 8, + 1 + ] + ] + }, + { + "name": "APB1RSTR1", + "offset": "0x38", + "fields": [ + [ + "TIM2RST", + 0, + 1 + ], + [ + "TIM3RST", + 1, + 1 + ], + [ + "TIM4RST", + 2, + 1 + ], + [ + "TIM5RST", + 3, + 1 + ], + [ + "TIM6RST", + 4, + 1 + ], + [ + "TIM7RST", + 5, + 1 + ], + [ + "CRSRST", + 8, + 1 + ], + [ + "SPI2RST", + 14, + 1 + ], + [ + "SPI3RST", + 15, + 1 + ], + [ + "USART2RST", + 17, + 1 + ], + [ + "USART3RST", + 18, + 1 + ], + [ + "UART4RST", + 19, + 1 + ], + [ + "UART5RST", + 20, + 1 + ], + [ + "I2C1RST", + 21, + 1 + ], + [ + "I2C2RST", + 22, + 1 + ], + [ + "USBRST", + 23, + 1 + ], + [ + "FDCANRST", + 25, + 1 + ], + [ + "PWRRST", + 28, + 1 + ], + [ + "I2C3RST", + 30, + 1 + ], + [ + "LPTIM1RST", + 31, + 1 + ] + ] + }, + { + "name": "APB1RSTR2", + "offset": "0x3C", + "fields": [ + [ + "LPUART1RST", + 0, + 1 + ], + [ + "I2C4RST", + 1, + 1 + ], + [ + "UCPD1RST", + 8, + 1 + ] + ] + }, + { + "name": "APB2RSTR", + "offset": "0x40", + "fields": [ + [ + "SYSCFGRST", + 0, + 1 + ], + [ + "TIM1RST", + 11, + 1 + ], + [ + "SPI1RST", + 12, + 1 + ], + [ + "TIM8RST", + 13, + 1 + ], + [ + "USART1RST", + 14, + 1 + ], + [ + "SPI4RST", + 15, + 1 + ], + [ + "TIM15RST", + 16, + 1 + ], + [ + "TIM16RST", + 17, + 1 + ], + [ + "TIM17RST", + 18, + 1 + ], + [ + "TIM20RST", + 20, + 1 + ], + [ + "SAI1RST", + 21, + 1 + ], + [ + "HRTIM1RST", + 26, + 1 + ] + ] + }, + { + "name": "AHB1ENR", + "offset": "0x48", + "reset": "0x00000100", + "fields": [ + [ + "DMA1EN", + 0, + 1 + ], + [ + "DMA2EN", + 1, + 1 + ], + [ + "DMAMUX1EN", + 2, + 1 + ], + [ + "CORDICEN", + 3, + 1 + ], + [ + "FMACEN", + 4, + 1 + ], + [ + "FLASHEN", + 8, + 1 + ], + [ + "CRCEN", + 12, + 1 + ] + ] + }, + { + "name": "AHB2ENR", + "offset": "0x4C", + "fields": [ + [ + "GPIOAEN", + 0, + 1 + ], + [ + "GPIOBEN", + 1, + 1 + ], + [ + "GPIOCEN", + 2, + 1 + ], + [ + "GPIODEN", + 3, + 1 + ], + [ + "GPIOEEN", + 4, + 1 + ], + [ + "GPIOFEN", + 5, + 1 + ], + [ + "GPIOGEN", + 6, + 1 + ], + [ + "ADC12EN", + 13, + 1 + ], + [ + "ADC345EN", + 14, + 1 + ], + [ + "DAC1EN", + 16, + 1 + ], + [ + "DAC2EN", + 17, + 1 + ], + [ + "DAC3EN", + 18, + 1 + ], + [ + "DAC4EN", + 19, + 1 + ], + [ + "AESEN", + 24, + 1 + ], + [ + "RNGEN", + 26, + 1 + ] + ] + }, + { + "name": "AHB3ENR", + "offset": "0x50", + "fields": [ + [ + "FMCEN", + 0, + 1 + ], + [ + "QSPIEN", + 8, + 1 + ] + ] + }, + { + "name": "APB1ENR1", + "offset": "0x58", + "reset": "0x00000400", + "fields": [ + [ + "TIM2EN", + 0, + 1 + ], + [ + "TIM3EN", + 1, + 1 + ], + [ + "TIM4EN", + 2, + 1 + ], + [ + "TIM5EN", + 3, + 1 + ], + [ + "TIM6EN", + 4, + 1 + ], + [ + "TIM7EN", + 5, + 1 + ], + [ + "CRSEN", + 8, + 1 + ], + [ + "RTCAPBEN", + 10, + 1 + ], + [ + "WWDGEN", + 11, + 1 + ], + [ + "SPI2EN", + 14, + 1 + ], + [ + "SPI3EN", + 15, + 1 + ], + [ + "USART2EN", + 17, + 1 + ], + [ + "USART3EN", + 18, + 1 + ], + [ + "UART4EN", + 19, + 1 + ], + [ + "UART5EN", + 20, + 1 + ], + [ + "I2C1EN", + 21, + 1 + ], + [ + "I2C2EN", + 22, + 1 + ], + [ + "USBEN", + 23, + 1 + ], + [ + "FDCANEN", + 25, + 1 + ], + [ + "PWREN", + 28, + 1 + ], + [ + "I2C3EN", + 30, + 1 + ], + [ + "LPTIM1EN", + 31, + 1 + ] + ] + }, + { + "name": "APB1ENR2", + "offset": "0x5C", + "fields": [ + [ + "LPUART1EN", + 0, + 1 + ], + [ + "I2C4EN", + 1, + 1 + ], + [ + "UCPD1EN", + 8, + 1 + ] + ] + }, + { + "name": "APB2ENR", + "offset": "0x60", + "fields": [ + [ + "SYSCFGEN", + 0, + 1 + ], + [ + "TIM1EN", + 11, + 1 + ], + [ + "SPI1EN", + 12, + 1 + ], + [ + "TIM8EN", + 13, + 1 + ], + [ + "USART1EN", + 14, + 1 + ], + [ + "SPI4EN", + 15, + 1 + ], + [ + "TIM15EN", + 16, + 1 + ], + [ + "TIM16EN", + 17, + 1 + ], + [ + "TIM17EN", + 18, + 1 + ], + [ + "TIM20EN", + 20, + 1 + ], + [ + "SAI1EN", + 21, + 1 + ], + [ + "HRTIM1EN", + 26, + 1 + ] + ] + }, + { + "name": "AHB1SMENR", + "offset": "0x68", + "reset": "0x0000130F", + "fields": [ + [ + "DMA1SMEN", + 0, + 1 + ], + [ + "DMA2SMEN", + 1, + 1 + ], + [ + "DMAMUX1SMEN", + 2, + 1 + ], + [ + "CORDICSMEN", + 3, + 1 + ], + [ + "FMACSMEN", + 4, + 1 + ], + [ + "FLASHSMEN", + 8, + 1 + ], + [ + "SRAM1SMEN", + 9, + 1 + ], + [ + "CRCSMEN", + 12, + 1 + ] + ] + }, + { + "name": "AHB2SMENR", + "offset": "0x6C", + "reset": "0x050F667F", + "fields": [ + [ + "GPIOASMEN", + 0, + 1 + ], + [ + "GPIOBSMEN", + 1, + 1 + ], + [ + "GPIOCSMEN", + 2, + 1 + ], + [ + "GPIODSMEN", + 3, + 1 + ], + [ + "GPIOESMEN", + 4, + 1 + ], + [ + "GPIOFSMEN", + 5, + 1 + ], + [ + "GPIOGSMEN", + 6, + 1 + ], + [ + "CCMSRAMSMEN", + 9, + 1 + ], + [ + "SRAM2SMEN", + 10, + 1 + ], + [ + "ADC12SMEN", + 13, + 1 + ], + [ + "ADC345SMEN", + 14, + 1 + ], + [ + "DAC1SMEN", + 16, + 1 + ], + [ + "DAC2SMEN", + 17, + 1 + ], + [ + "DAC3SMEN", + 18, + 1 + ], + [ + "DAC4SMEN", + 19, + 1 + ], + [ + "AESSMEN", + 24, + 1 + ], + [ + "RNGEN", + 26, + 1 + ] + ] + }, + { + "name": "AHB3SMENR", + "offset": "0x70", + "reset": "0x00000101", + "fields": [ + [ + "FMCSMEN", + 0, + 1 + ], + [ + "QSPISMEN", + 8, + 1 + ] + ] + }, + { + "name": "APB1SMENR1", + "offset": "0x78", + "reset": "0xD2FECD3F", + "fields": [ + [ + "TIM2SMEN", + 0, + 1 + ], + [ + "TIM3SMEN", + 1, + 1 + ], + [ + "TIM4SMEN", + 2, + 1 + ], + [ + "TIM5SMEN", + 3, + 1 + ], + [ + "TIM6SMEN", + 4, + 1 + ], + [ + "TIM7SMEN", + 5, + 1 + ], + [ + "CRSSMEN", + 8, + 1 + ], + [ + "RTCAPBSMEN", + 10, + 1 + ], + [ + "WWDGSMEN", + 11, + 1 + ], + [ + "SPI2SMEN", + 14, + 1 + ], + [ + "SPI3SMEN", + 15, + 1 + ], + [ + "USART2SMEN", + 17, + 1 + ], + [ + "USART3SMEN", + 18, + 1 + ], + [ + "UART4SMEN", + 19, + 1 + ], + [ + "UART5SMEN", + 20, + 1 + ], + [ + "I2C1SMEN", + 21, + 1 + ], + [ + "I2C2SMEN", + 22, + 1 + ], + [ + "USBSMEN", + 23, + 1 + ], + [ + "FDCANSMEN", + 25, + 1 + ], + [ + "PWRSMEN", + 28, + 1 + ], + [ + "I2C3SMEN", + 30, + 1 + ], + [ + "LPTIM1SMEN", + 31, + 1 + ] + ] + }, + { + "name": "APB1SMENR2", + "offset": "0x7C", + "reset": "0x00000103", + "fields": [ + [ + "LPUART1SMEN", + 0, + 1 + ], + [ + "I2C4SMEN", + 1, + 1 + ], + [ + "UCPD1SMEN", + 8, + 1 + ] + ] + }, + { + "name": "APB2SMENR", + "offset": "0x80", + "reset": "0x0437F801", + "fields": [ + [ + "SYSCFGSMEN", + 0, + 1 + ], + [ + "TIM1SMEN", + 11, + 1 + ], + [ + "SPI1SMEN", + 12, + 1 + ], + [ + "TIM8SMEN", + 13, + 1 + ], + [ + "USART1SMEN", + 14, + 1 + ], + [ + "SPI4SMEN", + 15, + 1 + ], + [ + "TIM15SMEN", + 16, + 1 + ], + [ + "TIM16SMEN", + 17, + 1 + ], + [ + "TIM17SMEN", + 18, + 1 + ], + [ + "TIM20SMEN", + 20, + 1 + ], + [ + "SAI1SMEN", + 21, + 1 + ], + [ + "HRTIM1SMEN", + 26, + 1 + ] + ] + }, + { + "name": "CCIPR", + "offset": "0x88", + "fields": [ + [ + "USART1SEL", + 0, + 2 + ], + [ + "USART2SEL", + 2, + 2 + ], + [ + "USART3SEL", + 4, + 2 + ], + [ + "UART4SEL", + 6, + 2 + ], + [ + "UART5SEL", + 8, + 2 + ], + [ + "LPUART1SEL", + 10, + 2 + ], + [ + "I2C1SEL", + 12, + 2 + ], + [ + "I2C2SEL", + 14, + 2 + ], + [ + "I2C3SEL", + 16, + 2 + ], + [ + "LPTIM1SEL", + 18, + 2 + ], + [ + "SAI1SEL", + 20, + 2 + ], + [ + "I2S23SEL", + 22, + 2 + ], + [ + "FDCANSEL", + 24, + 2 + ], + [ + "CLK48SEL", + 26, + 2 + ], + [ + "ADC12SEL", + 28, + 2 + ], + [ + "ADC345SEL", + 30, + 2 + ] + ] + }, + { + "name": "BDCR", + "offset": "0x90", + "fields": [ + [ + "LSEON", + 0, + 1 + ], + [ + "LSERDY", + 1, + 1, + "r" + ], + [ + "LSEBYP", + 2, + 1 + ], + [ + "LSEDRV", + 3, + 2 + ], + [ + "LSECSSON", + 5, + 1 + ], + [ + "LSECSSD", + 6, + 1, + "r" + ], + [ + "RTCSEL", + 8, + 2 + ], + [ + "RTCEN", + 15, + 1 + ], + [ + "BDRST", + 16, + 1 + ], + [ + "LSCOEN", + 24, + 1 + ], + [ + "LSCOSEL", + 25, + 1 + ] + ] + }, + { + "name": "CSR", + "offset": "0x94", + "reset": "0x0C000000", + "fields": [ + [ + "LSION", + 0, + 1 + ], + [ + "LSIRDY", + 1, + 1, + "r" + ], + [ + "RMVF", + 23, + 1 + ], + [ + "OBLRSTF", + 25, + 1, + "r" + ], + [ + "PINRSTF", + 26, + 1, + "r" + ], + [ + "BORRSTF", + 27, + 1, + "r" + ], + [ + "SFTRSTF", + 28, + 1, + "r" + ], + [ + "IWDGRSTF", + 29, + 1, + "r" + ], + [ + "WWDGRSTF", + 30, + 1, + "r" + ], + [ + "LPWRRSTF", + 31, + 1, + "r" + ] + ] + }, + { + "name": "CRRCR", + "offset": "0x98", + "fields": [ + [ + "HSI48ON", + 0, + 1 + ], + [ + "HSI48RDY", + 1, + 1, + "r" + ], + [ + "HSI48CAL", + 7, + 9, + "r" + ] + ] + }, + { + "name": "CCIPR2", + "offset": "0x9C", + "fields": [ + [ + "I2C4SEL", + 0, + 2 + ], + [ + "QSPISEL", + 20, + 2 + ] + ] + } + ] + }, + { + "name": "FMAC", + "base": "0x40021400", + "interrupts": [ + "FMAC" + ], + "registers": [ + { + "name": "X1BUFCFG", + "offset": "0x00", + "fields": [ + [ + "X1_BASE", + 0, + 8 + ], + [ + "X1_BUF_SIZE", + 8, + 8 + ], + [ + "FULL_WM", + 24, + 2 + ] + ] + }, + { + "name": "X2BUFCFG", + "offset": "0x04", + "fields": [ + [ + "X2_BASE", + 0, + 8 + ], + [ + "X2_BUF_SIZE", + 8, + 8 + ] + ] + }, + { + "name": "YBUFCFG", + "offset": "0x08", + "fields": [ + [ + "Y_BASE", + 0, + 8 + ], + [ + "Y_BUF_SIZE", + 8, + 8 + ], + [ + "EMPTY_WM", + 24, + 2 + ] + ] + }, + { + "name": "PARAM", + "offset": "0x0C", + "fields": [ + [ + "START", + 31, + 1 + ], + [ + "FUNC", + 24, + 7 + ], + [ + "R", + 16, + 8 + ], + [ + "Q", + 8, + 8 + ], + [ + "P", + 0, + 8 + ] + ] + }, + { + "name": "CR", + "offset": "0x10", + "fields": [ + [ + "RESET", + 16, + 1 + ], + [ + "CLIPEN", + 15, + 1 + ], + [ + "DMAWEN", + 9, + 1 + ], + [ + "DMAREN", + 8, + 1 + ], + [ + "SATIEN", + 4, + 1 + ], + [ + "UNFLIEN", + 3, + 1 + ], + [ + "OVFLIEN", + 2, + 1 + ], + [ + "WIEN", + 1, + 1 + ], + [ + "RIEN", + 0, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x14", + "fields": [ + [ + "YEMPTY", + 0, + 1, + "r" + ], + [ + "X1FULL", + 1, + 1, + "r" + ], + [ + "OVFL", + 8, + 1, + "r" + ], + [ + "UNFL", + 9, + 1, + "r" + ], + [ + "SAT", + 10, + 1, + "r" + ] + ] + }, + { + "name": "WDATA", + "offset": "0x18", + "fields": [ + [ + "WDATA", + 0, + 16, + "w" + ] + ] + }, + { + "name": "RDATA", + "offset": "0x1C", + "fields": [ + [ + "RDATA", + 0, + 16, + "r" + ] + ] + } + ] + }, + { + "name": "FLASH", + "base": "0x40022000", + "interrupts": [ + "FLASH" + ], + "registers": [ + { + "name": "ACR", + "offset": "0x00", + "reset": "0x00040601", + "fields": [ + [ + "LATENCY", + 0, + 4 + ], + [ + "PRFTEN", + 8, + 1 + ], + [ + "ICEN", + 9, + 1 + ], + [ + "DCEN", + 10, + 1 + ], + [ + "ICRST", + 11, + 1 + ], + [ + "DCRST", + 12, + 1 + ], + [ + "RUN_PD", + 13, + 1 + ], + [ + "SLEEP_PD", + 14, + 1 + ], + [ + "DBG_SWEN", + 18, + 1 + ] + ] + }, + { + "name": "PDKEYR", + "offset": "0x04", + "fields": [ + [ + "PDKEYR", + 0, + 32, + "w" + ] + ] + }, + { + "name": "KEYR", + "offset": "0x08", + "fields": [ + [ + "KEYR", + 0, + 32, + "w" + ] + ] + }, + { + "name": "OPTKEYR", + "offset": "0x0C", + "fields": [ + [ + "OPTKEYR", + 0, + 32, + "w" + ] + ] + }, + { + "name": "SR", + "offset": "0x10", + "fields": [ + [ + "EOP", + 0, + 1 + ], + [ + "OPERR", + 1, + 1 + ], + [ + "PROGERR", + 3, + 1 + ], + [ + "WRPERR", + 4, + 1 + ], + [ + "PGAERR", + 5, + 1 + ], + [ + "SIZERR", + 6, + 1 + ], + [ + "PGSERR", + 7, + 1 + ], + [ + "MISSERR", + 8, + 1 + ], + [ + "FASTERR", + 9, + 1 + ], + [ + "RDERR", + 14, + 1 + ], + [ + "OPTVERR", + 15, + 1 + ], + [ + "BSY", + 16, + 1, + "r" + ] + ] + }, + { + "name": "CR", + "offset": "0x14", + "reset": "0xC0000000", + "fields": [ + [ + "PG", + 0, + 1 + ], + [ + "PER", + 1, + 1 + ], + [ + "MER1", + 2, + 1 + ], + [ + "PNB", + 3, + 7 + ], + [ + "BKER", + 11, + 1 + ], + [ + "MER2", + 15, + 1 + ], + [ + "START", + 16, + 1 + ], + [ + "OPTSTRT", + 17, + 1 + ], + [ + "FSTPG", + 18, + 1 + ], + [ + "EOPIE", + 24, + 1 + ], + [ + "ERRIE", + 25, + 1 + ], + [ + "RDERRIE", + 26, + 1 + ], + [ + "OBL_LAUNCH", + 27, + 1 + ], + [ + "SEC_PROT1", + 28, + 1 + ], + [ + "SEC_PROT2", + 29, + 1 + ], + [ + "OPTLOCK", + 30, + 1 + ], + [ + "LOCK", + 31, + 1 + ] + ] + }, + { + "name": "ECCR", + "offset": "0x18", + "fields": [ + [ + "ADDR_ECC", + 0, + 19, + "r" + ], + [ + "BK_ECC", + 21, + 1, + "r" + ], + [ + "SYSF_ECC", + 22, + 1, + "r" + ], + [ + "ECCCIE", + 24, + 1 + ], + [ + "ECCC2", + 28, + 1 + ], + [ + "ECCD2", + 29, + 1 + ], + [ + "ECCC", + 30, + 1 + ], + [ + "ECCD", + 31, + 1 + ] + ] + }, + { + "name": "OPTR", + "offset": "0x20", + "fields": [ + [ + "RDP", + 0, + 8 + ], + [ + "BOR_LEV", + 8, + 3 + ], + [ + "nRST_STOP", + 12, + 1 + ], + [ + "nRST_STDBY", + 13, + 1 + ], + [ + "nRST_SHDW", + 14, + 1 + ], + [ + "IWDG_SW", + 16, + 1 + ], + [ + "IWDG_STOP", + 17, + 1 + ], + [ + "IWGD_STDBY", + 18, + 1 + ], + [ + "WWDG_SW", + 19, + 1 + ], + [ + "BFB2", + 20, + 1 + ], + [ + "DBANK", + 22, + 1 + ], + [ + "nBOOT1", + 23, + 1 + ], + [ + "SRAM_PE", + 24, + 1 + ], + [ + "CCMSRAM_RST", + 25, + 1 + ], + [ + "nSWBOOT0", + 26, + 1 + ], + [ + "nBOOT0", + 27, + 1 + ], + [ + "NRST_MODE", + 28, + 2 + ], + [ + "IRHEN", + 30, + 1 + ] + ], + "reset": "0xFFEFF8AA" + }, + { + "name": "PCROP1SR", + "offset": "0x24", + "reset": "0xFFFF0000", + "fields": [ + [ + "PCROP1_STRT", + 0, + 15 + ] + ] + }, + { + "name": "PCROP1ER", + "offset": "0x28", + "fields": [ + [ + "PCROP1_END", + 0, + 15 + ], + [ + "PCROP_RDP", + 31, + 1 + ] + ] + }, + { + "name": "WRP1AR", + "offset": "0x2C", + "fields": [ + [ + "WRP1A_STRT", + 0, + 7 + ], + [ + "WRP1A_END", + 16, + 7 + ] + ] + }, + { + "name": "WRP1BR", + "offset": "0x30", + "fields": [ + [ + "WRP1B_STRT", + 0, + 7 + ], + [ + "WRP1B_END", + 16, + 7 + ] + ] + }, + { + "name": "PCROP2SR", + "offset": "0x44", + "reset": "0xFFFF0000", + "fields": [ + [ + "PCROP2_STRT", + 0, + 15 + ] + ] + }, + { + "name": "PCROP2ER", + "offset": "0x48", + "fields": [ + [ + "PCROP2_END", + 0, + 15 + ] + ] + }, + { + "name": "WRP2AR", + "offset": "0x4C", + "fields": [ + [ + "WRP2A_STRT", + 0, + 7 + ], + [ + "WRP2A_END", + 16, + 7 + ] + ] + }, + { + "name": "WRP2BR", + "offset": "0x50", + "fields": [ + [ + "WRP2B_STRT", + 0, + 7 + ], + [ + "WRP2B_END", + 16, + 7 + ] + ] + }, + { + "name": "SEC1R", + "offset": "0x70", + "reset": "0xFFF0FF00", + "fields": [ + [ + "SEC_SIZE1", + 0, + 8 + ], + [ + "BOOT_LOCK", + 16, + 1 + ] + ] + }, + { + "name": "SEC2R", + "offset": "0x74", + "reset": "0xFFFFFF00", + "fields": [ + [ + "SEC_SIZE2", + 0, + 8 + ] + ] + } + ] + }, + { + "name": "CRC", + "base": "0x40023000", + "registers": [ + { + "name": "DR", + "offset": "0x00", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "DR", + 0, + 32 + ] + ] + }, + { + "name": "IDR", + "offset": "0x04", + "fields": [ + [ + "IDR", + 0, + 32 + ] + ] + }, + { + "name": "CR", + "offset": "0x08", + "fields": [ + [ + "REV_OUT", + 7, + 1 + ], + [ + "REV_IN", + 5, + 2 + ], + [ + "POLYSIZE", + 3, + 2 + ], + [ + "RESET", + 0, + 1, + "w" + ] + ] + }, + { + "name": "INIT", + "offset": "0x10", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "CRC_INIT", + 0, + 32 + ] + ] + }, + { + "name": "POL", + "offset": "0x14", + "reset": "0x04C11DB7", + "fields": [ + [ + "POL", + 0, + 32 + ] + ] + } + ] + }, + { + "name": "GPIOA", + "base": "0x48000000", + "registers": [ + { + "name": "MODER", + "offset": "0x00", + "reset": "0xABFFFFFF", + "fields": [ + [ + "MODER15", + 30, + 2 + ], + [ + "MODER14", + 28, + 2 + ], + [ + "MODER13", + 26, + 2 + ], + [ + "MODER12", + 24, + 2 + ], + [ + "MODER11", + 22, + 2 + ], + [ + "MODER10", + 20, + 2 + ], + [ + "MODER9", + 18, + 2 + ], + [ + "MODER8", + 16, + 2 + ], + [ + "MODER7", + 14, + 2 + ], + [ + "MODER6", + 12, + 2 + ], + [ + "MODER5", + 10, + 2 + ], + [ + "MODER4", + 8, + 2 + ], + [ + "MODER3", + 6, + 2 + ], + [ + "MODER2", + 4, + 2 + ], + [ + "MODER1", + 2, + 2 + ], + [ + "MODER0", + 0, + 2 + ] + ] + }, + { + "name": "OTYPER", + "offset": "0x04", + "fields": [ + [ + "OT15", + 15, + 1 + ], + [ + "OT14", + 14, + 1 + ], + [ + "OT13", + 13, + 1 + ], + [ + "OT12", + 12, + 1 + ], + [ + "OT11", + 11, + 1 + ], + [ + "OT10", + 10, + 1 + ], + [ + "OT9", + 9, + 1 + ], + [ + "OT8", + 8, + 1 + ], + [ + "OT7", + 7, + 1 + ], + [ + "OT6", + 6, + 1 + ], + [ + "OT5", + 5, + 1 + ], + [ + "OT4", + 4, + 1 + ], + [ + "OT3", + 3, + 1 + ], + [ + "OT2", + 2, + 1 + ], + [ + "OT1", + 1, + 1 + ], + [ + "OT0", + 0, + 1 + ] + ] + }, + { + "name": "OSPEEDR", + "offset": "0x08", + "reset": "0x0C000000", + "fields": [ + [ + "OSPEEDR15", + 30, + 2 + ], + [ + "OSPEEDR14", + 28, + 2 + ], + [ + "OSPEEDR13", + 26, + 2 + ], + [ + "OSPEEDR12", + 24, + 2 + ], + [ + "OSPEEDR11", + 22, + 2 + ], + [ + "OSPEEDR10", + 20, + 2 + ], + [ + "OSPEEDR9", + 18, + 2 + ], + [ + "OSPEEDR8", + 16, + 2 + ], + [ + "OSPEEDR7", + 14, + 2 + ], + [ + "OSPEEDR6", + 12, + 2 + ], + [ + "OSPEEDR5", + 10, + 2 + ], + [ + "OSPEEDR4", + 8, + 2 + ], + [ + "OSPEEDR3", + 6, + 2 + ], + [ + "OSPEEDR2", + 4, + 2 + ], + [ + "OSPEEDR1", + 2, + 2 + ], + [ + "OSPEEDR0", + 0, + 2 + ] + ] + }, + { + "name": "PUPDR", + "offset": "0x0C", + "reset": "0x64000000", + "fields": [ + [ + "PUPDR15", + 30, + 2 + ], + [ + "PUPDR14", + 28, + 2 + ], + [ + "PUPDR13", + 26, + 2 + ], + [ + "PUPDR12", + 24, + 2 + ], + [ + "PUPDR11", + 22, + 2 + ], + [ + "PUPDR10", + 20, + 2 + ], + [ + "PUPDR9", + 18, + 2 + ], + [ + "PUPDR8", + 16, + 2 + ], + [ + "PUPDR7", + 14, + 2 + ], + [ + "PUPDR6", + 12, + 2 + ], + [ + "PUPDR5", + 10, + 2 + ], + [ + "PUPDR4", + 8, + 2 + ], + [ + "PUPDR3", + 6, + 2 + ], + [ + "PUPDR2", + 4, + 2 + ], + [ + "PUPDR1", + 2, + 2 + ], + [ + "PUPDR0", + 0, + 2 + ] + ] + }, + { + "name": "IDR", + "offset": "0x10", + "fields": [ + [ + "IDR15", + 15, + 1, + "r" + ], + [ + "IDR14", + 14, + 1, + "r" + ], + [ + "IDR13", + 13, + 1, + "r" + ], + [ + "IDR12", + 12, + 1, + "r" + ], + [ + "IDR11", + 11, + 1, + "r" + ], + [ + "IDR10", + 10, + 1, + "r" + ], + [ + "IDR9", + 9, + 1, + "r" + ], + [ + "IDR8", + 8, + 1, + "r" + ], + [ + "IDR7", + 7, + 1, + "r" + ], + [ + "IDR6", + 6, + 1, + "r" + ], + [ + "IDR5", + 5, + 1, + "r" + ], + [ + "IDR4", + 4, + 1, + "r" + ], + [ + "IDR3", + 3, + 1, + "r" + ], + [ + "IDR2", + 2, + 1, + "r" + ], + [ + "IDR1", + 1, + 1, + "r" + ], + [ + "IDR0", + 0, + 1, + "r" + ] + ] + }, + { + "name": "ODR", + "offset": "0x14", + "fields": [ + [ + "ODR15", + 15, + 1 + ], + [ + "ODR14", + 14, + 1 + ], + [ + "ODR13", + 13, + 1 + ], + [ + "ODR12", + 12, + 1 + ], + [ + "ODR11", + 11, + 1 + ], + [ + "ODR10", + 10, + 1 + ], + [ + "ODR9", + 9, + 1 + ], + [ + "ODR8", + 8, + 1 + ], + [ + "ODR7", + 7, + 1 + ], + [ + "ODR6", + 6, + 1 + ], + [ + "ODR5", + 5, + 1 + ], + [ + "ODR4", + 4, + 1 + ], + [ + "ODR3", + 3, + 1 + ], + [ + "ODR2", + 2, + 1 + ], + [ + "ODR1", + 1, + 1 + ], + [ + "ODR0", + 0, + 1 + ] + ] + }, + { + "name": "BSRR", + "offset": "0x18", + "fields": [ + [ + "BR15", + 31, + 1, + "w" + ], + [ + "BR14", + 30, + 1, + "w" + ], + [ + "BR13", + 29, + 1, + "w" + ], + [ + "BR12", + 28, + 1, + "w" + ], + [ + "BR11", + 27, + 1, + "w" + ], + [ + "BR10", + 26, + 1, + "w" + ], + [ + "BR9", + 25, + 1, + "w" + ], + [ + "BR8", + 24, + 1, + "w" + ], + [ + "BR7", + 23, + 1, + "w" + ], + [ + "BR6", + 22, + 1, + "w" + ], + [ + "BR5", + 21, + 1, + "w" + ], + [ + "BR4", + 20, + 1, + "w" + ], + [ + "BR3", + 19, + 1, + "w" + ], + [ + "BR2", + 18, + 1, + "w" + ], + [ + "BR1", + 17, + 1, + "w" + ], + [ + "BR0", + 16, + 1, + "w" + ], + [ + "BS15", + 15, + 1, + "w" + ], + [ + "BS14", + 14, + 1, + "w" + ], + [ + "BS13", + 13, + 1, + "w" + ], + [ + "BS12", + 12, + 1, + "w" + ], + [ + "BS11", + 11, + 1, + "w" + ], + [ + "BS10", + 10, + 1, + "w" + ], + [ + "BS9", + 9, + 1, + "w" + ], + [ + "BS8", + 8, + 1, + "w" + ], + [ + "BS7", + 7, + 1, + "w" + ], + [ + "BS6", + 6, + 1, + "w" + ], + [ + "BS5", + 5, + 1, + "w" + ], + [ + "BS4", + 4, + 1, + "w" + ], + [ + "BS3", + 3, + 1, + "w" + ], + [ + "BS2", + 2, + 1, + "w" + ], + [ + "BS1", + 1, + 1, + "w" + ], + [ + "BS0", + 0, + 1, + "w" + ] + ] + }, + { + "name": "LCKR", + "offset": "0x1C", + "fields": [ + [ + "LCKK", + 16, + 1 + ], + [ + "LCK15", + 15, + 1 + ], + [ + "LCK14", + 14, + 1 + ], + [ + "LCK13", + 13, + 1 + ], + [ + "LCK12", + 12, + 1 + ], + [ + "LCK11", + 11, + 1 + ], + [ + "LCK10", + 10, + 1 + ], + [ + "LCK9", + 9, + 1 + ], + [ + "LCK8", + 8, + 1 + ], + [ + "LCK7", + 7, + 1 + ], + [ + "LCK6", + 6, + 1 + ], + [ + "LCK5", + 5, + 1 + ], + [ + "LCK4", + 4, + 1 + ], + [ + "LCK3", + 3, + 1 + ], + [ + "LCK2", + 2, + 1 + ], + [ + "LCK1", + 1, + 1 + ], + [ + "LCK0", + 0, + 1 + ] + ] + }, + { + "name": "AFRL", + "offset": "0x20", + "fields": [ + [ + "AFRL7", + 28, + 4 + ], + [ + "AFRL6", + 24, + 4 + ], + [ + "AFRL5", + 20, + 4 + ], + [ + "AFRL4", + 16, + 4 + ], + [ + "AFRL3", + 12, + 4 + ], + [ + "AFRL2", + 8, + 4 + ], + [ + "AFRL1", + 4, + 4 + ], + [ + "AFRL0", + 0, + 4 + ] + ] + }, + { + "name": "AFRH", + "offset": "0x24", + "fields": [ + [ + "AFRH15", + 28, + 4 + ], + [ + "AFRH14", + 24, + 4 + ], + [ + "AFRH13", + 20, + 4 + ], + [ + "AFRH12", + 16, + 4 + ], + [ + "AFRH11", + 12, + 4 + ], + [ + "AFRH10", + 8, + 4 + ], + [ + "AFRH9", + 4, + 4 + ], + [ + "AFRH8", + 0, + 4 + ] + ] + }, + { + "name": "BRR", + "offset": "0x28", + "fields": [ + [ + "BR0", + 0, + 1, + "w" + ], + [ + "BR1", + 1, + 1, + "w" + ], + [ + "BR2", + 2, + 1, + "w" + ], + [ + "BR3", + 3, + 1, + "w" + ], + [ + "BR4", + 4, + 1, + "w" + ], + [ + "BR5", + 5, + 1, + "w" + ], + [ + "BR6", + 6, + 1, + "w" + ], + [ + "BR7", + 7, + 1, + "w" + ], + [ + "BR8", + 8, + 1, + "w" + ], + [ + "BR9", + 9, + 1, + "w" + ], + [ + "BR10", + 10, + 1, + "w" + ], + [ + "BR11", + 11, + 1, + "w" + ], + [ + "BR12", + 12, + 1, + "w" + ], + [ + "BR13", + 13, + 1, + "w" + ], + [ + "BR14", + 14, + 1, + "w" + ], + [ + "BR15", + 15, + 1, + "w" + ] + ] + } + ] + }, + { + "name": "GPIOB", + "base": "0x48000400", + "registers": [ + { + "name": "MODER", + "offset": "0x00", + "reset": "0xFFFFFEBF", + "fields": [ + [ + "MODER15", + 30, + 2 + ], + [ + "MODER14", + 28, + 2 + ], + [ + "MODER13", + 26, + 2 + ], + [ + "MODER12", + 24, + 2 + ], + [ + "MODER11", + 22, + 2 + ], + [ + "MODER10", + 20, + 2 + ], + [ + "MODER9", + 18, + 2 + ], + [ + "MODER8", + 16, + 2 + ], + [ + "MODER7", + 14, + 2 + ], + [ + "MODER6", + 12, + 2 + ], + [ + "MODER5", + 10, + 2 + ], + [ + "MODER4", + 8, + 2 + ], + [ + "MODER3", + 6, + 2 + ], + [ + "MODER2", + 4, + 2 + ], + [ + "MODER1", + 2, + 2 + ], + [ + "MODER0", + 0, + 2 + ] + ] + }, + { + "name": "OTYPER", + "offset": "0x04", + "fields": [ + [ + "OT15", + 15, + 1 + ], + [ + "OT14", + 14, + 1 + ], + [ + "OT13", + 13, + 1 + ], + [ + "OT12", + 12, + 1 + ], + [ + "OT11", + 11, + 1 + ], + [ + "OT10", + 10, + 1 + ], + [ + "OT9", + 9, + 1 + ], + [ + "OT8", + 8, + 1 + ], + [ + "OT7", + 7, + 1 + ], + [ + "OT6", + 6, + 1 + ], + [ + "OT5", + 5, + 1 + ], + [ + "OT4", + 4, + 1 + ], + [ + "OT3", + 3, + 1 + ], + [ + "OT2", + 2, + 1 + ], + [ + "OT1", + 1, + 1 + ], + [ + "OT0", + 0, + 1 + ] + ] + }, + { + "name": "OSPEEDR", + "offset": "0x08", + "reset": "0x000000C0", + "fields": [ + [ + "OSPEEDR15", + 30, + 2 + ], + [ + "OSPEEDR14", + 28, + 2 + ], + [ + "OSPEEDR13", + 26, + 2 + ], + [ + "OSPEEDR12", + 24, + 2 + ], + [ + "OSPEEDR11", + 22, + 2 + ], + [ + "OSPEEDR10", + 20, + 2 + ], + [ + "OSPEEDR9", + 18, + 2 + ], + [ + "OSPEEDR8", + 16, + 2 + ], + [ + "OSPEEDR7", + 14, + 2 + ], + [ + "OSPEEDR6", + 12, + 2 + ], + [ + "OSPEEDR5", + 10, + 2 + ], + [ + "OSPEEDR4", + 8, + 2 + ], + [ + "OSPEEDR3", + 6, + 2 + ], + [ + "OSPEEDR2", + 4, + 2 + ], + [ + "OSPEEDR1", + 2, + 2 + ], + [ + "OSPEEDR0", + 0, + 2 + ] + ] + }, + { + "name": "PUPDR", + "offset": "0x0C", + "reset": "0x00000100", + "fields": [ + [ + "PUPDR15", + 30, + 2 + ], + [ + "PUPDR14", + 28, + 2 + ], + [ + "PUPDR13", + 26, + 2 + ], + [ + "PUPDR12", + 24, + 2 + ], + [ + "PUPDR11", + 22, + 2 + ], + [ + "PUPDR10", + 20, + 2 + ], + [ + "PUPDR9", + 18, + 2 + ], + [ + "PUPDR8", + 16, + 2 + ], + [ + "PUPDR7", + 14, + 2 + ], + [ + "PUPDR6", + 12, + 2 + ], + [ + "PUPDR5", + 10, + 2 + ], + [ + "PUPDR4", + 8, + 2 + ], + [ + "PUPDR3", + 6, + 2 + ], + [ + "PUPDR2", + 4, + 2 + ], + [ + "PUPDR1", + 2, + 2 + ], + [ + "PUPDR0", + 0, + 2 + ] + ] + }, + { + "name": "IDR", + "offset": "0x10", + "fields": [ + [ + "IDR15", + 15, + 1, + "r" + ], + [ + "IDR14", + 14, + 1, + "r" + ], + [ + "IDR13", + 13, + 1, + "r" + ], + [ + "IDR12", + 12, + 1, + "r" + ], + [ + "IDR11", + 11, + 1, + "r" + ], + [ + "IDR10", + 10, + 1, + "r" + ], + [ + "IDR9", + 9, + 1, + "r" + ], + [ + "IDR8", + 8, + 1, + "r" + ], + [ + "IDR7", + 7, + 1, + "r" + ], + [ + "IDR6", + 6, + 1, + "r" + ], + [ + "IDR5", + 5, + 1, + "r" + ], + [ + "IDR4", + 4, + 1, + "r" + ], + [ + "IDR3", + 3, + 1, + "r" + ], + [ + "IDR2", + 2, + 1, + "r" + ], + [ + "IDR1", + 1, + 1, + "r" + ], + [ + "IDR0", + 0, + 1, + "r" + ] + ] + }, + { + "name": "ODR", + "offset": "0x14", + "fields": [ + [ + "ODR15", + 15, + 1 + ], + [ + "ODR14", + 14, + 1 + ], + [ + "ODR13", + 13, + 1 + ], + [ + "ODR12", + 12, + 1 + ], + [ + "ODR11", + 11, + 1 + ], + [ + "ODR10", + 10, + 1 + ], + [ + "ODR9", + 9, + 1 + ], + [ + "ODR8", + 8, + 1 + ], + [ + "ODR7", + 7, + 1 + ], + [ + "ODR6", + 6, + 1 + ], + [ + "ODR5", + 5, + 1 + ], + [ + "ODR4", + 4, + 1 + ], + [ + "ODR3", + 3, + 1 + ], + [ + "ODR2", + 2, + 1 + ], + [ + "ODR1", + 1, + 1 + ], + [ + "ODR0", + 0, + 1 + ] + ] + }, + { + "name": "BSRR", + "offset": "0x18", + "fields": [ + [ + "BR15", + 31, + 1, + "w" + ], + [ + "BR14", + 30, + 1, + "w" + ], + [ + "BR13", + 29, + 1, + "w" + ], + [ + "BR12", + 28, + 1, + "w" + ], + [ + "BR11", + 27, + 1, + "w" + ], + [ + "BR10", + 26, + 1, + "w" + ], + [ + "BR9", + 25, + 1, + "w" + ], + [ + "BR8", + 24, + 1, + "w" + ], + [ + "BR7", + 23, + 1, + "w" + ], + [ + "BR6", + 22, + 1, + "w" + ], + [ + "BR5", + 21, + 1, + "w" + ], + [ + "BR4", + 20, + 1, + "w" + ], + [ + "BR3", + 19, + 1, + "w" + ], + [ + "BR2", + 18, + 1, + "w" + ], + [ + "BR1", + 17, + 1, + "w" + ], + [ + "BR0", + 16, + 1, + "w" + ], + [ + "BS15", + 15, + 1, + "w" + ], + [ + "BS14", + 14, + 1, + "w" + ], + [ + "BS13", + 13, + 1, + "w" + ], + [ + "BS12", + 12, + 1, + "w" + ], + [ + "BS11", + 11, + 1, + "w" + ], + [ + "BS10", + 10, + 1, + "w" + ], + [ + "BS9", + 9, + 1, + "w" + ], + [ + "BS8", + 8, + 1, + "w" + ], + [ + "BS7", + 7, + 1, + "w" + ], + [ + "BS6", + 6, + 1, + "w" + ], + [ + "BS5", + 5, + 1, + "w" + ], + [ + "BS4", + 4, + 1, + "w" + ], + [ + "BS3", + 3, + 1, + "w" + ], + [ + "BS2", + 2, + 1, + "w" + ], + [ + "BS1", + 1, + 1, + "w" + ], + [ + "BS0", + 0, + 1, + "w" + ] + ] + }, + { + "name": "LCKR", + "offset": "0x1C", + "fields": [ + [ + "LCKK", + 16, + 1 + ], + [ + "LCK15", + 15, + 1 + ], + [ + "LCK14", + 14, + 1 + ], + [ + "LCK13", + 13, + 1 + ], + [ + "LCK12", + 12, + 1 + ], + [ + "LCK11", + 11, + 1 + ], + [ + "LCK10", + 10, + 1 + ], + [ + "LCK9", + 9, + 1 + ], + [ + "LCK8", + 8, + 1 + ], + [ + "LCK7", + 7, + 1 + ], + [ + "LCK6", + 6, + 1 + ], + [ + "LCK5", + 5, + 1 + ], + [ + "LCK4", + 4, + 1 + ], + [ + "LCK3", + 3, + 1 + ], + [ + "LCK2", + 2, + 1 + ], + [ + "LCK1", + 1, + 1 + ], + [ + "LCK0", + 0, + 1 + ] + ] + }, + { + "name": "AFRL", + "offset": "0x20", + "fields": [ + [ + "AFRL7", + 28, + 4 + ], + [ + "AFRL6", + 24, + 4 + ], + [ + "AFRL5", + 20, + 4 + ], + [ + "AFRL4", + 16, + 4 + ], + [ + "AFRL3", + 12, + 4 + ], + [ + "AFRL2", + 8, + 4 + ], + [ + "AFRL1", + 4, + 4 + ], + [ + "AFRL0", + 0, + 4 + ] + ] + }, + { + "name": "AFRH", + "offset": "0x24", + "fields": [ + [ + "AFRH15", + 28, + 4 + ], + [ + "AFRH14", + 24, + 4 + ], + [ + "AFRH13", + 20, + 4 + ], + [ + "AFRH12", + 16, + 4 + ], + [ + "AFRH11", + 12, + 4 + ], + [ + "AFRH10", + 8, + 4 + ], + [ + "AFRH9", + 4, + 4 + ], + [ + "AFRH8", + 0, + 4 + ] + ] + }, + { + "name": "BRR", + "offset": "0x28", + "fields": [ + [ + "BR0", + 0, + 1, + "w" + ], + [ + "BR1", + 1, + 1, + "w" + ], + [ + "BR2", + 2, + 1, + "w" + ], + [ + "BR3", + 3, + 1, + "w" + ], + [ + "BR4", + 4, + 1, + "w" + ], + [ + "BR5", + 5, + 1, + "w" + ], + [ + "BR6", + 6, + 1, + "w" + ], + [ + "BR7", + 7, + 1, + "w" + ], + [ + "BR8", + 8, + 1, + "w" + ], + [ + "BR9", + 9, + 1, + "w" + ], + [ + "BR10", + 10, + 1, + "w" + ], + [ + "BR11", + 11, + 1, + "w" + ], + [ + "BR12", + 12, + 1, + "w" + ], + [ + "BR13", + 13, + 1, + "w" + ], + [ + "BR14", + 14, + 1, + "w" + ], + [ + "BR15", + 15, + 1, + "w" + ] + ] + } + ] + }, + { + "name": "GPIOC", + "base": "0x48000800", + "registers": [ + { + "name": "MODER", + "offset": "0x00", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "MODER15", + 30, + 2 + ], + [ + "MODER14", + 28, + 2 + ], + [ + "MODER13", + 26, + 2 + ], + [ + "MODER12", + 24, + 2 + ], + [ + "MODER11", + 22, + 2 + ], + [ + "MODER10", + 20, + 2 + ], + [ + "MODER9", + 18, + 2 + ], + [ + "MODER8", + 16, + 2 + ], + [ + "MODER7", + 14, + 2 + ], + [ + "MODER6", + 12, + 2 + ], + [ + "MODER5", + 10, + 2 + ], + [ + "MODER4", + 8, + 2 + ], + [ + "MODER3", + 6, + 2 + ], + [ + "MODER2", + 4, + 2 + ], + [ + "MODER1", + 2, + 2 + ], + [ + "MODER0", + 0, + 2 + ] + ] + }, + { + "name": "OTYPER", + "offset": "0x04", + "fields": [ + [ + "OT15", + 15, + 1 + ], + [ + "OT14", + 14, + 1 + ], + [ + "OT13", + 13, + 1 + ], + [ + "OT12", + 12, + 1 + ], + [ + "OT11", + 11, + 1 + ], + [ + "OT10", + 10, + 1 + ], + [ + "OT9", + 9, + 1 + ], + [ + "OT8", + 8, + 1 + ], + [ + "OT7", + 7, + 1 + ], + [ + "OT6", + 6, + 1 + ], + [ + "OT5", + 5, + 1 + ], + [ + "OT4", + 4, + 1 + ], + [ + "OT3", + 3, + 1 + ], + [ + "OT2", + 2, + 1 + ], + [ + "OT1", + 1, + 1 + ], + [ + "OT0", + 0, + 1 + ] + ] + }, + { + "name": "OSPEEDR", + "offset": "0x08", + "fields": [ + [ + "OSPEEDR15", + 30, + 2 + ], + [ + "OSPEEDR14", + 28, + 2 + ], + [ + "OSPEEDR13", + 26, + 2 + ], + [ + "OSPEEDR12", + 24, + 2 + ], + [ + "OSPEEDR11", + 22, + 2 + ], + [ + "OSPEEDR10", + 20, + 2 + ], + [ + "OSPEEDR9", + 18, + 2 + ], + [ + "OSPEEDR8", + 16, + 2 + ], + [ + "OSPEEDR7", + 14, + 2 + ], + [ + "OSPEEDR6", + 12, + 2 + ], + [ + "OSPEEDR5", + 10, + 2 + ], + [ + "OSPEEDR4", + 8, + 2 + ], + [ + "OSPEEDR3", + 6, + 2 + ], + [ + "OSPEEDR2", + 4, + 2 + ], + [ + "OSPEEDR1", + 2, + 2 + ], + [ + "OSPEEDR0", + 0, + 2 + ] + ] + }, + { + "name": "PUPDR", + "offset": "0x0C", + "fields": [ + [ + "PUPDR15", + 30, + 2 + ], + [ + "PUPDR14", + 28, + 2 + ], + [ + "PUPDR13", + 26, + 2 + ], + [ + "PUPDR12", + 24, + 2 + ], + [ + "PUPDR11", + 22, + 2 + ], + [ + "PUPDR10", + 20, + 2 + ], + [ + "PUPDR9", + 18, + 2 + ], + [ + "PUPDR8", + 16, + 2 + ], + [ + "PUPDR7", + 14, + 2 + ], + [ + "PUPDR6", + 12, + 2 + ], + [ + "PUPDR5", + 10, + 2 + ], + [ + "PUPDR4", + 8, + 2 + ], + [ + "PUPDR3", + 6, + 2 + ], + [ + "PUPDR2", + 4, + 2 + ], + [ + "PUPDR1", + 2, + 2 + ], + [ + "PUPDR0", + 0, + 2 + ] + ] + }, + { + "name": "IDR", + "offset": "0x10", + "fields": [ + [ + "IDR15", + 15, + 1, + "r" + ], + [ + "IDR14", + 14, + 1, + "r" + ], + [ + "IDR13", + 13, + 1, + "r" + ], + [ + "IDR12", + 12, + 1, + "r" + ], + [ + "IDR11", + 11, + 1, + "r" + ], + [ + "IDR10", + 10, + 1, + "r" + ], + [ + "IDR9", + 9, + 1, + "r" + ], + [ + "IDR8", + 8, + 1, + "r" + ], + [ + "IDR7", + 7, + 1, + "r" + ], + [ + "IDR6", + 6, + 1, + "r" + ], + [ + "IDR5", + 5, + 1, + "r" + ], + [ + "IDR4", + 4, + 1, + "r" + ], + [ + "IDR3", + 3, + 1, + "r" + ], + [ + "IDR2", + 2, + 1, + "r" + ], + [ + "IDR1", + 1, + 1, + "r" + ], + [ + "IDR0", + 0, + 1, + "r" + ] + ] + }, + { + "name": "ODR", + "offset": "0x14", + "fields": [ + [ + "ODR15", + 15, + 1 + ], + [ + "ODR14", + 14, + 1 + ], + [ + "ODR13", + 13, + 1 + ], + [ + "ODR12", + 12, + 1 + ], + [ + "ODR11", + 11, + 1 + ], + [ + "ODR10", + 10, + 1 + ], + [ + "ODR9", + 9, + 1 + ], + [ + "ODR8", + 8, + 1 + ], + [ + "ODR7", + 7, + 1 + ], + [ + "ODR6", + 6, + 1 + ], + [ + "ODR5", + 5, + 1 + ], + [ + "ODR4", + 4, + 1 + ], + [ + "ODR3", + 3, + 1 + ], + [ + "ODR2", + 2, + 1 + ], + [ + "ODR1", + 1, + 1 + ], + [ + "ODR0", + 0, + 1 + ] + ] + }, + { + "name": "BSRR", + "offset": "0x18", + "fields": [ + [ + "BR15", + 31, + 1, + "w" + ], + [ + "BR14", + 30, + 1, + "w" + ], + [ + "BR13", + 29, + 1, + "w" + ], + [ + "BR12", + 28, + 1, + "w" + ], + [ + "BR11", + 27, + 1, + "w" + ], + [ + "BR10", + 26, + 1, + "w" + ], + [ + "BR9", + 25, + 1, + "w" + ], + [ + "BR8", + 24, + 1, + "w" + ], + [ + "BR7", + 23, + 1, + "w" + ], + [ + "BR6", + 22, + 1, + "w" + ], + [ + "BR5", + 21, + 1, + "w" + ], + [ + "BR4", + 20, + 1, + "w" + ], + [ + "BR3", + 19, + 1, + "w" + ], + [ + "BR2", + 18, + 1, + "w" + ], + [ + "BR1", + 17, + 1, + "w" + ], + [ + "BR0", + 16, + 1, + "w" + ], + [ + "BS15", + 15, + 1, + "w" + ], + [ + "BS14", + 14, + 1, + "w" + ], + [ + "BS13", + 13, + 1, + "w" + ], + [ + "BS12", + 12, + 1, + "w" + ], + [ + "BS11", + 11, + 1, + "w" + ], + [ + "BS10", + 10, + 1, + "w" + ], + [ + "BS9", + 9, + 1, + "w" + ], + [ + "BS8", + 8, + 1, + "w" + ], + [ + "BS7", + 7, + 1, + "w" + ], + [ + "BS6", + 6, + 1, + "w" + ], + [ + "BS5", + 5, + 1, + "w" + ], + [ + "BS4", + 4, + 1, + "w" + ], + [ + "BS3", + 3, + 1, + "w" + ], + [ + "BS2", + 2, + 1, + "w" + ], + [ + "BS1", + 1, + 1, + "w" + ], + [ + "BS0", + 0, + 1, + "w" + ] + ] + }, + { + "name": "LCKR", + "offset": "0x1C", + "fields": [ + [ + "LCKK", + 16, + 1 + ], + [ + "LCK15", + 15, + 1 + ], + [ + "LCK14", + 14, + 1 + ], + [ + "LCK13", + 13, + 1 + ], + [ + "LCK12", + 12, + 1 + ], + [ + "LCK11", + 11, + 1 + ], + [ + "LCK10", + 10, + 1 + ], + [ + "LCK9", + 9, + 1 + ], + [ + "LCK8", + 8, + 1 + ], + [ + "LCK7", + 7, + 1 + ], + [ + "LCK6", + 6, + 1 + ], + [ + "LCK5", + 5, + 1 + ], + [ + "LCK4", + 4, + 1 + ], + [ + "LCK3", + 3, + 1 + ], + [ + "LCK2", + 2, + 1 + ], + [ + "LCK1", + 1, + 1 + ], + [ + "LCK0", + 0, + 1 + ] + ] + }, + { + "name": "AFRL", + "offset": "0x20", + "fields": [ + [ + "AFRL7", + 28, + 4 + ], + [ + "AFRL6", + 24, + 4 + ], + [ + "AFRL5", + 20, + 4 + ], + [ + "AFRL4", + 16, + 4 + ], + [ + "AFRL3", + 12, + 4 + ], + [ + "AFRL2", + 8, + 4 + ], + [ + "AFRL1", + 4, + 4 + ], + [ + "AFRL0", + 0, + 4 + ] + ] + }, + { + "name": "AFRH", + "offset": "0x24", + "fields": [ + [ + "AFRH15", + 28, + 4 + ], + [ + "AFRH14", + 24, + 4 + ], + [ + "AFRH13", + 20, + 4 + ], + [ + "AFRH12", + 16, + 4 + ], + [ + "AFRH11", + 12, + 4 + ], + [ + "AFRH10", + 8, + 4 + ], + [ + "AFRH9", + 4, + 4 + ], + [ + "AFRH8", + 0, + 4 + ] + ] + }, + { + "name": "BRR", + "offset": "0x28", + "fields": [ + [ + "BR0", + 0, + 1, + "w" + ], + [ + "BR1", + 1, + 1, + "w" + ], + [ + "BR2", + 2, + 1, + "w" + ], + [ + "BR3", + 3, + 1, + "w" + ], + [ + "BR4", + 4, + 1, + "w" + ], + [ + "BR5", + 5, + 1, + "w" + ], + [ + "BR6", + 6, + 1, + "w" + ], + [ + "BR7", + 7, + 1, + "w" + ], + [ + "BR8", + 8, + 1, + "w" + ], + [ + "BR9", + 9, + 1, + "w" + ], + [ + "BR10", + 10, + 1, + "w" + ], + [ + "BR11", + 11, + 1, + "w" + ], + [ + "BR12", + 12, + 1, + "w" + ], + [ + "BR13", + 13, + 1, + "w" + ], + [ + "BR14", + 14, + 1, + "w" + ], + [ + "BR15", + 15, + 1, + "w" + ] + ] + } + ] + }, + { + "name": "GPIOD", + "base": "0x48000C00", + "derived_from": "GPIOC" + }, + { + "name": "GPIOE", + "base": "0x48001000", + "derived_from": "GPIOC" + }, + { + "name": "GPIOF", + "base": "0x48001400", + "derived_from": "GPIOC" + }, + { + "name": "GPIOG", + "base": "0x48001800", + "derived_from": "GPIOC" + }, + { + "name": "ADC1", + "base": "0x50000000", + "interrupts": [ + "ADC1_2" + ], + "registers": [ + { + "name": "ISR", + "offset": "0x00", + "fields": [ + [ + "JQOVF", + 10, + 1 + ], + [ + "AWD3", + 9, + 1 + ], + [ + "AWD2", + 8, + 1 + ], + [ + "AWD1", + 7, + 1 + ], + [ + "JEOS", + 6, + 1 + ], + [ + "JEOC", + 5, + 1 + ], + [ + "OVR", + 4, + 1 + ], + [ + "EOS", + 3, + 1 + ], + [ + "EOC", + 2, + 1 + ], + [ + "EOSMP", + 1, + 1 + ], + [ + "ADRDY", + 0, + 1 + ] + ] + }, + { + "name": "IER", + "offset": "0x04", + "fields": [ + [ + "JQOVFIE", + 10, + 1 + ], + [ + "AWD3IE", + 9, + 1 + ], + [ + "AWD2IE", + 8, + 1 + ], + [ + "AWD1IE", + 7, + 1 + ], + [ + "JEOSIE", + 6, + 1 + ], + [ + "JEOCIE", + 5, + 1 + ], + [ + "OVRIE", + 4, + 1 + ], + [ + "EOSIE", + 3, + 1 + ], + [ + "EOCIE", + 2, + 1 + ], + [ + "EOSMPIE", + 1, + 1 + ], + [ + "ADRDYIE", + 0, + 1 + ] + ] + }, + { + "name": "CR", + "offset": "0x08", + "reset": "0x20000000", + "fields": [ + [ + "ADCAL", + 31, + 1 + ], + [ + "ADCALDIF", + 30, + 1 + ], + [ + "DEEPPWD", + 29, + 1 + ], + [ + "ADVREGEN", + 28, + 1 + ], + [ + "JADSTP", + 5, + 1 + ], + [ + "ADSTP", + 4, + 1 + ], + [ + "JADSTART", + 3, + 1 + ], + [ + "ADSTART", + 2, + 1 + ], + [ + "ADDIS", + 1, + 1 + ], + [ + "ADEN", + 0, + 1 + ] + ] + }, + { + "name": "CFGR", + "offset": "0x0C", + "reset": "0x80000000", + "fields": [ + [ + "JQDIS", + 31, + 1 + ], + [ + "AWD1CH", + 26, + 5 + ], + [ + "JAUTO", + 25, + 1 + ], + [ + "JAWD1EN", + 24, + 1 + ], + [ + "AWD1EN", + 23, + 1 + ], + [ + "AWD1SGL", + 22, + 1 + ], + [ + "JQM", + 21, + 1 + ], + [ + "JDISCEN", + 20, + 1 + ], + [ + "DISCNUM", + 17, + 3 + ], + [ + "DISCEN", + 16, + 1 + ], + [ + "ALIGN", + 15, + 1 + ], + [ + "AUTDLY", + 14, + 1 + ], + [ + "CONT", + 13, + 1 + ], + [ + "OVRMOD", + 12, + 1 + ], + [ + "EXTEN", + 10, + 2 + ], + [ + "EXTSEL", + 5, + 5 + ], + [ + "RES", + 3, + 2 + ], + [ + "DMACFG", + 1, + 1 + ], + [ + "DMAEN", + 0, + 1 + ] + ] + }, + { + "name": "CFGR2", + "offset": "0x10", + "fields": [ + [ + "SMPTRIG", + 27, + 1 + ], + [ + "BULB", + 26, + 1 + ], + [ + "SWTRIG", + 25, + 1 + ], + [ + "GCOMP", + 16, + 1 + ], + [ + "ROVSM", + 10, + 1 + ], + [ + "TROVS", + 9, + 1 + ], + [ + "OVSS", + 5, + 4 + ], + [ + "OVSR", + 2, + 3 + ], + [ + "JOVSE", + 1, + 1 + ], + [ + "ROVSE", + 0, + 1 + ] + ] + }, + { + "name": "SMPR1", + "offset": "0x14", + "fields": [ + [ + "SMP9", + 27, + 3 + ], + [ + "SMP8", + 24, + 3 + ], + [ + "SMP7", + 21, + 3 + ], + [ + "SMP6", + 18, + 3 + ], + [ + "SMP5", + 15, + 3 + ], + [ + "SMP4", + 12, + 3 + ], + [ + "SMP3", + 9, + 3 + ], + [ + "SMP2", + 6, + 3 + ], + [ + "SMP1", + 3, + 3 + ], + [ + "SMPPLUS", + 31, + 1 + ], + [ + "SMP0", + 0, + 3 + ] + ] + }, + { + "name": "SMPR2", + "offset": "0x18", + "fields": [ + [ + "SMP18", + 24, + 3 + ], + [ + "SMP17", + 21, + 3 + ], + [ + "SMP16", + 18, + 3 + ], + [ + "SMP15", + 15, + 3 + ], + [ + "SMP14", + 12, + 3 + ], + [ + "SMP13", + 9, + 3 + ], + [ + "SMP12", + 6, + 3 + ], + [ + "SMP11", + 3, + 3 + ], + [ + "SMP10", + 0, + 3 + ] + ] + }, + { + "name": "TR1", + "offset": "0x20", + "reset": "0x0FFF0000", + "fields": [ + [ + "HT1", + 16, + 12 + ], + [ + "AWDFILT", + 12, + 3 + ], + [ + "LT1", + 0, + 12 + ] + ] + }, + { + "name": "TR2", + "offset": "0x24", + "reset": "0x00FF0000", + "fields": [ + [ + "HT2", + 16, + 8 + ], + [ + "LT2", + 0, + 8 + ] + ] + }, + { + "name": "TR3", + "offset": "0x28", + "reset": "0x00FF0000", + "fields": [ + [ + "HT3", + 16, + 8 + ], + [ + "LT3", + 0, + 8 + ] + ] + }, + { + "name": "SQR1", + "offset": "0x30", + "fields": [ + [ + "SQ4", + 24, + 5 + ], + [ + "SQ3", + 18, + 5 + ], + [ + "SQ2", + 12, + 5 + ], + [ + "SQ1", + 6, + 5 + ], + [ + "L", + 0, + 4 + ] + ] + }, + { + "name": "SQR2", + "offset": "0x34", + "fields": [ + [ + "SQ9", + 24, + 5 + ], + [ + "SQ8", + 18, + 5 + ], + [ + "SQ7", + 12, + 5 + ], + [ + "SQ6", + 6, + 5 + ], + [ + "SQ5", + 0, + 5 + ] + ] + }, + { + "name": "SQR3", + "offset": "0x38", + "fields": [ + [ + "SQ14", + 24, + 5 + ], + [ + "SQ13", + 18, + 5 + ], + [ + "SQ12", + 12, + 5 + ], + [ + "SQ11", + 6, + 5 + ], + [ + "SQ10", + 0, + 5 + ] + ] + }, + { + "name": "SQR4", + "offset": "0x3C", + "fields": [ + [ + "SQ16", + 6, + 5 + ], + [ + "SQ15", + 0, + 5 + ] + ] + }, + { + "name": "DR", + "offset": "0x40", + "fields": [ + [ + "RDATA", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JSQR", + "offset": "0x4C", + "fields": [ + [ + "JSQ4", + 27, + 5 + ], + [ + "JSQ3", + 21, + 5 + ], + [ + "JSQ2", + 15, + 5 + ], + [ + "JSQ1", + 9, + 5 + ], + [ + "JEXTEN", + 7, + 2 + ], + [ + "JEXTSEL", + 2, + 5 + ], + [ + "JL", + 0, + 2 + ] + ] + }, + { + "name": "OFR1", + "offset": "0x60", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "OFR2", + "offset": "0x64", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "OFR3", + "offset": "0x68", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "OFR4", + "offset": "0x6C", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "JDR1", + "offset": "0x80", + "fields": [ + [ + "JDATA1", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JDR2", + "offset": "0x84", + "fields": [ + [ + "JDATA2", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JDR3", + "offset": "0x88", + "fields": [ + [ + "JDATA3", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JDR4", + "offset": "0x8C", + "fields": [ + [ + "JDATA4", + 0, + 16, + "r" + ] + ] + }, + { + "name": "AWD2CR", + "offset": "0xA0", + "fields": [ + [ + "AWD2CH", + 0, + 19 + ] + ] + }, + { + "name": "AWD3CR", + "offset": "0xA4", + "fields": [ + [ + "AWD3CH", + 0, + 19 + ] + ] + }, + { + "name": "DIFSEL", + "offset": "0xB0", + "fields": [ + [ + "DIFSEL_0", + 0, + 1, + "r" + ], + [ + "DIFSEL_1_18", + 1, + 18 + ] + ] + }, + { + "name": "CALFACT", + "offset": "0xB4", + "fields": [ + [ + "CALFACT_D", + 16, + 7 + ], + [ + "CALFACT_S", + 0, + 7 + ] + ] + }, + { + "name": "GCOMP", + "offset": "0xC0", + "fields": [ + [ + "GCOMPCOEFF", + 0, + 14 + ] + ] + } + ] + }, + { + "name": "ADC2", + "base": "0x50000100", + "derived_from": "ADC1", + "interrupts": [ + "ADC1_2" + ] + }, + { + "name": "ADC12_Common", + "base": "0x50000300", + "registers": [ + { + "name": "CSR", + "offset": "0x00", + "fields": [ + [ + "ADDRDY_MST", + 0, + 1, + "r" + ], + [ + "EOSMP_MST", + 1, + 1, + "r" + ], + [ + "EOC_MST", + 2, + 1, + "r" + ], + [ + "EOS_MST", + 3, + 1, + "r" + ], + [ + "OVR_MST", + 4, + 1, + "r" + ], + [ + "JEOC_MST", + 5, + 1, + "r" + ], + [ + "JEOS_MST", + 6, + 1, + "r" + ], + [ + "AWD1_MST", + 7, + 1, + "r" + ], + [ + "AWD2_MST", + 8, + 1, + "r" + ], + [ + "AWD3_MST", + 9, + 1, + "r" + ], + [ + "JQOVF_MST", + 10, + 1, + "r" + ], + [ + "ADRDY_SLV", + 16, + 1, + "r" + ], + [ + "EOSMP_SLV", + 17, + 1, + "r" + ], + [ + "EOC_SLV", + 18, + 1, + "r" + ], + [ + "EOS_SLV", + 19, + 1, + "r" + ], + [ + "OVR_SLV", + 20, + 1, + "r" + ], + [ + "JEOC_SLV", + 21, + 1, + "r" + ], + [ + "JEOS_SLV", + 22, + 1, + "r" + ], + [ + "AWD1_SLV", + 23, + 1, + "r" + ], + [ + "AWD2_SLV", + 24, + 1, + "r" + ], + [ + "AWD3_SLV", + 25, + 1, + "r" + ], + [ + "JQOVF_SLV", + 26, + 1, + "r" + ] + ] + }, + { + "name": "CCR", + "offset": "0x08", + "fields": [ + [ + "DUAL", + 0, + 5 + ], + [ + "DELAY", + 8, + 4 + ], + [ + "DMACFG", + 13, + 1 + ], + [ + "MDMA", + 14, + 2 + ], + [ + "CKMODE", + 16, + 2 + ], + [ + "VREFEN", + 22, + 1 + ], + [ + "VSENSESEL", + 23, + 1 + ], + [ + "VBATSEL", + 24, + 1 + ], + [ + "PRESC", + 18, + 4 + ] + ] + }, + { + "name": "CDR", + "offset": "0x0C", + "fields": [ + [ + "RDATA_SLV", + 16, + 16, + "r" + ], + [ + "RDATA_MST", + 0, + 16, + "r" + ] + ] + } + ] + }, + { + "name": "ADC3", + "base": "0x50000400", + "interrupts": [ + "ADC3" + ], + "registers": [ + { + "name": "ISR", + "offset": "0x00", + "fields": [ + [ + "JQOVF", + 10, + 1 + ], + [ + "AWD3", + 9, + 1 + ], + [ + "AWD2", + 8, + 1 + ], + [ + "AWD1", + 7, + 1 + ], + [ + "JEOS", + 6, + 1 + ], + [ + "JEOC", + 5, + 1 + ], + [ + "OVR", + 4, + 1 + ], + [ + "EOS", + 3, + 1 + ], + [ + "EOC", + 2, + 1 + ], + [ + "EOSMP", + 1, + 1 + ], + [ + "ADRDY", + 0, + 1 + ] + ] + }, + { + "name": "IER", + "offset": "0x04", + "fields": [ + [ + "JQOVFIE", + 10, + 1 + ], + [ + "AWD3IE", + 9, + 1 + ], + [ + "AWD2IE", + 8, + 1 + ], + [ + "AWD1IE", + 7, + 1 + ], + [ + "JEOSIE", + 6, + 1 + ], + [ + "JEOCIE", + 5, + 1 + ], + [ + "OVRIE", + 4, + 1 + ], + [ + "EOSIE", + 3, + 1 + ], + [ + "EOCIE", + 2, + 1 + ], + [ + "EOSMPIE", + 1, + 1 + ], + [ + "ADRDYIE", + 0, + 1 + ] + ] + }, + { + "name": "CR", + "offset": "0x08", + "reset": "0x20002000", + "fields": [ + [ + "ADCAL", + 31, + 1 + ], + [ + "ADCALDIF", + 30, + 1 + ], + [ + "DEEPPWD", + 29, + 1 + ], + [ + "ADVREGEN", + 28, + 1 + ], + [ + "JADSTP", + 5, + 1 + ], + [ + "ADSTP", + 4, + 1 + ], + [ + "JADSTART", + 3, + 1 + ], + [ + "ADSTART", + 2, + 1 + ], + [ + "ADDIS", + 1, + 1 + ], + [ + "ADEN", + 0, + 1 + ] + ] + }, + { + "name": "CFGR", + "offset": "0x0C", + "reset": "0x80000000", + "fields": [ + [ + "JQDIS", + 31, + 1 + ], + [ + "AWDCH1CH", + 26, + 5 + ], + [ + "JAUTO", + 25, + 1 + ], + [ + "JAWD1EN", + 24, + 1 + ], + [ + "AWD1EN", + 23, + 1 + ], + [ + "AWD1SGL", + 22, + 1 + ], + [ + "JQM", + 21, + 1 + ], + [ + "JDISCEN", + 20, + 1 + ], + [ + "DISCNUM", + 17, + 3 + ], + [ + "DISCEN", + 16, + 1 + ], + [ + "ALIGN", + 15, + 1 + ], + [ + "AUTDLY", + 14, + 1 + ], + [ + "CONT", + 13, + 1 + ], + [ + "OVRMOD", + 12, + 1 + ], + [ + "EXTEN", + 10, + 2 + ], + [ + "EXTSEL", + 5, + 5 + ], + [ + "RES", + 3, + 2 + ], + [ + "DMACFG", + 1, + 1 + ], + [ + "DMAEN", + 0, + 1 + ] + ] + }, + { + "name": "CFGR2", + "offset": "0x10", + "fields": [ + [ + "SMPTRIG", + 27, + 1 + ], + [ + "BULB", + 26, + 1 + ], + [ + "SWTRIG", + 25, + 1 + ], + [ + "GCOMP", + 16, + 1 + ], + [ + "ROVSM", + 10, + 1 + ], + [ + "TROVS", + 9, + 1 + ], + [ + "OVSS", + 5, + 4 + ], + [ + "OVSR", + 2, + 3 + ], + [ + "JOVSE", + 1, + 1 + ], + [ + "ROVSE", + 0, + 1 + ] + ] + }, + { + "name": "SMPR1", + "offset": "0x14", + "fields": [ + [ + "SMP9", + 27, + 3 + ], + [ + "SMP8", + 24, + 3 + ], + [ + "SMP7", + 21, + 3 + ], + [ + "SMP6", + 18, + 3 + ], + [ + "SMP5", + 15, + 3 + ], + [ + "SMP4", + 12, + 3 + ], + [ + "SMP3", + 9, + 3 + ], + [ + "SMP2", + 6, + 3 + ], + [ + "SMP1", + 3, + 3 + ], + [ + "SMPPLUS", + 31, + 1 + ], + [ + "SMP0", + 0, + 3 + ] + ] + }, + { + "name": "SMPR2", + "offset": "0x18", + "fields": [ + [ + "SMP18", + 24, + 3 + ], + [ + "SMP17", + 21, + 3 + ], + [ + "SMP16", + 18, + 3 + ], + [ + "SMP15", + 15, + 3 + ], + [ + "SMP14", + 12, + 3 + ], + [ + "SMP13", + 9, + 3 + ], + [ + "SMP12", + 6, + 3 + ], + [ + "SMP11", + 3, + 3 + ], + [ + "SMP10", + 0, + 3 + ] + ] + }, + { + "name": "TR1", + "offset": "0x20", + "reset": "0x0FFF0000", + "fields": [ + [ + "HT1", + 16, + 12 + ], + [ + "AWDFILT", + 12, + 3 + ], + [ + "LT1", + 0, + 12 + ] + ] + }, + { + "name": "TR2", + "offset": "0x24", + "reset": "0x00FF0000", + "fields": [ + [ + "HT2", + 16, + 8 + ], + [ + "LT2", + 0, + 8 + ] + ] + }, + { + "name": "TR3", + "offset": "0x28", + "reset": "0x00FF0000", + "fields": [ + [ + "HT3", + 16, + 8 + ], + [ + "LT3", + 0, + 8 + ] + ] + }, + { + "name": "SQR1", + "offset": "0x30", + "fields": [ + [ + "SQ4", + 24, + 5 + ], + [ + "SQ3", + 18, + 5 + ], + [ + "SQ2", + 12, + 5 + ], + [ + "SQ1", + 6, + 5 + ], + [ + "L", + 0, + 4 + ] + ] + }, + { + "name": "SQR2", + "offset": "0x34", + "fields": [ + [ + "SQ9", + 24, + 5 + ], + [ + "SQ8", + 18, + 5 + ], + [ + "SQ7", + 12, + 5 + ], + [ + "SQ6", + 6, + 5 + ], + [ + "SQ5", + 0, + 5 + ] + ] + }, + { + "name": "SQR3", + "offset": "0x38", + "fields": [ + [ + "SQ14", + 24, + 5 + ], + [ + "SQ13", + 18, + 5 + ], + [ + "SQ12", + 12, + 5 + ], + [ + "SQ11", + 6, + 5 + ], + [ + "SQ10", + 0, + 5 + ] + ] + }, + { + "name": "SQR4", + "offset": "0x3C", + "fields": [ + [ + "SQ16", + 6, + 5 + ], + [ + "SQ15", + 0, + 5 + ] + ] + }, + { + "name": "DR", + "offset": "0x40", + "fields": [ + [ + "RDATA", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JSQR", + "offset": "0x4C", + "fields": [ + [ + "JSQ4", + 27, + 5 + ], + [ + "JSQ3", + 21, + 5 + ], + [ + "JSQ2", + 15, + 5 + ], + [ + "JSQ1", + 9, + 5 + ], + [ + "JEXTEN", + 7, + 2 + ], + [ + "JEXTSEL", + 2, + 5 + ], + [ + "JL", + 0, + 2 + ] + ] + }, + { + "name": "OFR1", + "offset": "0x60", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "OFR2", + "offset": "0x64", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "OFR3", + "offset": "0x68", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "OFR4", + "offset": "0x6C", + "fields": [ + [ + "OFFSET1_EN", + 31, + 1 + ], + [ + "OFFSET1_CH", + 26, + 5 + ], + [ + "SATEN", + 25, + 1 + ], + [ + "OFFSETPOS", + 24, + 1 + ], + [ + "OFFSET1", + 0, + 12 + ] + ] + }, + { + "name": "JDR1", + "offset": "0x80", + "fields": [ + [ + "JDATA1", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JDR2", + "offset": "0x84", + "fields": [ + [ + "JDATA2", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JDR3", + "offset": "0x88", + "fields": [ + [ + "JDATA3", + 0, + 16, + "r" + ] + ] + }, + { + "name": "JDR4", + "offset": "0x8C", + "fields": [ + [ + "JDATA4", + 0, + 16, + "r" + ] + ] + }, + { + "name": "AWD2CR", + "offset": "0xA0", + "fields": [ + [ + "AWD2CH", + 0, + 19 + ] + ] + }, + { + "name": "AWD3CR", + "offset": "0xA4", + "fields": [ + [ + "AWD3CH", + 0, + 19 + ] + ] + }, + { + "name": "DIFSEL", + "offset": "0xB0", + "fields": [ + [ + "DIFSEL_0", + 0, + 1, + "r" + ], + [ + "DIFSEL_1_18", + 1, + 18 + ] + ] + }, + { + "name": "CALFACT", + "offset": "0xB4", + "fields": [ + [ + "CALFACT_D", + 16, + 7 + ], + [ + "CALFACT_S", + 0, + 7 + ] + ] + }, + { + "name": "GCOMP", + "offset": "0xC0", + "fields": [ + [ + "GCOMPCOEFF", + 0, + 14 + ] + ] + } + ] + }, + { + "name": "ADC4", + "base": "0x50000500", + "interrupts": [ + "ADC4" + ], + "derived_from": "ADC1" + }, + { + "name": "ADC5", + "base": "0x50000600", + "interrupts": [ + "ADC5" + ], + "derived_from": "ADC3" + }, + { + "name": "ADC345_Common", + "base": "0x50000700", + "derived_from": "ADC12_Common" + }, + { + "name": "DAC1", + "base": "0x50000800", + "registers": [ + { + "name": "CR", + "offset": "0x00", + "fields": [ + [ + "EN1", + 0, + 1 + ], + [ + "TEN1", + 1, + 1 + ], + [ + "TSEL1", + 2, + 4 + ], + [ + "WAVE1", + 6, + 2 + ], + [ + "MAMP1", + 8, + 4 + ], + [ + "DMAEN1", + 12, + 1 + ], + [ + "DMAUDRIE1", + 13, + 1 + ], + [ + "CEN1", + 14, + 1 + ], + [ + "EN2", + 16, + 1 + ], + [ + "TEN2", + 17, + 1 + ], + [ + "TSEL2", + 18, + 4 + ], + [ + "WAVE2", + 22, + 2 + ], + [ + "MAMP2", + 24, + 4 + ], + [ + "DMAEN2", + 28, + 1 + ], + [ + "DMAUDRIE2", + 29, + 1 + ], + [ + "CEN2", + 30, + 1 + ] + ] + }, + { + "name": "SWTRGR", + "offset": "0x04", + "fields": [ + [ + "SWTRIG1", + 0, + 1, + "w" + ], + [ + "SWTRIG2", + 1, + 1, + "w" + ], + [ + "SWTRIGB1", + 16, + 1, + "w" + ], + [ + "SWTRIGB2", + 17, + 1, + "w" + ] + ] + }, + { + "name": "DHR12R1", + "offset": "0x08", + "fields": [ + [ + "DACC1DHR", + 0, + 12 + ], + [ + "DACC1DHRB", + 16, + 12 + ] + ] + }, + { + "name": "DHR12L1", + "offset": "0x0C", + "fields": [ + [ + "DACC1DHR", + 4, + 12 + ], + [ + "DACC1DHRB", + 20, + 12 + ] + ] + }, + { + "name": "DHR8R1", + "offset": "0x10", + "fields": [ + [ + "DACC1DHR", + 0, + 8 + ], + [ + "DACC1DHRB", + 8, + 8 + ] + ] + }, + { + "name": "DHR12R2", + "offset": "0x14", + "fields": [ + [ + "DACC2DHR", + 0, + 12 + ], + [ + "DACC2DHRB", + 16, + 12 + ] + ] + }, + { + "name": "DHR12L2", + "offset": "0x18", + "fields": [ + [ + "DACC2DHR", + 4, + 12 + ], + [ + "DACC2DHRB", + 20, + 12 + ] + ] + }, + { + "name": "DHR8R2", + "offset": "0x1C", + "fields": [ + [ + "DACC2DHR", + 0, + 8 + ], + [ + "DACC2DHRB", + 8, + 8 + ] + ] + }, + { + "name": "DHR12RD", + "offset": "0x20", + "fields": [ + [ + "DACC1DHR", + 0, + 12 + ], + [ + "DACC2DHR", + 16, + 12 + ] + ] + }, + { + "name": "DHR12LD", + "offset": "0x24", + "fields": [ + [ + "DACC1DHR", + 4, + 12 + ], + [ + "DACC2DHR", + 20, + 12 + ] + ] + }, + { + "name": "DHR8RD", + "offset": "0x28", + "fields": [ + [ + "DACC1DHR", + 0, + 8 + ], + [ + "DACC2DHR", + 8, + 8 + ] + ] + }, + { + "name": "DOR1", + "offset": "0x2C", + "fields": [ + [ + "DACC1DOR", + 0, + 12, + "r" + ], + [ + "DACC1DORB", + 16, + 12, + "r" + ] + ] + }, + { + "name": "DOR2", + "offset": "0x30", + "fields": [ + [ + "DACC2DOR", + 0, + 12, + "r" + ], + [ + "DACC2DORB", + 16, + 12, + "r" + ] + ] + }, + { + "name": "SR", + "offset": "0x34", + "fields": [ + [ + "DAC1RDY", + 11, + 1 + ], + [ + "DORSTAT1", + 12, + 1 + ], + [ + "DMAUDR1", + 13, + 1 + ], + [ + "CAL_FLAG1", + 14, + 1, + "r" + ], + [ + "BWST1", + 15, + 1, + "r" + ], + [ + "DAC2RDY", + 27, + 1 + ], + [ + "DORSTAT2", + 28, + 1 + ], + [ + "DMAUDR2", + 29, + 1 + ], + [ + "CAL_FLAG2", + 30, + 1, + "r" + ], + [ + "BWST2", + 31, + 1, + "r" + ] + ] + }, + { + "name": "CCR", + "offset": "0x38", + "fields": [ + [ + "OTRIM1", + 0, + 5 + ], + [ + "OTRIM2", + 16, + 5 + ] + ] + }, + { + "name": "MCR", + "offset": "0x3C", + "fields": [ + [ + "MODE1", + 0, + 3 + ], + [ + "DMADOUBLE1", + 8, + 1 + ], + [ + "SINFORMAT1", + 9, + 1 + ], + [ + "HFSEL", + 14, + 2 + ], + [ + "MODE2", + 16, + 3 + ], + [ + "DMADOUBLE2", + 24, + 1 + ], + [ + "SINFORMAT2", + 25, + 1 + ] + ] + }, + { + "name": "SHSR1", + "offset": "0x40", + "fields": [ + [ + "TSAMPLE1", + 0, + 10 + ] + ] + }, + { + "name": "SHSR2", + "offset": "0x44", + "fields": [ + [ + "TSAMPLE2", + 0, + 10 + ] + ] + }, + { + "name": "SHHR", + "offset": "0x48", + "reset": "0x00010001", + "fields": [ + [ + "THOLD1", + 0, + 10 + ], + [ + "THOLD2", + 16, + 10 + ] + ] + }, + { + "name": "SHRR", + "offset": "0x4C", + "reset": "0x00010001", + "fields": [ + [ + "TREFRESH1", + 0, + 8 + ], + [ + "TREFRESH2", + 16, + 8 + ] + ] + }, + { + "name": "STR1", + "offset": "0x58", + "fields": [ + [ + "STRSTDATA1", + 0, + 12 + ], + [ + "STDIR1", + 12, + 1 + ], + [ + "STINCDATA1", + 16, + 16 + ] + ] + }, + { + "name": "STR2", + "offset": "0x5C", + "fields": [ + [ + "STRSTDATA2", + 0, + 12 + ], + [ + "STDIR2", + 12, + 1 + ], + [ + "STINCDATA2", + 16, + 16 + ] + ] + }, + { + "name": "STMODR", + "offset": "0x60", + "fields": [ + [ + "STRSTTRIGSEL1", + 0, + 4 + ], + [ + "STINCTRIGSEL1", + 8, + 4 + ], + [ + "STRSTTRIGSEL2", + 16, + 4 + ], + [ + "STINCTRIGSEL2", + 24, + 4 + ] + ] + } + ], + "interrupts": [ + "TIM6_DACUNDER" + ] + }, + { + "name": "DAC2", + "base": "0x50000C00", + "derived_from": "DAC1", + "interrupts": [ + "TIM7" + ] + }, + { + "name": "DAC3", + "base": "0x50001000", + "derived_from": "DAC1", + "interrupts": [ + "TIM6_DACUNDER" + ] + }, + { + "name": "DAC4", + "base": "0x50001400", + "derived_from": "DAC1", + "interrupts": [ + "TIM7" + ] + }, + { + "name": "RNG", + "base": "0x50060800", + "interrupts": [ + "RNG" + ], + "registers": [ + { + "name": "CR", + "offset": "0x00", + "fields": [ + [ + "CED", + 5, + 1 + ], + [ + "IE", + 3, + 1 + ], + [ + "RNGEN", + 2, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x04", + "fields": [ + [ + "SEIS", + 6, + 1 + ], + [ + "CEIS", + 5, + 1 + ], + [ + "SECS", + 2, + 1, + "r" + ], + [ + "CECS", + 1, + 1, + "r" + ], + [ + "DRDY", + 0, + 1, + "r" + ] + ] + }, + { + "name": "DR", + "offset": "0x08", + "fields": [ + [ + "RNDATA", + 0, + 32, + "r" + ] + ] + } + ] + }, + { + "name": "FMC", + "base": "0xA0000000", + "interrupts": [ + "FMC" + ], + "registers": [ + { + "name": "BCR1", + "offset": "0x00", + "reset": "0x000030D0", + "fields": [ + [ + "MBKEN", + 0, + 1 + ], + [ + "MUXEN", + 1, + 1 + ], + [ + "MTYP", + 2, + 2 + ], + [ + "MWID", + 4, + 2 + ], + [ + "FACCEN", + 6, + 1 + ], + [ + "BURSTEN", + 8, + 1 + ], + [ + "WAITPOL", + 9, + 1 + ], + [ + "WAITCFG", + 11, + 1 + ], + [ + "WREN", + 12, + 1 + ], + [ + "WAITEN", + 13, + 1 + ], + [ + "EXTMOD", + 14, + 1 + ], + [ + "ASYNCWAIT", + 15, + 1 + ], + [ + "CPSIZE", + 16, + 3 + ], + [ + "CBURSTRW", + 19, + 1 + ], + [ + "CCLKEN", + 20, + 1 + ], + [ + "WFDIS", + 21, + 1 + ], + [ + "NBLSET", + 22, + 2 + ] + ] + }, + { + "name": "BTR1", + "offset": "0x04", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "DATLAT", + 24, + 4 + ], + [ + "CLKDIV", + 20, + 4 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + }, + { + "name": "BCR2", + "offset": "0x08", + "reset": "0x000030D0", + "fields": [ + [ + "MBKEN", + 0, + 1 + ], + [ + "MUXEN", + 1, + 1 + ], + [ + "MTYP", + 2, + 2 + ], + [ + "MWID", + 4, + 2 + ], + [ + "FACCEN", + 6, + 1 + ], + [ + "BURSTEN", + 8, + 1 + ], + [ + "WAITPOL", + 9, + 1 + ], + [ + "WAITCFG", + 11, + 1 + ], + [ + "WREN", + 12, + 1 + ], + [ + "WAITEN", + 13, + 1 + ], + [ + "EXTMOD", + 14, + 1 + ], + [ + "ASYNCWAIT", + 15, + 1 + ], + [ + "CPSIZE", + 16, + 3 + ], + [ + "CBURSTRW", + 19, + 1 + ], + [ + "CCLKEN", + 20, + 1 + ], + [ + "WFDIS", + 21, + 1 + ], + [ + "NBLSET", + 22, + 2 + ] + ] + }, + { + "name": "BTR2", + "offset": "0x0C", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "DATLAT", + 24, + 4 + ], + [ + "CLKDIV", + 20, + 4 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + }, + { + "name": "BCR3", + "offset": "0x10", + "reset": "0x000030D0", + "fields": [ + [ + "MBKEN", + 0, + 1 + ], + [ + "MUXEN", + 1, + 1 + ], + [ + "MTYP", + 2, + 2 + ], + [ + "MWID", + 4, + 2 + ], + [ + "FACCEN", + 6, + 1 + ], + [ + "BURSTEN", + 8, + 1 + ], + [ + "WAITPOL", + 9, + 1 + ], + [ + "WAITCFG", + 11, + 1 + ], + [ + "WREN", + 12, + 1 + ], + [ + "WAITEN", + 13, + 1 + ], + [ + "EXTMOD", + 14, + 1 + ], + [ + "ASYNCWAIT", + 15, + 1 + ], + [ + "CPSIZE", + 16, + 3 + ], + [ + "CBURSTRW", + 19, + 1 + ], + [ + "CCLKEN", + 20, + 1 + ], + [ + "WFDIS", + 21, + 1 + ], + [ + "NBLSET", + 22, + 2 + ] + ] + }, + { + "name": "BTR3", + "offset": "0x14", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "DATLAT", + 24, + 4 + ], + [ + "CLKDIV", + 20, + 4 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + }, + { + "name": "BCR4", + "offset": "0x18", + "reset": "0x000030D0", + "fields": [ + [ + "MBKEN", + 0, + 1 + ], + [ + "MUXEN", + 1, + 1 + ], + [ + "MTYP", + 2, + 2 + ], + [ + "MWID", + 4, + 2 + ], + [ + "FACCEN", + 6, + 1 + ], + [ + "BURSTEN", + 8, + 1 + ], + [ + "WAITPOL", + 9, + 1 + ], + [ + "WAITCFG", + 11, + 1 + ], + [ + "WREN", + 12, + 1 + ], + [ + "WAITEN", + 13, + 1 + ], + [ + "EXTMOD", + 14, + 1 + ], + [ + "ASYNCWAIT", + 15, + 1 + ], + [ + "CPSIZE", + 16, + 3 + ], + [ + "CBURSTRW", + 19, + 1 + ], + [ + "CCLKEN", + 20, + 1 + ], + [ + "WFDIS", + 21, + 1 + ], + [ + "NBLSET", + 22, + 2 + ] + ] + }, + { + "name": "BTR4", + "offset": "0x1C", + "reset": "0xFFFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "DATLAT", + 24, + 4 + ], + [ + "CLKDIV", + 20, + 4 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + }, + { + "name": "PCSCNTR", + "offset": "0x20", + "fields": [ + [ + "CSCOUNT", + 0, + 16 + ], + [ + "CNTB1EN", + 16, + 1 + ], + [ + "CNTB2EN", + 17, + 1 + ], + [ + "CNTB3EN", + 18, + 1 + ], + [ + "CNTB4EN", + 19, + 1 + ] + ] + }, + { + "name": "PCR", + "offset": "0x80", + "reset": "0x00000018", + "fields": [ + [ + "ECCPS", + 17, + 3 + ], + [ + "TAR", + 13, + 4 + ], + [ + "TCLR", + 9, + 4 + ], + [ + "ECCEN", + 6, + 1 + ], + [ + "PWID", + 4, + 2 + ], + [ + "PTYP", + 3, + 1 + ], + [ + "PBKEN", + 2, + 1 + ], + [ + "PWAITEN", + 1, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x84", + "reset": "0x00000040", + "fields": [ + [ + "FEMPT", + 6, + 1, + "r" + ], + [ + "IFEN", + 5, + 1 + ], + [ + "ILEN", + 4, + 1 + ], + [ + "IREN", + 3, + 1 + ], + [ + "IFS", + 2, + 1 + ], + [ + "ILS", + 1, + 1 + ], + [ + "IRS", + 0, + 1 + ] + ] + }, + { + "name": "PMEM", + "offset": "0x88", + "reset": "0xFCFCFCFC", + "fields": [ + [ + "MEMHIZx", + 24, + 8 + ], + [ + "MEMHOLDx", + 16, + 8 + ], + [ + "MEMWAITx", + 8, + 8 + ], + [ + "MEMSETx", + 0, + 8 + ] + ] + }, + { + "name": "PATT", + "offset": "0x8C", + "reset": "0xFCFCFCFC", + "fields": [ + [ + "ATTHIZx", + 24, + 8 + ], + [ + "ATTHOLDx", + 16, + 8 + ], + [ + "ATTWAITx", + 8, + 8 + ], + [ + "ATTSETx", + 0, + 8 + ] + ] + }, + { + "name": "ECCR", + "offset": "0x94", + "fields": [ + [ + "ECCx", + 0, + 32, + "r" + ] + ] + }, + { + "name": "BWTR1", + "offset": "0x104", + "reset": "0x0FFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + }, + { + "name": "BWTR2", + "offset": "0x10C", + "reset": "0x0FFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + }, + { + "name": "BWTR3", + "offset": "0x114", + "reset": "0x0FFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + }, + { + "name": "BWTR4", + "offset": "0x11C", + "reset": "0x0FFFFFFF", + "fields": [ + [ + "DATAHLD", + 30, + 2 + ], + [ + "ACCMOD", + 28, + 2 + ], + [ + "BUSTURN", + 16, + 4 + ], + [ + "DATAST", + 8, + 8 + ], + [ + "ADDHLD", + 4, + 4 + ], + [ + "ADDSET", + 0, + 4 + ] + ] + } + ] + }, + { + "name": "QUADSPI", + "base": "0xA0001000", + "interrupts": [ + "QUADSPI" + ], + "registers": [ + { + "name": "CR", + "offset": "0x00", + "fields": [ + [ + "PRESCALER", + 24, + 8 + ], + [ + "PMM", + 23, + 1 + ], + [ + "APMS", + 22, + 1 + ], + [ + "TOIE", + 20, + 1 + ], + [ + "SMIE", + 19, + 1 + ], + [ + "FTIE", + 18, + 1 + ], + [ + "TCIE", + 17, + 1 + ], + [ + "TEIE", + 16, + 1 + ], + [ + "FTHRES", + 8, + 4 + ], + [ + "FSEL", + 7, + 1 + ], + [ + "DFM", + 6, + 1 + ], + [ + "SSHIFT", + 4, + 1 + ], + [ + "TCEN", + 3, + 1 + ], + [ + "DMAEN", + 2, + 1 + ], + [ + "ABORT", + 1, + 1 + ], + [ + "EN", + 0, + 1 + ] + ] + }, + { + "name": "DCR", + "offset": "0x04", + "fields": [ + [ + "FSIZE", + 16, + 5 + ], + [ + "CSHT", + 8, + 3 + ], + [ + "CKMODE", + 0, + 1 + ] + ] + }, + { + "name": "SR", + "offset": "0x08", + "fields": [ + [ + "FLEVEL", + 8, + 5, + "r" + ], + [ + "BUSY", + 5, + 1, + "r" + ], + [ + "TOF", + 4, + 1, + "r" + ], + [ + "SMF", + 3, + 1, + "r" + ], + [ + "FTF", + 2, + 1, + "r" + ], + [ + "TCF", + 1, + 1, + "r" + ], + [ + "TEF", + 0, + 1, + "r" + ] + ] + }, + { + "name": "FCR", + "offset": "0x0C", + "fields": [ + [ + "CTOF", + 4, + 1 + ], + [ + "CSMF", + 3, + 1 + ], + [ + "CTCF", + 1, + 1 + ], + [ + "CTEF", + 0, + 1 + ] + ] + }, + { + "name": "DLR", + "offset": "0x10", + "fields": [ + [ + "DL", + 0, + 32 + ] + ] + }, + { + "name": "CCR", + "offset": "0x14", + "fields": [ + [ + "DDRM", + 31, + 1 + ], + [ + "SIOO", + 28, + 1 + ], + [ + "FMODE", + 26, + 2 + ], + [ + "DMODE", + 24, + 2 + ], + [ + "DCYC", + 18, + 5 + ], + [ + "ABSIZE", + 16, + 2 + ], + [ + "ABMODE", + 14, + 2 + ], + [ + "ADSIZE", + 12, + 2 + ], + [ + "ADMODE", + 10, + 2 + ], + [ + "IMODE", + 8, + 2 + ], + [ + "INSTRUCTION", + 0, + 8 + ] + ] + }, + { + "name": "AR", + "offset": "0x18", + "fields": [ + [ + "ADDRESS", + 0, + 32 + ] + ] + }, + { + "name": "ABR", + "offset": "0x1C", + "fields": [ + [ + "ALTERNATE", + 0, + 32 + ] + ] + }, + { + "name": "DR", + "offset": "0x20", + "fields": [ + [ + "DATA", + 0, + 32 + ] + ] + }, + { + "name": "PSMKR", + "offset": "0x24", + "fields": [ + [ + "MASK", + 0, + 32 + ] + ] + }, + { + "name": "PSMAR", + "offset": "0x28", + "fields": [ + [ + "MATCH", + 0, + 32 + ] + ] + }, + { + "name": "PIR", + "offset": "0x2C", + "fields": [ + [ + "INTERVAL", + 0, + 16 + ] + ] + }, + { + "name": "LPTR", + "offset": "0x30", + "fields": [ + [ + "TIMEOUT", + 0, + 16 + ] + ] + } + ] + }, + { + "name": "DBGMCU", + "base": "0xE0042000", + "registers": [ + { + "name": "IDCODE", + "offset": "0x00", + "fields": [ + [ + "REV_ID", + 16, + 16, + "r" + ], + [ + "DEV_ID", + 0, + 12, + "r" + ] + ], + "reset": "0x20016469" + }, + { + "name": "CR", + "offset": "0x04", + "fields": [ + [ + "DBG_SLEEP", + 0, + 1 + ], + [ + "DBG_STOP", + 1, + 1 + ], + [ + "DBG_STANDBY", + 2, + 1 + ], + [ + "TRACE_IOEN", + 5, + 1 + ], + [ + "TRACE_MODE", + 6, + 2 + ] + ] + }, + { + "name": "APB1L_FZ", + "offset": "0x08", + "fields": [ + [ + "DBG_TIMER2_STOP", + 0, + 1 + ], + [ + "DBG_TIM3_STOP", + 1, + 1 + ], + [ + "DBG_TIM4_STOP", + 2, + 1 + ], + [ + "DBG_TIM5_STOP", + 3, + 1 + ], + [ + "DBG_TIMER6_STOP", + 4, + 1 + ], + [ + "DBG_TIM7_STOP", + 5, + 1 + ], + [ + "DBG_RTC_STOP", + 10, + 1 + ], + [ + "DBG_WWDG_STOP", + 11, + 1 + ], + [ + "DBG_IWDG_STOP", + 12, + 1 + ], + [ + "DBG_I2C1_STOP", + 21, + 1 + ], + [ + "DBG_I2C2_STOP", + 22, + 1 + ], + [ + "DBG_I2C3_STOP", + 30, + 1 + ], + [ + "DBG_LPTIMER_STOP", + 31, + 1 + ] + ] + }, + { + "name": "APB1H_FZ", + "offset": "0x0C", + "fields": [ + [ + "DBG_I2C4_STOP", + 1, + 1 + ] + ] + }, + { + "name": "APB2_FZ", + "offset": "0x10", + "fields": [ + [ + "DBG_TIM1_STOP", + 11, + 1 + ], + [ + "DBG_TIM8_STOP", + 13, + 1 + ], + [ + "DBG_TIM15_STOP", + 16, + 1 + ], + [ + "DBG_TIM16_STOP", + 17, + 1 + ], + [ + "DBG_TIM17_STOP", + 18, + 1 + ], + [ + "DBG_TIM20_STOP", + 20, + 1 + ], + [ + "DBG_HRTIM0_STOP", + 26, + 1 + ], + [ + "DBG_HRTIM1_STOP", + 27, + 1 + ], + [ + "DBG_HRTIM2_STOP", + 28, + 1 + ], + [ + "DBG_HRTIM3_STOP", + 29, + 1 + ] + ] + } + ] + } + ] +} diff --git a/core/analog/devices.c b/core/analog/devices.c index 2d70b5e39..9484899b0 100644 --- a/core/analog/devices.c +++ b/core/analog/devices.c @@ -2644,6 +2644,11 @@ typedef struct reg_state { #define REG_RREV 1e6 /* reverse (sinking) leakage resistance of the output, ohms */ +#define REG_ROUT 1e-3 /* the output's own resistance while it regulates, ohms: a + * real regulator's load regulation (about 1 mV per + * ampere here), and what keeps it from being an ideal + * source against its output capacitor, which the + * operating point holds at its initial voltage */ static es_status reg_setup(esk_adev *d) { @@ -2698,7 +2703,7 @@ static void reg_load(esk_adev *d, esk_amatrix *m) double p = s->pol; double vin = p * esk_am_v(m, nin, ng), ib = esk_am_x(m, b); double avail = vin - s->dropout, vo, dvo_dvin; - double iout = -p * ib, excess = iout - (s->thermal ? s->ilim : s->imax), rl = 0.0; + double iout = -p * ib, excess = iout - (s->thermal ? s->ilim : s->imax), rl = REG_ROUT; if (avail < 0.0) { vo = 0.0; dvo_dvin = 0.0; @@ -2709,16 +2714,17 @@ static void reg_load(esk_adev *d, esk_amatrix *m) vo = s->vout * scale; dvo_dvin = 0.0; } + vo -= iout * REG_ROUT; if (excess > 0.0) { vo -= excess * s->rlim; /* a soft current limit */ - rl = s->rlim; + rl += s->rlim; } else if (iout < 0.0 || (iout <= 0.0 && p * esk_am_v(m, nout, ng) >= vo)) { /* the pass element cannot sink: a reverse current only flows through a * large leakage resistance, so a pulled-up output rises above vo. The * output above vo with no current yet (the first iteration against a * supply that holds it) is this case too: regulating there would set * two voltage sources against each other */ - vo -= iout * REG_RREV; + vo -= iout * (REG_RREV - REG_ROUT); rl = REG_RREV; } /* output branch: v_out - v_gnd - p vo(vin) + rl * (iout - i_knee) = 0 (the diff --git a/core/analog/mna.c b/core/analog/mna.c index d20988c4c..bea700de8 100644 --- a/core/analog/mna.c +++ b/core/analog/mna.c @@ -1309,21 +1309,29 @@ static es_time_t step_horizon(const esk_island *isl, es_time_t until) } /* the step to x_iter changed no unknown by more than the solver resolves: - * a node voltage by vntol (1 uV), a branch current by abstol (1 pA), the - * absolute tolerances Newton's convergence test uses. Below them two - * solutions are the same to the solver; an exponential tail (an RC on a - * reset pin approaching its supply) would otherwise keep an island stepping - * for dozens of time constants after anything could see it move. The - * relative tolerance is left out on purpose: a slow ramp moving by less - * than reltol of its value per step can still be heading for a threshold. */ + * a node voltage by vntol (1 uV), the absolute tolerance Newton's + * convergence test uses. Below it two solutions are the same to the + * solver; an exponential tail (an RC on a reset pin approaching its supply) + * would otherwise keep an island stepping for dozens of time constants + * after anything could see it move. The relative tolerance is left out on + * purpose for the nodes: a slow ramp moving by less than reltol of its + * value per step can still be heading for a threshold. A branch current + * (a source's, an inductor's, an LED's) is still within a nanoampere and a + * millionth of its value: an LED's milliamps drifting by picoamps as its + * junction warms, or the trapezoidal rule's sub-nanoampere ringing of an + * LC tank whose period is far shorter than the step (a ferrite bead + * between two capacitors), move no node any instrument would see. */ +#define MNA_STILL_ABS_I 1e-9 +#define MNA_STILL_REL_I 1e-6 + static int unchanged(const esk_island *isl) { const mna *p = (const mna *)isl->priv; int i; for (i = 0; i < p->n; i++) { double a = isl->x[i], b = p->x_iter[i]; - double tol = i + 1 < p->nnodes ? isl->p.vntol : isl->p.abstol; - if (fabs(a - b) > tol + 1e-14 * fabs(a)) + double tol = i + 1 < p->nnodes ? isl->p.vntol + 1e-14 * fabs(a) : MNA_STILL_ABS_I + MNA_STILL_REL_I * fabs(a); + if (fabs(a - b) > tol) return 0; } return 1; diff --git a/core/analog/oscilloscope.c b/core/analog/oscilloscope.c index 006a0cf9e..0526c85e6 100644 --- a/core/analog/oscilloscope.c +++ b/core/analog/oscilloscope.c @@ -265,7 +265,7 @@ static void acquire(esk_adev *d, es_time_t t, int forced) } y = hist_v(s, k, ti - (es_time_t)(settle * 1e12)); for (tt = -settle + si; tt <= 1e-15; tt += si) - y += alpha * (hist_v(s, k, ti + (es_time_t)(tt * 1e12)) - y); + y += alpha * (hist_v(s, k, ti - (es_time_t)(-tt * 1e12)) - y); /* tt <= 0: not a negative double cast to unsigned */ s->acq[k][i] = (float)quantize(y, scale, offset, &code); } } diff --git a/core/mcu/cortexm/cortexm.c b/core/mcu/cortexm/cortexm.c index 5a5599cac..05a2a0374 100644 --- a/core/mcu/cortexm/cortexm.c +++ b/core/mcu/cortexm/cortexm.c @@ -353,6 +353,7 @@ static void exc_taken(struct esk_cm_state *cs, int n, u32 lr) { cs->R[14] = lr; esk_cm_use_psp(cs, 0); + cs->control &= ~2u; /* ExceptionTaken: CONTROL.SPSEL = 0, the handler on the main stack */ cs->ipsr = (u32)n; cs->active[n] = 1; esk_cm_clr_pend(cs, n); diff --git a/core/mcu/mach.h b/core/mcu/mach.h index e0e2b200a..e4ee938a5 100644 --- a/core/mcu/mach.h +++ b/core/mcu/mach.h @@ -547,6 +547,12 @@ struct esk_mach { * (an RP2040's QSPI_SS, BOOTSEL's): strap_low is called when it is low */ const char *strap_pin; void (*strap_low)(struct esk_mach *m); + /* the boot's choice where it is not a BOOT0 pin's alone (an STM32G4's: + * BOOT0 is PB8 or an option bit, RM0440 2.6): `boot_pin`'s level once + * the circuit has settled (0 when it names none or floats) goes to + * boot_system, which says whether the part boots its system memory */ + const char *boot_pin; + int (*boot_system)(struct esk_mach *m, int pin_high); /* that reset is the core's alone (an ESP32-C3's CPU reset): the * devices keep their state */ int reset_cpu_only; diff --git a/core/mcu/mcu.c b/core/mcu/mcu.c index 05464c286..5a299e84b 100644 --- a/core/mcu/mcu.c +++ b/core/mcu/mcu.c @@ -3,6 +3,7 @@ /* mcu.c -- the MCU runtime (mcu.h says what it does). */ #include #include +#include #include #include "mcu/analysis.h" @@ -141,6 +142,7 @@ typedef struct mcu_state { mcu_uart uart[MCU_UARTS]; int nuart; char console[16]; + int console_pin[2]; /* the bridge's TX and RX pins (port * 32 + bit), or -1 */ esk_an *an; /* the analyses watching the firmware, or NULL */ unsigned an_what; esk_air_node air; /* its radio on the session's air, when it has one */ @@ -505,7 +507,8 @@ static void quantum_cb(void *ctx, void *arg, es_time_t now) } if (st->m.strap_pin && st->m.strap_low && !level_of(esk_comp_pin(st->c, st->m.strap_pin), 1)) st->m.strap_low(&st->m); - if (level_of(st->boot0, 0)) { + if (st->m.boot_system ? st->m.boot_system(&st->m, st->m.boot_pin ? level_of(esk_comp_pin(st->c, st->m.boot_pin), 0) : 0) + : level_of(st->boot0, 0)) { st->boot_fail = 1; raise(st, ES_SEV_WARNING, "mcu.boot_mode", "BOOT0 is high: the part boots its system memory (the vendor's bootloader), which is " @@ -821,6 +824,23 @@ static mcu_uart *uart_named(mcu_state *st, const char *unit, int add) return &st->uart[st->nuart++]; } +/* the console's unit: the UART whose TX (tx 1) or RX the firmware has + * muxed onto the bridge's pin, as the bridge hears the pin whichever + * peripheral drives it (an ST-LINK's VCP on PA2/PA3 is LPUART1's or + * USART2's, as the firmware chooses); the configured one otherwise */ +static const char *console_unit(mcu_state *st, int tx) +{ + int want = st->console_pin[tx ? 0 : 1], k, port, bit; + if (want < 0 || !st->m.uart_pin) + return st->console; + if (st->m.uart_pin(&st->m, st->console, tx, &port, &bit) == 0 && port * 32 + bit == want) + return st->console; + for (k = 0; k < st->m.nrx; k++) + if (st->m.uart_pin(&st->m, st->m.rx[k].unit, tx, &port, &bit) == 0 && port * 32 + bit == want) + return st->m.rx[k].unit; + return st->console; +} + /* the console's bytes, NULs too (a boot loader's binary replies reach * the host port whole); text views skip them (text_view) */ static void text_append(mcu_uart *u, int c) @@ -1685,7 +1705,7 @@ static es_status mcu_on_set(esk_comp *c, const char *input, const esk_json *valu return ES_OK; } if (!strcmp(input, "serial") || !strcmp(input, "tx_text")) - return serial_input(st, st->console, value); + return serial_input(st, console_unit(st, 0), value); if (esk_str_has_prefix(input, "serial:")) return serial_input(st, input + 7, value); return ES_EINVAL; @@ -1724,12 +1744,12 @@ static void mcu_observe(esk_comp *c, esk_json *out) snprintf(key, sizeof key, "serial.%s", st->uart[i].unit); esk_json_set_string(a, out, key, t ? t : ""); /* the console under the virtual terminal's name, for serial probes */ - if (!strcmp(st->uart[i].unit, st->console)) + if (!strcmp(st->uart[i].unit, console_unit(st, 1))) esk_json_set_string(a, out, "rx_text", t ? t : ""); if (t) esk_free(a, t, n + 1); } - if (!uart_named(st, st->console, 0)) + if (!uart_named(st, console_unit(st, 1), 0)) esk_json_set_string(a, out, "rx_text", ""); } @@ -1933,7 +1953,7 @@ esk_an *esk_mcu_analysis(const esk_comp *c) const char *esk_mcu_console(esk_comp *c, size_t *len, u64 *total) { mcu_state *st = esk_mcu_is(c) ? state_of(c) : NULL; - mcu_uart *u = st && st->attached ? uart_named(st, st->console, 0) : NULL; + mcu_uart *u = st && st->attached ? uart_named(st, console_unit(st, 1), 0) : NULL; *len = u ? u->text_len : 0; *total = u ? u->text_total : 0; return u ? u->text : ""; @@ -1985,14 +2005,14 @@ esk_json *esk_mcu_serial_json(esk_comp *c, esk_alloc *a) return o; for (i = 0; i < st->nuart; i++) esk_json_set_string(a, o, st->uart[i].unit, st->uart[i].text); - esk_json_set_string(a, o, "console", st->console); + esk_json_set_string(a, o, "console", console_unit(st, 1)); return o; } uint32_t esk_mcu_console_baud_of(esk_comp *c, uint64_t index, uint64_t *until) { mcu_state *st = esk_mcu_is(c) ? state_of(c) : NULL; - mcu_uart *u = st && st->attached ? uart_named(st, st->console, 0) : NULL; + mcu_uart *u = st && st->attached ? uart_named(st, console_unit(st, 1), 0) : NULL; int i; *until = UINT64_MAX; for (i = u ? u->nrate - 1 : -1; i >= 0; i--) @@ -2009,7 +2029,7 @@ uint32_t esk_mcu_console_baud_of(esk_comp *c, uint64_t index, uint64_t *until) uint32_t esk_mcu_console_baud(esk_comp *c) { mcu_state *st = esk_mcu_is(c) ? state_of(c) : NULL; - mcu_uart *u = st && st->attached ? uart_named(st, st->console, 0) : NULL; + mcu_uart *u = st && st->attached ? uart_named(st, console_unit(st, 1), 0) : NULL; u64 hz; u32 bc; if (!u || !u->rx || !u->rx->bit_cycles) @@ -2299,6 +2319,17 @@ es_status esk_mcu_attach(esk_comp *c, const esk_mcu_setup *su, char *why, size_t speed_table(esk_json_get(esk_json_get(esk_json_get(su->mcu, "io"), "electrical"), "slew_v_per_us"), st->slew); snprintf(st->console, sizeof st->console, "%s", su->console ? su->console : "USART1"); + { + const char *pin[2]; + int k; + pin[0] = su->console_tx; + pin[1] = su->console_rx; + for (k = 0; k < 2; k++) + st->console_pin[k] = pin[k] && pin[k][0] == 'P' && pin[k][1] >= 'A' && pin[k][1] <= 'K' && + pin[k][2] >= '0' && pin[k][2] <= '9' + ? (pin[k][1] - 'A') * 32 + (int)strtol(pin[k] + 2, NULL, 10) + : -1; + } for (port = 0; port < MCU_PORTS; port++) for (bit = 0; bit < 16; bit++) { snprintf(name, sizeof name, "P%c%d", 'A' + port, bit); diff --git a/core/mcu/mcu.h b/core/mcu/mcu.h index 1073ec743..4a0518a03 100644 --- a/core/mcu/mcu.h +++ b/core/mcu/mcu.h @@ -50,6 +50,10 @@ typedef struct esk_mcu_setup { const char *image_name; es_time_t quantum_ps; /* 0: 10 us */ const char *console; /* the default serial unit ("USART1") */ + /* the board's serial bridge's pins (an ST-LINK's VCP on PA2/PA3), or + * NULL: the console is then whichever UART the firmware muxes onto + * them, as the bridge is wired to the pins, not to a peripheral */ + const char *console_tx, *console_rx; const esk_mcu_file *files; /* the memory regions' factory files */ int nfiles; const unsigned char *mac; /* this chip's factory MAC (6 bytes), or NULL */ diff --git a/core/mcu/models.c b/core/mcu/models.c index b7cfbea77..f3dd4172d 100644 --- a/core/mcu/models.c +++ b/core/mcu/models.c @@ -17,10 +17,12 @@ static const struct esk_rf_model_type model_types[] = { { "stm32-rcc", &esk_stm32_rcc_ops, esk_stm32_rcc_create }, + { "stm32g4-rcc", &esk_stm32g4_rcc_ops, esk_stm32g4_rcc_create }, { "stm32f1-gpio", &esk_stm32f1_gpio_ops, esk_stm32f1_gpio_create }, { "stm32f1-afio", &esk_stm32f1_afio_ops, esk_stm32f1_afio_create }, { "stm32-exti", &esk_stm32_exti_ops, esk_stm32_exti_create }, { "stm32-usart", &esk_stm32_usart_ops, esk_stm32_usart_create }, + { "stm32-usart-v2", &esk_stm32_usartv2_ops, esk_stm32_usartv2_create }, { "stm32-tim", &esk_stm32_tim_ops, esk_stm32_tim_create }, { "stm32f1-adc", &esk_stm32f1_adc_ops, esk_stm32f1_adc_create }, { "stm32-spi", &esk_stm32_spi_ops, esk_stm32_spi_create }, @@ -28,11 +30,15 @@ static const struct esk_rf_model_type model_types[] = { { "stm32f1-flash", &esk_stm32f1_flash_ops, esk_stm32f1_flash_create }, { "stm32-pwr", &esk_stm32_storage_ops, esk_stm32_storage_create }, { "stm32f4-pwr", &esk_stm32f4_pwr_ops, esk_stm32f4_pwr_create }, + { "stm32g4-pwr", &esk_stm32g4_pwr_ops, esk_stm32g4_pwr_create }, { "stm32f4-flash", &esk_stm32f4_flash_ops, esk_stm32f4_flash_create }, + { "stm32g4-flash", &esk_stm32g4_flash_ops, esk_stm32g4_flash_create }, { "stm32f4-gpio", &esk_stm32f4_gpio_ops, esk_stm32f4_gpio_create }, { "stm32f4-syscfg", &esk_stm32f4_syscfg_ops, esk_stm32f4_syscfg_create }, { "stm32f4-dbgmcu", &esk_stm32f4_dbgmcu_ops, esk_stm32f4_dbgmcu_create }, { "stm32f4-dma", &esk_stm32f4_dma_ops, esk_stm32f4_dma_create }, + { "stm32g4-dma", &esk_stm32g4_dma_ops, esk_stm32g4_dma_create }, + { "stm32g4-dmamux", &esk_stm32g4_dmamux_ops, esk_stm32g4_dmamux_create }, { "stm32f4-adc", &esk_stm32f4_adc_ops, esk_stm32f4_adc_create }, { "stm32f4-adc-common", &esk_stm32f4_adc_common_ops, esk_stm32f4_adc_common_create }, { "stm32f4-dac", &esk_stm32f4_dac_ops, esk_stm32f4_dac_create }, diff --git a/core/mcu/rf.c b/core/mcu/rf.c index 09688157d..2ebf47b9d 100644 --- a/core/mcu/rf.c +++ b/core/mcu/rf.c @@ -490,7 +490,9 @@ es_status esk_rf_dma_requests(struct esk_mach *m, const esk_json *map, char *why for (k = 0; k < esk_json_len(st); k++) { const esk_json *ch = esk_json_at(st, k); long chn = ch && ch->key ? strtol(ch->key, NULL, 10) : -1; - if (sn < 0 || sn > 15 || chn < 0 || chn > 15) { + /* a multiplexer's request inputs are numbered past 15 (an + * STM32G4's DMAMUX: 0 to 115) */ + if (sn < 0 || sn > 15 || chn < 0 || chn > (strcmp(cn, "DMAMUX") ? 15 : 255)) { snprintf(why, cap, "dma_requests: %s has a bad stream or channel", cn); return ES_ESCHEMA; } @@ -544,15 +546,27 @@ es_status esk_rf_analog(struct esk_mach *m, const esk_json *an, char *why, size_ int esk_rf_analog_pin(const struct esk_rf *rf, int unit, int ch) { int i; + /* each pin's entry names one group of channels (ADC123_IN0), or several + * where its ADCs number it differently (an STM32G4's PB0: "ADC1_IN15, + * ADC3_IN12") */ for (i = 0; rf && i < rf->nan; i++) { - const char *s = rf->an_sig[i], *in; - int k, has = 0; - if (strncmp(s, "ADC", 3) || !(in = strstr(s, "_IN")) || strtol(in + 3, NULL, 10) != ch) - continue; - for (k = 3; s + k < in; k++) - has |= s[k] - '0' == unit; - if (has) - return rf->an_at[i]; + const char *s = rf->an_sig[i]; + while (s && *s) { + const char *in; + int k, has = 0; + while (*s == ' ' || *s == ',') + s++; + if (!strncmp(s, "ADC", 3) && (in = strstr(s, "_IN")) != 0 && strtol(in + 3, NULL, 10) == ch) { + const char *end = strchr(s, ','); + if (!end || in < end) { + for (k = 3; s + k < in; k++) + has |= s[k] - '0' == unit; + if (has) + return rf->an_at[i]; + } + } + s = strchr(s, ','); + } } return -1; } diff --git a/core/mcu/stm32/adc_f4.c b/core/mcu/stm32/adc_f4.c index b45c72d3c..2a82f6a41 100644 --- a/core/mcu/stm32/adc_f4.c +++ b/core/mcu/stm32/adc_f4.c @@ -776,4 +776,5 @@ void esk_stm32_trigger(struct esk_mach *s, const char *sig, int level) group_start(a, 1); } esk_stm32_dac_trigger(s, sig, level); + esk_stm32g4_dmamux_input(s, sig, level); } diff --git a/core/mcu/stm32/crc.c b/core/mcu/stm32/crc.c index c3136a8aa..e5ad7c34d 100644 --- a/core/mcu/stm32/crc.c +++ b/core/mcu/stm32/crc.c @@ -11,6 +11,16 @@ * - IDR is a byte of storage the RESET bit leaves alone; * - its clock is RCC's CRCEN (the register file's gate). * + * The programmable unit (an STM32G4's, RM0440 16; registers INIT and POL): + * - CR's POLYSIZE gives the CRC's width (32, 16, 8 or 7 bits) and POL its + * polynomial; RESET loads DR with INIT; DR is written a byte, halfword + * or word at a time, the access's width of data fed most significant + * bit first; + * - REV_IN reverses the data's bits by bytes (01), halfwords (10) or the + * word (11), within the width written (a byte written with 11 is + * reversed as a byte); REV_OUT makes DR read the CRC bit-reversed + * within its width. + * * Inside: the four AHB clocks a word takes are not seen (a write to DR * while the unit computes stalls the bus until it is done, so the program * reads the finished value either way); the bus stall itself is not @@ -22,9 +32,69 @@ struct crc { struct esk_rf_periph *p; - struct esk_rf_reg *dr, *cr; + struct esk_rf_reg *dr, *cr, *init, *pol; + u32 crc; /* the programmable unit's CRC, DR shows it (REV_OUT) */ }; +static u32 reverse(u32 v, int width) +{ + u32 r = 0; + int k; + for (k = 0; k < width; k++) + r |= (v >> k & 1u) << (width - 1 - k); + return r; +} + +static int poly_width(const struct crc *c) +{ + static const int w[4] = { 32, 16, 8, 7 }; + return w[(u32)c->cr->value >> 3 & 3u]; +} + +static u32 width_mask(int w) { return w >= 32 ? 0xffffffffu : (1u << w) - 1; } + +/* DR as the programmable unit shows its CRC */ +static void show(struct crc *c) +{ + int w = poly_width(c); + u32 v = c->crc & width_mask(w); + if (c->cr->value & (1u << 7)) + v = reverse(v, w); + esk_rf_hw(c->dr, v); +} + +/* `nbits` of `data` (its most significant first) into the CRC */ +static void feed(struct crc *c, u32 data, int nbits) +{ + int w = poly_width(c), k; + u32 poly = (u32)c->pol->value & width_mask(w), top = 1u << (w - 1), crc = c->crc; + for (k = nbits - 1; k >= 0; k--) { + u32 in = data >> k & 1u, msb = (crc & top) != 0; + crc = (crc << 1) & width_mask(w); + if (in ^ msb) + crc ^= poly; + } + c->crc = crc; +} + +static void v2_write(struct crc *c, int n, u32 v) +{ + u32 rev = (u32)c->cr->value >> 5 & 3u; + int bits = 8 * n, unit = rev == 1 ? 8 : rev == 2 ? 16 : 32, k; + if (n < 4) + v &= width_mask(bits); + if (rev) { + u32 out = 0; + if (unit > bits) + unit = bits; + for (k = 0; k < bits; k += unit) + out |= reverse(v >> k & width_mask(unit), unit) << k; + v = out; + } + feed(c, v, bits); + show(c); +} + /* the CRC-32 of `crc` followed by the word `w`, MSB first */ static u32 crc_word(u32 crc, u32 w) { @@ -44,6 +114,21 @@ static u32 crc_read(void *ctx, u32 off, int n) static void crc_write(void *ctx, u32 off, int n, u32 v) { struct crc *c = (struct crc *)ctx; + if (c->pol) { /* the programmable unit */ + if (off - esk_rf_off(c->dr) < 4) { + v2_write(c, n, v); + return; + } + esk_rf_write(c->p, off, n, v); + if (off - esk_rf_off(c->cr) < 4) { + if (c->cr->value & 1u) { + c->crc = (u32)c->init->value & width_mask(poly_width(c)); + esk_rf_hw(c->cr, c->cr->value & ~(u64)1u); /* RESET reads 0 */ + } + show(c); + } + return; + } if (c->dr && off - esk_rf_off(c->dr) < 4) { if (n == 1) v &= 0xffu; @@ -60,7 +145,11 @@ static void crc_write(void *ctx, u32 off, int n, u32 v) esk_rf_write(c->p, off, n, v); } -static void crc_reset(void *ctx) { (void)ctx; } +static void crc_reset(void *ctx) +{ + struct crc *c = (struct crc *)ctx; + c->crc = 0xffffffffu; +} const struct esk_dev_ops esk_stm32_crc_ops = { "stm32-crc", crc_read, crc_write, crc_reset, 0, 0, @@ -77,5 +166,10 @@ void *esk_stm32_crc_create(struct esk_mach *m, struct esk_rf_periph *p) c->p = p; c->dr = esk_rf_reg(p, "DR"); c->cr = esk_rf_reg(p, "CR"); + c->init = esk_rf_reg(p, "INIT"); + c->pol = esk_rf_reg(p, "POL"); + if (!c->init || !c->cr) + c->pol = 0; + c->crc = 0xffffffffu; return c; } diff --git a/core/mcu/stm32/dbgmcu_f4.c b/core/mcu/stm32/dbgmcu_f4.c index 4cc49a701..a39052111 100644 --- a/core/mcu/stm32/dbgmcu_f4.c +++ b/core/mcu/stm32/dbgmcu_f4.c @@ -76,6 +76,11 @@ void *esk_stm32f4_dbgmcu_create(struct esk_mach *s, struct esk_rf_periph *p) d->cr = esk_rf_reg(p, "DBGMCU_CR"); d->apb1 = esk_rf_reg(p, "DBGMCU_APB1_FZ"); d->apb2 = esk_rf_reg(p, "DBGMCU_APB2_FZ"); + if (!d->cr) { /* a G4's names (RM0440 47.6): CR, APB1L_FZ, APB2_FZ */ + d->cr = esk_rf_reg(p, "CR"); + d->apb1 = esk_rf_reg(p, "APB1L_FZ"); + d->apb2 = esk_rf_reg(p, "APB2_FZ"); + } if (!d->cr) return 0; return d; diff --git a/core/mcu/stm32/dma_f4.c b/core/mcu/stm32/dma_f4.c index d9dcb27cb..32cb6cf36 100644 --- a/core/mcu/stm32/dma_f4.c +++ b/core/mcu/stm32/dma_f4.c @@ -270,7 +270,7 @@ static int item(struct dma *d, int s) return fifo_to_memory(d, s, v32(x->ndtr) <= 1); } -static void items_left(struct esk_mach *s, const char *sig, u32 left) +void esk_stm32_dma_items_left(struct esk_mach *s, const char *sig, u32 left) { if (!left) { esk_stm32_spi_dma_end(s, sig); @@ -278,6 +278,7 @@ static void items_left(struct esk_mach *s, const char *sig, u32 left) esk_stm32_dac_dma_end(s, sig); } esk_stm32_i2c_dma_left(s, sig, left); + esk_stm32_spi_dma_left(s, sig, left); } /* a request served by stream s: a peripheral burst of items; the last two @@ -297,7 +298,7 @@ static void serve(struct dma *d, int s, const char *sig) counted(d, s); /* the peripheral hears of the last items (EOT, I2C's EOT-1) */ if (before <= 2) - items_left(d->s, sig, before - 1); + esk_stm32_dma_items_left(d->s, sig, before - 1); } fifo_status(x); } @@ -390,7 +391,7 @@ void esk_stm32_dma_request(struct esk_mach *s, const char *sig, int level) pend_add(d, sig); /* served now if a stream takes it, else it waits */ if (!esk_rf_gated(d->p)) drain(d); - } + } esk_stm32g4_dma_request(s, sig, level); /* the G4's DMAMUX (dma_g4.c) */ } /* ---- memory to memory ------------------------------------------------------ */ diff --git a/core/mcu/stm32/dma_g4.c b/core/mcu/stm32/dma_g4.c new file mode 100644 index 000000000..da7e5e5d4 --- /dev/null +++ b/core/mcu/stm32/dma_g4.c @@ -0,0 +1,736 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* dma_g4.c -- the STM32G4's DMA controllers (RM0440 12) and its DMA request + * multiplexer (RM0440 13), over the register file. + * + * DMA1 and DMA2 (stm32g4-dma), eight channels each: + * - a channel (CCRx.EN) moves one item a request, peripheral to memory + * (DIR 0) or memory to peripheral (DIR 1), or, with MEM2MEM, the + * whole block without requests, one item every two cycles, as the bus + * lets it; the source is read at its size and written at the + * destination's, zero-extended or truncated as table 89 gives, both + * addresses stepping by their own sizes (PINC, MINC); + * - CNDTRx counts the items left: half of them done sets HTIF, all of + * them TCIF (and GIF with either); circular mode (CIRC) reloads CNDTR + * and the addresses; otherwise the channel stays enabled and serves no + * more requests until it is disabled and programmed again; a channel + * enabled with CNDTR 0 serves nothing; + * - an access the bus refuses sets TEIF and clears EN, which cannot be + * set again while TEIF is; + * - while EN is set, MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC and DIR, and + * CNDTR, keep their values; CPAR and CMAR take a write the transfer in + * progress does not use (it keeps its internal addresses); + * - IFCR's CGIFx clears the channel's four flags, CTEIFx, CHTIFx and + * CTCIFx their own flag (and GIF once none of the three is left); a + * channel's interrupt is pending while TCIF with TCIE, HTIF with HTIE + * or TEIF with TEIE; + * - the last two items of a round tell the peripheral (an SPI's CRC + * follows the last, an I2C NACKs the byte after the next-to-last). + * + * DMAMUX (stm32g4-dmamux): sixteen request-line channels, 0 to 7 to DMA1's + * channels 1 to 8 and 8 to 15 to DMA2's, and four request generators: + * - CxCR's DMAREQ_ID selects the request line (the description's + * dma_requests, the HAL's numbering, 1 to 4 the generators); + * - SE: the line reaches the DMA only after an edge (SPOL) on the + * synchronisation input SYNC_ID, if a request is pending then (an edge + * with none is discarded), for NBREQ + 1 served requests; an edge + * while the counter is below NBREQ sets SOFx; + * - EGE: an event each NBREQ + 1 served requests (each one with NBREQ 0), + * channels 0 to 3's on trigger and synchronisation inputs 16 to 19; + * - a generator (RGxCR.GE) produces GNBREQ + 1 requests from an edge + * (GPOL) of its trigger input SIG_ID; an edge before they are all + * served sets OFx; + * - the trigger and synchronisation inputs: EXTI lines 0 to 15 (0 to 15), + * the channels' events (16 to 19), LPTIM1_OUT (20); + * - CFR and RGCFR clear SOF and OF; DMAMUX_OVR is pending while a flag + * is set with its channel's SOIE or generator's OIE. + * + * Not modelled: the arbitration's delays (a request is served at once, the + * channel priority deciding only between channels taking the same + * request), the bus matrix's timing, the edge filter's two AHB cycles and + * the three cycles a CxCR or RGxCR write masks the inputs for, the byte and + * half-word lanes duplicated for an APB peripheral that ignores the access + * size (the register file takes each size as it is), LPTIM1_OUT (no LPTIM + * model yet). */ +#include +#include +#include + +#include "mcu/stm32/stm32.h" + +/* CCR */ +#define EN (1u << 0) +#define TCIE (1u << 1) +#define HTIE (1u << 2) +#define TEIE (1u << 3) +#define DIR (1u << 4) +#define CIRC (1u << 5) +#define PINC (1u << 6) +#define MINC (1u << 7) +#define MEM2MEM (1u << 14) +/* read-only while EN: MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, DIR */ +#define CCR_LOCKED 0x7FD0u +/* ISR, a channel's nibble */ +#define F_GIF 0 +#define F_TC 1 +#define F_HT 2 +#define F_TE 3 + +/* DMAMUX CxCR */ +#define C_SOIE (1u << 8) +#define C_EGE (1u << 9) +#define C_SE (1u << 16) +/* RGxCR */ +#define G_OIE (1u << 8) +#define G_GE (1u << 16) + +#define NCH 8 +#define NMUX 16 +#define NGEN 4 +#define NIN 21 +#define NPEND 32 +#define NID 128 + +struct chan { + struct esk_rf_reg *ccr, *cndtr, *cpar, *cmar; + u32 pa, ma; /* the addresses in use */ + u32 total; /* CNDTR as the channel was enabled, for HT and reloads */ + int ht; /* HTIF set this round */ + int irq; +}; + +struct g4dma { + struct esk_mach *s; + struct esk_rf_periph *p; + struct esk_rf_reg *isr, *ifcr; + struct chan ch[NCH]; + int mux0; /* the DMAMUX channel of channel 1 (0 for DMA1, 8 for DMA2) */ + int running; + u32 frac; /* memory to memory: cycles toward the next item */ +}; + +struct dmamux { + struct esk_mach *s; + struct esk_rf_periph *p; + struct esk_rf_reg *cr[NMUX], *rg[NGEN], *csr, *cfr, *rgsr, *rgcfr; + int nch, irq; + const char *id_sig[NID]; /* request line ID -> its request */ + const char *pend[NPEND]; /* requests waiting for a channel */ + int npend; + int conn[NMUX]; /* SE: the line connected since a sync edge */ + u32 cnt[NMUX]; /* served requests left before the counter reloads */ + u32 gen_left[NGEN]; /* a generator's requests still to serve */ + int level[NIN]; /* the trigger and sync inputs' levels */ + int busy, depth; +}; + +static const char *const gen_sig[NGEN] = { "DMAMUX_REQ_GEN0", "DMAMUX_REQ_GEN1", "DMAMUX_REQ_GEN2", + "DMAMUX_REQ_GEN3" }; + +static u32 v32(const struct esk_rf_reg *r) { return r ? (u32)r->value : 0; } + +/* ---- the DMA controllers ---------------------------------------------------- */ + +static u32 psize(const struct chan *c) { return 1u << (v32(c->ccr) >> 8 & 3); } +static u32 msize(const struct chan *c) { return 1u << (v32(c->ccr) >> 10 & 3); } + +static void irq_check(struct g4dma *d, int k) +{ + struct chan *c = &d->ch[k]; + u32 f = v32(d->isr) >> (4 * k), cr = v32(c->ccr); + if (((f >> F_TC & 1) && (cr & TCIE)) || ((f >> F_HT & 1) && (cr & HTIE)) || ((f >> F_TE & 1) && (cr & TEIE))) + esk_rf_interrupt(d->p, c->irq); +} + +static void set_flag(struct g4dma *d, int k, int f) +{ + esk_rf_hw(d->isr, d->isr->value | ((u64)1u << (4 * k + f)) | ((u64)1u << (4 * k + F_GIF))); + irq_check(d, k); +} + +/* the bus refused an access: TEIF, the channel off */ +static void transfer_error(struct g4dma *d, int k) +{ + esk_rf_hw(d->ch[k].ccr, d->ch[k].ccr->value & ~(u64)EN); + set_flag(d, k, F_TE); +} + +static int active(const struct chan *c) { return (v32(c->ccr) & EN) && v32(c->cndtr); } + +/* one item from the source to the destination at their sizes (table 89): + * 0, or -1 on a bus error */ +static int item(struct g4dma *d, int k) +{ + struct chan *c = &d->ch[k]; + u32 cr = v32(c->ccr), v = 0; + int to_p = (cr & DIR) != 0; + u32 *src = to_p ? &c->ma : &c->pa, *dst = to_p ? &c->pa : &c->ma; + u32 ss = to_p ? msize(c) : psize(c), ds = to_p ? psize(c) : msize(c); + int sinc = (cr & (to_p ? MINC : PINC)) != 0, dinc = (cr & (to_p ? PINC : MINC)) != 0; + if (esk_bus_read(&d->s->bus, *src, (int)ss, &v)) + return -1; + if (ss < 4) + v &= (1u << (8 * ss)) - 1u; + if (ds < 4) + v &= (1u << (8 * ds)) - 1u; + if (esk_bus_write(&d->s->bus, *dst, (int)ds, v)) + return -1; + if (sinc) + *src += ss; + if (dinc) + *dst += ds; + return 0; +} + +/* one item counted: HT, TC, the circular reload */ +static void counted(struct g4dma *d, int k) +{ + struct chan *c = &d->ch[k]; + u32 n = v32(c->cndtr); + if (n) + esk_rf_hw(c->cndtr, --n); + if (!c->ht && c->total > 1 && n <= c->total / 2) { + c->ht = 1; + set_flag(d, k, F_HT); + } + if (n) + return; + set_flag(d, k, F_TC); + if (v32(c->ccr) & CIRC) { + esk_rf_hw(c->cndtr, c->total); + c->pa = v32(c->cpar); + c->ma = v32(c->cmar); + c->ht = 0; + } +} + +/* a request served by channel k: one item; 1 when served */ +static int serve(struct g4dma *d, int k, const char *sig) +{ + struct chan *c = &d->ch[k]; + u32 before; + if (!active(c) || esk_rf_gated(d->p)) + return 0; + if (item(d, k)) { + transfer_error(d, k); + return 1; /* the request was taken, and the channel is off */ + } + before = v32(c->cndtr); + counted(d, k); + if (before <= 2 && sig) + esk_stm32_dma_items_left(d->s, sig, before - 1); + return 1; +} + +static int m2m_any(const struct g4dma *d) +{ + int k; + for (k = 0; k < NCH; k++) + if (active(&d->ch[k]) && (v32(d->ch[k].ccr) & MEM2MEM)) + return 1; + return 0; +} + +static void run_clock(struct g4dma *d) +{ + esk_rf_clock(d->p, &d->running, m2m_any(d)); +} + +static void dma_tick(void *ctx, u32 cycles) +{ + struct g4dma *d = (struct g4dma *)ctx; + u32 items = (d->frac + cycles) / 2; + int pl, k; + d->frac = (d->frac + cycles) % 2; + /* the most urgent memory-to-memory channel first */ + for (pl = 3; pl >= 0 && items; pl--) + for (k = 0; k < NCH && items; k++) { + struct chan *c = &d->ch[k]; + if ((int)(v32(c->ccr) >> 12 & 3) != pl || !(v32(c->ccr) & MEM2MEM)) + continue; + while (items && active(c)) { + if (item(d, k)) { + transfer_error(d, k); + break; + } + counted(d, k); + items--; + } + } + run_clock(d); +} + +static int dma_next_event(void *ctx, u32 *cycles) +{ + struct g4dma *d = (struct g4dma *)ctx; + if (!m2m_any(d)) + return 0; + *cycles = 2; + return 1; +} + +static struct dmamux *mux_of(struct esk_mach *s); +static void mux_drain(struct dmamux *x); + +static void enable(struct g4dma *d, int k) +{ + struct chan *c = &d->ch[k]; + c->total = v32(c->cndtr); + c->pa = v32(c->cpar); + c->ma = v32(c->cmar); + c->ht = 0; +} + +static u32 dma_read(void *ctx, u32 off, int n) +{ + struct g4dma *d = (struct g4dma *)ctx; + return esk_rf_read(d->p, off, n); +} + +static void dma_write(void *ctx, u32 off, int n, u32 v) +{ + struct g4dma *d = (struct g4dma *)ctx; + int k; + if (off == esk_rf_off(d->isr)) + return; + if (off == esk_rf_off(d->ifcr)) { + u32 isr = v32(d->isr); + for (k = 0; k < NCH; k++) { + u32 w = v >> (4 * k) & 0xFu, f = isr >> (4 * k) & 0xFu; + if (w & 1u) + f = 0; + f &= ~(w & 0xEu); + if (!(f & 0xEu)) + f = 0; + isr = (isr & ~(0xFu << (4 * k))) | f << (4 * k); + } + esk_rf_hw(d->isr, isr); + return; + } + for (k = 0; k < NCH; k++) { + struct chan *c = &d->ch[k]; + u32 cr = v32(c->ccr); + if (off == esk_rf_off(c->ccr)) { + u32 nv; + esk_rf_write(d->p, off, n, v); + nv = v32(c->ccr); + if (cr & EN) + nv = (nv & ~CCR_LOCKED) | (cr & CCR_LOCKED); + if ((nv & EN) && (v32(d->isr) >> (4 * k + F_TE) & 1)) + nv &= ~EN; /* not again until TEIF is cleared */ + esk_rf_hw(c->ccr, nv); + if ((nv & EN) && !(cr & EN)) { + enable(d, k); + run_clock(d); + mux_drain(mux_of(d->s)); + } + return; + } + if (off == esk_rf_off(c->cndtr)) { + if (!(cr & EN)) + esk_rf_write(d->p, off, n, v); + return; + } + } + esk_rf_write(d->p, off, n, v); +} + +static void dma_reset(void *ctx) +{ + struct g4dma *d = (struct g4dma *)ctx; + int k; + d->running = 0; + d->frac = 0; + for (k = 0; k < NCH; k++) { + d->ch[k].total = 0; + d->ch[k].ht = 0; + d->ch[k].pa = d->ch[k].ma = 0; + } +} + +const struct esk_dev_ops esk_stm32g4_dma_ops = { + "stm32g4-dma", dma_read, dma_write, dma_reset, dma_tick, dma_next_event, +}; + +void *esk_stm32g4_dma_create(struct esk_mach *m, struct esk_rf_periph *p) +{ + struct g4dma *d = (struct g4dma *)esk_mach_alloc(m, sizeof *d); + char n[16]; + int k; + if (!d) + return 0; + d->s = m; + d->p = p; + d->isr = esk_rf_reg(p, "ISR"); + d->ifcr = esk_rf_reg(p, "IFCR"); + if (!d->isr || !d->ifcr) + return 0; + d->mux0 = !strcmp(p->name, "DMA2") ? 8 : 0; + for (k = 0; k < NCH; k++) { + struct chan *c = &d->ch[k]; + snprintf(n, sizeof n, "CCR%d", k + 1); + c->ccr = esk_rf_reg(p, n); + snprintf(n, sizeof n, "CNDTR%d", k + 1); + c->cndtr = esk_rf_reg(p, n); + snprintf(n, sizeof n, "CPAR%d", k + 1); + c->cpar = esk_rf_reg(p, n); + snprintf(n, sizeof n, "CMAR%d", k + 1); + c->cmar = esk_rf_reg(p, n); + if (!c->ccr || !c->cndtr || !c->cpar || !c->cmar) + return 0; + snprintf(n, sizeof n, "_CH%d", k + 1); + c->irq = esk_rf_irq(p, n); + } + esk_rf_set_mwv(d->ifcr, ~(u64)0, ESK_MWV_MODIFY); + return d; +} + +/* ---- the request multiplexer ------------------------------------------------- */ + +static struct dmamux *mux_of(struct esk_mach *s) +{ + struct esk_rf_periph *p = s->rf ? esk_rf_periph(s->rf, "DMAMUX") : 0; + return p && p->ops == &esk_stm32g4_dmamux_ops ? (struct dmamux *)p->ctx : 0; +} + +/* the DMA channel a multiplexer channel feeds */ +static struct g4dma *dma_for(struct dmamux *x, int c, int *k) +{ + struct esk_rf_periph *p = esk_rf_periph(x->s->rf, c < 8 ? "DMA1" : "DMA2"); + *k = c % 8; + return p && p->ops == &esk_stm32g4_dma_ops ? (struct g4dma *)p->ctx : 0; +} + +static const char *line_of(const struct dmamux *x, int c) +{ + u32 id = v32(x->cr[c]) & 0x7Fu; + return id ? x->id_sig[id] : 0; +} + +static u32 nbreq(const struct dmamux *x, int c) { return (v32(x->cr[c]) >> 19 & 31u) + 1u; } + +static void mux_irq(struct dmamux *x) +{ + u32 sof = v32(x->csr), of = v32(x->rgsr); + int c; + for (c = 0; c < x->nch; c++) + if ((sof >> c & 1) && (v32(x->cr[c]) & C_SOIE)) { + esk_rf_interrupt(x->p, x->irq); + return; + } + for (c = 0; c < NGEN; c++) + if ((of >> c & 1) && (v32(x->rg[c]) & G_OIE)) { + esk_rf_interrupt(x->p, x->irq); + return; + } +} + +static void mux_input(struct dmamux *x, int in, int level); + +/* channel c's event output, a pulse on inputs 16 to 19 */ +static void event_out(struct dmamux *x, int c) +{ + if (c > 3 || x->depth > 4) + return; + x->depth++; + mux_input(x, 16 + c, 1); + mux_input(x, 16 + c, 0); + x->depth--; +} + +/* may channel c pass its line now (SE: connected by a sync edge) */ +static int passes(const struct dmamux *x, int c) +{ + return !(v32(x->cr[c]) & C_SE) || x->conn[c]; +} + +/* a served request on channel c: the counter for SE and EGE */ +static void counted_req(struct dmamux *x, int c) +{ + u32 cr = v32(x->cr[c]); + if (!(cr & (C_SE | C_EGE))) + return; + if (x->cnt[c] > 1) { + x->cnt[c]--; + return; + } + x->cnt[c] = nbreq(x, c); + if (cr & C_SE) + x->conn[c] = 0; + if (cr & C_EGE) + event_out(x, c); +} + +/* a request on line `sig`: every channel selecting it that passes it + * serves one item; 1 when one did */ +static int offer(struct dmamux *x, const char *sig) +{ + int c, served = 0, pl; + if (esk_rf_gated(x->p)) + return 0; + for (pl = 3; pl >= 0; pl--) + for (c = 0; c < x->nch; c++) { + const char *l = line_of(x, c); + struct g4dma *d; + int k; + if (!l || strcmp(l, sig) || !passes(x, c) || !(d = dma_for(x, c, &k))) + continue; + if ((int)(v32(d->ch[k].ccr) >> 12 & 3) != pl || (v32(d->ch[k].ccr) & MEM2MEM)) + continue; + if (serve(d, k, sig)) { + served = 1; + counted_req(x, c); + } + } + return served; +} + +/* could a channel take `sig` now */ +static int taken(struct dmamux *x, const char *sig) +{ + int c; + for (c = 0; c < x->nch; c++) { + const char *l = line_of(x, c); + struct g4dma *d; + int k; + if (l && !strcmp(l, sig) && passes(x, c) && (d = dma_for(x, c, &k)) && active(&d->ch[k]) && + !(v32(d->ch[k].ccr) & MEM2MEM) && !esk_rf_gated(d->p)) + return 1; + } + return 0; +} + +static int pending(const struct dmamux *x, const char *sig) +{ + int i; + for (i = 0; i < x->npend; i++) + if (!strcmp(x->pend[i], sig)) + return 1; + for (i = 0; i < NGEN; i++) + if (x->gen_left[i] && !strcmp(gen_sig[i], sig)) + return 1; + return 0; +} + +static void pend_add(struct dmamux *x, const char *sig) +{ + int i; + for (i = 0; i < x->npend; i++) + if (!strcmp(x->pend[i], sig)) + return; + if (x->npend < NPEND) + x->pend[x->npend++] = sig; +} + +static void pend_remove(struct dmamux *x, const char *sig) +{ + int i; + for (i = 0; i < x->npend; i++) + if (!strcmp(x->pend[i], sig)) { + x->pend[i] = x->pend[--x->npend]; + return; + } +} + +/* the generators' requests, served while a channel takes them */ +static int run_generators(struct dmamux *x) +{ + int g, any = 0; + for (g = 0; g < NGEN; g++) + while (x->gen_left[g] && taken(x, gen_sig[g]) && offer(x, gen_sig[g])) { + x->gen_left[g]--; + any = 1; + } + return any; +} + +/* the waiting requests a channel now takes */ +static void mux_drain(struct dmamux *x) +{ + int i, again = 1; + if (!x || x->busy) + return; + x->busy = 1; + while (again) { + again = run_generators(x); + for (i = 0; i < x->npend; i++) { + const char *sig = x->pend[i]; + if (!taken(x, sig)) + continue; + pend_remove(x, sig); + (void)offer(x, sig); + again = 1; + break; + } + } + x->busy = 0; +} + +static int edge(u32 pol, int level) +{ + return pol == 3 || (pol == 1 && level) || (pol == 2 && !level); +} + +/* a trigger and synchronisation input's level (0 to 20) */ +static void mux_input(struct dmamux *x, int in, int level) +{ + int c; + if (in < 0 || in >= NIN || x->level[in] == !!level) + return; + x->level[in] = !!level; + if (esk_rf_gated(x->p)) + return; + for (c = 0; c < NGEN; c++) { + u32 rg = v32(x->rg[c]); + if (!(rg & G_GE) || (int)(rg & 31u) != in || !edge(rg >> 17 & 3, level)) + continue; + if (x->gen_left[c]) { + esk_rf_hw(x->rgsr, x->rgsr->value | (u64)1u << c); + mux_irq(x); + continue; + } + x->gen_left[c] = (rg >> 19 & 31u) + 1u; + } + for (c = 0; c < x->nch; c++) { + u32 cr = v32(x->cr[c]); + const char *l = line_of(x, c); + if (!(cr & C_SE) || (int)(cr >> 24 & 31u) != in || !edge(cr >> 17 & 3, level)) + continue; + if (x->conn[c] && x->cnt[c] < nbreq(x, c)) { + esk_rf_hw(x->csr, x->csr->value | (u64)1u << c); + mux_irq(x); + continue; + } + if (l && pending(x, l)) { + x->conn[c] = 1; + x->cnt[c] = nbreq(x, c); + } + } + mux_drain(x); +} + +static u32 mux_read(void *ctx, u32 off, int n) +{ + struct dmamux *x = (struct dmamux *)ctx; + return esk_rf_read(x->p, off, n); +} + +static void mux_write(void *ctx, u32 off, int n, u32 v) +{ + struct dmamux *x = (struct dmamux *)ctx; + int c; + if ((x->csr && off == esk_rf_off(x->csr)) || (x->rgsr && off == esk_rf_off(x->rgsr))) + return; + if (x->cfr && off == esk_rf_off(x->cfr)) { + esk_rf_hw(x->csr, x->csr->value & ~(u64)(v & 0xFFFFu)); + return; + } + if (x->rgcfr && off == esk_rf_off(x->rgcfr)) { + esk_rf_hw(x->rgsr, x->rgsr->value & ~(u64)(v & 0xFu)); + return; + } + esk_rf_write(x->p, off, n, v); + for (c = 0; c < x->nch; c++) + if (off >= esk_rf_off(x->cr[c]) && off < esk_rf_off(x->cr[c]) + 4) { + u32 cr = v32(x->cr[c]); + if (!(cr & (C_SE | C_EGE))) + x->cnt[c] = nbreq(x, c); + if (!(cr & C_SE)) + x->conn[c] = 0; + else if (!x->cnt[c]) + x->cnt[c] = nbreq(x, c); + } + for (c = 0; c < NGEN; c++) + if (off >= esk_rf_off(x->rg[c]) && off < esk_rf_off(x->rg[c]) + 4 && !(v32(x->rg[c]) & G_GE)) + x->gen_left[c] = 0; + mux_drain(x); +} + +static void mux_reset(void *ctx) +{ + struct dmamux *x = (struct dmamux *)ctx; + int c; + x->npend = 0; + x->busy = x->depth = 0; + for (c = 0; c < NMUX; c++) { + x->conn[c] = 0; + x->cnt[c] = 1; + } + for (c = 0; c < NGEN; c++) + x->gen_left[c] = 0; + for (c = 0; c < NIN; c++) + x->level[c] = 0; +} + +const struct esk_dev_ops esk_stm32g4_dmamux_ops = { + "stm32g4-dmamux", mux_read, mux_write, mux_reset, 0, 0, +}; + +void *esk_stm32g4_dmamux_create(struct esk_mach *m, struct esk_rf_periph *p) +{ + struct dmamux *x = (struct dmamux *)esk_mach_alloc(m, sizeof *x); + const struct esk_rf *rf = m->rf; + char n[16]; + int c, i; + if (!x) + return 0; + x->s = m; + x->p = p; + for (c = 0; c < NMUX; c++) { + snprintf(n, sizeof n, "C%dCR", c); + x->cr[c] = esk_rf_reg(p, n); + if (!x->cr[c]) + break; + } + x->nch = c; + for (c = 0; c < NGEN; c++) { + snprintf(n, sizeof n, "RG%dCR", c); + x->rg[c] = esk_rf_reg(p, n); + if (!x->rg[c]) + return 0; + } + x->csr = esk_rf_reg(p, "CSR"); + x->cfr = esk_rf_reg(p, "CFR"); + x->rgsr = esk_rf_reg(p, "RGSR"); + x->rgcfr = esk_rf_reg(p, "RGCFR"); + if (!x->nch || !x->csr || !x->cfr || !x->rgsr || !x->rgcfr) + return 0; + x->irq = esk_rf_irq(p, "OVR"); + /* the request lines, as the description numbers them */ + for (i = 0; rf && i < rf->ndma; i++) + if (!strcmp(rf->dma_ctl[i], "DMAMUX") && rf->dma_chan[i] > 0 && rf->dma_chan[i] < NID) + x->id_sig[rf->dma_chan[i]] = rf->dma_sig[i]; + esk_rf_set_mwv(x->cfr, ~(u64)0, ESK_MWV_MODIFY); + esk_rf_set_mwv(x->rgcfr, ~(u64)0, ESK_MWV_MODIFY); + mux_reset(x); + return x; +} + +/* ---- the peripherals' side ----------------------------------------------------- */ + +void esk_stm32g4_dma_request(struct esk_mach *s, const char *sig, int level) +{ + struct dmamux *x = mux_of(s); + if (!x) + return; + if (!level) { + pend_remove(x, sig); + return; + } + pend_add(x, sig); /* served now if a channel takes it, else it waits */ + mux_drain(x); +} + +void esk_stm32g4_dmamux_input(struct esk_mach *s, const char *sig, int level) +{ + struct dmamux *x = mux_of(s); + int in = -1; + if (!x || !sig) + return; + if (!strncmp(sig, "EXTI", 4) && sig[4] >= '0' && sig[4] <= '9') + in = (int)strtol(sig + 4, NULL, 10); + else if (!strcmp(sig, "LPTIM1_OUT")) + in = 20; + if ((in >= 0 && in < 16) || in == 20) + mux_input(x, in, level); +} diff --git a/core/mcu/stm32/exti.c b/core/mcu/stm32/exti.c index 5f344034a..a49b0c14a 100644 --- a/core/mcu/stm32/exti.c +++ b/core/mcu/stm32/exti.c @@ -21,26 +21,43 @@ * - an edge or a SWIER trigger on a line whose EMR bit is set is an event * to the core: it ends a WFE (esk_cortexm_event); * - an edge on line 9 is the DAC's external trigger, on lines 11 and 15 - * the ADCs' (EXTI_11, EXTI_15). */ + * the ADCs' (EXTI_11, EXTI_15). + * + * The STM32G4's (RM0440 15), its registers in two banks (IMR1 to PR1 for + * lines 0 to 31, IMR2 to PR2 for 32 to 43): the configurable lines as + * above, their internal sources' interrupts by the G4's names (16 and 38 + * to 41 PVD_PVM, 17 RTC_ALARM, 19 RTC_TAMP_CSS_LSE, 20 RTC_WKUP, 21, 22 + * and 29 COMP1_2_3, 30 to 32 COMP4_5_6, 33 COMP7); the direct lines (18, + * 23 to 28, 34 to 37, 42, 43: the USB's, the I2Cs', U(S)ARTs', LPUART's + * and LPTIM's wake-ups) have no edge detection or pending bit, their + * peripherals' interrupts being their own; an edge on lines 0 to 15 is also + * the DMA request multiplexer's synchronisation and trigger input. */ #include #include #include "mcu/stm32/stm32.h" +#define MAX_LINES 64 + struct exti { struct esk_mach *s; struct esk_rf_periph *p; - struct esk_rf_reg *imr, *emr, *rtsr, *ftsr, *swier, *pr; - int nlines; - int irq[32]; + /* bank 0: lines 0-31, bank 1: lines 32-63 */ + struct esk_rf_reg *imr[2], *emr[2], *rtsr[2], *ftsr[2], *swier[2], *pr[2]; + int nbanks, nlines, g4; + int irq[MAX_LINES]; }; +static u64 pending(const struct exti *x, int b) +{ + return x->pr[b] && x->imr[b] ? x->pr[b]->value & x->imr[b]->value : 0; +} + static void pend(struct exti *x) { - u32 act = (u32)(x->pr->value & x->imr->value); int k, last = -1; for (k = 0; k < x->nlines; k++) - if ((act >> k & 1) && x->irq[k] >= 0 && x->irq[k] != last) { + if ((pending(x, k / 32) >> (k % 32) & 1) && x->irq[k] >= 0 && x->irq[k] != last) { esk_rf_interrupt(x->p, x->irq[k]); last = x->irq[k]; } @@ -56,15 +73,26 @@ void esk_stm32_exti_input(struct esk_mach *s, int line, int level) { struct exti *x = exti_of(s); u64 bit; + int b; if (!x || line < 0 || line >= x->nlines) return; - bit = (u64)1u << line; - if ((level && (x->rtsr->value & bit)) || (!level && (x->ftsr->value & bit))) { - esk_rf_hw(x->pr, x->pr->value | bit); - if (x->emr && (x->emr->value & bit)) + b = line / 32; + bit = (u64)1u << (line % 32); + if (!x->rtsr[b] || !x->ftsr[b] || !x->pr[b]) + return; + if (line < 16 && x->g4) { + /* the DMA request multiplexer's synchronisation and trigger inputs + * see every edge of lines 0-15 (dmamux_g4.c) */ + char sig[8]; + snprintf(sig, sizeof sig, "EXTI%d", line); + esk_stm32_trigger(s, sig, level); + } + if ((level && (x->rtsr[b]->value & bit)) || (!level && (x->ftsr[b]->value & bit))) { + esk_rf_hw(x->pr[b], x->pr[b]->value | bit); + if (x->emr[b] && (x->emr[b]->value & bit)) esk_cortexm_event(s); pend(x); - if (line == 9 || line == 11 || line == 15) { + if (!x->g4 && (line == 9 || line == 11 || line == 15)) { /* the line's edge: the DAC's (9) and the ADCs' (11, 15) trigger */ char sig[8]; snprintf(sig, sizeof sig, "EXTI%d", line); @@ -74,6 +102,19 @@ void esk_stm32_exti_input(struct esk_mach *s, int line, int level) } } +/* a direct line's event (a G4's wake-up lines): an event to the core when + * its EMR bit is set */ +void esk_stm32_exti_direct(struct esk_mach *s, int line) +{ + struct exti *x = exti_of(s); + int b; + if (!x || line < 0 || line >= x->nlines) + return; + b = line / 32; + if (x->emr[b] && (x->emr[b]->value >> (line % 32) & 1)) + esk_cortexm_event(s); +} + static u32 exti_read(void *ctx, u32 off, int n) { struct exti *x = (struct exti *)ctx; @@ -83,19 +124,26 @@ static u32 exti_read(void *ctx, u32 off, int n) static void exti_write(void *ctx, u32 off, int n, u32 v) { struct exti *x = (struct exti *)ctx; - u64 sw0 = x->swier->value, pr0 = x->pr->value; - esk_rf_write(x->p, off, n, v); - if (off == esk_rf_off(x->swier)) { - u64 up = x->swier->value & ~sw0; - if (up) - esk_rf_hw(x->pr, x->pr->value | up); - if (x->emr && (up & x->emr->value)) - esk_cortexm_event(x->s); + u64 sw0[2], pr0[2]; + int b; + for (b = 0; b < x->nbanks; b++) { + sw0[b] = x->swier[b] ? x->swier[b]->value : 0; + pr0[b] = x->pr[b] ? x->pr[b]->value : 0; } - if (off == esk_rf_off(x->pr)) { - u64 cleared = pr0 & ~x->pr->value; - if (cleared) - esk_rf_hw(x->swier, x->swier->value & ~cleared); + esk_rf_write(x->p, off, n, v); + for (b = 0; b < x->nbanks; b++) { + if (x->swier[b] && off == esk_rf_off(x->swier[b])) { + u64 up = x->swier[b]->value & ~sw0[b]; + if (up && x->pr[b]) + esk_rf_hw(x->pr[b], x->pr[b]->value | up); + if (x->emr[b] && (up & x->emr[b]->value)) + esk_cortexm_event(x->s); + } + if (x->pr[b] && off == esk_rf_off(x->pr[b])) { + u64 cleared = pr0[b] & ~x->pr[b]->value; + if (cleared && x->swier[b]) + esk_rf_hw(x->swier[b], x->swier[b]->value & ~cleared); + } } pend(x); } @@ -106,7 +154,7 @@ const struct esk_dev_ops esk_stm32_exti_ops = { /* the interrupt of an internal line (16 and up), by the names the parts * give them, or -1 */ -static int line_irq(struct esk_rf *rf, int k) +static int line_irq(struct esk_rf *rf, int k, int g4) { static const char *const names[][3] = { { "PVD", 0, 0 }, /* 16 */ @@ -118,6 +166,15 @@ static int line_irq(struct esk_rf *rf, int k) { "RTC_WKUP", 0, 0 }, /* 22 */ }; int i, n; + if (g4) { + static const char *const g4names[44] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "PVD_PVM", "RTC_ALARM", 0, "RTC_TAMP_CSS_LSE", "RTC_WKUP", "COMP1_2_3", "COMP1_2_3", 0, + 0, 0, 0, 0, 0, "COMP1_2_3", "COMP4_5_6", "COMP4_5_6", + "COMP4_5_6", "COMP7", 0, 0, 0, 0, "PVD_PVM", "PVD_PVM", "PVD_PVM", "PVD_PVM", 0, 0, + }; + return k < 44 && g4names[k] ? esk_rf_irq_named(rf, g4names[k]) : -1; + } if (k < 16 || k - 16 >= (int)(sizeof names / sizeof names[0])) return -1; for (i = 0; i < 3 && names[k - 16][i]; i++) @@ -126,36 +183,70 @@ static int line_irq(struct esk_rf *rf, int k) return -1; } +static int bank_lines(const struct esk_rf_reg *imr) +{ + int k, n = 0; + for (k = 0; imr && k < imr->nf; k++) + if (imr->f[k].name && imr->f[k].lsb + imr->f[k].width > n) + n = imr->f[k].lsb + imr->f[k].width; + return n; +} + void *esk_stm32_exti_create(struct esk_mach *s, struct esk_rf_periph *p) { struct exti x, *c; + static const char *const sfx[2] = { "1", "2" }; char name[16]; - int k; + int k, b; memset(&x, 0, sizeof x); x.s = s; x.p = p; - x.imr = esk_rf_reg(p, "IMR"); - x.emr = esk_rf_reg(p, "EMR"); - x.rtsr = esk_rf_reg(p, "RTSR"); - x.ftsr = esk_rf_reg(p, "FTSR"); - x.swier = esk_rf_reg(p, "SWIER"); - x.pr = esk_rf_reg(p, "PR"); - if (!x.imr || !x.rtsr || !x.ftsr || !x.swier || !x.pr) + x.imr[0] = esk_rf_reg(p, "IMR"); + if (x.imr[0]) { + x.nbanks = 1; + x.emr[0] = esk_rf_reg(p, "EMR"); + x.rtsr[0] = esk_rf_reg(p, "RTSR"); + x.ftsr[0] = esk_rf_reg(p, "FTSR"); + x.swier[0] = esk_rf_reg(p, "SWIER"); + x.pr[0] = esk_rf_reg(p, "PR"); + } else { + /* the G4's two banks */ + for (b = 0; b < 2; b++) { + snprintf(name, sizeof name, "IMR%s", sfx[b]); + x.imr[b] = esk_rf_reg(p, name); + snprintf(name, sizeof name, "EMR%s", sfx[b]); + x.emr[b] = esk_rf_reg(p, name); + snprintf(name, sizeof name, "RTSR%s", sfx[b]); + x.rtsr[b] = esk_rf_reg(p, name); + snprintf(name, sizeof name, "FTSR%s", sfx[b]); + x.ftsr[b] = esk_rf_reg(p, name); + snprintf(name, sizeof name, "SWIER%s", sfx[b]); + x.swier[b] = esk_rf_reg(p, name); + snprintf(name, sizeof name, "PR%s", sfx[b]); + x.pr[b] = esk_rf_reg(p, name); + if (x.imr[b]) + x.nbanks = b + 1; + } + x.g4 = 1; + } + if (!x.imr[0] || !x.rtsr[0] || !x.ftsr[0] || !x.swier[0] || !x.pr[0]) return 0; /* the lines IMR has a bit for */ - for (k = 0; k < x.imr->nf; k++) - if (x.imr->f[k].name && x.imr->f[k].lsb + x.imr->f[k].width > x.nlines) - x.nlines = x.imr->f[k].lsb + x.imr->f[k].width; - if (x.nlines < 16 || x.nlines > 32) + x.nlines = bank_lines(x.imr[0]); + if (x.nbanks == 2) + x.nlines = 32 + bank_lines(x.imr[1]); + if (x.nlines < 16 || x.nlines > MAX_LINES) x.nlines = 16; for (k = 0; k < x.nlines; k++) { if (k < 5) snprintf(name, sizeof name, "EXTI%d", k); else snprintf(name, sizeof name, "%s", k < 10 ? "EXTI9_5" : "EXTI15_10"); - x.irq[k] = k < 16 ? esk_rf_irq(p, name) : line_irq(s->rf, k); + x.irq[k] = k < 16 ? esk_rf_irq(p, name) : line_irq(s->rf, k, x.g4); } - esk_rf_set_mwv(x.pr, ~(u64)0, ESK_MWV_1CLR); + for (b = 0; b < x.nbanks; b++) + if (x.pr[b]) + esk_rf_set_mwv(x.pr[b], ~(u64)0, ESK_MWV_1CLR); c = (struct exti *)esk_mach_alloc(s, sizeof *c); if (c) *c = x; diff --git a/core/mcu/stm32/flash_g4.c b/core/mcu/stm32/flash_g4.c new file mode 100644 index 000000000..4641495f1 --- /dev/null +++ b/core/mcu/stm32/flash_g4.c @@ -0,0 +1,731 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* flash_g4.c -- the STM32G4's flash interface (RM0440 5), over the + * register file, for the 512 KiB category 3 parts (the STM32G474xE): + * - the organisation: with the option bytes' DBANK set (the factory's) + * two banks of 256 KiB, bank 1 at 0x08000000 and bank 2 at + * 0x08040000, of 128 pages of 2 KiB each; with DBANK clear one bank of + * 128 pages of 4 KiB; + * - KEYR's keys (0x45670123, then 0xCDEF89AB) clear CR's LOCK; a wrong + * key is a bus error and keeps CR locked until the next reset; LOCK + * set by the program locks it again. A locked CR ignores writes; + * - programming (PG): a double word at a time, its first word stored at + * an address aligned on 8 bytes and its second at the next word; the + * program starts with the second. A store that is not a word is + * SIZERR, one out of the pair's place PGAERR, one without PG (or with + * PER or MER set) PGSERR, one to a page the option bytes' WRP areas + * protect WRPERR; a double word that is not erased is PROGERR unless + * all of it is written 0. A refused store changes nothing; + * - fast programming (FSTPG): a row of 32 double words (256 bytes) from + * its first, each stored in order; a double word out of order is + * MISSERR, and the row is programmed at once when its last arrives; + * - erasing: PER with PNB (and BKER in dual-bank mode) and STRT erases a + * page, MER1 and MER2 their banks (both: the main memory), to 0xFF; a + * protected page is WRPERR and stays; + * - SR: EOP at an operation's end when EOPIE is set; an error sets + * OPERR when ERRIE is set; both raise the FLASH interrupt; the flags + * are cleared by writing 1; + * - read-while-write: an operation on one bank stalls a program running + * from that bank until it ends (the bus waits, nothing runs); one + * running from the other bank, or from SRAM, goes on and polls BSY; a + * store to the flash while BSY is set waits for it; + * - timing: BSY for DS12288's typical times: a double word 81.7 us, a + * fast-programmed row 1.91 ms, a page's erase 22.02 ms, a bank's 22.13 + * ms; EOP at their end; + * - the option bytes: OPTKEYR's keys (0x08192A3B, 0x4C5D6E7F) clear CR's + * OPTLOCK; OPTSTRT writes OPTR, PCROP1SR/ER, WRP1AR/BR, SEC1R to bank + * 1's option bytes (0x1FFF7800) and PCROP2SR/ER, WRP2AR/BR, SEC2R to + * bank 2's (0x1FFFF808), each word followed by its complement; each + * reset loads them, a word whose complement does not match taking its + * default (and OPTVERR); OBL_LAUNCH reloads them through a system + * reset (RCC_CSR's OBLRSTF). What they say acts from then: the write + * protection and the banks here, the watchdogs' hardware start + * (wdg.c), the low-power resets (pwr_g4.c), the boot: BOOT0 is PB8's + * level at reset while nSWBOOT0 is 1, else nBOOT0's complement; BOOT0 + * high with nBOOT1 set boots the system memory (ST's bootloader, not + * simulated: the runtime says so and the core stays idle); + * - read timing (RM0440 5.3.2): the memory is read 64 bits at a time, + * each read taking ACR.LATENCY wait states; a fetch from the double + * word being executed waits nothing; with PRFTEN the next one is read + * meanwhile; with ICEN the instruction cache holds 32 lines, with DCEN + * the data cache 8 (LRU); ICRST and DCRST empty them. + * + * Not modelled: the times' spread and maximum values (the typical value + * each time), the option bytes' programming time (OPTSTRT is done at once), + * the read protection's levels and their regression's mass erase (RDP is + * stored), PCROP's read refusal (RDERR) and the securable area's + * protection (SEC_PROT, BOOT_LOCK), ECC (ECCR never reports an error), + * the bank swap (BFB2 and SYSCFG's FB_MODE are kept; bank 1 stays at + * 0x08000000), the boot from SRAM (BOOT0 high with nBOOT1 clear: the + * part boots its flash here), a reset during an operation leaving the memory + * half-programmed, the power-down modes (PDKEYR, RUN_PD, SLEEP_PD), the + * caches' line length (lines of one double word here). */ +#include + +#include "mcu/stm32/stm32.h" + +#define FLASH_BASE 0x08000000u +#define FLASH_SIZE (512u * 1024u) +#define BANK_SIZE (256u * 1024u) +#define OTP_BASE 0x1FFF7000u +#define OTP_SIZE 1024u +#define OB1_BASE 0x1FFF7800u +#define OB2_BASE 0x1FFFF800u + +#define KEY1 0x45670123u +#define KEY2 0xCDEF89ABu +#define OPTKEY1 0x08192A3Bu +#define OPTKEY2 0x4C5D6E7Fu + +#define SR_EOP (1u << 0) +#define SR_OPERR (1u << 1) +#define SR_PROGERR (1u << 3) +#define SR_WRPERR (1u << 4) +#define SR_PGAERR (1u << 5) +#define SR_SIZERR (1u << 6) +#define SR_PGSERR (1u << 7) +#define SR_MISSERR (1u << 8) +#define SR_FASTERR (1u << 9) +#define SR_RDERR (1u << 14) +#define SR_OPTVERR (1u << 15) +#define SR_BSY (1u << 16) +#define SR_W1C 0xC3FBu + +#define CR_PG (1u << 0) +#define CR_PER (1u << 1) +#define CR_MER1 (1u << 2) +#define CR_BKER (1u << 11) +#define CR_MER2 (1u << 15) +#define CR_STRT (1u << 16) +#define CR_OPTSTRT (1u << 17) +#define CR_FSTPG (1u << 18) +#define CR_EOPIE (1u << 24) +#define CR_ERRIE (1u << 25) +#define CR_OBL_LAUNCH (1u << 27) +#define CR_OPTLOCK (1u << 30) +#define CR_LOCK (1u << 31) + +#define OPTR_DBANK (1u << 22) + +#define ACR_PRFTEN 0x100u +#define ACR_ICEN 0x200u +#define ACR_DCEN 0x400u +#define ACR_ICRST 0x800u +#define ACR_DCRST 0x1000u + +#define ILINES 32 +#define DLINES 8 +#define NO_LINE 0xFFFFFFFFu + +/* DS12288 Rev 6's typical programming times (table 47) */ +#define PS_US 1000000ull +#define PROGRAM_PS (81700000ull) +#define ROW_PS (1910ull * PS_US) +#define PAGE_ERASE_PS (22020ull * PS_US) +#define BANK_ERASE_PS (22130ull * PS_US) + +/* the option registers and their place in the option bytes: bank 1's at + * OB1_BASE + off, bank 2's at OB2_BASE + off */ +static const struct { const char *reg; int bank; u32 off; u32 dflt; } obs[] = { + { "OPTR", 1, 0x00, 0xFFEFF8AAu }, { "PCROP1SR", 1, 0x08, 0x00007FFFu }, { "PCROP1ER", 1, 0x10, 0 }, + { "WRP1AR", 1, 0x18, 0x0000007Fu }, { "WRP1BR", 1, 0x20, 0x0000007Fu }, { "SEC1R", 1, 0x28, 0 }, + { "PCROP2SR", 2, 0x08, 0x00007FFFu }, { "PCROP2ER", 2, 0x10, 0 }, { "WRP2AR", 2, 0x18, 0x0000007Fu }, + { "WRP2BR", 2, 0x20, 0x0000007Fu }, { "SEC2R", 2, 0x28, 0 }, +}; +#define NOBS ((int)(sizeof obs / sizeof obs[0])) + +struct g4flash { + struct esk_mach *s; + struct esk_rf_periph *p; + struct esk_rf_reg *acr, *keyr, *optkeyr, *sr, *cr, *optr, *ob[NOBS]; + int irq; + int key_step, optkey_step, wrong_key; + /* the double word being programmed: its first word's address and value */ + int half; + u32 at, lo; + /* fast programming: the row's start, the double words received, the data */ + u32 row; + int row_n; + u32 row_data[64]; + /* the operation in progress */ + int busy, running, bank; + u64 left_ps, since; + /* read timing */ + u32 cur_line, pf_line; + u64 pf_ready, use; + u32 iline[ILINES], dline[DLINES]; + u64 iuse[ILINES], duse[DLINES]; +}; + +static int dual(const struct g4flash *f) { return f->optr && (f->optr->value & OPTR_DBANK) != 0; } + +static u32 page_size(const struct g4flash *f) { return dual(f) ? 2048u : 4096u; } + +/* the bank (1 or 2) holding main-memory offset `off` */ +static int bank_of(const struct g4flash *f, u32 off) +{ + return dual(f) && off >= BANK_SIZE ? 2 : 1; +} + +/* whether the WRP areas protect the page at `off` */ +static int protected_at(const struct g4flash *f, u32 off) +{ + int b = bank_of(f, off), k; + u32 page = (dual(f) ? off % BANK_SIZE : off) / page_size(f); + for (k = 0; k < 2; k++) { + const char *name = b == 1 ? (k ? "WRP1BR" : "WRP1AR") : (k ? "WRP2BR" : "WRP2AR"); + struct esk_rf_reg *r = esk_rf_reg(f->p, name); + u32 v, strt, end; + if (!r) + continue; + v = (u32)r->value; + strt = v & 0x7Fu; + end = v >> 16 & 0x7Fu; + if (strt <= end && page >= strt && page <= end) + return 1; + } + return 0; +} + +static void irq_if(struct g4flash *f) +{ + u32 sr = (u32)f->sr->value, cr = (u32)f->cr->value; + if (((sr & SR_EOP) && (cr & CR_EOPIE)) || ((sr & SR_OPERR) && (cr & CR_ERRIE))) + esk_rf_interrupt(f->p, f->irq); +} + +static void done(struct g4flash *f, u32 err) +{ + u32 sr = (u32)f->sr->value; + if (err) { + sr |= err; + if (f->cr->value & CR_ERRIE) + sr |= SR_OPERR; + } else if (f->cr->value & CR_EOPIE) { + sr |= SR_EOP; + } + esk_rf_hw(f->sr, sr); + irq_if(f); +} + +static void flash_clock(struct g4flash *f) +{ + if (f->busy && !f->running) + f->since = f->s->cycles; + esk_rf_clock(f->p, &f->running, f->busy); +} + +static void finish(struct g4flash *f) +{ + if (!f->busy) + return; + f->busy = 0; + esk_rf_hw(f->sr, f->sr->value & ~(u64)SR_BSY); + esk_rf_hw(f->cr, f->cr->value & ~(u64)CR_STRT); + flash_clock(f); + done(f, 0); +} + +static u64 ps_to_cycles(const struct g4flash *f, u64 ps) +{ + u64 khz = esk_mach_core_hz(f->s) / 1000u; + return (ps * (khz ? khz : 16000u) + 999999999ull) / 1000000000ull; +} + +/* an accepted operation on bank `bank` (0: both) takes `ps`; a program + * running from that bank stalls until it ends */ +static void begin(struct g4flash *f, u64 ps, int bank) +{ + u32 pc = f->s->cpu ? f->s->cpu->ops->pc(f->s->cpu) : 0, off; + finish(f); + f->busy = 1; + f->bank = bank; + f->left_ps = ps; + esk_rf_hw(f->sr, f->sr->value | SR_BSY); + flash_clock(f); + off = pc >= FLASH_BASE && pc < FLASH_BASE + FLASH_SIZE ? pc - FLASH_BASE : pc < FLASH_SIZE ? pc : FLASH_SIZE; + if (off < FLASH_SIZE && (!bank || !dual(f) || bank_of(f, off) == bank)) + f->s->bus_stall += ps_to_cycles(f, ps); +} + +static void changed(struct g4flash *f) +{ + f->s->flash_written = 1; + esk_bus_code_changed(&f->s->bus); +} + +/* ---- programming ---------------------------------------------------------------- */ + +static int erased_dw(const u8 *p) +{ + int k; + for (k = 0; k < 8; k++) + if (p[k] != 0xFF) + return 0; + return 1; +} + +static void put_dw(struct g4flash *f, struct esk_region *r, u32 a, u32 lo, u32 hi) +{ + u8 *p = r->mem + (a - r->base); + esk_mem_wr_le(p, 4, esk_mem_rd_le(p, 4) & lo); + esk_mem_wr_le(p + 4, 4, esk_mem_rd_le(p + 4, 4) & hi); + (void)f; +} + +static void rom_write(void *ctx, struct esk_region *r, u32 a, int n, u32 v) +{ + struct g4flash *f = (struct g4flash *)ctx; + u32 cr = (u32)f->cr->value, off; + int otp = 0; + if (r->size == FLASH_SIZE && r->kind != ESK_MEM_ROM) + off = a - r->base; + else if (a >= OTP_BASE && a + (u32)n <= OTP_BASE + OTP_SIZE) + off = 0, otp = 1; + else + return; /* system memory, the option bytes: read-only to stores */ + if (f->busy && f->s->bus_stall == 0) + f->s->bus_stall = ps_to_cycles(f, f->left_ps); /* a store while BSY waits */ + if ((cr & CR_LOCK) || !(cr & (CR_PG | CR_FSTPG)) || (cr & (CR_PER | CR_MER1 | CR_MER2))) { + f->half = 0; + done(f, SR_PGSERR); + return; + } + if (n != 4) { + f->half = 0; + done(f, SR_SIZERR); + return; + } + if (!f->half) { + if (a & 7u) { + done(f, SR_PGAERR); + return; + } + if (!otp && protected_at(f, off)) { + done(f, SR_WRPERR); + return; + } + f->half = 1; + f->at = a; + f->lo = v; + return; + } + f->half = 0; + if (a != f->at + 4u) { + done(f, SR_PGAERR); + return; + } + { + const u8 *p = r->mem + (f->at - r->base); + if (!erased_dw(p) && (f->lo || v)) { + done(f, SR_PROGERR); + return; + } + } + if (cr & CR_FSTPG) { + u32 row = (f->at & ~255u); + if (f->row_n == 0) { + if (f->at != row) { + done(f, SR_MISSERR); + return; + } + f->row = row; + } else if (f->at != f->row + 8u * (u32)f->row_n) { + f->row_n = 0; + done(f, SR_MISSERR); + return; + } + f->row_data[2 * f->row_n] = f->lo; + f->row_data[2 * f->row_n + 1] = v; + if (++f->row_n < 32) + return; + { + int k; + for (k = 0; k < 32; k++) + put_dw(f, r, f->row + 8u * (u32)k, f->row_data[2 * k], f->row_data[2 * k + 1]); + } + f->row_n = 0; + changed(f); + begin(f, ROW_PS, otp ? 1 : bank_of(f, off)); + return; + } + put_dw(f, r, f->at, f->lo, v); + changed(f); + begin(f, PROGRAM_PS, otp ? 1 : bank_of(f, off)); +} + +/* ---- erasing -------------------------------------------------------------------- */ + +static void erase(struct g4flash *f, u32 off, u32 size) +{ + struct esk_region *r = esk_bus_region(&f->s->bus, FLASH_BASE + off, size); + if (r) + memset(r->mem + (FLASH_BASE + off - r->base), 0xff, size); + changed(f); +} + +static int range_protected(const struct g4flash *f, u32 off, u32 size) +{ + u32 a; + for (a = off; a < off + size; a += page_size(f)) + if (protected_at(f, a)) + return 1; + return 0; +} + +static void start(struct g4flash *f) +{ + u32 cr = (u32)f->cr->value; + if (cr & (CR_MER1 | CR_MER2)) { + u32 off = 0, size = FLASH_SIZE; + int bank = 0; + if (dual(f) && !((cr & CR_MER1) && (cr & CR_MER2))) { + bank = cr & CR_MER1 ? 1 : 2; + off = bank == 1 ? 0 : BANK_SIZE; + size = BANK_SIZE; + } + if (range_protected(f, off, size)) { + done(f, SR_WRPERR); + return; + } + erase(f, off, size); + begin(f, BANK_ERASE_PS, bank); + return; + } + if (cr & CR_PER) { + u32 pnb = cr >> 3 & 0x7Fu, off; + if (dual(f)) + off = ((cr & CR_BKER) ? BANK_SIZE : 0) + pnb * 2048u; + else + off = pnb * 4096u; + if (protected_at(f, off)) { + done(f, SR_WRPERR); + return; + } + erase(f, off, page_size(f)); + begin(f, PAGE_ERASE_PS, bank_of(f, off)); + return; + } + done(f, SR_PGSERR); /* STRT with neither PER nor MER */ +} + +/* ---- the option bytes ---------------------------------------------------------- */ + +static u32 ob_addr(int k) { return (obs[k].bank == 1 ? OB1_BASE : OB2_BASE) + obs[k].off; } + +static void load_options(struct g4flash *f) +{ + int k, bad = 0; + for (k = 0; k < NOBS; k++) { + u32 v = 0xFFFFFFFFu, nv = 0xFFFFFFFFu; + if (!f->ob[k]) + continue; + if (esk_bus_debug_read(&f->s->bus, ob_addr(k), 4, &v) || esk_bus_debug_read(&f->s->bus, ob_addr(k) + 4u, 4, &nv) || + (v ^ nv) != 0xFFFFFFFFu) { + v = obs[k].dflt; + bad = 1; + } + esk_rf_hw(f->ob[k], v); /* the reserved bits too: they read the option bytes */ + } + if (bad) + esk_rf_hw(f->sr, f->sr->value | SR_OPTVERR); +} + +static void program_options(struct g4flash *f) +{ + int k; + for (k = 0; k < NOBS; k++) { + u32 v; + if (!f->ob[k]) + continue; + v = (u32)f->ob[k]->value | (u32)~esk_rf_fields(f->ob[k]); + if (esk_bus_debug_write(&f->s->bus, ob_addr(k), 4, v) == 0) + (void)esk_bus_debug_write(&f->s->bus, ob_addr(k) + 4u, 4, ~v); + } + f->s->flash_written = 1; + done(f, 0); +} + +/* ---- read timing --------------------------------------------------------------- */ + +static void cache_clear(u32 *line, u64 *use, int n) +{ + int i; + for (i = 0; i < n; i++) { + line[i] = NO_LINE; + use[i] = 0; + } +} + +static int cache_hit(struct g4flash *f, u32 *line, u64 *use, int n, u32 l) +{ + int i; + for (i = 0; i < n; i++) + if (line[i] == l) { + use[i] = ++f->use; + return 1; + } + return 0; +} + +static void cache_fill(struct g4flash *f, u32 *line, u64 *use, int n, u32 l) +{ + int i, lru = 0; + for (i = 1; i < n; i++) + if (use[i] < use[lru]) + lru = i; + line[lru] = l; + use[lru] = ++f->use; +} + +static u32 ifetch(void *ctx, u32 off, u64 now) +{ + struct g4flash *f = (struct g4flash *)ctx; + u32 acr = (u32)f->acr->value, ws = acr & 0xfu, l = off >> 3, st; + if (l == f->cur_line) + return 0; + if ((acr & ACR_PRFTEN) && l == f->pf_line) + st = f->pf_ready > now ? (u32)(f->pf_ready - now) : 0; + else if ((acr & ACR_ICEN) && cache_hit(f, f->iline, f->iuse, ILINES, l)) + st = 0; + else { + st = ws; + if (acr & ACR_ICEN) + cache_fill(f, f->iline, f->iuse, ILINES, l); + } + f->cur_line = l; + if (acr & ACR_PRFTEN) { + f->pf_line = l + 1; + f->pf_ready = now + st + ws + 1; + } else { + f->pf_line = NO_LINE; + } + return st; +} + +static u32 dread(void *ctx, u32 off) +{ + struct g4flash *f = (struct g4flash *)ctx; + u32 acr = (u32)f->acr->value, ws = acr & 0xfu, l = off >> 3; + if (!ws) + return 0; + if (acr & ACR_DCEN) { + if (cache_hit(f, f->dline, f->duse, DLINES, l)) + return 0; + cache_fill(f, f->dline, f->duse, DLINES, l); + } + return ws; +} + +static void timing_reset(struct g4flash *f) +{ + const struct esk_region *r = esk_bus_region(&f->s->bus, FLASH_BASE, 4); + f->cur_line = f->pf_line = NO_LINE; + f->pf_ready = 0; + cache_clear(f->iline, f->iuse, ILINES); + cache_clear(f->dline, f->duse, DLINES); + if (r && f->acr) { + f->s->ftime.mem = r->mem; + f->s->ftime.ifetch = ifetch; + f->s->ftime.dread = dread; + f->s->ftime.ctx = f; + } +} + +/* ---- the registers -------------------------------------------------------------- */ + +static u32 flash_read(void *ctx, u32 off, int n) +{ + struct g4flash *f = (struct g4flash *)ctx; + if (off - esk_rf_off(f->keyr) < 4 || off - esk_rf_off(f->optkeyr) < 4) + return 0; /* write-only */ + return esk_rf_read(f->p, off, n); +} + +static int is_ob_reg(const struct g4flash *f, u32 off) +{ + int k; + for (k = 0; k < NOBS; k++) + if (f->ob[k] && off - esk_rf_off(f->ob[k]) < 4) + return 1; + return 0; +} + +static void flash_write(void *ctx, u32 off, int n, u32 v) +{ + struct g4flash *f = (struct g4flash *)ctx; + if (off - esk_rf_off(f->keyr) < 4) { + if (f->wrong_key || !(f->cr->value & CR_LOCK)) + return; + if (f->key_step == 0 && v == KEY1) { + f->key_step = 1; + } else if (f->key_step == 1 && v == KEY2) { + f->key_step = 0; + esk_rf_hw(f->cr, f->cr->value & ~(u64)CR_LOCK); + } else { + f->key_step = 0; + f->wrong_key = 1; + esk_bus_fault(&f->s->bus); + } + return; + } + if (off - esk_rf_off(f->optkeyr) < 4) { + if (!(f->cr->value & CR_OPTLOCK) || (f->cr->value & CR_LOCK)) + return; + if (f->optkey_step == 0 && v == OPTKEY1) { + f->optkey_step = 1; + } else if (f->optkey_step == 1 && v == OPTKEY2) { + f->optkey_step = 0; + esk_rf_hw(f->cr, f->cr->value & ~(u64)CR_OPTLOCK); + } else { + f->optkey_step = 0; + esk_bus_fault(&f->s->bus); + } + return; + } + if (off - esk_rf_off(f->sr) < 4) { + u32 clr = (v << 8 * (off - esk_rf_off(f->sr))) & SR_W1C; + esk_rf_hw(f->sr, f->sr->value & ~(u64)clr); + return; + } + if (off - esk_rf_off(f->cr) < 4) { + u32 was = (u32)f->cr->value, now; + if (was & CR_LOCK) + return; + if (f->busy) + return; + esk_rf_write(f->p, off, n, v); + now = (u32)f->cr->value; + if (was & CR_OPTLOCK) /* OPTSTRT and OBL_LAUNCH need OPTLOCK clear */ + now &= ~(CR_OPTSTRT | CR_OBL_LAUNCH); + if ((was & CR_OPTLOCK) && !(now & CR_OPTLOCK)) + now |= CR_OPTLOCK; /* cleared only by the keys */ + esk_rf_hw(f->cr, now); + if (!(now & (CR_PG | CR_FSTPG))) + f->half = 0, f->row_n = 0; + if ((now & CR_STRT) && !(was & CR_STRT)) { + start(f); + if (!f->busy) + esk_rf_hw(f->cr, f->cr->value & ~(u64)CR_STRT); + } + if ((now & CR_OPTSTRT) && !(was & CR_OPTSTRT)) { + program_options(f); + esk_rf_hw(f->cr, f->cr->value & ~(u64)CR_OPTSTRT); + } + if (now & CR_OBL_LAUNCH) { + /* the option bytes reload through a system reset */ + esk_stm32g4_rcc_obl(f->s); + if (!f->s->reset_req) { + f->s->reset_cause = ESK_RESET_SOFTWARE; + f->s->reset_req = 1; + f->s->yield = 1; + } + } + return; + } + if (is_ob_reg(f, off)) { + if (f->cr->value & CR_OPTLOCK) + return; /* the option registers are written only with OPTLOCK clear */ + esk_rf_write(f->p, off, n, v); + return; + } + esk_rf_write(f->p, off, n, v); /* ACR, ECCR, PDKEYR */ + if (f->acr && off - esk_rf_off(f->acr) < 4) { + u32 acr = (u32)f->acr->value; + if ((acr & ACR_ICRST) && !(acr & ACR_ICEN)) + cache_clear(f->iline, f->iuse, ILINES); + if ((acr & ACR_DCRST) && !(acr & ACR_DCEN)) + cache_clear(f->dline, f->duse, DLINES); + esk_stm32g4_rcc_check(f->s); + } +} + +static void flash_tick(void *ctx, u32 cycles) +{ + struct g4flash *f = (struct g4flash *)ctx; + u64 ps, khz; + if (!f->running) + return; + if (f->since > f->s->cycles) + f->since = 0; + cycles = esk_mach_after(f->s, cycles, f->since); + f->since = 0; + khz = esk_mach_core_hz(f->s) / 1000u; + ps = (u64)cycles * 1000000000ull / (khz ? khz : 16000u); + if (f->left_ps <= ps) + finish(f); + else + f->left_ps -= ps; +} + +static int flash_next(void *ctx, u32 *cycles) +{ + struct g4flash *f = (struct g4flash *)ctx; + u64 n; + if (!f->running) + return 0; + n = ps_to_cycles(f, f->left_ps); + *cycles = n == 0 ? 1 : n > 0xffffffffu ? 0xffffffffu : (u32)n; + return 1; +} + +static void flash_reset(void *ctx) +{ + struct g4flash *f = (struct g4flash *)ctx; + timing_reset(f); + f->busy = f->running = 0; + f->key_step = f->optkey_step = 0; + f->wrong_key = 0; + f->half = 0; + f->row_n = 0; + load_options(f); +} + +/* RM0440 2.6, table 6: BOOT0 from PB8 (nSWBOOT0 1) or the complement of + * nBOOT0; with BOOT0 high and nBOOT1 set, the system memory */ +static int boot_system(struct esk_mach *s, int pin_high) +{ + struct esk_rf_periph *p = s->rf ? esk_rf_periph(s->rf, "FLASH") : 0; + struct esk_rf_reg *optr = p ? esk_rf_reg(p, "OPTR") : 0; + u32 o; + int boot0; + if (!optr) + return 0; + o = (u32)optr->value; + boot0 = (o >> 26 & 1u) ? pin_high : !(o >> 27 & 1u); + return boot0 && (o >> 23 & 1u); +} + +const struct esk_dev_ops esk_stm32g4_flash_ops = { + "stm32g4-flash", flash_read, flash_write, flash_reset, flash_tick, flash_next, +}; + +void *esk_stm32g4_flash_create(struct esk_mach *s, struct esk_rf_periph *p) +{ + struct g4flash *f; + int k; + if (!esk_rf_reg(p, "OPTR") || !esk_rf_reg(p, "KEYR") || !esk_rf_reg(p, "CR") || !esk_rf_reg(p, "SR")) + return 0; + f = (struct g4flash *)esk_mach_alloc(s, sizeof *f); + if (!f) + return 0; + f->s = s; + f->p = p; + f->acr = esk_rf_reg(p, "ACR"); + f->keyr = esk_rf_reg(p, "KEYR"); + f->optkeyr = esk_rf_reg(p, "OPTKEYR"); + f->sr = esk_rf_reg(p, "SR"); + f->cr = esk_rf_reg(p, "CR"); + f->optr = esk_rf_reg(p, "OPTR"); + if (!f->optkeyr) + return 0; + for (k = 0; k < NOBS; k++) + f->ob[k] = esk_rf_reg(p, obs[k].reg); + f->irq = esk_rf_irq(p, "FLASH"); + s->bus.rom_write = rom_write; + s->bus.rom_write_ctx = f; + s->boot_pin = "PB8"; + s->boot_system = boot_system; + timing_reset(f); + return f; +} diff --git a/core/mcu/stm32/gpio_f4.c b/core/mcu/stm32/gpio_f4.c index 57ee105fe..68c9857ef 100644 --- a/core/mcu/stm32/gpio_f4.c +++ b/core/mcu/stm32/gpio_f4.c @@ -11,7 +11,8 @@ * from the description's io.electrical; PUPDR's pull-up (01) or * pull-down (10) is on in every mode but analog (11 is reserved: none); * - BSRR's low half sets ODR's bits and its high half resets them, the set - * winning when both are written; it reads 0; + * winning when both are written; it reads 0; BRR (the G4's, RM0440 + * 8.4.11) resets the bits its low half has set, and reads 0; * - IDR is what each pin reads through its Schmitt trigger, sampled as it * is read: an output's level (an open-drain output's 1 lets go, and the * pin reads what the circuit makes of it, else the pull, else 0, @@ -56,10 +57,11 @@ struct f4gpio { struct esk_mach *s; struct esk_rf_periph *p; - struct esk_rf_reg *moder, *otyper, *ospeedr, *pupdr, *idr, *odr, *bsrr, *lckr, *afrl, *afrh; + struct esk_rf_reg *moder, *otyper, *ospeedr, *pupdr, *idr, *odr, *bsrr, *lckr, *afrl, *afrh, *brr; int port; /* 0 for A */ esk_mach_pin out[16]; /* what each pin was told to be */ int af_in[16]; /* the level last given to a pin's AF inputs, -1 none */ + u32 af_num[16]; /* the alternate function that level went to */ int known; int lck_step; /* the lock sequence's writes so far (3: a read locks) */ u32 lck_bits; @@ -118,8 +120,9 @@ static void update_once(struct f4gpio *g) o.drive = -1; if (standby || (wkup >> i & 1u)) { /* Standby lets the pins go; an enabled WKUP pin is an input - * with a pull-down (pwr_f4.c) */ - o.pull = (wkup >> i & 1u) ? 2 : 0; + * with its pull (an F4's pull-down, pwr_f4.c), a G4's pins the + * pulls PWR keeps (pwr_g4.c) */ + o.pull = esk_stm32f4_pwr_standby_pull(s, g->port, i); } else if (mode == 3) { o.analog = 1; } else { @@ -156,8 +159,12 @@ static void update_once(struct f4gpio *g) else lvl = o.pull == 1; idr |= (u32)lvl << i; - if (mode == 2 && lvl != g->af_in[i]) { + if (mode == 2 && (lvl != g->af_in[i] || af_of(g, i) != g->af_num[i])) { + /* a level changed, or another function took the pin: it hears + * the pin's level at once (SPI1_SCK on PB3, after its reset's + * AF0) */ g->af_in[i] = lvl; + g->af_num[i] = af_of(g, i); af_input(g, i, af_of(g, i), lvl); } else if (mode != 2) { g->af_in[i] = -1; @@ -295,6 +302,13 @@ static void f4gpio_write(void *ctx, u32 off, int n, u32 v) esk_rf_hw(g->odr, odr); esk_rf_hw(g->bsrr, 0); } + if (g->brr && off - esk_rf_off(g->brr) < 4) { + u32 w = (n < 4 ? v & ((1u << (8 * n)) - 1) : v) << (8 * (off - esk_rf_off(g->brr))); + odr = g->odr->value & ~(u64)(w & 0xffffu); + if (odr != g->odr->value) + esk_rf_hw(g->odr, odr); + esk_rf_hw(g->brr, 0); + } update(g); } @@ -373,6 +387,7 @@ void *esk_stm32f4_gpio_create(struct esk_mach *s, struct esk_rf_periph *p) g.lckr = esk_rf_reg(p, "LCKR"); g.afrl = esk_rf_reg(p, "AFRL"); g.afrh = esk_rf_reg(p, "AFRH"); + g.brr = esk_rf_reg(p, "BRR"); if (!g.moder || !g.otyper || !g.ospeedr || !g.pupdr || !g.idr || !g.odr || !g.bsrr || !g.lckr || !g.afrl || !g.afrh || strncmp(p->name, "GPIO", 4) || p->name[4] < 'A' || p->name[4] > 'K' || p->name[5]) diff --git a/core/mcu/stm32/pwr_f4.c b/core/mcu/stm32/pwr_f4.c index 0b0882e46..e3f14a56f 100644 --- a/core/mcu/stm32/pwr_f4.c +++ b/core/mcu/stm32/pwr_f4.c @@ -143,8 +143,10 @@ static void standby_ends(struct esk_mach *m) void esk_stm32f4_pwr_wakeup(struct esk_mach *m) { struct pwr *w = f4_pwr(m); - if (!w) + if (!w) { + esk_stm32g4_pwr_wakeup(m); /* a G4's internal wake-up line */ return; + } csr_set(w, w->csr->value | CSR_WUF); if (w->mode == STANDBY) standby_ends(m); @@ -167,7 +169,9 @@ u32 esk_stm32f4_pwr_wkup_mask(struct esk_mach *m, int port) struct pwr *w = f4_pwr(m); u32 mask = 0; int pin; - if (!w || (port != 0 && port != 2)) + if (!w) + return esk_stm32g4_pwr_wkup_mask(m, port); + if (port != 0 && port != 2) return 0; for (pin = 0; pin < 16; pin++) if (wkup_bit(port, pin) && (w->csr->value & wkup_bit(port, pin))) @@ -177,6 +181,10 @@ u32 esk_stm32f4_pwr_wkup_mask(struct esk_mach *m, int port) void esk_stm32f4_pwr_pin_edge(struct esk_mach *m, int port, int pin, int level) { + if (esk_stm32g4_pwr(m)) { + esk_stm32g4_pwr_pin_edge(m, port, pin, level); + return; + } if (level && esk_stm32f4_pwr_wkup_pin(m, port, pin)) esk_stm32f4_pwr_wakeup(m); } @@ -184,7 +192,16 @@ void esk_stm32f4_pwr_pin_edge(struct esk_mach *m, int port, int pin, int level) int esk_stm32f4_pwr_standby(struct esk_mach *m) { struct pwr *w = f4_pwr(m); - return w && w->mode == STANDBY; + if (!w) + return esk_stm32g4_pwr_standby(m); + return w->mode == STANDBY; +} + +int esk_stm32f4_pwr_standby_pull(struct esk_mach *m, int port, int pin) +{ + if (esk_stm32g4_pwr(m)) + return esk_stm32g4_pwr_standby_pull(m, port, pin); + return (esk_stm32f4_pwr_wkup_mask(m, port) >> pin & 1u) ? 2 : 0; } /* a WKUP pin's level as its port reads it */ diff --git a/core/mcu/stm32/pwr_g4.c b/core/mcu/stm32/pwr_g4.c new file mode 100644 index 000000000..5fffa62d9 --- /dev/null +++ b/core/mcu/stm32/pwr_g4.c @@ -0,0 +1,411 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* pwr_g4.c -- the STM32G4's power control (RM0440 6), over the register + * file. + * + * - the voltage ranges: CR1.VOS 01 range 1 (CR5.R1MODE 0 its boost mode, + * to 170 MHz; 1 normal, to 150 MHz), 10 range 2 (26 MHz); the RCC model + * says when SYSCLK or the flash's wait states do not fit (rcc_g4.c). + * SR2.VOSF reads 0: the regulator is taken to settle at once; + * - low-power run: CR1.LPR puts the regulator in low-power mode, SR2's + * REGLPF follows it; REGLPS reads 1 (the low-power regulator ready); + * - the programmable voltage detector: with CR2.PVDE, SR2.PVDO is 1 while + * VDD is below the threshold PLS selects (DS12288's: falling 2.05 to + * 2.90 V, rising about 100 mV higher), or with PLS 111 while PVD_IN + * (PB7) is below VREFINT (1.212 V); its changes are + * EXTI line 16's input; the peripheral voltage monitors' outputs + * (PVMOx) read 0, VDDA being at VDD; + * - DBP (CR1) allows writes to the backup domain (RCC's BDCR, rcc_g4.c); + * - the wake-up pins WKUP1 to WKUP5 (PA0, PC13, PE6, PA2, PC5) with + * CR3.EWUPx: an edge of the polarity CR4.WPx gives (0 rising, 1 + * falling) sets SR1.WUFx; in Standby and Shutdown each enabled pin is + * an input with a pull-down (WPx 0) or a pull-up (WPx 1); + * - SCR's CWUFx and CSBF clear WUFx and SBF. + * + * The low-power modes (RM0440 6.3): the core's WFI or WFE with SLEEPDEEP + * set enters the mode CR1.LPMS gives: + * - Stop 0 (000) or Stop 1 (001): the core's domain's clocks stop but + * the RTC's and the IWDG's; HSE and the PLL turn off (rcc_g4.c); RAM, + * the registers and the pins keep their state; any EXTI line's + * interrupt or event wakes the core, on HSI16; + * - Standby (011): the core's domain is off. RAM is lost but SRAM2 while + * CR3.RRS keeps it; the pins let go, those CR3.APC applies keeping the + * pull-up or pull-down PUCRx or PDCRx gives them, the enabled wake-up + * pins their pull; a wake-up pin's edge, an RTC or TAMP event with its + * interrupt enabled (CR3.EIWUL, the internal wake-up line), NRST or the + * IWDG ends it with a reset of all but the backup domain, SR1.SBF set; + * - Shutdown (1xx): as Standby, SRAM2 lost too and no SBF; leaving it is + * a brownout reset (RCC_CSR's BORRSTF, rcc_g4.c). + * A wake-up flag already set as Standby or Shutdown is entered ends it + * at once. The option bytes' nRST_STOP, nRST_STDBY or nRST_SHDW cleared + * (FLASH_OPTR) makes entering that mode a reset instead (LPWRRSTF). + * + * Not modelled: the regulator's settling (VOSF never set) and the wake-up + * times (the core runs at the wake-up event), the low-power run and Stop + * modes' supply currents, the PVD's hysteresis and the PVMs' thresholds + * (VDDA is VDD here), the USB Type-C dead-battery bits (UCPD1_DBDIS, + * UCPD1_STDBY), VBAT charging (CR4.VBE, VBRS), the PVD thresholds' spread + * between parts (the typical values here). */ +#include "mcu/stm32/stm32.h" + +#define CR1_LPMS 7u +#define CR1_DBP (1u << 8) +#define CR1_LPR (1u << 14) +#define CR2_PVDE (1u << 0) +#define CR3_RRS (1u << 8) +#define CR3_APC (1u << 10) +#define CR3_EIWUL (1u << 15) +#define SR1_SBF (1u << 8) +#define SR1_WUFI (1u << 15) +#define SR2_REGLPS (1u << 8) +#define SR2_REGLPF (1u << 9) +#define SR2_PVDO (1u << 11) +/* FLASH_OPTR's user options (RM0440 5.7.6) */ +#define OPT_NRST_STOP (1u << 12) +#define OPT_NRST_STDBY (1u << 13) +#define OPT_NRST_SHDW (1u << 14) + +#define SRAM2_BASE 0x20014000u +#define SRAM2_SIZE 0x4000u + +enum { RUN, STOP, STANDBY, SHUTDOWN }; + +/* the wake-up pins: port, pin */ +static const int wkup_pin[5][2] = { { 0, 0 }, { 2, 13 }, { 4, 6 }, { 0, 2 }, { 2, 5 } }; + +struct g4pwr { + struct esk_mach *s; + struct esk_rf_periph *p; + struct esk_rf_reg *cr1, *cr2, *cr3, *cr4, *sr1, *sr2, *scr, *pucr[7], *pdcr[7]; + int mode, was_shutdown; + u64 sr1_was; + int pvdo; + int level[5]; /* each wake-up pin's level as last seen, -1 unknown */ +}; + +static struct g4pwr *g4pwr(struct esk_mach *m) +{ + struct esk_rf_periph *p = m && m->rf ? esk_rf_periph(m->rf, "PWR") : 0; + return p && p->ops == &esk_stm32g4_pwr_ops ? (struct g4pwr *)p->ctx : 0; +} + +int esk_stm32g4_pwr(struct esk_mach *m) +{ + return g4pwr(m) != 0; +} + +int esk_stm32g4_pwr_was_shutdown(struct esk_mach *m) +{ + struct g4pwr *w = g4pwr(m); + return w && w->mode == SHUTDOWN; +} + +static void sr1_set(struct g4pwr *w, u64 v) +{ + if (v != w->sr1->value) + esk_rf_hw(w->sr1, v); + w->sr1_was = v; +} + +/* ---- the PVD ------------------------------------------------------------- */ + +static int pin_volts(struct esk_mach *m, int port, int bit, double *v) +{ + return m->host.pin_volts && m->host.pin_volts(m->host.ctx, port, bit, v); +} + +static void pvd(struct g4pwr *w) +{ + /* DS12288 Rev 6 table 19's typical thresholds: PVDO rises as VDD falls + * below the falling one and clears once VDD rises above the rising one */ + static const double fall[7] = { 2.05, 2.20, 2.36, 2.52, 2.64, 2.81, 2.90 }; + static const double rise[7] = { 2.15, 2.31, 2.46, 2.61, 2.74, 2.91, 2.98 }; + struct esk_mach *m = w->s; + u32 cr2 = (u32)w->cr2->value, pls = cr2 >> 1 & 7; + int o = 0; + u64 v; + if (cr2 & CR2_PVDE) { + double vdd = m->vdd > 0.0 ? m->vdd : 3.3, in; + if (pls < 7) + o = vdd < (w->pvdo ? rise[pls] : fall[pls]); + else + o = pin_volts(m, 1, 7, &in) && in < 1.212; + } + v = (w->sr2->value & ~(u64)(SR2_PVDO | SR2_REGLPF | 0xF000u)) | SR2_REGLPS; + if (o) + v |= SR2_PVDO; + if (w->cr1->value & CR1_LPR) + v |= SR2_REGLPF; + if (v != w->sr2->value) + esk_rf_hw(w->sr2, v); + if (o != w->pvdo) { + w->pvdo = o; + esk_stm32_exti_input(m, 16, o); + } +} + +/* ---- wake-up -------------------------------------------------------------- */ + +static void standby_ends(struct esk_mach *m) +{ + if (m->reset_req) + return; + m->reset_cause = ESK_RESET_STANDBY; + m->reset_req = 1; + m->yield = 1; +} + +/* an internal wake-up event (the RTC's or TAMP's, its interrupt enabled) */ +void esk_stm32g4_pwr_wakeup(struct esk_mach *m) +{ + struct g4pwr *w = g4pwr(m); + if (!w || !(w->cr3->value & CR3_EIWUL)) + return; + sr1_set(w, w->sr1->value | SR1_WUFI); + if (w->mode == STANDBY || w->mode == SHUTDOWN) + standby_ends(m); +} + +static int wkup_of(int port, int pin) +{ + int k; + for (k = 0; k < 5; k++) + if (wkup_pin[k][0] == port && wkup_pin[k][1] == pin) + return k; + return -1; +} + +u32 esk_stm32g4_pwr_wkup_mask(struct esk_mach *m, int port) +{ + struct g4pwr *w = g4pwr(m); + u32 mask = 0; + int k; + if (!w) + return 0; + for (k = 0; k < 5; k++) + if (wkup_pin[k][0] == port && (w->cr3->value >> k & 1)) + mask |= 1u << wkup_pin[k][1]; + return mask; +} + +int esk_stm32g4_pwr_standby(struct esk_mach *m) +{ + struct g4pwr *w = g4pwr(m); + return w && (w->mode == STANDBY || w->mode == SHUTDOWN); +} + +/* the pull a pin has in Standby or Shutdown: 1 up, 2 down, 0 none */ +int esk_stm32g4_pwr_standby_pull(struct esk_mach *m, int port, int pin) +{ + struct g4pwr *w = g4pwr(m); + int k = wkup_of(port, pin); + if (!w) + return 0; + if (k >= 0 && (w->cr3->value >> k & 1)) + return (w->cr4->value >> k & 1) ? 1 : 2; + if ((w->cr3->value & CR3_APC) && port >= 0 && port < 7) { + if (w->pucr[port] && (w->pucr[port]->value >> pin & 1)) + return 1; + if (w->pdcr[port] && (w->pdcr[port]->value >> pin & 1)) + return 2; + } + return 0; +} + +void esk_stm32g4_pwr_pin_edge(struct esk_mach *m, int port, int pin, int level) +{ + struct g4pwr *w = g4pwr(m); + int k = wkup_of(port, pin); + if (!w || k < 0) + return; + if (w->level[k] == level) + return; + w->level[k] = level; + if (!(w->cr3->value >> k & 1)) + return; + if (level == !((w->cr4->value >> k) & 1)) { /* WPx 0: rising; 1: falling */ + sr1_set(w, w->sr1->value | (u64)1u << k); + if (w->mode == STANDBY || w->mode == SHUTDOWN) + standby_ends(m); + } +} + +/* ---- Stop, Standby and Shutdown -------------------------------------------- */ + +static int allowed(struct esk_mach *m, u32 opt) +{ + struct esk_rf_periph *f = esk_rf_periph(m->rf, "FLASH"); + struct esk_rf_reg *optr = f ? esk_rf_reg(f, "OPTR") : 0; + return !optr || (optr->value & opt) != 0; +} + +/* RAM lost, but [keep, keep + n) */ +static void ram_lost(struct esk_mach *m, u32 keep, u32 n) +{ + int r; + for (r = 0; r < m->bus.nrg; r++) { + struct esk_region *g = &m->bus.rg[r]; + u32 a; + if (g->kind != ESK_MEM_RAM || g->mirror || !g->mem) + continue; + if (!n || keep + n <= g->base || keep >= g->base + g->size) { + esk_bus_erase(g); + continue; + } + for (a = 0; a + 4 <= g->size; a += 4) + if (g->base + a < keep || g->base + a >= keep + n) + esk_mem_wr_le(g->mem + a, 4, g->erased); + g->gen++; + } +} + +static void deep_sleep(struct esk_mach *m) +{ + struct g4pwr *w = g4pwr(m); + u32 lpms, opt; + if (!w || w->mode != RUN) + return; + esk_mach_sync(m); + lpms = (u32)w->cr1->value & CR1_LPMS; + opt = lpms <= 1 ? OPT_NRST_STOP : lpms == 3 ? OPT_NRST_STDBY : lpms & 4 ? OPT_NRST_SHDW : OPT_NRST_STOP; + if (!allowed(m, opt)) { + esk_rf_diag(m, ES_SEV_INFO, "mcu.low_power_reset", "%s", + opt == OPT_NRST_STOP ? "the option bytes' nRST_STOP is 0: entering Stop resets the part" + : opt == OPT_NRST_STDBY ? "the option bytes' nRST_STDBY is 0: entering Standby resets the part" + : "the option bytes' nRST_SHDW is 0: entering Shutdown resets the part"); + if (!m->reset_req) { + m->reset_cause = ESK_RESET_LOW_POWER; + m->reset_req = 1; + m->yield = 1; + } + return; + } + esk_stm32g4_rcc_stop(m, 1); + if (lpms <= 1 || lpms == 2) { /* 010 is reserved: taken as Stop 1 */ + w->mode = STOP; + esk_mach_clocks(m, 1); + return; + } + w->mode = lpms == 3 ? STANDBY : SHUTDOWN; + if (w->mode == STANDBY && (w->cr3->value & CR3_RRS)) + ram_lost(m, SRAM2_BASE, SRAM2_SIZE); + else + ram_lost(m, 0, 0); + m->powered_down = 1; + esk_mach_clocks(m, 1); + esk_stm32f4_pins_changed(m); /* they let go */ + if (w->sr1->value & (0x1Fu | SR1_WUFI)) + standby_ends(m); +} + +static void deep_wake(struct esk_mach *m) +{ + struct g4pwr *w = g4pwr(m); + if (w && (w->mode == STANDBY || w->mode == SHUTDOWN)) { + m->asleep = 1; /* only a reset ends them */ + return; + } + if (w) + w->mode = RUN; + esk_mach_clocks(m, 0); +} + +/* ---- the registers ----------------------------------------------------------------- */ + +static u32 pwr_read(void *ctx, u32 off, int n) +{ + struct g4pwr *w = (struct g4pwr *)ctx; + if (off == esk_rf_off(w->sr2)) + pvd(w); + return esk_rf_read(w->p, off, n); +} + +static void pwr_write(void *ctx, u32 off, int n, u32 v) +{ + struct g4pwr *w = (struct g4pwr *)ctx; + struct esk_mach *m = w->s; + u64 cr3 = w->cr3->value, cr4 = w->cr4->value, cr1 = w->cr1->value, cr5 = 0; + struct esk_rf_reg *r5 = esk_rf_reg(w->p, "CR5"); + if (r5) + cr5 = r5->value; + esk_rf_write(w->p, off, n, v); + if (w->scr && off == esk_rf_off(w->scr)) { + u64 clear = (w->scr->value & 0x1Fu) | ((w->scr->value & 0x100u) ? SR1_SBF : 0u); + esk_rf_hw(w->scr, 0); + sr1_set(w, w->sr1->value & ~clear); + if (clear & 0x1Fu) + esk_rf_hw(w->sr1, w->sr1->value & ~(u64)SR1_WUFI); + } + pvd(w); + if (((cr1 ^ w->cr1->value) >> 9 & 3) || (r5 && ((cr5 ^ r5->value) & 0x100u))) + esk_stm32g4_rcc_check(m); + if ((cr3 ^ w->cr3->value) & (0x1Fu | CR3_APC) || (cr4 ^ w->cr4->value) & 0x1Fu) { + int port; + for (port = 0; port < 7; port++) + esk_stm32f4_port_changed(m, port); /* the wake-up pins' pulls */ + } +} + +static void pwr_reset(void *ctx) +{ + struct g4pwr *w = (struct g4pwr *)ctx; + struct esk_mach *m = w->s; + u64 keep = 0; + int k; + if (m->reset_cause == ESK_RESET_STANDBY && w->mode == STANDBY) + keep = (w->sr1_was & 0x801Fu) | SR1_SBF; + else if (m->reset_cause == ESK_RESET_STANDBY) + keep = w->sr1_was & 0x801Fu; /* Shutdown: no SBF */ + else if (m->reset_cause != ESK_RESET_POWER) + keep = w->sr1_was & SR1_SBF; + w->was_shutdown = w->mode == SHUTDOWN; + w->mode = RUN; + w->pvdo = 0; + for (k = 0; k < 5; k++) + w->level[k] = -1; + esk_rf_hw(w->sr1, keep); + w->sr1_was = keep; + pvd(w); +} + +const struct esk_dev_ops esk_stm32g4_pwr_ops = { "stm32g4-pwr", pwr_read, pwr_write, pwr_reset, 0, 0 }; + +void *esk_stm32g4_pwr_create(struct esk_mach *m, struct esk_rf_periph *p) +{ + struct g4pwr *w; + char name[8]; + int k; + if (!esk_rf_reg(p, "CR1") || !esk_rf_reg(p, "SR1") || !esk_rf_reg(p, "SCR") || !esk_rf_reg(p, "CR3") || + !esk_rf_reg(p, "CR4") || !esk_rf_reg(p, "SR2") || !esk_rf_reg(p, "CR2")) + return 0; + w = (struct g4pwr *)esk_mach_alloc(m, sizeof *w); + if (!w) + return 0; + w->s = m; + w->p = p; + w->cr1 = esk_rf_reg(p, "CR1"); + w->cr2 = esk_rf_reg(p, "CR2"); + w->cr3 = esk_rf_reg(p, "CR3"); + w->cr4 = esk_rf_reg(p, "CR4"); + w->sr1 = esk_rf_reg(p, "SR1"); + w->sr2 = esk_rf_reg(p, "SR2"); + w->scr = esk_rf_reg(p, "SCR"); + for (k = 0; k < 7; k++) { + name[0] = 'P'; + name[1] = 'U'; + name[2] = 'C'; + name[3] = 'R'; + name[4] = (char)('A' + k); + name[5] = 0; + w->pucr[k] = esk_rf_reg(p, name); + name[1] = 'D'; + w->pdcr[k] = esk_rf_reg(p, name); + } + for (k = 0; k < 5; k++) + w->level[k] = -1; + /* the flags read-only to the program, cleared through SCR */ + esk_rf_set_acc(w->sr1, 0x811Fu, ESK_ACC_RO); + m->deep_sleep = deep_sleep; + m->deep_wake = deep_wake; + return w; +} diff --git a/core/mcu/stm32/rcc.c b/core/mcu/stm32/rcc.c index 0c504e6b2..599a73dca 100644 --- a/core/mcu/stm32/rcc.c +++ b/core/mcu/stm32/rcc.c @@ -568,12 +568,16 @@ static u32 f4_core_hz(struct esk_mach *s) u32 esk_stm32_hclk(struct esk_mach *s) { struct rcc *c = any_rcc(s); + if (esk_stm32g4_rcc(s)) + return esk_stm32g4_hclk(s); return c && (c->f1 || c->f4) ? c->hclk : 0; } u32 esk_stm32_pclk(struct esk_mach *s, int apb) { struct rcc *c = any_rcc(s); + if (esk_stm32g4_rcc(s)) + return esk_stm32g4_pclk(s, apb); if (c && c->f4) return c->hclk / f4_ppre_div(c, apb); return esk_stm32f1_pclk(s, apb); @@ -583,6 +587,8 @@ u32 esk_stm32_timclk(struct esk_mach *s, int apb) { struct rcc *c = any_rcc(s); u32 d; + if (esk_stm32g4_rcc(s)) + return esk_stm32g4_timclk(s, apb); if (!c || !c->f4) { u32 p = esk_stm32f1_pclk(s, apb), h = esk_stm32f1_hclk(s); return p == h ? p : 2 * p; @@ -753,6 +759,10 @@ static void rcc_write(void *ctx, u32 off, int n, u32 v) void esk_stm32_rcc_lsi(struct esk_mach *s) { struct esk_rf_periph *p = s->rf ? esk_rf_periph(s->rf, "RCC") : 0; + if (esk_stm32g4_rcc(s)) { + esk_stm32g4_rcc_lsi(s); + return; + } if (p && p->ops == &esk_stm32_rcc_ops) lsi_forced((struct rcc *)p->ctx); } diff --git a/core/mcu/stm32/rcc_g4.c b/core/mcu/stm32/rcc_g4.c new file mode 100644 index 000000000..dfddfd7fd --- /dev/null +++ b/core/mcu/stm32/rcc_g4.c @@ -0,0 +1,919 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* rcc_g4.c -- the STM32G4's reset and clock control (RM0440 7), over the + * register file. + * + * The clocks (RM0440 7.2): + * - HSI16 16 MHz (CR.HSION, out of reset), HSE the board's crystal or + * clock (esk_mach.hse_hz), ready only as the board drives OSC_IN: a + * crystal with HSEBYP clear, a clock with it set; LSI 32 kHz + * (CSR.LSION, or forced by the IWDG); LSE the board's 32.768 kHz + * crystal (BDCR.LSEON, not with LSEBYP); HSI48 48 MHz (CRRCR.HSI48ON); + * - each is ready its start-up time after it is turned on and its ready + * bit then sets (HSIRDY, HSERDY, LSIRDY, LSERDY, HSI48RDY); off, it is + * not ready at once. LSE keeps running through every reset but a + * power-on one, as the backup domain does; + * - the main PLL from HSI16 or HSE (PLLCFGR.PLLSRC 10, 11; 00 none): its + * VCO's input is the source over PLLM + 1, its output that times PLLN; + * PLLP the VCO over PLLPDIV (2 to 31), or 7 or 17 (PLLP) while PLLPDIV + * is 0; PLLQ and PLLR the VCO over 2, 4, 6 or 8; each output on while + * its PLLxEN is set; PLLRDY sets the PLL's lock time after PLLON with + * its source ready; + * - SYSCLK from HSI16 (SW 01), HSE (10) or PLLR (11, with PLLREN), + * switched once the source is ready (CFGR.SWS); HCLK over HPRE (1 to + * 512), PCLK1 and PCLK2 over PPRE1 and PPRE2 (1 to 16); the timers' + * clock is the APB's when its prescaler is 1, else twice it; + * - what the system clock uses cannot be turned off (RM0440 7.4.1: + * HSION, HSEON and PLLON stay set while used, directly or through the + * PLL), and HSEBYP keeps its value while HSE is on; + * - CIER, CIFR, CICR: a source that becomes ready with its RDYIE set sets + * its RDYF and makes the RCC interrupt pending; CICR's bits clear the + * flags (CICR reads 0); + * - the peripherals' kernel clocks as CCIPR and CCIPR2 select them + * (esk_stm32g4_kernel_hz: the U(S)ARTs and LPUART, the I2Cs, LPTIM1, + * the ADCs, the FDCANs, the 48 MHz clock, the QUADSPI, SAI1 and I2S); + * - MCO (CFGR.MCOSEL, MCOPRE) as a frequency (esk_stm32g4_mco_hz) for + * the pins' model; + * - BDCR is written only while PWR_CR1's DBP allows it; BDRST resets the + * backup domain (the RTC's and TAMP's registers); + * - what the datasheet forbids is said, once, as a warning + * (mcu.clock_out_of_spec): a VCO input outside 2.66 to 16 MHz or + * output outside 96 to 344 MHz, a PLL output above 170 MHz, SYSCLK + * above the voltage range's limit (PWR's: range 1 boost 170 MHz, range + * 1 normal 150, range 2 26); and too few flash wait states for HCLK + * (mcu.flash_wait_states, RM0440 table 9): the part would fetch wrong + * instructions, the model only warns. + * + * Resets (RM0440 7.1): a peripheral's bit in an *RSTR register set by a + * write resets it, its registers back to their reset values; CSR's flags + * record each reset: BORRSTF and PINRSTF at power-on; PINRSTF with every + * other (the part drives NRST low) and SFTRSTF, IWDGRSTF, WWDGRSTF, + * LPWRRSTF or OBLRSTF (the option bytes' reload) with its cause, the + * earlier flags kept until RMVF clears them; leaving Standby keeps them. + * BDCR keeps its value through every reset but a power-on one; LSIRDY sets + * while the IWDG runs, which forces LSI on. + * + * The start-up times, in DS12288's typical values: HSI16 0.8 us, an HSE + * crystal 2 ms (an external clock six of its periods), LSI 80 us, LSE 2 s, + * HSI48 2.5 us, the PLL's lock 15 us. + * + * Not modelled: the clock security systems (CSSON and LSECSSON are kept; + * the board's oscillators never fail), the start-up times' spread and + * their dependence on temperature, LSEDRV's drive strength, HSITRIM's and + * HSI48CAL's effect on the frequencies (the nominal frequencies always), + * the CRS's trimming of HSI48 (the CRS model's), a peripheral held in + * reset while its *RSTR bit stays set (its reset happens on the write), + * the brownout reset (BORRSTF only at power-on), the low-power modes' + * sleep enables (*SMENR: a peripheral's clock in Sleep is its run + * clock). */ +#include +#include + +#include "mcu/stm32/stm32.h" + +#define HSI_HZ 16000000u +#define LSI_HZ 32000u +#define HSI48_HZ 48000000u + +/* CR */ +#define HSION (1u << 8) +#define HSIRDY (1u << 10) +#define HSEON (1u << 16) +#define HSERDY (1u << 17) +#define HSEBYP (1u << 18) +#define PLLON (1u << 24) +#define PLLRDY (1u << 25) +/* CSR */ +#define LSION (1u << 0) +#define LSIRDY (1u << 1) +#define RMVF (1u << 23) +#define CSR_FLAGS 0xfe000000u +#define OBLRSTF (1u << 25) +#define PINRSTF (1u << 26) +#define BORRSTF (1u << 27) +#define SFTRSTF (1u << 28) +#define IWDGRSTF (1u << 29) +#define WWDGRSTF (1u << 30) +#define LPWRRSTF (1u << 31) +/* BDCR */ +#define LSEON (1u << 0) +#define LSERDY (1u << 1) +#define LSEBYP (1u << 2) +#define BDRST (1u << 16) +/* CRRCR */ +#define HSI48ON (1u << 0) +#define HSI48RDY (1u << 1) +/* PLLCFGR */ +#define PLLPEN (1u << 16) +#define PLLQEN (1u << 20) +#define PLLREN (1u << 24) + +#define PS_US 1000000ull + +/* the clock sources, the PLL after its sources */ +enum { O_HSI, O_HSE, O_PLL, O_LSI, O_LSE, O_HSI48, O_N }; +/* CIER/CIFR/CICR's bit for each */ +static const int osc_irq_bit[O_N] = { 3, 4, 5, 0, 1, 10 }; + +enum { W_VCO_IN = 1, W_VCO_OUT = 2, W_SYSCLK = 4, W_FLASH = 8, W_PLL_OUT = 16 }; + +struct g4rcc { + struct esk_mach *s; + struct esk_rf_periph *p; + struct esk_rf_reg *cr, *cfgr, *pllcfgr, *cier, *cifr, *cicr, *csr, *bdcr, *crrcr, *ccipr, *ccipr2; + struct osc { int ready, starting; u64 left_ps; } osc[O_N]; + int running, irq; + u64 since; + u32 hclk; + unsigned warned; + u32 csr_flags; + u64 bdcr_kept; + int obl; /* the coming reset is the option bytes' reload */ + struct rst { struct esk_rf_periph *q; struct esk_rf_reg *r; u64 m; } *rst; + int nrst; +}; + +static u32 bits(const struct esk_rf_reg *r, int lsb, int width) +{ + return r ? (u32)(r->value >> lsb) & ((1u << width) - 1) : 0; +} + +static void set_bit(u64 *v, u32 bit, int on) +{ + *v = on ? (*v | bit) : (*v & ~(u64)bit); +} + +static u32 g4_core_hz(struct esk_mach *s); + +static struct g4rcc *g4(struct esk_mach *s) +{ + return s && s->core_hz == g4_core_hz ? (struct g4rcc *)s->clock_ctx : 0; +} + +int esk_stm32g4_rcc(struct esk_mach *s) +{ + return g4(s) != 0; +} + +/* ---- frequencies -------------------------------------------------------- */ + +static u32 pll_src_hz(const struct g4rcc *c) +{ + u32 src = bits(c->pllcfgr, 0, 2); + return src == 2 ? HSI_HZ : src == 3 ? c->s->hse_hz : 0; +} + +static u32 vco_in(const struct g4rcc *c) +{ + return pll_src_hz(c) / (bits(c->pllcfgr, 4, 4) + 1); +} + +static u64 vco(const struct g4rcc *c) +{ + return (u64)vco_in(c) * bits(c->pllcfgr, 8, 7); +} + +/* the PLL's P, Q and R outputs ('P', 'Q', 'R'): 0 while it is not locked or + * the output is off */ +static u32 pll_out(const struct g4rcc *c, char which) +{ + u32 d; + if (!(c->cr->value & PLLRDY)) + return 0; + switch (which) { + case 'P': + if (!(c->pllcfgr->value & PLLPEN)) + return 0; + d = bits(c->pllcfgr, 27, 5); + if (d == 1) + return 0; /* reserved */ + if (!d) + d = bits(c->pllcfgr, 17, 1) ? 17 : 7; + break; + case 'Q': + if (!(c->pllcfgr->value & PLLQEN)) + return 0; + d = 2 * (bits(c->pllcfgr, 21, 2) + 1); + break; + default: + if (!(c->pllcfgr->value & PLLREN)) + return 0; + d = 2 * (bits(c->pllcfgr, 25, 2) + 1); + break; + } + return (u32)(vco(c) / d); +} + +static u32 sysclk_of(const struct g4rcc *c, u32 sw) +{ + return sw == 1 ? HSI_HZ : sw == 2 ? c->s->hse_hz : sw == 3 ? pll_out(c, 'R') : HSI_HZ; +} + +static u32 sysclk(const struct g4rcc *c) +{ + return sysclk_of(c, bits(c->cfgr, 2, 2)); +} + +static u32 hpre_div(u32 hpre) +{ + static const u32 d[8] = { 2, 4, 8, 16, 64, 128, 256, 512 }; + return hpre & 8 ? d[hpre & 7] : 1; +} + +static u32 ppre_div(const struct g4rcc *c, int apb) +{ + u32 v = bits(c->cfgr, apb == 2 ? 11 : 8, 3); + return v & 4 ? 2u << (v & 3) : 1; +} + +static u32 calc_hclk(const struct g4rcc *c) +{ + return sysclk(c) / hpre_div(bits(c->cfgr, 4, 4)); +} + +static int src_ready(const struct g4rcc *c, u32 sw) +{ + if (sw == 1) + return c->osc[O_HSI].ready; + if (sw == 2) + return c->osc[O_HSE].ready; + if (sw == 3) + return c->osc[O_PLL].ready && (c->pllcfgr->value & PLLREN); + return 0; +} + +static struct esk_rf_reg *other_reg(struct esk_mach *s, const char *periph, const char *reg) +{ + struct esk_rf_periph *p = s->rf ? esk_rf_periph(s->rf, periph) : 0; + return p ? esk_rf_reg(p, reg) : 0; +} + +/* ---- the datasheet's limits ----------------------------------------------- */ + +static void warn(struct g4rcc *c, unsigned w, const char *code, const char *fmt, u32 a, u32 b) +{ + char msg[200]; + if (c->warned & w) + return; + c->warned |= w; + snprintf(msg, sizeof msg, fmt, a, b); + esk_rf_diag(c->s, ES_SEV_WARNING, code, "%s", msg); +} + +/* PWR's voltage range: 1 boost, 1 normal or 2 (PWR_CR1.VOS, PWR_CR5.R1MODE) */ +static u32 range_limit(struct esk_mach *s, u32 *lim) +{ + struct esk_rf_reg *cr1 = other_reg(s, "PWR", "CR1"), *cr5 = other_reg(s, "PWR", "CR5"); + u32 vos = cr1 ? (u32)(cr1->value >> 9 & 3) : 1; + if (vos == 2) { + *lim = 26000000u; + return 2; + } + if (cr5 && !(cr5->value & (1u << 8))) { + *lim = 170000000u; + return 0; /* range 1 boost (R1MODE 0) */ + } + *lim = 150000000u; + return 1; +} + +/* RM0440 table 9: the highest HCLK each wait-state count allows */ +static u32 flash_limit(u32 range, u32 ws) +{ + static const u32 boost[5] = { 34, 68, 102, 136, 170 }, normal[5] = { 30, 60, 90, 120, 150 }, + r2[3] = { 12, 24, 26 }; + if (range == 2) + return ws < 3 ? r2[ws] * 1000000u : 26000000u; + if (ws > 4) + return 170000000u; + return (range == 0 ? boost[ws] : normal[ws]) * 1000000u; +} + +static void check(struct g4rcc *c) +{ + u32 lim, range = range_limit(c->s, &lim), sys = sysclk(c); + struct esk_rf_reg *acr = other_reg(c->s, "FLASH", "ACR"); + if (c->cr->value & PLLON) { + u32 in = vco_in(c); + u64 out = vco(c); + if (in && (in < 2660000u || in > 16000000u)) + warn(c, W_VCO_IN, "mcu.clock_out_of_spec", + "the PLL's VCO input is %u Hz, outside 2.66 to 16 MHz (DS12288)", in, 0); + if (out && (out < 96000000u || out > 344000000u)) + warn(c, W_VCO_OUT, "mcu.clock_out_of_spec", + "the PLL's VCO output is %u Hz, outside 96 to 344 MHz (DS12288)", (u32)out, 0); + if (pll_out(c, 'R') > 170000000u || pll_out(c, 'Q') > 170000000u || pll_out(c, 'P') > 170000000u) + warn(c, W_PLL_OUT, "mcu.clock_out_of_spec", "a PLL output is above 170 MHz (DS12288)", 0, 0); + } + if (sys > lim) + warn(c, W_SYSCLK, "mcu.clock_out_of_spec", "SYSCLK %u Hz is above the voltage range's %u Hz (RM0440 6.1.5)", + sys, lim); + if (acr && c->hclk > flash_limit(range, (u32)(acr->value & 15))) + warn(c, W_FLASH, "mcu.flash_wait_states", + "HCLK %u Hz needs more flash wait states than LATENCY %u (RM0440 table 9)", c->hclk, + (u32)(acr->value & 15)); +} + +void esk_stm32g4_rcc_check(struct esk_mach *s) +{ + struct g4rcc *c = g4(s); + if (c) { + c->warned &= ~(unsigned)(W_SYSCLK | W_FLASH); /* a new setting: said again if still wrong */ + check(c); + } +} + +/* ---- the oscillators' start-ups ---------------------------------------- */ + +static u64 startup_ps(const struct g4rcc *c, int i) +{ + switch (i) { + case O_HSI: return 800000ull; + case O_HSE: + if (c->s->hse_clock) + return c->s->hse_hz ? 6000000000000ull / c->s->hse_hz : 1; + return 2000ull * PS_US; + case O_PLL: return 15ull * PS_US; + case O_LSI: return 80ull * PS_US; + case O_LSE: return 2000000ull * PS_US; + default: return 2500000ull; /* HSI48 */ + } +} + +static void clock_run(struct g4rcc *c) +{ + int i, any = 0; + for (i = 0; i < O_N; i++) + any |= c->osc[i].starting; + if (any && !c->running) + c->since = c->s->cycles; + esk_rf_clock(c->p, &c->running, any); +} + +static void follow(struct g4rcc *c, int i, int want) +{ + struct osc *o = &c->osc[i]; + if (!want) { + o->ready = o->starting = 0; + } else if (!o->ready && !o->starting) { + o->starting = 1; + o->left_ps = startup_ps(c, i); + } +} + +static int ready_bit(const struct g4rcc *c, int i) +{ + switch (i) { + case O_HSI: return (c->cr->value & HSIRDY) != 0; + case O_HSE: return (c->cr->value & HSERDY) != 0; + case O_PLL: return (c->cr->value & PLLRDY) != 0; + case O_LSI: return c->csr && (c->csr->value & LSIRDY); + case O_LSE: return c->bdcr && (c->bdcr->value & LSERDY); + default: return c->crrcr && (c->crrcr->value & HSI48RDY); + } +} + +/* the ready bits, the clock in use; a new HCLK ends the quantum */ +static void settle(struct g4rcc *c) +{ + u64 cr = c->cr->value, v; + u32 sws = bits(c->cfgr, 2, 2), sw = bits(c->cfgr, 0, 2), src = bits(c->pllcfgr, 0, 2), h; + int want[O_N], i, hse_ok; + unsigned was = 0; + for (i = 0; i < O_N; i++) + if (ready_bit(c, i)) + was |= 1u << i; + /* what the system clock uses cannot be turned off */ + if (sws == 1 || (sws == 3 && src == 2)) + cr |= HSION; + if (sws == 2 || (sws == 3 && src == 3)) + cr |= HSEON; + if (sws == 3) + cr |= PLLON; + hse_ok = c->s->hse_hz && ((cr & HSEBYP) != 0) == (c->s->hse_clock != 0); + want[O_HSI] = (cr & HSION) != 0; + want[O_HSE] = (cr & HSEON) && hse_ok; + want[O_LSI] = c->csr && ((c->csr->value & LSION) || esk_stm32_iwdg_running(c->s)); + want[O_LSE] = c->bdcr && (c->bdcr->value & LSEON) && c->s->lse_hz && !(c->bdcr->value & LSEBYP); + want[O_HSI48] = c->crrcr && (c->crrcr->value & HSI48ON); + for (i = 0; i < O_N; i++) { + if (i == O_PLL) { + int src_ok = src == 2 ? c->osc[O_HSI].ready : src == 3 ? c->osc[O_HSE].ready : 0; + want[O_PLL] = (cr & PLLON) && src_ok; + } + follow(c, i, want[i]); + } + set_bit(&cr, HSIRDY, c->osc[O_HSI].ready); + set_bit(&cr, HSERDY, c->osc[O_HSE].ready); + set_bit(&cr, PLLRDY, c->osc[O_PLL].ready); + if (cr != c->cr->value) + esk_rf_hw(c->cr, cr); + if (c->csr) { + v = c->csr->value; + set_bit(&v, LSIRDY, c->osc[O_LSI].ready); + if (v != c->csr->value) + esk_rf_hw(c->csr, v); + } + if (c->bdcr) { + v = c->bdcr->value; + set_bit(&v, LSERDY, c->osc[O_LSE].ready); + if (v != c->bdcr->value) + esk_rf_hw(c->bdcr, v); + } + if (c->crrcr) { + v = c->crrcr->value; + set_bit(&v, HSI48RDY, c->osc[O_HSI48].ready); + if (v != c->crrcr->value) + esk_rf_hw(c->crrcr, v); + } + /* CIFR: a source that has become ready with its interrupt enabled */ + for (i = 0; i < O_N; i++) + if (c->osc[i].ready && !(was >> i & 1) && c->cier && c->cifr) { + u64 f = (u64)1 << osc_irq_bit[i]; + if ((c->cier->value & f) && !(c->cifr->value & f)) { + esk_rf_hw(c->cifr, c->cifr->value | f); + if (c->irq >= 0) + esk_rf_interrupt(c->p, c->irq); + } + } + clock_run(c); + if (sw != sws && src_ready(c, sw)) + esk_rf_hw(c->cfgr, (c->cfgr->value & ~(u64)0xC) | (u64)sw << 2); + else if (sws == 3 && !src_ready(c, 3)) + esk_rf_hw(c->cfgr, (c->cfgr->value & ~(u64)0xF) | 5u); /* the PLL lost: back to HSI16 */ + h = calc_hclk(c); + if (h != c->hclk) { + c->hclk = h; + c->s->yield = 1; + } + check(c); +} + +/* ---- the clocks other models ask for --------------------------------------- */ + +static u32 g4_core_hz(struct esk_mach *s) +{ + struct g4rcc *c = g4(s); + return c ? c->hclk : 0; +} + +u32 esk_stm32g4_hclk(struct esk_mach *s) +{ + struct g4rcc *c = g4(s); + return c ? c->hclk : 0; +} + +u32 esk_stm32g4_pclk(struct esk_mach *s, int apb) +{ + struct g4rcc *c = g4(s); + return c ? c->hclk / ppre_div(c, apb) : 0; +} + +u32 esk_stm32g4_timclk(struct esk_mach *s, int apb) +{ + struct g4rcc *c = g4(s); + u32 d; + if (!c) + return 0; + d = ppre_div(c, apb); + return d == 1 ? c->hclk : 2 * (c->hclk / d); +} + +u32 esk_stm32g4_sysclk(struct esk_mach *s) +{ + struct g4rcc *c = g4(s); + return c ? sysclk(c) : 0; +} + +int esk_stm32g4_osc_ready(struct esk_mach *s, char which) +{ + struct g4rcc *c = g4(s); + if (!c) + return 0; + switch (which) { + case 'H': return c->osc[O_HSI].ready; + case 'E': return c->osc[O_HSE].ready; + case 'I': return c->osc[O_LSI].ready; + case 'L': return c->osc[O_LSE].ready; + case '4': return c->osc[O_HSI48].ready; + default: return 0; + } +} + +u32 esk_stm32g4_pll_hz(struct esk_mach *s, char which) +{ + struct g4rcc *c = g4(s); + return c ? pll_out(c, which) : 0; +} + +/* a 2-bit CCIPR selection of PCLK (00), SYSCLK (01), HSI16 (10), LSE (11) */ +static u32 sel_pclk_sys_hsi_lse(const struct g4rcc *c, u32 sel, int apb) +{ + switch (sel) { + case 0: return c->hclk / ppre_div(c, apb); + case 1: return sysclk(c); + case 2: return c->osc[O_HSI].ready ? HSI_HZ : 0; + default: return c->osc[O_LSE].ready ? c->s->lse_hz : 0; + } +} + +u32 esk_stm32g4_kernel_hz(struct esk_mach *s, const char *periph) +{ + struct g4rcc *c = g4(s); + u32 sel; + if (!c || !periph) + return 0; + if (!strcmp(periph, "USART1")) + return sel_pclk_sys_hsi_lse(c, bits(c->ccipr, 0, 2), 2); + if (!strcmp(periph, "USART2")) + return sel_pclk_sys_hsi_lse(c, bits(c->ccipr, 2, 2), 1); + if (!strcmp(periph, "USART3")) + return sel_pclk_sys_hsi_lse(c, bits(c->ccipr, 4, 2), 1); + if (!strcmp(periph, "UART4")) + return sel_pclk_sys_hsi_lse(c, bits(c->ccipr, 6, 2), 1); + if (!strcmp(periph, "UART5")) + return sel_pclk_sys_hsi_lse(c, bits(c->ccipr, 8, 2), 1); + if (!strcmp(periph, "LPUART1")) + return sel_pclk_sys_hsi_lse(c, bits(c->ccipr, 10, 2), 1); + if (!strncmp(periph, "I2C", 3)) { + int k = periph[3] - '0'; + sel = k == 4 ? bits(c->ccipr2, 0, 2) : k >= 1 && k <= 3 ? bits(c->ccipr, 12 + 2 * (k - 1), 2) : 0; + return sel == 3 ? 0 : sel_pclk_sys_hsi_lse(c, sel, 1); + } + if (!strcmp(periph, "LPTIM1")) { + sel = bits(c->ccipr, 18, 2); + return sel == 0 ? c->hclk / ppre_div(c, 1) + : sel == 1 ? (c->osc[O_LSI].ready ? LSI_HZ : 0) + : sel == 2 ? (c->osc[O_HSI].ready ? HSI_HZ : 0) + : (c->osc[O_LSE].ready ? c->s->lse_hz : 0); + } + if (!strcmp(periph, "SAI1") || !strcmp(periph, "I2S23")) { + sel = bits(c->ccipr, !strcmp(periph, "SAI1") ? 20 : 22, 2); + return sel == 0 ? sysclk(c) : sel == 1 ? pll_out(c, 'Q') : sel == 3 ? (c->osc[O_HSI].ready ? HSI_HZ : 0) : 0; + } + if (!strncmp(periph, "FDCAN", 5)) { + sel = bits(c->ccipr, 24, 2); + return sel == 0 ? (c->osc[O_HSE].ready ? c->s->hse_hz : 0) : sel == 1 ? pll_out(c, 'Q') + : sel == 2 ? c->hclk / ppre_div(c, 1) : 0; + } + if (!strcmp(periph, "CLK48")) { + sel = bits(c->ccipr, 26, 2); + return sel == 0 ? (c->osc[O_HSI48].ready ? HSI48_HZ : 0) : sel == 2 ? pll_out(c, 'Q') : 0; + } + if (!strcmp(periph, "ADC12") || !strcmp(periph, "ADC345")) { + sel = bits(c->ccipr, !strcmp(periph, "ADC12") ? 28 : 30, 2); + return sel == 1 ? pll_out(c, 'P') : sel == 2 ? sysclk(c) : 0; + } + if (!strcmp(periph, "QUADSPI")) { + sel = bits(c->ccipr2, 20, 2); + return sel == 0 ? sysclk(c) : sel == 1 ? (c->osc[O_HSI].ready ? HSI_HZ : 0) : sel == 2 ? pll_out(c, 'Q') : 0; + } + if (!strcmp(periph, "RTC")) { + sel = c->bdcr ? (u32)(c->bdcr->value >> 8 & 3) : 0; + return sel == 1 ? (c->osc[O_LSE].ready ? c->s->lse_hz : 0) : sel == 2 ? (c->osc[O_LSI].ready ? LSI_HZ : 0) + : sel == 3 ? (c->osc[O_HSE].ready ? c->s->hse_hz / 32 : 0) : 0; + } + return 0; +} + +u32 esk_stm32g4_mco_hz(struct esk_mach *s) +{ + struct g4rcc *c = g4(s); + u32 sel, pre, hz; + if (!c) + return 0; + sel = bits(c->cfgr, 24, 4); + pre = bits(c->cfgr, 28, 3); + switch (sel) { + case 1: hz = sysclk(c); break; + case 3: hz = c->osc[O_HSI].ready ? HSI_HZ : 0; break; + case 4: hz = c->osc[O_HSE].ready ? c->s->hse_hz : 0; break; + case 5: hz = pll_out(c, 'R') ? (u32)(vco(c) / (2 * (bits(c->pllcfgr, 25, 2) + 1))) : 0; break; + case 6: hz = c->osc[O_LSI].ready ? LSI_HZ : 0; break; + case 7: hz = c->osc[O_LSE].ready ? c->s->lse_hz : 0; break; + case 8: hz = c->osc[O_HSI48].ready ? HSI48_HZ : 0; break; + default: hz = 0; break; + } + return pre <= 4 ? hz >> pre : 0; +} + +/* ---- Stop and Standby -------------------------------------------------------- */ + +void esk_stm32g4_rcc_stop(struct esk_mach *s, int wake_hsi) +{ + struct g4rcc *c = g4(s); + u64 cr; + if (!c) + return; + esk_stm32_rtc_sync(s); + /* RM0440 7.2.7: HSE and the PLL stop; the part wakes on HSI16 (STOPWUCK + * is the G4's HSI16 only) */ + cr = c->cr->value & ~(u64)(HSEON | PLLON); + (void)wake_hsi; + esk_rf_hw(c->cr, cr | HSION); + esk_rf_hw(c->cfgr, (c->cfgr->value & ~(u64)0xF) | 5u); + settle(c); + esk_stm32_rtc_sync(s); +} + +void esk_stm32g4_rcc_obl(struct esk_mach *s) +{ + struct g4rcc *c = g4(s); + if (c) + c->obl = 1; +} + +/* ---- the device -------------------------------------------------------------- */ + +static u32 tick_hz(const struct g4rcc *c) { return c->hclk >= 1000u ? c->hclk : HSI_HZ; } + +static void rcc_tick(void *ctx, u32 cycles) +{ + struct g4rcc *c = (struct g4rcc *)ctx; + u64 ps; + int i, done = 0; + if (!c->running) + return; + if (c->since > c->s->cycles) + c->since = 0; + cycles = esk_mach_after(c->s, cycles, c->since); + c->since = 0; + ps = (u64)cycles * 1000000000ull / (tick_hz(c) / 1000u); + for (i = 0; i < O_N; i++) { + struct osc *o = &c->osc[i]; + if (!o->starting) + continue; + if (o->left_ps <= ps) { + o->starting = 0; + o->ready = 1; + done = 1; + } else { + o->left_ps -= ps; + } + } + if (done) { + esk_stm32_rtc_sync(c->s); + settle(c); + esk_stm32_rtc_sync(c->s); + c->s->yield = 1; + } else { + clock_run(c); + } +} + +static int rcc_next(void *ctx, u32 *cycles) +{ + struct g4rcc *c = (struct g4rcc *)ctx; + u64 best = ~(u64)0, k = tick_hz(c) / 1000u; + int i; + if (!c->running) + return 0; + for (i = 0; i < O_N; i++) + if (c->osc[i].starting) { + u64 n = (c->osc[i].left_ps * k + 999999999ull) / 1000000000ull; + if (n < best) + best = n; + } + if (best == ~(u64)0) + return 0; + *cycles = best == 0 ? 1 : best > 0xffffffffu ? 0xffffffffu : (u32)best; + return 1; +} + +static u32 rcc_read(void *ctx, u32 off, int n) +{ + struct g4rcc *c = (struct g4rcc *)ctx; + return esk_rf_read(c->p, off, n); +} + +static void lsi_forced(struct g4rcc *c) +{ + if (esk_stm32_iwdg_running(c->s) && !c->osc[O_LSI].ready && !c->osc[O_LSI].starting) + settle(c); +} + +static void rcc_write(void *ctx, u32 off, int n, u32 v) +{ + struct g4rcc *c = (struct g4rcc *)ctx; + int i; + esk_stm32_rtc_sync(c->s); + if (c->bdcr && off - esk_rf_off(c->bdcr) < 4) { + struct esk_rf_reg *pcr = other_reg(c->s, "PWR", "CR1"); + if (pcr && !(pcr->value & (1u << 8))) + return; /* DBP clear: the backup domain is write-protected */ + } + if (c->csr && off - esk_rf_off(c->csr) < 4 && (v & RMVF)) { + c->csr_flags = 0; + v &= ~CSR_FLAGS; + esk_rf_hw(c->csr, c->csr->value & ~(u64)CSR_FLAGS); + } + if (c->bdcr && off - esk_rf_off(c->bdcr) < 4 && (v & BDRST)) { + static const char *const dom[2] = { "RTC", "TAMP" }; + int k; + for (k = 0; k < 2; k++) { + struct esk_rf_periph *q = esk_rf_periph(c->s->rf, dom[k]); + if (q) { + int keep = q->backup; + q->backup = 0; + esk_rf_periph_reset(q); + q->backup = keep; + } + } + } + if (c->cicr && off - esk_rf_off(c->cicr) < 4) { + if (c->cifr) + esk_rf_hw(c->cifr, c->cifr->value & ~(u64)(v & 0x7bbu)); + return; /* CICR reads 0 */ + } + if (off - esk_rf_off(c->cr) < 4) { + u64 was = c->cr->value; + esk_rf_write(c->p, off, n, v); + if (was & (HSEON | HSERDY)) /* HSEBYP kept while HSE is on */ + esk_rf_hw(c->cr, (c->cr->value & ~(u64)HSEBYP) | (was & HSEBYP)); + } else { + esk_rf_write(c->p, off, n, v); + } + if (c->csr && (c->csr->value & RMVF)) + esk_rf_hw(c->csr, c->csr->value & ~(u64)RMVF); + if (c->bdcr && (c->bdcr->value & BDRST) && off - esk_rf_off(c->bdcr) < 4) { + esk_rf_hw(c->bdcr, c->bdcr->value & BDRST); /* the domain's reset: all else cleared */ + c->osc[O_LSE].ready = c->osc[O_LSE].starting = 0; + } + for (i = 0; i < c->nrst; i++) + if (off - esk_rf_off(c->rst[i].r) < 4 && (c->rst[i].r->value & c->rst[i].m)) + esk_rf_periph_reset(c->rst[i].q); + settle(c); + lsi_forced(c); + if (c->bdcr) + c->bdcr_kept = c->bdcr->value; + esk_stm32_rtc_sync(c->s); +} + +void esk_stm32g4_rcc_lsi(struct esk_mach *s) +{ + struct g4rcc *c = g4(s); + if (c) + lsi_forced(c); +} + +static void reset_flags(struct g4rcc *c) +{ + int cause = c->s->reset_cause; + if (c->csr) { + u32 f; + if (cause == ESK_RESET_POWER || cause < 0) + f = BORRSTF | PINRSTF; + else if (cause == ESK_RESET_STANDBY && esk_stm32g4_pwr_was_shutdown(c->s)) + f = c->csr_flags | BORRSTF | PINRSTF; /* leaving Shutdown: a brownout reset */ + else if (cause == ESK_RESET_STANDBY) + f = c->csr_flags; /* leaving Standby: the flags kept */ + else { + f = c->csr_flags | PINRSTF; + if (c->obl) + f |= OBLRSTF; + else if (cause == ESK_RESET_SOFTWARE) + f |= SFTRSTF; + else if (cause == ESK_RESET_WATCHDOG) + f |= IWDGRSTF; + else if (cause == ESK_RESET_WINDOW) + f |= WWDGRSTF; + else if (cause == ESK_RESET_LOW_POWER) + f |= LPWRRSTF; + } + esk_rf_hw(c->csr, (c->csr->value & ~(u64)CSR_FLAGS) | f); + c->csr_flags = f; + } + c->obl = 0; + if (c->bdcr) { + if (c->s->reset_cause != ESK_RESET_POWER) + esk_rf_hw(c->bdcr, c->bdcr_kept); + c->bdcr_kept = c->bdcr->value; + } +} + +static void rcc_reset(void *ctx) +{ + struct g4rcc *c = (struct g4rcc *)ctx; + int i, k, listed = 0; + reset_flags(c); + c->hclk = 0; + c->warned = 0; + for (k = 0; k < c->p->rf->ntk; k++) + listed |= c->p->rf->tk[k] == c->p; + if (listed) + esk_rf_clock(c->p, &c->running, 0); + c->running = 0; + for (i = 0; i < O_N; i++) + if (i != O_LSE || c->s->reset_cause == ESK_RESET_POWER) + c->osc[i].ready = c->osc[i].starting = 0; + c->osc[O_HSI].ready = 1; /* the part leaves reset on HSI16 */ + settle(c); + c->since = 0; + lsi_forced(c); +} + +const struct esk_dev_ops esk_stm32g4_rcc_ops = { + "stm32g4-rcc", rcc_read, rcc_write, rcc_reset, rcc_tick, rcc_next, +}; + +/* ---- gates and resets ---------------------------------------------------------- */ + +/* the clock-enable field's stem of a peripheral the RCC does not name after + * it (DMAMUX1EN for DMAMUX, ADC12EN for ADC1), or its own name */ +static const char *gate_stem(const char *name) +{ + static const char *const map[][2] = { + { "DMAMUX", "DMAMUX1" }, { "ADC1", "ADC12" }, { "ADC2", "ADC12" }, { "ADC12_Common", "ADC12" }, + { "ADC3", "ADC345" }, { "ADC4", "ADC345" }, { "ADC5", "ADC345" }, { "ADC345_Common", "ADC345" }, + { "QUADSPI", "QSPI" }, { "RTC", "RTCAPB" }, { "TAMP", "RTCAPB" }, { "USB_FS_device", "USB" }, + { "FDCAN1", "FDCAN" }, { "FDCAN2", "FDCAN" }, { "FDCAN3", "FDCAN" }, { "COMP", "SYSCFG" }, + { "OPAMP", "SYSCFG" }, { "VREFBUF", "SYSCFG" }, { "SAI", "SAI1" }, + }; + size_t i; + if (!strncmp(name, "HRTIM_", 6)) + return "HRTIM1"; + for (i = 0; i < sizeof map / sizeof map[0]; i++) + if (!strcmp(name, map[i][0])) + return map[i][1]; + return name; +} + +static int ends_with(const char *s, const char *t) +{ + size_t a = strlen(s), b = strlen(t); + return a >= b && !strcmp(s + a - b, t); +} + +static int gates(struct esk_mach *s, struct g4rcc *c) +{ + struct esk_rf_periph *q; + int i, k; + c->rst = (struct rst *)esk_mach_alloc(s, (size_t)(s->rf->np > 0 ? s->rf->np : 1) * sizeof *c->rst); + if (!c->rst) + return -1; + for (i = 0; (q = esk_rf_periph_at(s->rf, i)) != 0; i++) { + char en[64], rst[64]; + const char *stem; + if (q == c->p || !strcmp(q->name, "FLASH") || strlen(q->name) > 40) + continue; /* the flash interface's clock goes off only in power-down */ + stem = gate_stem(q->name); + snprintf(en, sizeof en, "%sEN", stem); + snprintf(rst, sizeof rst, "%sRST", stem); + for (k = 0; k < c->p->nreg; k++) { + struct esk_rf_reg *r = c->p->reg[k]; + u64 m; + if (!q->gate && (ends_with(r->name, "ENR") || ends_with(r->name, "ENR1") || ends_with(r->name, "ENR2")) && + !strstr(r->name, "SMENR") && (m = esk_rf_mask(r, en)) != 0) { + size_t l = strlen(c->p->name) + strlen(r->name) + strlen(en) + 3; + char *g = (char *)esk_mach_alloc(s, l); + if (!g) + return -1; + snprintf(g, l, "%s.%s.%s", c->p->name, r->name, en); + q->gate = r; + q->gate_mask = m; + q->gate_name = g; + } + if (strstr(r->name, "RSTR") && (m = esk_rf_mask(r, rst)) != 0) { + c->rst[c->nrst].q = q; + c->rst[c->nrst].r = r; + c->rst[c->nrst].m = m; + c->nrst++; + } + } + } + return 0; +} + +void *esk_stm32g4_rcc_create(struct esk_mach *s, struct esk_rf_periph *p) +{ + struct g4rcc *c; + if (!esk_rf_reg(p, "PLLCFGR") || !esk_rf_reg(p, "CIER") || !esk_rf_reg(p, "CCIPR")) + return 0; /* not the G4's layout */ + c = (struct g4rcc *)esk_mach_alloc(s, sizeof *c); + if (!c) + return 0; + c->s = s; + c->p = p; + c->cr = esk_rf_reg(p, "CR"); + c->cfgr = esk_rf_reg(p, "CFGR"); + c->pllcfgr = esk_rf_reg(p, "PLLCFGR"); + c->cier = esk_rf_reg(p, "CIER"); + c->cifr = esk_rf_reg(p, "CIFR"); + c->cicr = esk_rf_reg(p, "CICR"); + c->csr = esk_rf_reg(p, "CSR"); + c->bdcr = esk_rf_reg(p, "BDCR"); + c->crrcr = esk_rf_reg(p, "CRRCR"); + c->ccipr = esk_rf_reg(p, "CCIPR"); + c->ccipr2 = esk_rf_reg(p, "CCIPR2"); + if (!c->cr || !c->cfgr) + return 0; + c->irq = esk_rf_irq(p, "RCC"); + c->osc[O_HSI].ready = 1; + p->always_on = 1; /* LSE and LSI start through Stop too */ + s->core_hz = g4_core_hz; + s->clock_ctx = c; + if (gates(s, c)) + return 0; + settle(c); + return c; +} diff --git a/core/mcu/stm32/spi.c b/core/mcu/stm32/spi.c index 493863ae3..83f5b265d 100644 --- a/core/mcu/stm32/spi.c +++ b/core/mcu/stm32/spi.c @@ -79,6 +79,7 @@ #define CR1_SSM (1u << 9) #define CR1_RXONLY (1u << 10) #define CR1_DFF (1u << 11) +#define CR1_CRCL (1u << 11) /* the FIFO SPI's: the CRC's length */ #define CR1_CRCNEXT (1u << 12) #define CR1_CRCEN (1u << 13) #define CR1_BIDIOE (1u << 14) @@ -86,10 +87,14 @@ #define CR2_RXDMAEN (1u << 0) #define CR2_TXDMAEN (1u << 1) #define CR2_SSOE (1u << 2) +#define CR2_NSSP (1u << 3) #define CR2_FRF (1u << 4) #define CR2_ERRIE (1u << 5) #define CR2_RXNEIE (1u << 6) #define CR2_TXEIE (1u << 7) +#define CR2_FRXTH (1u << 12) +#define CR2_LDMA_RX (1u << 13) +#define CR2_LDMA_TX (1u << 14) #define SR_RXNE (1u << 0) #define SR_TXE (1u << 1) #define SR_CRCERR (1u << 4) @@ -97,6 +102,8 @@ #define SR_OVR (1u << 6) #define SR_BSY (1u << 7) #define SR_FRE (1u << 8) +#define SR_FRLVL (3u << 9) +#define SR_FTLVL (3u << 11) enum { P_NSS, P_SCK, P_MISO, P_MOSI }; static const char *const fn_names[4] = { "NSS", "SCK", "MISO", "MOSI" }; @@ -125,6 +132,15 @@ struct spi { int armed; /* a TI slave saw the pulse: a frame starts */ int in_sck, in_nss; /* the levels last seen on the pins, -1 none yet */ int ovr_dr, modf_sr; /* the clearing sequences' first steps */ + /* the FIFO SPI (RM0440 42, an SR with FRLVL): 32-bit transmit and + * receive FIFOs of frames, each one byte (DS <= 8) or two */ + int fifo; + u16 txq[4], rxq[4]; + int txn, rxn; + int gap; /* NSSP: half bits of NSS high left before the next frame */ + int crc_part; /* a 16-bit CRC after 8-bit frames: its second frame is next */ + u32 crc_word, crc_in; /* the CRC going out, and coming in, in two frames */ + int ldma_tx, ldma_rx; /* LDMA: the DMA's last access carries one frame */ }; static u32 reg(const struct esk_rf_reg *r) { return r ? (u32)r->value : 0; } @@ -136,6 +152,7 @@ static int active(const struct spi *k) { return enabled(k) || k->busy; } static int ti(const struct spi *k) { return k->has_ti && (reg(k->cr2) & CR2_FRF); } static int cpol(const struct spi *k) { return ti(k) ? 0 : (reg(k->cr1) & CR1_CPOL) != 0; } static int cpha(const struct spi *k) { return ti(k) ? 1 : (reg(k->cr1) & CR1_CPHA) != 0; } +static int nssp(const struct spi *k); /* the data go out, and come in */ static int sending(const struct spi *k) @@ -220,7 +237,7 @@ static int drive(const struct spi *k, int fn) if (fn == P_MOSI) return sending(k) ? k->mosi : -1; if (fn == P_NSS) { - if (ti(k)) + if (ti(k) || nssp(k)) return k->nss_out; return (c2 & CR2_SSOE) && !(c1 & CR1_SSM) ? 0 : -1; } @@ -254,9 +271,12 @@ static void pins(struct spi *k) /* the DMA requests and the interrupt as the flags are now: a request the * DMA serves at once changes them (it writes DR, it reads it) */ +static void levels(struct spi *k); + static void update(struct spi *k) { u32 sr, c2 = reg(k->cr2); + levels(k); esk_stm32_dma_request(k->s, k->sig_tx, enabled(k) && (c2 & CR2_TXDMAEN) && (reg(k->sr) & SR_TXE)); esk_stm32_dma_request(k->s, k->sig_rx, enabled(k) && (c2 & CR2_RXDMAEN) && (reg(k->sr) & SR_RXNE)); sr = reg(k->sr); @@ -272,14 +292,71 @@ static void sr_set(struct spi *k, u32 set, u32 clear) /* ---- CRC -------------------------------------------------------------------------- */ -static int width(const struct spi *k) { return (reg(k->cr1) & CR1_DFF) ? 16 : 8; } +static int width(const struct spi *k) +{ + if (k->fifo) { + u32 ds = reg(k->cr2) >> 8 & 15u; + return ds < 3 ? 8 : (int)ds + 1; /* DS: 4 to 16 bits */ + } + return (reg(k->cr1) & CR1_DFF) ? 16 : 8; +} + +/* the CRC's length: the FIFO SPI's CRCL, else the frame's */ +static int crc_len(const struct spi *k) { return k->fifo ? ((reg(k->cr1) & CR1_CRCL) ? 16 : 8) : width(k); } + +/* ---- the FIFOs (RM0440 42.5.9) ------------------------------------------------------ */ + +/* a frame takes one byte of a 32-bit FIFO (DS <= 8) or two */ +static int frame_bytes(const struct spi *k) { return width(k) > 8 ? 2 : 1; } +static u32 frame_mask(const struct spi *k) { return (1u << width(k)) - 1u; } + +/* TXE while the transmit FIFO is at most half full; RXNE once the receive + * FIFO holds FRXTH's quarter (8 bits) or half (16 bits), a quarter for the + * DMA's last access with LDMA_RX; FTLVL and FRLVL their levels (3/4 and + * full both read full) */ +static void levels(struct spi *k) +{ + int tb, rb, thr; + u32 sr; + if (!k->fifo) + return; + tb = k->txn * frame_bytes(k); + rb = k->rxn * frame_bytes(k); + thr = (reg(k->cr2) & CR2_FRXTH) || k->ldma_rx ? 1 : 2; + sr = reg(k->sr) & ~(SR_FRLVL | SR_FTLVL | SR_TXE | SR_RXNE); + if (tb <= 2) + sr |= SR_TXE; + if (rb >= thr) + sr |= SR_RXNE; + sr |= (u32)(rb > 3 ? 3 : rb) << 9 | (u32)(tb > 3 ? 3 : tb) << 11; + esk_rf_hw(k->sr, sr); +} + +static void tx_push(struct spi *k, u32 v) +{ + if ((k->txn + 1) * frame_bytes(k) <= 4) + k->txq[k->txn++] = (u16)(v & frame_mask(k)); +} + +static u32 rx_pop(struct spi *k) +{ + u32 v; + if (!k->rxn) + return 0; + v = k->rxq[0]; + memmove(k->rxq, k->rxq + 1, (size_t)(--k->rxn) * sizeof k->rxq[0]); + return v; +} + +/* a frame waits to go out */ +static int tx_ready(const struct spi *k) { return k->fifo ? k->txn > 0 : k->tx_full; } /* the frame's bit i (0 first on the line) of a `bits`-bit word */ static int line_pos(const struct spi *k, int i) { return (reg(k->cr1) & CR1_LSBFIRST) ? i : k->bits - 1 - i; } static u32 crc_step(const struct spi *k, u32 crc, u32 word) { - int w = width(k), i; + int w = crc_len(k), i; u32 mask = w == 16 ? 0xffffu : 0xffu, poly = reg(k->crcpr) & mask; for (i = 0; i < k->bits; i++) { u32 b = word >> line_pos(k, i) & 1u, fb = (crc >> (w - 1) & 1u) ^ b; @@ -292,7 +369,16 @@ static u32 crc_step(const struct spi *k, u32 crc, u32 word) static int crc_due(const struct spi *k) { - return (reg(k->cr1) & CR1_CRCEN) && ((reg(k->cr1) & CR1_CRCNEXT) || k->crc_tx_end || k->crc_rx_end); + return k->crc_part || + ((reg(k->cr1) & CR1_CRCEN) && ((reg(k->cr1) & CR1_CRCNEXT) || k->crc_tx_end || k->crc_rx_end)); +} + +/* a 16-bit CRC after 8-bit frames goes out as two frames, its first byte + * on the line first */ +static u32 crc_piece(const struct spi *k, int second) +{ + int lsb = (reg(k->cr1) & CR1_LSBFIRST) != 0; + return (second ? !lsb : lsb) ? (k->crc_word & 0xffu) : (k->crc_word >> 8 & 0xffu); } /* ---- frames ------------------------------------------------------------------------ */ @@ -305,13 +391,30 @@ static void load(struct spi *k) k->crc_frame = 0; k->bits = width(k); k->fresh = 1; - if (k->tx_full && sending(k)) { - k->out = k->tx_buf; - k->tx_full = 0; - sr_set(k, SR_TXE, 0); + if (k->crc_part) { + k->out = crc_piece(k, 1); + k->crc_part = 0; + k->crc_frame = 2; + } else if (tx_ready(k) && sending(k)) { + if (k->fifo) { + k->out = k->txq[0]; + memmove(k->txq, k->txq + 1, (size_t)(--k->txn) * sizeof k->txq[0]); + levels(k); + } else { + k->out = k->tx_buf; + k->tx_full = 0; + sr_set(k, SR_TXE, 0); + } } else if (crc_due(k)) { - k->out = reg(k->txcrcr); - k->crc_frame = 1; + k->crc_word = reg(k->txcrcr); + if (crc_len(k) > k->bits) { + k->out = crc_piece(k, 0); /* the second follows */ + k->crc_part = 1; + k->crc_frame = 1; + } else { + k->out = k->crc_word; + k->crc_frame = 2; + } k->crc_tx_end = k->crc_rx_end = 0; esk_rf_hw(k->cr1, k->cr1->value & ~(u64)CR1_CRCNEXT); } else { @@ -333,9 +436,14 @@ static void in_bit(struct spi *k, int i, int v) /* the received frame to DR, the CRCs */ static void received(struct spi *k) { - u32 mask = k->bits == 16 ? 0xffffu : 0xffu; - if (k->crc_frame) { - if (receiving(k) && (k->in & mask) != (reg(k->rxcrcr) & mask)) + u32 mask = crc_len(k) == 16 ? 0xffffu : 0xffu; + if (k->crc_frame == 1) { + k->crc_in = k->in & 0xffu; /* the CRC's first frame */ + } else if (k->crc_frame) { + u32 got = k->in; + if (crc_len(k) > k->bits) + got = (reg(k->cr1) & CR1_LSBFIRST) ? (k->in & 0xffu) << 8 | k->crc_in : k->crc_in << 8 | (k->in & 0xffu); + if (receiving(k) && (got & mask) != (reg(k->rxcrcr) & mask)) sr_set(k, SR_CRCERR, 0); } else if (reg(k->cr1) & CR1_CRCEN) { if (sending(k)) @@ -346,6 +454,15 @@ static void received(struct spi *k) k->crc_frame = 0; if (!receiving(k)) return; + if (k->fifo) { + /* a full receive FIFO: OVR, the frame lost */ + if ((k->rxn + 1) * frame_bytes(k) > 4) + sr_set(k, SR_OVR, 0); + else + k->rxq[k->rxn++] = (u16)(k->in & frame_mask(k)); + levels(k); + return; + } if (k->sr->value & SR_RXNE) { sr_set(k, SR_OVR, 0); } else { @@ -376,11 +493,21 @@ static void wait(struct spi *k) /* a frame follows the one under way */ static int next_waiting(const struct spi *k) { - return enabled(k) && master(k) && ((k->tx_full && sending(k)) || crc_due(k) || receive_only(k)); + return enabled(k) && master(k) && ((tx_ready(k) && sending(k)) || crc_due(k) || receive_only(k)); +} + +/* NSS pulse mode: a Motorola master with CPHA 0 driving NSS (RM0440 42.5.12) */ +static int nssp(const struct spi *k) +{ + u32 c1 = reg(k->cr1), c2 = reg(k->cr2); + return k->fifo && master(k) && (c2 & CR2_NSSP) && (c2 & CR2_SSOE) && !(c1 & CR1_SSM) && !ti(k) && + !(c1 & CR1_CPHA); } static void start(struct spi *k) { + if (nssp(k)) + k->nss_out = 0; load(k); k->leading = 1; k->busy = 1; @@ -407,9 +534,19 @@ static void frame_end(struct spi *k) received(k); update(k); /* a DMA reading the last item says the CRC is next */ if (next_waiting(k)) { + if (nssp(k)) { + /* NSS high for one clock between the frames, SCK idle */ + k->nss_out = 1; + k->gap = 2; + pins(k); + wait(k); + return; + } start(k); return; } + if (nssp(k)) + k->nss_out = 1; /* and high after the last one */ stop(k); pins(k); update(k); @@ -418,6 +555,14 @@ static void frame_end(struct spi *k) static void edge(struct spi *k) { int ph = cpha(k), pol = cpol(k); + if (k->gap) { + if (--k->gap) { + wait(k); + return; + } + start(k); + return; + } if (k->leading) { k->sck = !pol; if (k->bit < 0) { @@ -478,6 +623,8 @@ static void mode_fault(struct spi *k) esk_rf_hw(k->cr1, k->cr1->value & ~(u64)(CR1_SPE | CR1_MSTR)); k->busy = 0; k->tx_full = 0; + k->txn = 0; + k->gap = k->crc_part = 0; sr_set(k, SR_TXE, SR_BSY); esk_rf_clock(k->p, &k->running, 0); pins(k); @@ -597,6 +744,19 @@ static u32 spi_read(void *ctx, u32 off, int n) { struct spi *k = (struct spi *)ctx; u32 v = esk_rf_read(k->p, off, n); + if (k->fifo && off == esk_rf_off(k->dr)) { + /* the oldest frame, or two packed in a 16-bit access (DS <= 8) */ + if (k->s->bus.debug) + return k->rxn ? k->rxq[0] : 0; + k->ovr_dr = (k->sr->value & SR_OVR) != 0; + v = rx_pop(k); + if (n >= 2 && frame_bytes(k) == 1 && !k->ldma_rx) + v |= rx_pop(k) << 8; + k->ldma_rx = 0; + esk_rf_hw(k->dr, v); + update(k); + return v; + } if (k->s->bus.debug) return v; if (off == esk_rf_off(k->dr)) { @@ -618,9 +778,19 @@ static void spi_write(void *ctx, u32 off, int n, u32 v) { struct spi *k = (struct spi *)ctx; if (off == esk_rf_off(k->dr)) { - k->tx_buf = v & ((reg(k->cr1) & CR1_DFF) ? 0xffffu : 0xffu); - k->tx_full = 1; - sr_set(k, 0, SR_TXE); + if (k->fifo) { + /* one frame, or two packed in a 16-bit access (DS <= 8), but + * the DMA's last with LDMA_TX */ + tx_push(k, v); + if (n >= 2 && frame_bytes(k) == 1 && !k->ldma_tx) + tx_push(k, v >> 8); + k->ldma_tx = 0; + levels(k); + } else { + k->tx_buf = v & ((reg(k->cr1) & CR1_DFF) ? 0xffffu : 0xffu); + k->tx_full = 1; + sr_set(k, 0, SR_TXE); + } if (enabled(k) && master(k) && !k->busy) start(k); else if (enabled(k) && !master(k) && !k->busy && !k->fresh) @@ -675,6 +845,8 @@ static void spi_write(void *ctx, u32 off, int n, u32 v) } esk_rf_write(k->p, off, n, v); if (off == esk_rf_off(k->cr2)) { + if (k->fifo && (reg(k->cr2) >> 8 & 15u) < 3) + esk_rf_hw(k->cr2, (k->cr2->value & ~(u64)0xF00u) | 0x700u); /* not used: 8 bits */ if (enabled(k) && master(k) && !k->busy) k->sck = cpol(k); mode_fault(k); @@ -696,7 +868,11 @@ static void spi_reset(void *ctx) k->nss_out = k->synced = k->armed = 0; k->ovr_dr = k->modf_sr = 0; k->left = 0; + k->txn = k->rxn = k->gap = k->crc_part = 0; + k->ldma_tx = k->ldma_rx = 0; + k->crc_word = k->crc_in = 0; esk_rf_hw(k->sr, k->sr->value | SR_TXE); + levels(k); } const struct esk_dev_ops esk_stm32_spi_ops = { @@ -762,6 +938,29 @@ void esk_stm32_spi_signal_input(struct esk_mach *s, const char *sig, int level) } } +/* the DMA's items left for an SPI's request: with one left, LDMA_TX and + * LDMA_RX make its last access carry one frame */ +void esk_stm32_spi_dma_left(struct esk_mach *s, const char *sig, u32 left) +{ + char name[8]; + const char *us = strchr(sig, '_'); + size_t l = us ? (size_t)(us - sig) : 0; + struct spi *k; + if (left != 1 || !us || l >= sizeof name || strncmp(sig, "SPI", 3)) + return; + memcpy(name, sig, l); + name[l] = 0; + k = spi_named(s, name); + if (!k || !k->fifo || frame_bytes(k) != 1) + return; + if (!strcmp(us + 1, "TX") && (reg(k->cr2) & CR2_LDMA_TX)) + k->ldma_tx = 1; + else if (!strcmp(us + 1, "RX") && (reg(k->cr2) & CR2_LDMA_RX)) { + k->ldma_rx = 1; + update(k); + } +} + void esk_stm32_spi_dma_end(struct esk_mach *s, const char *sig) { char name[8]; @@ -841,6 +1040,7 @@ void *esk_stm32_spi_create(struct esk_mach *s, struct esk_rf_periph *p) k.apb = p->gate_name && strstr(p->gate_name, "APB2") ? 2 : 1; k.irq = esk_rf_irq(p, "SPI"); k.has_ti = esk_rf_mask(k.cr2, "FRF") != 0; + k.fifo = esk_rf_mask(k.sr, "FRLVL") != 0; k.in_sck = k.in_nss = -1; esk_rf_set_reset(k.sr, k.sr->reset | SR_TXE); snprintf(k.sig_tx, sizeof k.sig_tx, "%s_TX", p->name); diff --git a/core/mcu/stm32/stm32.h b/core/mcu/stm32/stm32.h index a86386798..935da0391 100644 --- a/core/mcu/stm32/stm32.h +++ b/core/mcu/stm32/stm32.h @@ -18,7 +18,8 @@ * dma_f4.c the F4's DMA controllers: streams, channels, FIFO, double buffer * flash_f1.c the F1's flash interface (FPEC): program, erase, option bytes * storage.c registers that only keep what is written (PWR's CR) - * crc.c the CRC calculation unit: CRC-32 of the words written to DR */ + * crc.c the CRC calculation unit: CRC-32 of the words written to DR + * rcc_g4.c the G4's reset and clock control: HSI16, HSE, PLL, kernel clocks */ #ifndef ESK_MCU_STM32_H #define ESK_MCU_STM32_H @@ -55,6 +56,56 @@ u32 esk_stm32f1_pclk(struct esk_mach *m, int apb); u32 esk_stm32_hclk(struct esk_mach *m); u32 esk_stm32_pclk(struct esk_mach *m, int apb); u32 esk_stm32_timclk(struct esk_mach *m, int apb); +/* the G4's RCC (rcc_g4.c): whether the machine's clock model is it; its + * HCLK, PCLK1 or PCLK2, the timers' clock on an APB, SYSCLK; whether an + * oscillator is ready ('H' HSI16, 'E' HSE, 'I' LSI, 'L' LSE, '4' HSI48); + * the PLL's P, Q or R output (0 off or unlocked); a peripheral's kernel + * clock as CCIPR selects it ("USART1", "LPUART1", "I2C2", "LPTIM1", + * "FDCAN1", "CLK48", "ADC12", "ADC345", "QUADSPI", "SAI1", "I2S23", "RTC"); + * MCO's frequency; the flash or voltage settings changed (warnings + * again); Stop begins (HSE and the PLL off, SYSCLK on HSI16); the coming + * reset is the option bytes' reload (OBLRSTF); LSI forced on by the IWDG */ +int esk_stm32g4_rcc(struct esk_mach *m); +extern const struct esk_dev_ops esk_stm32g4_rcc_ops; +void *esk_stm32g4_rcc_create(struct esk_mach *m, struct esk_rf_periph *p); +u32 esk_stm32g4_hclk(struct esk_mach *m); +u32 esk_stm32g4_pclk(struct esk_mach *m, int apb); +u32 esk_stm32g4_timclk(struct esk_mach *m, int apb); +u32 esk_stm32g4_sysclk(struct esk_mach *m); +int esk_stm32g4_osc_ready(struct esk_mach *m, char which); +u32 esk_stm32g4_pll_hz(struct esk_mach *m, char which); +u32 esk_stm32g4_kernel_hz(struct esk_mach *m, const char *periph); +u32 esk_stm32g4_mco_hz(struct esk_mach *m); +void esk_stm32g4_rcc_check(struct esk_mach *m); +void esk_stm32g4_rcc_stop(struct esk_mach *m, int wake_hsi); +void esk_stm32g4_rcc_obl(struct esk_mach *m); +void esk_stm32g4_rcc_lsi(struct esk_mach *m); +/* the G4's PWR (pwr_g4.c): whether the machine's PWR is it; an internal + * wake-up event (the RTC's, TAMP's); the wake-up pins enabled on a port; + * whether the part is in Standby or Shutdown (its pins let go), and the + * pull a pin keeps then (1 up, 2 down, 0 none); a wake-up pin's level; + * whether the reset under way leaves Shutdown */ +extern const struct esk_dev_ops esk_stm32g4_pwr_ops; +void *esk_stm32g4_pwr_create(struct esk_mach *m, struct esk_rf_periph *p); +int esk_stm32g4_pwr(struct esk_mach *m); +void esk_stm32g4_pwr_wakeup(struct esk_mach *m); +u32 esk_stm32g4_pwr_wkup_mask(struct esk_mach *m, int port); +int esk_stm32g4_pwr_standby(struct esk_mach *m); +int esk_stm32g4_pwr_standby_pull(struct esk_mach *m, int port, int pin); +void esk_stm32g4_pwr_pin_edge(struct esk_mach *m, int port, int pin, int level); +int esk_stm32g4_pwr_was_shutdown(struct esk_mach *m); +/* the G4's flash interface: programming, erasing, the option bytes (flash_g4.c) */ +extern const struct esk_dev_ops esk_stm32g4_flash_ops; +void *esk_stm32g4_flash_create(struct esk_mach *m, struct esk_rf_periph *p); +/* a USART, UART or LPUART of the ISR/ICR/TDR/RDR layout (usart_v2.c): its + * alternate-function signals (USART1_TX, LPUART1_RTS, _DE, _CK) as + * esk_stm32_usart_signal's, nCTS's level, its TX or RX pin (CR2's SWAP + * exchanging them) */ +extern const struct esk_dev_ops esk_stm32_usartv2_ops; +void *esk_stm32_usartv2_create(struct esk_mach *m, struct esk_rf_periph *p); +int esk_stm32_usartv2_signal(struct esk_mach *m, const char *sig); +void esk_stm32_usartv2_signal_input(struct esk_mach *m, const char *sig, int level); +int esk_stm32_usartv2_pin(struct esk_mach *m, const char *unit, int tx, int *port, int *bit); /* the F4's 48 MHz clock (CK48) in Hz: 0 while its PLL is not locked */ u32 esk_stm32f4_ck48(struct esk_mach *m); /* the F4's PWR: VOSRDY, ODRDY and ODSWRDY as the RCC's PLL and PWR's @@ -75,6 +126,9 @@ u32 esk_stm32f4_pwr_wkup_mask(struct esk_mach *m, int port); void esk_stm32f4_pwr_pin_edge(struct esk_mach *m, int port, int pin, int level); void esk_stm32f4_pwr_pins_settled(struct esk_mach *m); int esk_stm32f4_pwr_standby(struct esk_mach *m); +/* the pull a pin keeps in Standby (1 up, 2 down, 0 none): an F4's WKUP + * pin's pull-down, a G4's PWR settings */ +int esk_stm32f4_pwr_standby_pull(struct esk_mach *m, int port, int pin); /* the F4's GPIO ports and SYSCFG (gpio_f4.c, syscfg_f4.c) */ extern const struct esk_dev_ops esk_stm32f4_gpio_ops, esk_stm32f4_syscfg_ops; void *esk_stm32f4_gpio_create(struct esk_mach *m, struct esk_rf_periph *p); @@ -118,6 +172,17 @@ void *esk_stm32f4_dma_create(struct esk_mach *m, struct esk_rf_periph *p); * or falls: a stream that takes it moves the data now, else it waits for * one; nothing without a DMA model. `sig` must outlive the request. */ void esk_stm32_dma_request(struct esk_mach *m, const char *sig, int level); +/* a DMA channel's last items for request `sig` (the peripheral hears of + * them: an SPI's CRC follows the last, an I2C NACKs after EOT-1) */ +void esk_stm32_dma_items_left(struct esk_mach *m, const char *sig, u32 left); +/* the G4's DMA controllers and request multiplexer (dma_g4.c): a request + * through DMAMUX; a trigger or synchronisation input's level (EXTI0 to + * EXTI15, LPTIM1_OUT) */ +extern const struct esk_dev_ops esk_stm32g4_dma_ops, esk_stm32g4_dmamux_ops; +void *esk_stm32g4_dma_create(struct esk_mach *m, struct esk_rf_periph *p); +void *esk_stm32g4_dmamux_create(struct esk_mach *m, struct esk_rf_periph *p); +void esk_stm32g4_dma_request(struct esk_mach *m, const char *sig, int level); +void esk_stm32g4_dmamux_input(struct esk_mach *m, const char *sig, int level); /* a USART's alternate-function signal (USART2_TX, _RTS, _CK): the level it * drives, or -1; nCTS's level from its pin; the pin (port, bit) of its TX * (tx 1) or RX, as the family maps it (the runtime's uart_pin) */ @@ -131,6 +196,7 @@ int esk_stm32_usart_pin(struct esk_mach *m, const char *unit, int tx, int *port, int esk_stm32_spi_signal(struct esk_mach *m, const char *sig); void esk_stm32_spi_signal_input(struct esk_mach *m, const char *sig, int level); void esk_stm32_spi_dma_end(struct esk_mach *m, const char *sig); +void esk_stm32_spi_dma_left(struct esk_mach *m, const char *sig, u32 left); /* an I2C's alternate-function signal (I2C1_SCL, _SDA, _SMBA): the level it * drives (1 let go), or -1; a level its pin gives it; a DMA stream's items * left after one for its request (I2C1_RX's EOT-1, I2C1_TX's end) */ @@ -189,5 +255,8 @@ int esk_stm32f1_i2c_pin(struct esk_mach *m, int port, int bit); void esk_stm32f1_port_changed(struct esk_mach *m, int port); /* an input line's level, as GPIO's IDR has it: EXTI's edge detector */ void esk_stm32_exti_input(struct esk_mach *m, int line, int level); +/* a direct line's event (an STM32G4's peripheral wake-up lines): an event + * to the core when its EMR bit is set */ +void esk_stm32_exti_direct(struct esk_mach *m, int line); #endif diff --git a/core/mcu/stm32/syscfg_f4.c b/core/mcu/stm32/syscfg_f4.c index bb22de161..357ca90b4 100644 --- a/core/mcu/stm32/syscfg_f4.c +++ b/core/mcu/stm32/syscfg_f4.c @@ -2,7 +2,9 @@ /* Copyright 2026 Junior Deogracias */ /* syscfg_f4.c -- the STM32F4's system configuration controller (RM0390 8): * - EXTICR1 to EXTICR4 pick the port each EXTI line 0-15 listens to - * (0 port A ... 7 port H), for the GPIO model's edges (gpio_f4.c); + * (0 port A ... 7 port H), for the GPIO model's edges (gpio_f4.c); a + * line given another port sees the new pin's level at once, an edge + * when it differs from the old one's; * - MEMRMP's MEM_MODE picks what answers at 0x00000000: the main flash * (000, out of reset with BOOT0 low), the system memory (001), SRAM1's * 112 KiB (011); FMC's bank 1 (010) and SDRAM bank 1 (100) and the @@ -14,7 +16,16 @@ * mode Plus drive) keep what is written. * The alias at 0 is the description's memory mirror at that address, as * large as the memory it shows; SRAM1 is the first 112 KiB of the - * description's SRAM (RM0390 2.3: SRAM1 112 KiB, then SRAM2 16 KiB). */ + * description's SRAM (RM0390 2.3: SRAM1 112 KiB, then SRAM2 16 KiB). + * + * The STM32G4's (RM0440 9, a SYSCFG with SCSR): MEM_MODE as above, SRAM1 + * its first 80 KiB, 100 the QUADSPI's memory (none on the bus: nothing + * there); SCSR's CCMER erases the CCM SRAM (32 KiB at 0x20018000, its + * alias at 0x10000000) to 0, CCMBSY reading 0 at once; CFGR1 (the FPU's + * interrupt enables, the I2C pins' Fast-mode Plus drive), CFGR2, SWPR, + * SKR and MEMRMP's FB_MODE keep what is written. Not modelled: the erase's + * time (CCMBSY), SWPR's write protection of the CCM SRAM's pages, the + * parity errors CFGR2 reports, FB_MODE's bank swap. */ #include #include "mcu/stm32/stm32.h" @@ -24,8 +35,9 @@ struct syscfg { struct esk_mach *s; struct esk_rf_periph *p; - struct esk_rf_reg *memrmp, *exticr[4], *cmpcr; + struct esk_rf_reg *memrmp, *exticr[4], *cmpcr, *scsr; u32 mode; /* the MEM_MODE mapped now */ + int g4; }; static struct syscfg *syscfg_of(struct esk_mach *s) @@ -58,7 +70,7 @@ static void remap(struct syscfg *c) (void)esk_bus_remap_mirror(&c->s->bus, BOOT_ALIAS, 0x1FFF0000u, ~0u); break; case 3: - (void)esk_bus_remap_mirror(&c->s->bus, BOOT_ALIAS, 0x20000000u, 112u * 1024u); + (void)esk_bus_remap_mirror(&c->s->bus, BOOT_ALIAS, 0x20000000u, (c->g4 ? 80u : 112u) * 1024u); break; default: (void)esk_bus_remap_mirror(&c->s->bus, BOOT_ALIAS, 0, 0); @@ -83,10 +95,40 @@ static u32 syscfg_read(void *ctx, u32 off, int n) return esk_rf_read(((struct syscfg *)ctx)->p, off, n); } +/* the level of a pin's input (IDR), port and bit */ +static int pin_level(struct esk_mach *s, int port, int bit) +{ + char name[8] = "GPIOx"; + struct esk_rf_periph *g; + struct esk_rf_reg *idr; + name[4] = (char)('A' + port); + g = esk_rf_periph(s->rf, name); + idr = g ? esk_rf_reg(g, "IDR") : 0; + return idr ? (int)(idr->value >> bit & 1) : 0; +} + static void syscfg_write(void *ctx, u32 off, int n, u32 v) { struct syscfg *c = (struct syscfg *)ctx; + int before[16], i; + for (i = 0; i < 16; i++) + before[i] = esk_stm32f4_exti_port(c->s, i); esk_rf_write(c->p, off, n, v); + /* a line given another port sees that pin's level at once: its edge + * detector follows the multiplexer's output (a switch from a high pin + * to a low one is a falling edge) */ + for (i = 0; i < 16; i++) + if (esk_stm32f4_exti_port(c->s, i) != before[i]) + esk_stm32_exti_input(c->s, i, pin_level(c->s, esk_stm32f4_exti_port(c->s, i), i)); + if (c->scsr && off == esk_rf_off(c->scsr) && (c->scsr->value & 1u)) { + /* CCMER: the CCM SRAM erased */ + struct esk_region *r = esk_bus_region(&c->s->bus, 0x20018000u, 32u * 1024u); + if (r && r->mem) { + memset(r->mem + (0x20018000u - r->base), 0, 32u * 1024u); + r->gen++; + } + esk_rf_hw(c->scsr, c->scsr->value & ~(u64)3u); + } settle(c); } @@ -118,6 +160,8 @@ void *esk_stm32f4_syscfg_create(struct esk_mach *s, struct esk_rf_periph *p) if (!c.memrmp) c.memrmp = esk_rf_reg(p, "MEMRMP"); c.cmpcr = esk_rf_reg(p, "CMPCR"); + c.scsr = esk_rf_reg(p, "SCSR"); + c.g4 = c.scsr != 0; c.mode = 0xFF; x = (struct syscfg *)esk_mach_alloc(s, sizeof *x); if (x) diff --git a/core/mcu/stm32/tim.c b/core/mcu/stm32/tim.c index 965ebbc5b..102416e65 100644 --- a/core/mcu/stm32/tim.c +++ b/core/mcu/stm32/tim.c @@ -26,7 +26,8 @@ * counting down) and makes an update event; * - SR's flags are rc_w0; * - it does not count while its clock is gated off (RCC's enable bit). - * The counter's width is CNT's fields' (TIM2 and TIM5 are 32-bit). + * The counter's width is CNT's fields' (TIM2 and TIM5 are 32-bit), a + * G4's UIFCPY in bit 31 aside. * * Capture/compare channels (as many as CCRx registers): * - output compare (CCxS 00): a match is the counter becoming CCRx, in @@ -98,6 +99,12 @@ * the OTG controllers' SOF (none here). A remapped clock's edges come at * its half periods, at the core clock. * + * A G4's TISEL (RM0440 28.6.25 and the like) puts a clock inside the part on + * TI1 the same way: TIM16's and TIM17's TI1SEL 2 MCO, 3 HSE/32, 5 LSE, 6 + * LSI (as HAL's way of measuring LSI does); TIM5's 1 LSI, 2 LSE; TIM15's + * 1 LSE. The comparators' outputs and the RTC's wake-up on TISEL are not + * modelled (no edges). + * * Not modelled: TIM5's TI4 on the RTC's wake-up interrupt (IT4_RMP 11: * no edges), the OTG controllers' SOF on TIM2's ITR1, MSM's delay (TRGI acts at once * anyway), the forced idle levels' dead time after a break, the fast @@ -157,6 +164,7 @@ struct tim { struct esk_rf_reg *ccmr[2], *ccer, *ccr[4]; int nch; /* capture/compare channels */ int apb; /* 1 or 2 */ + int fz_word, fz_bit; /* its DBG_TIMx_STOP in DBGMCU (dbg.fz), or -1 */ int unit; /* TIMn's n */ int itr[4]; /* ITR0-ITR3: the masters' units, 0 none */ u64 cntmask; @@ -196,13 +204,13 @@ struct tim { /* TIMx_OR's internal remaps: the input (0 for TI1, 3 for TI4) a clock * inside the part drives instead of its pin, -1 none; its kind; the * next edge, counted from t0 at the core clock it was scheduled at */ - struct esk_rf_reg *orr; + struct esk_rf_reg *orr, *tisel; int src_x, src_kind; u64 src_t0, src_k, src_at; u32 src_core_hz, src_hz_last; }; -enum { SRC_NONE, SRC_LSI, SRC_LSE, SRC_HSE_RTC }; +enum { SRC_NONE, SRC_LSI, SRC_LSE, SRC_HSE_RTC, SRC_HSE_32, SRC_MCO }; static void interconnect(struct tim *t); @@ -965,6 +973,15 @@ static u32 src_hz(const struct tim *t) { struct esk_rf_reg *r; u32 pre; + if (esk_stm32g4_rcc(t->s)) { /* a G4's RCC */ + switch (t->src_kind) { + case SRC_LSI: return esk_stm32g4_osc_ready(t->s, 'I') ? 32000u : 0; + case SRC_LSE: return esk_stm32g4_osc_ready(t->s, 'L') ? (t->s->lse_hz ? t->s->lse_hz : 32768u) : 0; + case SRC_HSE_32: return esk_stm32g4_osc_ready(t->s, 'E') ? t->s->hse_hz / 32u : 0; + case SRC_MCO: return esk_stm32g4_mco_hz(t->s); + default: return 0; + } + } switch (t->src_kind) { case SRC_LSI: r = rcc_reg(t->s, "CSR"); @@ -1022,7 +1039,16 @@ static void remap(struct tim *t) { u32 v = t->orr ? (u32)t->orr->value : 0; int kind = SRC_NONE, x = -1; - if (t->unit == 5) { + if (t->tisel) { /* a G4's TI1SEL */ + u32 sel = (u32)t->tisel->value & 15u; + if (t->unit == 16 || t->unit == 17) + kind = sel == 2 ? SRC_MCO : sel == 3 ? SRC_HSE_32 : sel == 5 ? SRC_LSE : sel == 6 ? SRC_LSI : SRC_NONE; + else if (t->unit == 5) + kind = sel == 1 ? SRC_LSI : sel == 2 ? SRC_LSE : SRC_NONE; + else if (t->unit == 15) + kind = sel == 1 ? SRC_LSE : SRC_NONE; + x = kind ? 0 : -1; + } else if (t->unit == 5) { u32 r = v >> 6 & 3u; /* IT4_RMP: GPIO, LSI, LSE, the RTC's wake-up interrupt */ kind = r == 1 ? SRC_LSI : r == 2 ? SRC_LSE : SRC_NONE; x = kind ? 3 : -1; @@ -1077,11 +1103,39 @@ static int frozen(const struct tim *t) int u = t->unit; if (!t->s->dbg.halted) return 0; + if (t->fz_word >= 0) /* found by name (a G4's: APB1L_FZ, APB2_FZ) */ + return (t->s->dbg.fz[t->fz_word] >> t->fz_bit & 1u) != 0; if (u > 0 && u < 15 && apb1[u] >= 0 && (t->s->dbg.fz[0] >> apb1[u] & 1u)) return 1; return u > 0 && u < 12 && apb2[u] >= 0 && (t->s->dbg.fz[1] >> apb2[u] & 1u); } +/* the timer's DBG_TIMx_STOP (or DBG_TIMERx_STOP) in DBGMCU's APB1 or APB2 + * freeze register, found by name: the word of dbg.fz and the bit, or -1 */ +static void freeze_bit(struct tim *t) +{ + struct esk_rf_periph *d = t->s->rf ? esk_rf_periph(t->s->rf, "DBGMCU") : 0; + char a[32], b[32]; + int k, i; + t->fz_word = t->fz_bit = -1; + if (!d || t->unit <= 0) + return; + snprintf(a, sizeof a, "DBG_TIM%d_STOP", t->unit); + snprintf(b, sizeof b, "DBG_TIMER%d_STOP", t->unit); + for (k = 0; k < d->nreg; k++) { + const struct esk_rf_reg *r = d->reg[k]; + int word = strstr(r->name, "APB1") ? 0 : strstr(r->name, "APB2") ? 1 : -1; + if (word < 0 || strstr(r->name, "APB1H")) + continue; + for (i = 0; i < r->nf; i++) + if (r->f[i].name && (!strcmp(r->f[i].name, a) || !strcmp(r->f[i].name, b))) { + t->fz_word = word; + t->fz_bit = r->f[i].lsb; + return; + } + } +} + /* frozen: every deadline moves on with the time, the counter holds */ static void hold(struct tim *t, u32 cycles) { @@ -1363,7 +1417,7 @@ static void tim_write(void *ctx, u32 off, int n, u32 v) if (!(t->dier->value & (1u << 13))) esk_stm32_dma_request(t->s, t->sig_com, 0); } - if (t->orr && off == esk_rf_off(t->orr)) + if ((t->orr && off == esk_rf_off(t->orr)) || (t->tisel && off == esk_rf_off(t->tisel))) remap(t); run_clock(t); irq_check(t); @@ -1584,6 +1638,8 @@ void *esk_stm32_tim_create(struct esk_mach *s, struct esk_rf_periph *p) } for (i = 0; i < t.cnt->nf; i++) { int top = t.cnt->f[i].lsb + t.cnt->f[i].width; + if (t.cnt->f[i].name && !strncmp(t.cnt->f[i].name, "UIFCPY", 6)) + continue; /* a G4's copy of UIF in bit 31, not the counter's */ u64 m = top >= 64 ? ~0ULL : (1ULL << top) - 1; if (m > t.cntmask) t.cntmask = m; @@ -1607,6 +1663,8 @@ void *esk_stm32_tim_create(struct esk_mach *s, struct esk_rf_periph *p) t.dcr = esk_rf_reg(p, "DCR"); t.dmar = esk_rf_reg(p, "DMAR"); t.orr = t.unit == 2 || t.unit == 5 || t.unit == 11 ? esk_rf_reg(p, "OR") : 0; + t.tisel = esk_rf_reg(p, "TISEL"); + freeze_bit(&t); t.src_x = -1; snprintf(t.sig_up, sizeof t.sig_up, "%s_UP", p->name); snprintf(t.sig_trig, sizeof t.sig_trig, "%s_TRIG", p->name); diff --git a/core/mcu/stm32/usart.c b/core/mcu/stm32/usart.c index 273d125a3..26a9221b9 100644 --- a/core/mcu/stm32/usart.c +++ b/core/mcu/stm32/usart.c @@ -602,7 +602,9 @@ int esk_stm32_usart_signal(struct esk_mach *s, const char *sig) { const char *fn; struct usart *u = signal_of(s, sig, &fn); - if (!u || !(v32(u->cr1) & UE)) + if (!u) + return esk_stm32_usartv2_signal(s, sig); /* a G4's (usart_v2.c) */ + if (!(v32(u->cr1) & UE)) return -1; if (!strcmp(fn, "TX")) return (v32(u->cr1) & TE) || (v32(u->cr3) & HDSEL) ? 1 : -1; /* idle high; the waveform is the runtime's */ @@ -617,7 +619,11 @@ void esk_stm32_usart_signal_input(struct esk_mach *s, const char *sig, int level { const char *fn; struct usart *u = signal_of(s, sig, &fn); - if (!u || strcmp(fn, "CTS")) + if (!u) { + esk_stm32_usartv2_signal_input(s, sig, level); + return; + } + if (strcmp(fn, "CTS")) return; level = level != 0; if (level == u->cts) diff --git a/core/mcu/stm32/usart_v2.c b/core/mcu/stm32/usart_v2.c new file mode 100644 index 000000000..35d4ad14f --- /dev/null +++ b/core/mcu/stm32/usart_v2.c @@ -0,0 +1,980 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* usart_v2.c -- an STM32 USART, UART or LPUART of the ISR/ICR/TDR/RDR + * layout (the G4's: RM0440 37 and 38; the same IP on the L4, G0, H7), + * over the register file, at its baud rate. + * + * The frame: + * - a start bit, 7, 8 or 9 bits (CR1's M1:M0: 10, 00, 01), the last of + * them the parity bit with PCE (PS: even or odd), and the stop bits + * (CR2.STOP: 1, 0.5, 2 or 1.5; an LPUART has no 0.5 or 1.5); + * - its data least significant bit first, or most with CR2.MSBFIRST, + * inverted with DATAINV (the bits on the line, and so the character a + * terminal decodes from them); + * - the bit time from the kernel clock (RCC's CCIPR selection, + * esk_stm32g4_kernel_hz) over PRESC's prescaler (1 to 256): a USART's + * USARTDIV clocks (BRR with 16 times oversampling; with OVER8, + * BRR[15:4] << 1 | BRR[2:0]... as RM0440 37.5.7 gives it, 8 times), an + * LPUART's 256 x clock / BRR. + * Transmitting: + * - TE and RE, with UE, set TEACK and REACK (ISR), which the HAL waits + * for; TE set sends an idle frame first; + * - a write to TDR goes to the transmit FIFO with CR1.FIFOEN (8 frames, + * TXFNF in ISR's bit 7 while it is not full, TXFE when empty, TXFT at + * CR3.TXFTCFG's threshold), else to the transmit data register (TXE, + * bit 7, while it is empty); a frame starts as the shift register + * empties, TC at the end of the last one; + * - RQR's SBKRQ sends a break after the current frame (SBKF meanwhile): + * the frame's length of 0s (13 with LINEN) and a stop bit; TXFRQ + * empties the transmit FIFO; + * - with CR3.CTSE a frame starts only while nCTS is low; its changes set + * CTSIF (CTS the line's level); with CR3.DEM, DE (on the RTS pin, + * DEP's polarity) is asserted from a frame's start to its end, then + * deasserted; + * - each frame goes to the MCU runtime (esk_mach_host.uart_frame), with + * its format and bit time: the serial stream, and the TX pin's waveform + * (TX idles high while UE and TE are set; with CR2.SWAP TX and RX + * exchange pins). + * Receiving (RE): + * - a frame comes from the RX pin's waveform (the runtime's decoder at + * this format) or from the session's serial input; it goes to the + * receive FIFO (FIFOEN, 8 frames: RXFNE in ISR's bit 5 while not + * empty, RXFF when full, RXFT at CR3.RXFTCFG's threshold) or to RDR + * (RXNE); one that finds no room is an overrun (ORE, the frame lost; + * with CR3.OVRDIS it overwrites RDR instead and ORE stays clear); + * a parity mismatch sets PE, a low stop bit FE (a break: FE with 0, and + * LBDF with LINEN); a line idle for a frame after a reception sets + * IDLE; a received character equal to CR2's ADD sets CMF; with RTOEN, + * RTOR's count of bit times after the last stop bit sets RTOF; + * the error flags are cleared through ICR; reading RDR takes a frame; + * - mute mode (MME, entered by RQR.MMRQ: RWU): frames are ignored until + * an idle line (WAKE 0) or an address frame (WAKE 1: the MSB set and + * ADD's 4 low bits, or its 7 with ADDM7) wakes it; an address frame + * for another node mutes it again; + * - with CR3.RTSE nRTS is low while the receiver has room; + * - half-duplex (HDSEL): the receiver listens on the TX pin. + * - in Stop, a receiver whose kernel clock runs there (CR1.UESM with + * HSI16 or LSE selected) still receives, setting WUF on the event + * CR3.WUS selects (00 address match, 10 a start bit, 11 RXNE) and so + * waking the core through its interrupt (WUFIE) and EXTI's direct + * line; otherwise a frame arriving in Stop is lost. + * Synchronous mode (CR2.CLKEN, master): the CK pin clocks each data bit + * (the last with LBCL), idling at CPOL, the data valid at the edge CPHA + * picks; RX is sampled at that edge. + * DMA (CR3): DMAT requests the transmitter's DMA while TXE/TXFNF is set, + * DMAR the receiver's while RXNE/RXFNE is set (USARTn_TX, USARTn_RX, + * LPUART1_TX, ...); DDRE: a reception error stops DMAR's requests until + * the error is cleared. + * The interrupt is pending while a flag is set with its enable: TXE/TXFNF + * with TXEIE, TC with TCIE, RXNE/RXFNE or ORE with RXNEIE, IDLE with + * IDLEIE, PE with PEIE, LBDF with LBDIE, CTSIF with CTSIE, CMF with + * CMIE, RTOF with RTOIE, WUF with WUFIE, TXFE with TXFEIE, RXFF with + * RXFFIE, TXFT with TXFTIE, RXFT with RXFTIE, or FE, NE or ORE with EIE. + * + * Not modelled: noise detection (one sample a bit: NE never sets, ONEBIT + * changes nothing), auto baud rate detection (ABREN: ABRF never sets and + * the rate stays BRR's), TXINV and RXINV (the line's levels are the + * standard ones: the runtime's waveform knows no inverted line), the DE + * assertion and deassertion times (DEAT, DEDT: DE spans the frame), the + * synchronous slave (SLVEN), smartcard (SCEN, NACK, GTPR, SCARCNT, EOBF) + * and IrDA (IREN, IRLP) modes, which no catalog part speaks, the + * TCBGT flag. */ +#include +#include + +#include "mcu/stm32/stm32.h" + +/* ISR */ +#define PE (1u << 0) +#define FE (1u << 1) +#define NE (1u << 2) +#define ORE (1u << 3) +#define IDLE (1u << 4) +#define RXNE (1u << 5) +#define TC (1u << 6) +#define TXE (1u << 7) +#define LBDF (1u << 8) +#define CTSIF (1u << 9) +#define CTS (1u << 10) +#define RTOF (1u << 11) +#define BUSY (1u << 16) +#define CMF (1u << 17) +#define SBKF (1u << 18) +#define RWU (1u << 19) +#define WUF (1u << 20) +#define TEACK (1u << 21) +#define REACK (1u << 22) +#define TXFE (1u << 23) +#define RXFF (1u << 24) +#define RXFT (1u << 26) +#define TXFT (1u << 27) +/* CR1 */ +#define UE (1u << 0) +#define UESM (1u << 1) +#define RE (1u << 2) +#define TE (1u << 3) +#define IDLEIE (1u << 4) +#define RXNEIE (1u << 5) +#define TCIE (1u << 6) +#define TXEIE (1u << 7) +#define PEIE (1u << 8) +#define PS (1u << 9) +#define PCE (1u << 10) +#define WAKE (1u << 11) +#define M0 (1u << 12) +#define MME (1u << 13) +#define CMIE (1u << 14) +#define OVER8 (1u << 15) +#define RTOIE (1u << 26) +#define M1 (1u << 28) +#define FIFOEN (1u << 29) +#define TXFEIE (1u << 30) +#define RXFFIE (1u << 31) +/* CR2 */ +#define ADDM7 (1u << 4) +#define LBDIE (1u << 6) +#define LBCL (1u << 8) +#define CPHA (1u << 9) +#define CPOL (1u << 10) +#define CLKEN (1u << 11) +#define LINEN (1u << 14) +#define SWAP (1u << 15) +#define DATAINV (1u << 18) +#define MSBFIRST (1u << 19) +#define RTOEN (1u << 23) +/* CR3 */ +#define EIE (1u << 0) +#define HDSEL (1u << 3) +#define DMAR (1u << 6) +#define DMAT (1u << 7) +#define RTSE (1u << 8) +#define CTSE (1u << 9) +#define CTSIE (1u << 10) +#define OVRDIS (1u << 12) +#define DDRE (1u << 13) +#define DEM (1u << 14) +#define DEP (1u << 15) +#define WUFIE (1u << 22) +#define TXFTIE (1u << 23) +#define RXFTIE (1u << 28) +/* RQR */ +#define SBKRQ (1u << 1) +#define MMRQ (1u << 2) +#define RXFRQ (1u << 3) +#define TXFRQ (1u << 4) + +#define FIFO 8 +#define CK_MAX 20 + +struct uv2 { + struct esk_mach *s; + struct esk_rf_periph *p; + struct esk_rf_reg *cr1, *cr2, *cr3, *brr, *rtor, *rqr, *isr, *icr, *rdr, *tdr, *presc; + int irq, lp, running; + /* the transmitter: the frames waiting (TDR, or the FIFO), the shift register */ + u16 txq[FIFO]; + int ntx; + int busy, brk, idle_frame; + u64 left; + /* the receiver */ + u16 rxq[FIFO]; + u8 rxerr[FIFO]; /* each frame's PE and FE */ + int nrx; + u64 idle_left, rto_left; + int cts, rts, ck, de; + u64 ck_at[CK_MAX]; + int nck, ck_next, ck_sample[CK_MAX]; + u16 sync_rx; + int sync_bits; + char sig_tx[16], sig_rx[16]; +}; + +static u32 v32(const struct esk_rf_reg *r) { return r ? (u32)r->value : 0; } + +static int fifo(const struct uv2 *u) { return (v32(u->cr1) & FIFOEN) != 0; } + +static int depth(const struct uv2 *u) { return fifo(u) ? FIFO : 1; } + +static void isr_set(struct uv2 *u, u32 set, u32 clear) +{ + u64 v = (u->isr->value & ~(u64)clear) | set; + if (v != u->isr->value) + esk_rf_hw(u->isr, v); +} + +/* the FIFO thresholds (TXFTCFG, RXFTCFG): 1/8, 1/4, 1/2, 3/4, 7/8, full */ +static int threshold(u32 cfg) +{ + static const int n[8] = { 1, 2, 4, 6, 7, 8, 8, 8 }; + return n[cfg & 7]; +} + +/* ISR's flags as the queues have them */ +static void flags(struct uv2 *u) +{ + u32 set = 0, clear = 0, c3 = v32(u->cr3); + int room = depth(u) - u->ntx; + if (room > 0) + set |= TXE; + else + clear |= TXE; + if (u->ntx == 0) + set |= TXFE; + else + clear |= TXFE; + if (u->nrx > 0) + set |= RXNE; + else + clear |= RXNE; + if (fifo(u)) { + if (u->nrx >= FIFO) + set |= RXFF; + else + clear |= RXFF; + /* TXFT: the FIFO holds no more than its threshold's free slots' worth */ + if (FIFO - u->ntx >= threshold(c3 >> 29)) + set |= TXFT; + else + clear |= TXFT; + if (u->nrx >= threshold(c3 >> 25)) + set |= RXFT; + else + clear |= RXFT; + } else { + clear |= RXFF | RXFT | TXFT; + } + if (u->busy) + set |= BUSY; + else + clear |= BUSY; + isr_set(u, set, clear); +} + +static void dma_check(struct uv2 *u) +{ + u32 isr = v32(u->isr), c3 = v32(u->cr3), c1 = v32(u->cr1); + int err = (c3 & DDRE) && (isr & (PE | FE | NE | ORE)); + esk_stm32_dma_request(u->s, u->sig_tx, (c3 & DMAT) && (isr & TXE) && (c1 & UE) && (c1 & TE)); + esk_stm32_dma_request(u->s, u->sig_rx, (c3 & DMAR) && (isr & RXNE) && (c1 & UE) && !err); +} + +static void update_irq(struct uv2 *u) +{ + u32 isr = v32(u->isr), c1 = v32(u->cr1), c2 = v32(u->cr2), c3 = v32(u->cr3); + if (((isr & TXE) && (c1 & TXEIE)) || ((isr & TC) && (c1 & TCIE)) || ((isr & (RXNE | ORE)) && (c1 & RXNEIE)) || + ((isr & IDLE) && (c1 & IDLEIE)) || ((isr & PE) && (c1 & PEIE)) || ((isr & LBDF) && (c2 & LBDIE)) || + ((isr & CTSIF) && (c3 & CTSIE)) || ((isr & CMF) && (c1 & CMIE)) || ((isr & RTOF) && (c1 & RTOIE)) || + ((isr & WUF) && (c3 & WUFIE)) || ((isr & TXFE) && (c1 & TXFEIE) && fifo(u)) || + ((isr & RXFF) && (c1 & RXFFIE)) || ((isr & TXFT) && (c3 & TXFTIE)) || ((isr & RXFT) && (c3 & RXFTIE)) || + ((isr & (FE | NE | ORE)) && (c3 & EIE))) + esk_rf_interrupt(u->p, u->irq); +} + +/* ---- the frame's format and time --------------------------------------------- */ + +static int data_bits(const struct uv2 *u) +{ + u32 c1 = v32(u->cr1); + return (c1 & M1) ? 7 : (c1 & M0) ? 9 : 8; +} + +static int stop_halves(const struct uv2 *u) +{ + static const int halves[4] = { 2, 1, 4, 3 }; + int h = halves[v32(u->cr2) >> 12 & 3]; + if (u->lp && (h == 1 || h == 3)) + h = 2; /* an LPUART's: 1 or 2 stop bits */ + return h; +} + +static u32 presc_div(const struct uv2 *u) +{ + static const u32 d[12] = { 1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256 }; + u32 k = v32(u->presc) & 15u; + return k < 12 ? d[k] : 256; +} + +static u32 kernel_hz(const struct uv2 *u) +{ + u32 hz = esk_stm32g4_kernel_hz(u->s, u->p->name); + if (!hz && !esk_stm32g4_rcc(u->s)) + hz = esk_stm32_pclk(u->s, u->p->gate_name && strstr(u->p->gate_name, "APB2") ? 2 : 1); + return hz / presc_div(u); +} + +/* core cycles per bit */ +static u32 bit_cycles(const struct uv2 *u) +{ + u32 brr = v32(u->brr), ker = kernel_hz(u), core = esk_mach_core_hz(u->s); + u64 num, den, c; + if (!ker || !brr || !core) + return 1; + if (u->lp) { + num = (u64)brr * core; /* bit = BRR / (256 x ker) */ + den = (u64)256u * ker; + } else { + u32 div = brr & 0xffffu; + if (v32(u->cr1) & OVER8) + div = (div & 0xfff0u) | (div & 7u) << 1; /* BRR[3] must be 0 */ + num = (u64)div * core; + den = ker; + if (v32(u->cr1) & OVER8) + den *= 2u; + } + c = (num + den / 2) / den; + return c ? (u32)(c > 0xffffffu ? 0xffffffu : c) : 1; +} + +static u64 frame_cycles(const struct uv2 *u) +{ + return (u64)bit_cycles(u) * (u64)(2 * (1 + data_bits(u)) + stop_halves(u)) / 2u; +} + +static u32 parity_of(u32 v, int n) +{ + u32 ones = 0; + int k; + for (k = 0; k < n; k++) + ones += v >> k & 1u; + return ones & 1u; +} + +/* the bits on the line (LSB first) of data `v`: MSBFIRST and DATAINV + * applied to the data, then the parity bit */ +static u32 line_bits(const struct uv2 *u, u32 v) +{ + int n = data_bits(u), d = (v32(u->cr1) & PCE) ? n - 1 : n, k; + u32 data = v & ((1u << d) - 1), out = 0; + if (v32(u->cr2) & DATAINV) + data = ~data & ((1u << d) - 1); + if (v32(u->cr2) & MSBFIRST) { + for (k = 0; k < d; k++) + out |= (data >> k & 1u) << (d - 1 - k); + data = out; + } + if (v32(u->cr1) & PCE) + data |= (parity_of(data, d) ^ ((v32(u->cr1) & PS) ? 1u : 0u)) << d; + return data; +} + +/* the data a frame's line bits carry, and whether its parity is right */ +static u32 data_of(const struct uv2 *u, u32 bits, int *parity_ok) +{ + int n = data_bits(u), d = (v32(u->cr1) & PCE) ? n - 1 : n, k; + u32 data = bits & ((1u << d) - 1), out = 0; + *parity_ok = 1; + if (v32(u->cr1) & PCE) + *parity_ok = (parity_of(bits, n) ^ ((v32(u->cr1) & PS) ? 1u : 0u)) == 0; + if (v32(u->cr2) & MSBFIRST) { + for (k = 0; k < d; k++) + out |= (data >> k & 1u) << (d - 1 - k); + data = out; + } + if (v32(u->cr2) & DATAINV) + data = ~data & ((1u << d) - 1); + /* RDR holds the parity bit in its place, as the frame had it */ + if (v32(u->cr1) & PCE) + data |= (bits >> d & 1u) << d; + return data; +} + +static void run_clock(struct uv2 *u) +{ + esk_rf_clock(u->p, &u->running, u->busy || u->idle_left || u->rto_left || u->ck_next < u->nck); +} + +static void pins(struct uv2 *u) +{ + if (u->s->pins_changed) + u->s->pins_changed(u->s); +} + +static void rts_update(struct uv2 *u) +{ + int r = (v32(u->cr3) & RTSE) ? u->nrx >= depth(u) : 1; + if (r != u->rts) { + u->rts = r; + pins(u); + } +} + +static void de_set(struct uv2 *u, int on) +{ + if ((v32(u->cr3) & DEM) && on != u->de) { + u->de = on; + pins(u); + } +} + +/* ---- the receiver -------------------------------------------------------- */ + +static int receiving(const struct uv2 *u) +{ + u32 c1 = v32(u->cr1); + if (!(c1 & UE) || !(c1 & RE)) + return 0; + if (u->s->clocks_stopped) { + /* Stop: only a kernel clock that runs there (HSI16, LSE) with UESM */ + u32 sel = 0; + struct esk_rf_periph *rcc = esk_rf_periph(u->s->rf, "RCC"); + struct esk_rf_reg *ccipr = rcc ? esk_rf_reg(rcc, "CCIPR") : 0; + int k = !strcmp(u->p->name, "LPUART1") ? 5 : u->p->name[strlen(u->p->name) - 1] - '1'; + if (ccipr && k >= 0 && k <= 5) + sel = (u32)(ccipr->value >> (2 * k) & 3); + return (c1 & UESM) && (sel == 2 || sel == 3); + } + return 1; +} + +static void wake_event(struct uv2 *u, u32 wus) +{ + u32 c3 = v32(u->cr3); + if (!u->s->clocks_stopped || ((c3 >> 20) & 3) != wus) + return; + isr_set(u, WUF, 0); + if (c3 & WUFIE) + esk_rf_interrupt(u->p, u->irq); +} + +static void receive(struct uv2 *u, u32 bits, int framing_error) +{ + u32 c1 = v32(u->cr1), c2 = v32(u->cr2), n = (u32)data_bits(u), raw = bits & ((1u << n) - 1), v; + int brk = framing_error && raw == 0, pok; + if (!receiving(u)) + return; + v = data_of(u, raw, &pok); + u->idle_left = frame_cycles(u); + u->rto_left = (c2 & RTOEN) ? (u64)bit_cycles(u) * (v32(u->rtor) & 0xffffffu) : 0; + run_clock(u); + if (brk && (c2 & LINEN)) + isr_set(u, LBDF, 0); + { + /* address mark (WAKE 1): the data's MSB (below the parity bit) set, + * ADD's 4 (or 7, ADDM7) low bits matching */ + u32 msb = (c1 & PCE) ? n - 2 : n - 1, amask = (c2 & ADDM7) ? 0x7fu : 0x0fu; + int address = (c1 & WAKE) && (v >> msb & 1); + int ours = address && (v & amask) == ((c2 >> 24) & amask); + if (ours) + wake_event(u, 0); + if (v32(u->isr) & RWU) { + if (!ours) { + update_irq(u); + return; + } + isr_set(u, 0, RWU); + } else if (address && !ours && (c1 & MME)) { + isr_set(u, RWU, 0); + update_irq(u); + return; + } + } + if ((v & 0xffu) == (c2 >> 24)) + isr_set(u, CMF, 0); + if (u->nrx >= depth(u)) { + if (v32(u->cr3) & OVRDIS) { + u->rxq[u->nrx - 1] = (u16)v; /* the last frame overwritten */ + } else { + isr_set(u, ORE, 0); + } + } else { + u->rxq[u->nrx] = (u16)v; + u->rxerr[u->nrx] = (u8)((pok ? 0 : PE) | (framing_error ? FE : 0)); + u->nrx++; + if (u->nrx == 1) { + esk_rf_hw(u->rdr, u->rxq[0]); + isr_set(u, u->rxerr[0], 0); + } + } + flags(u); + wake_event(u, 3); + rts_update(u); + update_irq(u); + dma_check(u); +} + +static u32 uv2_format(void *ctx) +{ + const struct uv2 *u = (const struct uv2 *)ctx; + return (u32)data_bits(u) | (u32)stop_halves(u) << 8; +} + +static void uv2_put_frame(void *ctx, u32 bits, int framing_error) +{ + receive((struct uv2 *)ctx, bits, framing_error); +} + +static void uv2_started(void *ctx) +{ + struct uv2 *u = (struct uv2 *)ctx; + u->idle_left = 0; + u->rto_left = 0; + if (receiving(u)) + wake_event(u, 2); +} + +/* the session's serial input: a byte as a terminal sends it (LSB first, + * the parity it is set up for); the receiver reads it as its own format + * says, MSBFIRST and DATAINV included */ +static void uv2_put(void *ctx, int c) +{ + struct uv2 *u = (struct uv2 *)ctx; + int n = data_bits(u), d = (v32(u->cr1) & PCE) ? n - 1 : n; + u32 bits = (u32)c & ((1u << d) - 1); + if (v32(u->cr1) & PCE) + bits |= (parity_of(bits, d) ^ ((v32(u->cr1) & PS) ? 1u : 0u)) << d; + receive(u, bits, 0); +} + +static int uv2_room(void *ctx) +{ + struct uv2 *u = (struct uv2 *)ctx; + return (v32(u->cr1) & UE) && (v32(u->cr1) & RE) && !(v32(u->cr2) & CLKEN); +} + +static u32 uv2_bit_cycles(void *ctx) +{ + return bit_cycles((const struct uv2 *)ctx); +} + +/* ---- the transmitter ----------------------------------------------------- */ + +static void sync_clock(struct uv2 *u, u64 b) +{ + u32 c2 = v32(u->cr2); + int n = data_bits(u), k, pulses = (c2 & LBCL) ? n : n - 1; + u->nck = 0; + u->ck_next = 0; + u->sync_rx = 0; + u->sync_bits = 0; + for (k = 0; k < pulses && u->nck + 2 <= CK_MAX; k++) { + u64 bit0 = b + (u64)k * b; + u64 e1 = (c2 & CPHA) ? bit0 : bit0 + b / 2, e2 = e1 + b / 2; + u->ck_at[u->nck] = e1; + u->ck_sample[u->nck++] = !(c2 & CPHA); + u->ck_at[u->nck] = e2; + u->ck_sample[u->nck++] = (c2 & CPHA) != 0; + } +} + +static void start_frame(struct uv2 *u, u32 v, int brk, int idle) +{ + struct esk_mach *s = u->s; + int n = data_bits(u); + u64 b = bit_cycles(u); + u->busy = 1; + u->brk = brk; + u->idle_frame = idle; + u->left = frame_cycles(u); + isr_set(u, BUSY, TC); + if (brk) { + int zeros = (v32(u->cr2) & LINEN) ? 12 : n + 1; + u->left = b * (u64)(1 + zeros) + b; + isr_set(u, SBKF, 0); + if (s->host.uart_frame) + s->host.uart_frame(s->host.ctx, u->p->name, -1, 0, zeros, 2, (u32)b); + } else if (!idle) { + u32 bits = line_bits(u, v); + int d = (v32(u->cr1) & PCE) ? n - 1 : n; + int c = (int)(bits & ((1u << (d > 8 ? 8 : d)) - 1)); + de_set(u, 1); + if (s->host.uart_frame) + s->host.uart_frame(s->host.ctx, u->p->name, c, bits, n, stop_halves(u), (u32)b); + else if (s->host.uart_tx) + s->host.uart_tx(s->host.ctx, u->p->name, c, (u32)b); + if (v32(u->cr2) & CLKEN) + sync_clock(u, b); + } + run_clock(u); +} + +static void next_frame(struct uv2 *u) +{ + if (u->busy) + return; + if (!(v32(u->cr1) & UE) || !(v32(u->cr1) & TE)) + return; + if ((v32(u->cr3) & CTSE) && u->cts) + return; + if (v32(u->isr) & SBKF) { + start_frame(u, 0, 1, 0); + return; + } + if (u->ntx) { + u16 v = u->txq[0]; + memmove(u->txq, u->txq + 1, (size_t)(u->ntx - 1) * sizeof u->txq[0]); + u->ntx--; + flags(u); + start_frame(u, v, 0, 0); + } +} + +static void frame_end(struct uv2 *u) +{ + u->busy = 0; + u->left = 0; + if (u->brk) + isr_set(u, 0, SBKF); + u->brk = u->idle_frame = 0; + next_frame(u); + if (!u->busy) { + isr_set(u, TC, BUSY); + de_set(u, 0); + } + flags(u); +} + +static int rx_level(struct uv2 *u) +{ + int port, bit, lvl = 1; + if (esk_stm32_usartv2_pin(u->s, u->p->name, 0, &port, &bit) == 0 && u->s->host.pin_in && + !u->s->host.pin_in(u->s->host.ctx, port, bit, &lvl)) + lvl = 1; + return lvl != 0; +} + +static void sync_edges(struct uv2 *u, u64 elapsed) +{ + u32 c2 = v32(u->cr2); + int changed = 0; + while (u->ck_next < u->nck && u->ck_at[u->ck_next] <= elapsed) { + int first = !(u->ck_next & 1); + u->ck = first ? !(c2 & CPOL) : (c2 & CPOL) != 0; + if (u->ck_sample[u->ck_next]) { + if (rx_level(u)) + u->sync_rx |= (u16)(1u << u->sync_bits); + u->sync_bits++; + } + u->ck_next++; + changed = 1; + } + if (changed) + pins(u); +} + +/* ---- the device -------------------------------------------------------------- */ + +static void uv2_tick(void *ctx, u32 cycles) +{ + struct uv2 *u = (struct uv2 *)ctx; + if (u->idle_left) { + if (u->idle_left > cycles) { + u->idle_left -= cycles; + } else { + u->idle_left = 0; + if ((v32(u->cr1) & UE) && (v32(u->cr1) & RE)) { + if ((v32(u->isr) & RWU) && !(v32(u->cr1) & WAKE)) + isr_set(u, 0, RWU); /* an idle line wakes it */ + else if (!(v32(u->isr) & RWU)) + isr_set(u, IDLE, 0); + update_irq(u); + } + } + } + if (u->rto_left) { + if (u->rto_left > cycles) { + u->rto_left -= cycles; + } else { + u->rto_left = 0; + isr_set(u, RTOF, 0); + update_irq(u); + } + } + if (u->busy) { + u64 total = frame_cycles(u); + if (u->ck_next < u->nck) + sync_edges(u, total - (u->left > cycles ? u->left - cycles : 0)); + if (u->left > cycles) { + u->left -= cycles; + } else { + if (v32(u->cr2) & CLKEN) { + u->ck = (v32(u->cr2) & CPOL) != 0; + u->nck = u->ck_next = 0; + if (u->sync_bits && !u->idle_frame && !u->brk) + receive(u, u->sync_rx, 0); + pins(u); + } + frame_end(u); + update_irq(u); + dma_check(u); + } + } + run_clock(u); +} + +static int uv2_next(void *ctx, u32 *cycles) +{ + struct uv2 *u = (struct uv2 *)ctx; + u64 best = 0; + if (u->busy) { + best = u->left; + if (u->ck_next < u->nck) { + u64 elapsed = frame_cycles(u) - u->left, at = u->ck_at[u->ck_next]; + u64 c = at > elapsed ? at - elapsed : 1; + if (c < best) + best = c; + } + } + if (u->idle_left && (!best || u->idle_left < best)) + best = u->idle_left; + if (u->rto_left && (!best || u->rto_left < best)) + best = u->rto_left; + if (!best) + return 0; + *cycles = best > 0xffffffffu ? 0xffffffffu : (u32)best; + return 1; +} + +static void take_rx(struct uv2 *u) +{ + if (!u->nrx) + return; + memmove(u->rxq, u->rxq + 1, (size_t)(u->nrx - 1) * sizeof u->rxq[0]); + memmove(u->rxerr, u->rxerr + 1, (size_t)(u->nrx - 1)); + u->nrx--; + if (u->nrx) { + esk_rf_hw(u->rdr, u->rxq[0]); + isr_set(u, u->rxerr[0], 0); /* the next frame's errors show */ + } +} + +static u32 uv2_read(void *ctx, u32 off, int n) +{ + struct uv2 *u = (struct uv2 *)ctx; + u32 v; + if (off == esk_rf_off(u->rdr)) { + v = u->nrx ? u->rxq[0] : (u32)u->rdr->value; + if (u->s->bus.debug) + return v; + take_rx(u); + flags(u); + rts_update(u); + update_irq(u); + dma_check(u); + return v; + } + return esk_rf_read(u->p, off, n); +} + +static void enables(struct uv2 *u, u32 was) +{ + u32 c1 = v32(u->cr1); + u32 set = 0, clear = 0; + if ((c1 & UE) && (c1 & TE)) + set |= TEACK; + else + clear |= TEACK; + if ((c1 & UE) && (c1 & RE)) + set |= REACK; + else + clear |= REACK; + isr_set(u, set, clear); + if ((c1 & UE) && (c1 & TE) && !((was & UE) && (was & TE)) && !u->busy) + start_frame(u, 0x1ff, 0, 1); /* TE: an idle frame */ + if (!(c1 & UE)) { + /* disabled: the transmitter and receiver stop, their queues empty */ + u->ntx = u->nrx = 0; + u->busy = 0; + u->left = u->idle_left = u->rto_left = 0; + u->nck = u->ck_next = 0; + esk_rf_hw(u->isr, TXE | TC | TXFE); /* UE clear: the flags as at reset */ + de_set(u, 0); + } + if ((c1 & UE) != (was & UE) || (c1 & TE) != (was & TE)) + pins(u); +} + +static void uv2_write(void *ctx, u32 off, int n, u32 v) +{ + struct uv2 *u = (struct uv2 *)ctx; + u32 c1 = v32(u->cr1); + if (off == esk_rf_off(u->tdr)) { + if (!(c1 & UE)) + return; + if (u->ntx < depth(u)) { + u->txq[u->ntx++] = (u16)(v & 0x1ffu); + isr_set(u, 0, TC); + } + flags(u); + next_frame(u); + update_irq(u); + dma_check(u); + return; + } + if (off == esk_rf_off(u->icr)) { + u32 clr = v & (PE | FE | NE | ORE | IDLE | TC | LBDF | CTSIF | RTOF | (1u << 12) | CMF | WUF); + if (v & (1u << 7)) + clr |= 1u << 25; /* TCBGTCF */ + isr_set(u, 0, clr); + update_irq(u); + dma_check(u); + return; + } + if (off == esk_rf_off(u->rqr)) { + if (v & SBKRQ) { + isr_set(u, SBKF, 0); + next_frame(u); + } + if (v & MMRQ && (c1 & MME)) + isr_set(u, RWU, 0); + if (v & RXFRQ) { + u->nrx = 0; + isr_set(u, 0, RXNE); + } + if (v & TXFRQ) + u->ntx = 0; + flags(u); + rts_update(u); + update_irq(u); + dma_check(u); + return; + } + esk_rf_write(u->p, off, n, v); + if (off == esk_rf_off(u->cr1)) + enables(u, c1); + if (off == esk_rf_off(u->cr2) || off == esk_rf_off(u->cr1)) { + int ck = (v32(u->cr2) & CLKEN) && (v32(u->cr1) & UE) ? (v32(u->cr2) & CPOL) != 0 : -1; + if (ck != u->ck && u->ck_next >= u->nck) { + u->ck = ck; + pins(u); + } + } + flags(u); + rts_update(u); + run_clock(u); + update_irq(u); + dma_check(u); +} + +static void uv2_reset(void *ctx) +{ + struct uv2 *u = (struct uv2 *)ctx; + u->ntx = u->nrx = 0; + u->busy = u->brk = u->idle_frame = 0; + u->left = u->idle_left = u->rto_left = 0; + u->running = 0; + u->rts = 1; + u->de = 0; + u->ck = -1; + u->nck = u->ck_next = 0; +} + +const struct esk_dev_ops esk_stm32_usartv2_ops = { + "stm32-usart-v2", uv2_read, uv2_write, uv2_reset, uv2_tick, uv2_next, +}; + +/* ---- the pins -------------------------------------------------------------- */ + +static struct uv2 *uv2_named(struct esk_mach *s, const char *name) +{ + struct esk_rf_periph *p = s->rf ? esk_rf_periph(s->rf, name) : 0; + return p && p->ops == &esk_stm32_usartv2_ops && !esk_rf_gated(p) ? (struct uv2 *)p->ctx : 0; +} + +static struct uv2 *signal_of(struct esk_mach *s, const char *sig, const char **fn) +{ + char name[16]; + const char *us = strchr(sig, '_'); + size_t l = us ? (size_t)(us - sig) : 0; + if (!us || l >= sizeof name || (strncmp(sig, "USART", 5) && strncmp(sig, "UART", 4) && strncmp(sig, "LPUART", 6))) + return 0; + memcpy(name, sig, l); + name[l] = 0; + *fn = us + 1; + return uv2_named(s, name); +} + +int esk_stm32_usartv2_signal(struct esk_mach *s, const char *sig) +{ + const char *fn; + struct uv2 *u = signal_of(s, sig, &fn); + u32 c2; + if (!u || !(v32(u->cr1) & UE)) + return -1; + c2 = v32(u->cr2); + if (!strcmp(fn, (c2 & SWAP) ? "RX" : "TX")) + return (v32(u->cr1) & TE) || (v32(u->cr3) & HDSEL) ? 1 : -1; + if (!strcmp(fn, "DE") && (v32(u->cr3) & DEM)) + return u->de ? !(v32(u->cr3) & DEP) : (v32(u->cr3) & DEP) != 0; + if (!strcmp(fn, "RTS")) + return (v32(u->cr3) & RTSE) ? u->rts : -1; + if (!strcmp(fn, "CK")) + return u->ck; + return -1; +} + +void esk_stm32_usartv2_signal_input(struct esk_mach *s, const char *sig, int level) +{ + const char *fn; + struct uv2 *u = signal_of(s, sig, &fn); + if (!u || strcmp(fn, "CTS")) + return; + level = level != 0; + if (level == u->cts) + return; + u->cts = level; + isr_set(u, level ? 0 : CTS, level ? CTS : 0); /* CTS: the nCTS line's state, inverted */ + if (v32(u->cr3) & CTSE) { + isr_set(u, CTSIF, 0); + next_frame(u); + update_irq(u); + } +} + +int esk_stm32_usartv2_pin(struct esk_mach *s, const char *unit, int tx, int *port, int *bit) +{ + struct uv2 *u = uv2_named(s, unit); + char sig[24]; + int at; + if (u && !tx && (v32(u->cr3) & HDSEL)) + tx = 1; + if (u && (v32(u->cr2) & SWAP)) + tx = !tx; + snprintf(sig, sizeof sig, "%s_%s", unit, tx ? "TX" : "RX"); + at = esk_stm32f4_af_pin(s, sig); + if (at < 0) + return -1; + *port = at / 32; + *bit = at % 32; + return 0; +} + +void *esk_stm32_usartv2_create(struct esk_mach *s, struct esk_rf_periph *p) +{ + struct uv2 *u; + if (!esk_rf_reg(p, "ISR") || !esk_rf_reg(p, "ICR") || !esk_rf_reg(p, "TDR") || !esk_rf_reg(p, "RDR") || + !esk_rf_reg(p, "CR1") || !esk_rf_reg(p, "BRR")) + return 0; + u = (struct uv2 *)esk_mach_alloc(s, sizeof *u); + if (!u) + return 0; + u->s = s; + u->p = p; + u->cr1 = esk_rf_reg(p, "CR1"); + u->cr2 = esk_rf_reg(p, "CR2"); + u->cr3 = esk_rf_reg(p, "CR3"); + u->brr = esk_rf_reg(p, "BRR"); + u->rtor = esk_rf_reg(p, "RTOR"); + u->rqr = esk_rf_reg(p, "RQR"); + u->isr = esk_rf_reg(p, "ISR"); + u->icr = esk_rf_reg(p, "ICR"); + u->rdr = esk_rf_reg(p, "RDR"); + u->tdr = esk_rf_reg(p, "TDR"); + u->presc = esk_rf_reg(p, "PRESC"); + if (!u->cr2 || !u->cr3) + return 0; + u->lp = !strncmp(p->name, "LPUART", 6); + u->irq = esk_rf_irq(p, 0); + /* ISR is the hardware's: its flags are cleared through ICR, RQR */ + esk_rf_set_acc(u->isr, ~(u64)0, ESK_ACC_RO); + esk_rf_set_acc(u->icr, ~(u64)0, ESK_ACC_WO); + esk_rf_set_acc(u->rdr, ~(u64)0, ESK_ACC_RO); + esk_rf_set_reset(u->isr, TXE | TC | TXFE); + uv2_reset(u); + u->cts = 1; + snprintf(u->sig_tx, sizeof u->sig_tx, "%s_TX", p->name); + snprintf(u->sig_rx, sizeof u->sig_rx, "%s_RX", p->name); + s->uart_pin = esk_stm32_usartv2_pin; + esk_mach_rx_port(s, p->name, uv2_room, uv2_put, uv2_bit_cycles, u); + esk_mach_rx_frames(s, uv2_format, uv2_put_frame, uv2_started); + return u; +} diff --git a/core/mcu/stm32/wdg.c b/core/mcu/stm32/wdg.c index e00397717..7ceb528d0 100644 --- a/core/mcu/stm32/wdg.c +++ b/core/mcu/stm32/wdg.c @@ -12,12 +12,19 @@ * is lost). At 0 it resets the part (IWDGRSTF): it runs until a reset * stops it; * - with the option bytes' hardware watchdog (WDG_SW 0 in their user - * byte, which the part loads into FLASH's option register at reset) it - * starts by itself at every reset. + * byte, which the part loads into FLASH's option register at reset; a + * G4's IWDG_SW in OPTR) it starts by itself at every reset; + * - the window (a G4's WINR, RM0440 41): a refresh while the counter is + * above WINR resets the part; writing WINR reloads the counter, the + * value reaching the counter's domain five LSI clocks later (WVU); + * WINR's reset value 0xFFF leaves the window open; + * - a G4's option bytes' IWDG_STOP and IWDG_STDBY cleared freeze the + * counter in Stop and in Standby. * * The WWDG: * - its 7-bit counter (CR.T) counts down every 4096 x 2^WDGTB PCLK1 - * clocks while its clock is on; CFR holds the window W and EWI; + * clocks while its clock is on (WDGTB 2 bits at CFR[8:7], a G4's 3 at + * CFR[13:11]); CFR holds the window W and EWI; * - once WDGA is set (it clears only with a reset) the part resets * (WWDGRSTF) when T6 clears (0x40 to 0x3F), when CR is written with T6 * clear, or when CR is written while the counter is above W; @@ -38,20 +45,21 @@ #define KR_ACCESS 0x5555u #define SR_PVU (1u << 0) #define SR_RVU (1u << 1) +#define SR_WVU (1u << 2) /* ---- IWDG ------------------------------------------------------------------------ */ struct iwdg { struct esk_mach *s; struct esk_rf_periph *p; - struct esk_rf_reg *kr, *pr, *rlr, *sr; + struct esk_rf_reg *kr, *pr, *rlr, *sr, *winr; int running, on, access; - u32 count, pr_now, rlr_now; + u32 count, pr_now, rlr_now, winr_now; u64 acc; /* core cycles x LSI_HZ toward the next count */ u64 since; - u32 upd; /* PVU/RVU: bits waiting */ + u32 upd; /* PVU/RVU/WVU: bits waiting */ u64 upd_left; /* core cycles until they land */ - u32 pr_new, rlr_new; + u32 pr_new, rlr_new, winr_new; }; static u32 reg(const struct esk_rf_reg *r) { return r ? (u32)r->value : 0; } @@ -88,12 +96,27 @@ static void iw_start(struct iwdg *w) * watchdog stops while a debugger holds the core halted */ static int frozen(const struct esk_mach *s, int bit) { return s->dbg.halted && (s->dbg.fz[0] >> bit & 1u); } +/* a G4's option bytes' IWDG_STOP (OPTR bit 17) or IWDG_STDBY (18) clear: + * the counter frozen in Stop or Standby */ +static int option_frozen(const struct esk_mach *s) +{ + struct esk_rf_periph *f; + struct esk_rf_reg *optr; + if (!s->clocks_stopped || !s->rf) + return 0; + f = esk_rf_periph(s->rf, "FLASH"); + optr = f ? esk_rf_reg(f, "OPTR") : 0; + if (!optr || !esk_rf_mask(optr, "IWDG_SW")) + return 0; + return !(optr->value >> (esk_stm32f4_pwr_standby((struct esk_mach *)s) ? 18 : 17) & 1u); +} + static void iw_tick(void *ctx, u32 cycles) { struct iwdg *w = (struct iwdg *)ctx; if (!w->running) return; - if (frozen(w->s, 12)) { + if (frozen(w->s, 12) || option_frozen(w->s)) { w->since = 0; return; } @@ -107,6 +130,11 @@ static void iw_tick(void *ctx, u32 cycles) w->pr_now = w->pr_new; if (w->upd & SR_RVU) w->rlr_now = w->rlr_new; + if (w->upd & SR_WVU) { + w->winr_now = w->winr_new; + w->count = w->rlr_now & 0xfffu; /* writing WINR reloads the counter */ + w->acc = 0; + } w->upd = 0; esk_rf_hw(w->sr, 0); } @@ -134,7 +162,7 @@ static int iw_next(void *ctx, u32 *cycles) { struct iwdg *w = (struct iwdg *)ctx; u64 best = ~(u64)0; - if (!w->running || frozen(w->s, 12)) + if (!w->running || frozen(w->s, 12) || option_frozen(w->s)) return 0; if (w->on) { u64 need = ((u64)w->count + 1) * iw_unit(w); @@ -165,6 +193,15 @@ static void iw_write(void *ctx, u32 off, int n, u32 v) if (key == KR_START) iw_start(w); else if (key == KR_RELOAD && w->on) { + if (w->winr && w->count > (w->winr_now & 0xfffu) && !w->s->reset_req) { + /* refreshed before the window opened */ + esk_rf_diag(w->s, ES_SEV_INFO, "mcu.watchdog_reset", "%s", + "the independent watchdog was refreshed outside its window: it resets the part"); + w->s->reset_cause = ESK_RESET_WATCHDOG; + w->s->reset_req = 1; + w->s->yield = 1; + return; + } w->count = w->rlr_now & 0xfffu; w->acc = 0; } @@ -180,6 +217,10 @@ static void iw_write(void *ctx, u32 off, int n, u32 v) w->rlr_new = v & 0xfffu; esk_rf_hw(w->rlr, w->rlr_new); w->upd |= SR_RVU; + } else if (w->winr && off == esk_rf_off(w->winr) && !(w->upd & SR_WVU)) { + w->winr_new = v & 0xfffu; + esk_rf_hw(w->winr, w->winr_new); + w->upd |= SR_WVU; } else { return; } @@ -197,7 +238,10 @@ static int hardware_watchdog(struct esk_mach *s) { struct esk_rf_periph *f = s->rf ? esk_rf_periph(s->rf, "FLASH") : 0; struct esk_rf_reg *optcr = f ? esk_rf_reg(f, "OPTCR") : 0, *obr = f ? esk_rf_reg(f, "OBR") : 0; + struct esk_rf_reg *optr = f ? esk_rf_reg(f, "OPTR") : 0; u32 v = 0; + if (optr && esk_rf_mask(optr, "IWDG_SW")) + return !(optr->value & esk_rf_mask(optr, "IWDG_SW")); /* a G4's, loaded by flash_g4.c */ if (optcr && esk_rf_mask(optcr, "WDG_SW") && !esk_bus_debug_read(&s->bus, 0x1FFFC000u, 2, &v)) { esk_rf_hw(optcr, (optcr->value & ~(u64)0xffecu) | (v & 0xffecu)); /* RDP, USER, BOR_LEV */ return !(v & 0x20u); @@ -217,6 +261,7 @@ static void iw_reset(void *ctx) w->upd = 0; w->pr_now = 0; w->rlr_now = 0xfffu; + w->winr_now = 0xfffu; w->count = 0xfffu; w->acc = 0; w->since = 0; @@ -244,9 +289,11 @@ void *esk_stm32_iwdg_create(struct esk_mach *s, struct esk_rf_periph *p) w.pr = esk_rf_reg(p, "PR"); w.rlr = esk_rf_reg(p, "RLR"); w.sr = esk_rf_reg(p, "SR"); + w.winr = esk_rf_reg(p, "WINR"); if (!w.kr || !w.pr || !w.rlr || !w.sr) return 0; w.rlr_now = 0xfffu; + w.winr_now = 0xfffu; w.count = 0xfffu; p->always_on = 1; /* on LSI: it counts through Stop and Standby */ c = (struct iwdg *)esk_mach_alloc(s, sizeof *c); @@ -276,7 +323,11 @@ static u64 ww_unit(const struct wwdg *w) { u32 core = esk_mach_core_hz(w->s), pclk = esk_stm32_pclk(w->s, 1); u64 ratio = core && pclk && core >= pclk ? core / pclk : 1; - return ratio * ((u64)4096u << (reg(w->cfr) >> 7 & 3u)); + u64 tb = esk_rf_mask(w->cfr, "WDGTB"); + u32 sh = 0; + while (tb && !(tb >> sh & 1)) + sh++; + return ratio * ((u64)4096u << (tb ? (u32)((reg(w->cfr) & tb) >> sh) : (reg(w->cfr) >> 7 & 3u))); } /* the counter now (T[6:0]); its clock off: as it was */ @@ -384,7 +435,7 @@ static void ww_write(void *ctx, u32 off, int n, u32 v) } else if (off == esk_rf_off(w->cfr)) { u32 keep = reg(w->cfr) & CFR_EWI; /* EWI only sets */ u32 t = ww_count(w); - esk_rf_hw(w->cfr, (v & 0x3ffu) | keep); + esk_rf_hw(w->cfr, (v & (u32)esk_rf_fields(w->cfr)) | keep); ww_rebase(w, t); } else if (off == esk_rf_off(w->sr)) { if (!(v & SR_EWIF)) diff --git a/core/project/loader.c b/core/project/loader.c index b4cec2bf2..894daa1fc 100644 --- a/core/project/loader.c +++ b/core/project/loader.c @@ -776,7 +776,7 @@ static es_status join_ties(graph *g, esk_comp *c) /* the board's firmware on its MCU's runtime (SPEC-009): the image, the register * description beside the MCU description, the board's oscillator */ -#define LD_MAX_FILES 4 +#define LD_MAX_FILES 8 /* the MCU's memory regions' factory files (a boot ROM's image), checked * against their SHA-256: n of them in files[], their bytes to be freed */ @@ -819,6 +819,51 @@ static int read_memory_files(es_session *s, const esk_board_inst *bi, const esk_ return n; } +static int hex_nibble(char c) +{ + return c >= '0' && c <= '9' ? c - '0' : c >= 'a' && c <= 'f' ? c - 'a' + 10 : c >= 'A' && c <= 'F' ? c - 'A' + 10 : -1; +} + +/* the MCU's memory as the board ships it (board.json's mcu.memory: the + * option bytes ST programs on a NUCLEO-G474RE), after the MCU's own: + * appended to files[], their bytes to be freed */ +static int board_memory(es_session *s, const esk_board_inst *bi, const esk_json *board_desc, esk_mcu_file *files, + int n) +{ + const esk_json *mem = esk_json_get(esk_json_get(board_desc, "mcu"), "memory"); + size_t i; + for (i = 0; i < esk_json_len(mem) && n < LD_MAX_FILES; i++) { + const esk_json *r = esk_json_at(mem, i); + const char *hex = esk_json_get_str(r, "bytes", NULL); + size_t len = hex ? strlen(hex) / 2 : 0, k; + u64 base = 0; + char *data; + if (!hex || !len || esk_json_to_u64(esk_json_get(r, "base"), &base)) + continue; + data = (char *)esk_malloc(s->a, len + 1); + if (!data) + break; + for (k = 0; k < len; k++) { + int hi = hex_nibble(hex[2 * k]), lo = hex_nibble(hex[2 * k + 1]); + if (hi < 0 || lo < 0) { + esk_diag_raise(&s->diag, ES_SEV_ERROR, "mcu.memory_file", 0, "board", bi->id, NULL, 0, + "%s: the board's mcu.memory at 0x%08x is not hexadecimal", bi->id, (unsigned)base); + break; + } + data[k] = (char)(hi << 4 | lo); + } + if (k < len) { + esk_free(s->a, data, len + 1); + continue; + } + files[n].base = (u32)base; + files[n].data = (const unsigned char *)data; + files[n].len = len; + n++; + } + return n; +} + /* an ELF image older than a source its line tables name was built before * that source last changed (issue #91): a warning, never a refusal, since a * touched-but-unchanged file looks the same. A minute of slack keeps a fresh @@ -947,8 +992,12 @@ static es_status attach_firmware(es_session *s, esk_board_inst *bi, const esk_ca su.image_len = len; su.image_name = rel; su.console = esk_json_get_str(esk_json_get(mi->desc, "console"), "default", "USART1"); + /* the pins the board's serial bridge is wired to */ + su.console_tx = esk_json_get_str(esk_json_get(board->desc, "console"), "tx", NULL); + su.console_rx = esk_json_get_str(esk_json_get(board->desc, "console"), "rx", NULL); su.quantum_ps = s->core_quantum_ps; nfiles = read_memory_files(s, bi, mi, files); + nfiles = board_memory(s, bi, board->desc, files, nfiles); su.files = files; su.nfiles = nfiles; { diff --git a/core/util/diag_fr.c b/core/util/diag_fr.c index de775c3f3..b08ecf6cf 100644 --- a/core/util/diag_fr.c +++ b/core/util/diag_fr.c @@ -258,9 +258,13 @@ static const fr_row rows[] = { { "mcu.lockup", "the core locked up: %s%s", "le cล“ur s'est bloquรฉ (lockup) : %s%s" }, { "mcu.low_power_reset", "the option bytes' nRST_STDBY is 0: entering Standby resets the part", "nRST_STDBY des octets d'option vaut 0 : entrer en Standby rรฉinitialise la puce" }, + { "mcu.low_power_reset", "the option bytes' nRST_SHDW is 0: entering Shutdown resets the part", + "le nRST_SHDW des octets d'option vaut 0 : entrer en mode Shutdown rรฉinitialise la puce" }, { "mcu.low_power_reset", "the option bytes' nRST_STOP is 0: entering Stop resets the part", "nRST_STOP des octets d'option vaut 0 : entrer en Stop rรฉinitialise la puce" }, { "mcu.memory_file", "%s: %s cannot be read", "%s : impossible de lire %s" }, + { "mcu.memory_file", "%s: the board's mcu.memory at 0x%08x is not hexadecimal", + "%s : le mcu.memory de la carte ร  0x%08x n'est pas en hexadรฉcimal" }, { "mcu.memory_file", "%s: %s is not the file the description names (sha256 %s)", "%s : %s n'est pas le fichier que nomme la description (sha256 %s)" }, { "mcu.model_missing", "no behavioural model yet for %s: those peripherals are plain registers", @@ -301,6 +305,8 @@ static const fr_row rows[] = { "OTG_FS : la FIFO de rรฉception est lue sans qu'aucune donnรฉe de paquet n'ait รฉtรฉ prise (GRXSTSP d'abord)" }, { "mcu.watchdog_reset", "the always-on watchdog's comparator fired with wdogrsten set: it resets the chip", "le comparateur du chien de garde toujours alimentรฉ s'est dรฉclenchรฉ avec wdogrsten positionnรฉ : il rรฉinitialise la puce" }, + { "mcu.watchdog_reset", "the independent watchdog was refreshed outside its window: it resets the part", + "le chien de garde indรฉpendant a รฉtรฉ rafraรฎchi hors de sa fenรชtre : il rรฉinitialise la puce" }, { "mcu.watchdog_reset", "the independent watchdog counted down to 0: it resets the part", "le chien de garde indรฉpendant a dรฉcomptรฉ jusqu'ร  0 : il rรฉinitialise la puce" }, { "mcu.watchdog_reset", "the watchdog timed out in system reset mode: it resets the part", diff --git a/docs/STATUS.md b/docs/STATUS.md index 3e8a165db..c235f130e 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -5,6 +5,92 @@ maintained by hand until evidence tooling exists. It is not a generated support matrix. Specifications define target contracts; their acceptance does not mean the described behaviour exists. +## The STM32G474RE and the NUCLEO-G474RE (2026-11-12) + +A second STM32 family: `st/stm32g474re` (Cortex-M4F at 170 MHz, 512 KiB of +dual-bank flash, SRAM1, SRAM2 and the CCM SRAM) on `emblink/nucleo_g474re` +(MB1367). Its registers come from ST's STM32G474.svd v3.0 with the +corrections `tools/importers/stm32g474_regs.sh` lists, its pins and +alternate functions from ST's open pin data. The G4's own IP has new models: +the RCC (`stm32g4-rcc`), PWR (`stm32g4-pwr`), flash interface +(`stm32g4-flash`), the U(S)ARTs and LPUART (`stm32-usart-v2`), and DMA1, +DMA2 and DMAMUX (`stm32g4-dma`, `stm32g4-dmamux`); GPIO, SYSCFG, EXTI, the +timers, CRC, the watchdogs, DBGMCU and the SPIs (the FIFO SPI) are the F4's +models taught the G4's registers. 41 of the 82 peripheral blocks are +modelled (`docs/coverage.md`); the ADCs, DACs, comparators, op-amps, I2C, RTC, the FDCANs, USB, HRTIM, the math accelerators and the rest +keep their registers until their models land. + +Evidence: +- `test_stm32g4` (13 tests): reset values and the factory option bytes, + 170 MHz from HSI16 and from the 24 MHz crystal in range 1 boost, the + spec warnings, the oscillators' start-up times and ready interrupts, the + reset flags, GPIO with BRR and EXTI13 on PC13, LPUART1 at 115200 with + TEACK, its FIFO and ORE, USART1's 7-bit MSB-first frames from HSI16, the + programmable CRC on ST's examples' values, double-word programming, + PROGERR and SIZERR, a page erase's 22 ms and the option bytes' write + protection through OBL_LAUNCH, the IWDG's window, the WWDG's /128, Stop 1 + and Standby with SRAM2 kept and PA0's wake-up, and CONTROL.SPSEL in a + handler; +- the board's seven fixtures (USB, VIN, E5V, VIN without JP5, the IDD + ammeter, B1, LD2 through Q1); +- 26 of STM32CubeG4's NUCLEO-G474RE examples built unmodified + (`tests/vendor/stm32cubeg4/run.py`, also in CI): GPIO_IOToggle, + GPIO_EXTI, HAL_TimeBase_TIM, RCC_ClockConfig (the PLL moved between HSI16 + and the crystal on B1), UART_Printf, the four CRC examples, + CORTEXM_ModePrivilege, CORTEXM_ProcessStack, CORTEXM_SysTick, + FLASH_EraseProgram (5.3 s of erasing and programming the bank it runs + from, stalled through each operation), FLASH_FastProgram (bank 2 written + while bank 1 runs on), IWDG_Reset, IWDG_WindowMode (a refresh before the + window resets the part), WWDG_Example, PWR_STOP0, TIM_PWMOutput (85 kHz + on TIM1's four channels), TIM_OCToggle, DMA_FLASHToRAM and LL's + DMA_CopyFromFlashToMemory_Init (memory to memory), UART_HyperTerminal_DMA + (USART2 on PA2/PA3, both directions by DMA) and + UART_ReceptionToIdle_CircularDMA (LPUART1's receiver by circular DMA), + SPI_FullDuplex_ComPolling and SPI_FullDuplex_ComDMA on two boards (each + board's _Master or _Slave project, SPI1 on PB3 to PB5); SPI_FullDuplex_ComIT + is not among them yet: the master's fourth received byte loses a bit, + the slave's MISO change, made in its TXE interrupt, reaching the line + after the master's next sample; +- `test_stm32g4`'s SPI test: DS, the FIFOs' levels and thresholds, packed + reads, OVR, NSSP; +- `test_stm32g4`'s DMA test: memory to memory, table 89's packing, the + bits locked while EN is set, LPUART1's transmitter through DMAMUX, + synchronisation on EXTI13 with NBREQ and its overrun, a channel's event + triggering a request generator, a bus error's TEIF. + +The STLINK-V3E's virtual COM port is the UART the firmware muxes onto +PA2/PA3 (LPUART1, or USART2 as UART_HyperTerminal_DMA uses it): a board's +console follows its bridge's pins, as the wiring does. An EXTI line given +another port by SYSCFG now sees the new pin's level at once, an edge if it +differs, as the line's edge detector follows the multiplexer. + +In the functional policy a resistor is still a wire: on the NUCLEO-G474RE +R29 and R28 join PA5 to GND, and R27 and R26 PC13, so LD2 and B1 work in +the electrical policy only (the board's fidelity says so). Two boards on +SPI under the electrical policy run about 230 times slower than real time +(their supply islands stepping with the bus's edges). + +Found on the way: exception entry did not clear CONTROL.SPSEL (every +Cortex-M part), and IWDG_Reset's "invalid address" 0x00040001 lies inside +the G474's 512 KiB flash alias: the store sets PGSERR without a fault, so +on this part the example's IWDG reset does not come (its scenario says so; +not checked on a board). + +The board follows MB1367 D-01's schematic, part by part and value by +value (U4 and LD4, U11, U12, the decoupling, VREF from the TL1431 U14 and +Q2 at 3.26 V on VREF+ through JP8's factory position, LD2 switched by Q1, +B1 active high with R26, R27 and C35), UM2505 Rev 7 (the jumpers, solder +bridges, connectors and crystals), and the part DS12288 Rev 6 (start-up, +flash and PVD values) and RM0440 Rev 9 (reset values, EXTI's direct lines, +the package code). Two parts came with it: `emblink/tl1431cl5t` (ST's +shunt reference, against its datasheet's figures 19 and 22) and +`emblink/bsr14` (onsemi's SPICE model). The regulator primitive's output +has 1 mOhm, so an LDO starting into a discharged capacitor solves. + +Not yet: the peripherals above, the timers' G4 additions (OCxM's and SMS's +fourth bits, channels 5 and 6, dithering, the encoder index, the G4's ITR +table), the STLINK-V3E itself (its USB, SWD and drive). + ## DC motors and their driver, the robot's first parts (2026-11-08) M7's robot on the floor begins with its motors. `dc_motor` diff --git a/docs/coverage.md b/docs/coverage.md index ad9dc481a..c4f8d424b 100644 --- a/docs/coverage.md +++ b/docs/coverage.md @@ -19,6 +19,7 @@ evidence for each model is in [STATUS.md](STATUS.md). | STM32F103C8 | 26 | 0 | 1 | 27 | | STM32F446RE | 53 | 0 | 15 | 68 | | STM32F446ZE | 53 | 0 | 15 | 68 | +| STM32G474RE | 41 | 0 | 41 | 82 | ## ESP32 (`espressif/esp32`) @@ -577,3 +578,95 @@ Boards: NUCLEO-F446ZE (STM32F446ZE). | DBG | `stm32f4-dbgmcu` | modelled | Declared omissions: DBGMCU's freeze bits for the RTC, the I2C SMBus time-outs and CAN (they run on while the core is halted); TRACE_IOEN and TRACE_MODE (no trace port); the debug monitor exception (DEMCR's MON_ bits), C_SNAPSTALL, the FPB's flash patching (FP_REMAP), the DWT's counters other than CYCCNT, PC sampling, data value matching and linked comparators, the ITM's timestamp, synchronisation and overflow packets and the DWT's packets (PC sampling, exception and data trace), the TPIU's parallel trace port and formatter (SWO is modelled: cortexm/itm.c); a halted core draws its sleep current; watchdogs: LSI's spread (32 kHz here), the debug freeze bits (a debugger's halt stops all of the machine's time); the WWDG's counter while WDGA is clear counts from the last access made while its clock is on; RTC: the reference clock detection (REFCKON, RTC_REFIN), RTC_AF2 (PI8, not bonded), the tamper input's precharge and pull-up, the 8 and 16 s calibration windows (the rate is applied evenly), RECALPF's wait; ADC: the start-up time after ADON (conversions are exact at once), the input's source impedance against the sampling time, the converter's offset, gain, linearity errors and noise (the code is the ideal one), the die's self-heating; DAC: the buffer's offset and gain errors and load regulation, the conversion's non-linearity; I2C: FLTR's analog and digital noise filters (the circuit's edges are taken as they come), the SMBus's cumulative clock low extensions (TLOW:SEXT, TLOW:MEXT), clock synchronization between two masters, TRISE's rise time compensation, CR2.FREQ (times come from the real PCLK1); FMPI2C1 (another IP) keeps its registers; SPI: I2S (I2SCFGR's I2SMOD keeps its value and the SPI stays an SPI; no catalog part speaks I2S), the TI slave's MISO release half a clock after the last bit (let go at the frame's end); DMA: the arbitration's delays between streams (a request is served at once), the direct mode and FIFO overrun/underrun errors (DMEIF never sets, FEIF only for the configuration error), the peripheral flow controller (PFCTRL), the bus matrix's timing (memory-to-memory moves an item every two cycles); dma_requests omits SAI2's and SPI4's requests; USART: noise detection (one sample a bit: NF never sets, ONEBIT changes nothing), smartcard mode (SCEN, NACK, GTPR) and IrDA (IREN, IRLP), which no catalog part speaks; timers: TIM5's TI4 on the RTC's wake-up interrupt (IT4_RMP 11) and TIM2's ITR1 on the OTG controllers' SOF, MSM's delay, the idle levels' dead time after a break, OCxFE; TIMx_CCy as an ADC trigger is OCyREF for an output channel and a pulse at a capture or a frozen channel's match; SysTick: STK_CALIB's TENMS (RM0390's value not taken: it reads 0 with SKEW set); GPIO: EVENTOUT (AF15, SEV's pulse), the I/O compensation cell's effect on the edges; SYSCFG: the FMC memories MEMRMP can map at 0 (none is on the bus), PMC's ADC DC2 bits' effect; EXTI: the internal lines' sources but the RTC's (the PVD, the USB OTG controllers' wake-ups) until their models land; SWIER triggers them; RCC: the clock security system's detection (CSSON is kept; the board's HSE never fails), a peripheral held in reset while its *RSTR bit stays set (its reset happens on the write), the brownout reset (BORRSTF only at power-on), the start-up times' spread between parts and with temperature and LSEMOD's drive level (the typical times always), MCO1 and MCO2 on their pins, and the I2S, SAI, SPDIF-RX, CEC and FMPI2C clocks from PLLI2S and PLLSAI (DCKCFGR, DCKCFGR2) beyond TIMPRE and the 48 MHz clock's CK48MSEL (PLL_Q or PLLSAI_P, which the USB OTG FS core needs); PWR: the regulator's settling times and the low-power modes' wake-up times (DS10693's low-power mode wake-up timings: the core runs at the wake-up event), the regulator's settings (LPDS, FPDS, LPLVDS, MRLVDS: the supply current is not modelled), the programmable voltage detector, DBG_STOP's clocks (with it set, a probe reaches the part in Stop, but HCLK is not kept running from HSI), the tamper and timestamp pin in Standby beyond RTC_OUT; DWT's CYCCNT counts through Stop; CAN, SDIO, QUADSPI, SAI, SPDIF-RX, HDMI-CEC, DCMI, FMC, FMPI2C and the USB OTG HS controller; USB OTG FS: the ID pin, SRP and HNP, split transactions through a hub, isochronous endpoints' frame parity and incomplete-transfer interrupts and a host's isochronous channels, FRMOR, LPM, GCCFG's battery-charging detection, the OTG_FS_WKUP interrupt through EXTI line 18, the SOF pulse on PA8; the device's turnaround inside a transaction (a transaction is whole), a host channel's OUT data kept per channel rather than in the shared FIFO's order (the words free are the same); GSNPSID reads 0x4F54320A (core 3.20a), the value TinyUSB's dwc2_info table measures on the F412's and F76x's OTG_FS, the same generation of the core (ST's HAL groups the F446 with the F412, F413 and F469); no ST document gives it and it was not read from an F446; flash: the times' spread and their maximum values (the typical ones always), the ART accelerator's cache hits during an operation (a program in the flash stalls whatever its cache holds), a program in SRAM whose interrupt handler is in the flash (it does not stall), the option bytes' programming time (OPTSTRT is done at once), a reset during an operation leaving the memory half-programmed, HCLK's 1 MHz minimum, the read protection's levels (RDP stored, no mass erase on a regression), PCROP's read refusal (RDERR), the ART accelerator's caches (DCRST, ICRST); CRC: the bus stall of a DR access while a word is computed (four AHB clocks), and a byte or halfword write to DR, which RM0390 does not allow, feeding its value zero-extended. + +## STM32G474RE (`st/stm32g474re`) + +Boards: NUCLEO-G474RE. +41 of 82 peripherals modelled, 0 registers only, 41 missing. + +| Peripheral | Model | State | +|---|---|---| +| TIM2 | `stm32-tim` | modelled | +| TIM3 | `stm32-tim` | modelled | +| TIM4 | `stm32-tim` | modelled | +| TIM5 | `stm32-tim` | modelled | +| TIM6 | `stm32-tim` | modelled | +| TIM7 | `stm32-tim` | modelled | +| CRS | โ€” | **missing** | +| TAMP | โ€” | **missing** | +| RTC | โ€” | **missing** | +| WWDG | `stm32-wwdg` | modelled | +| IWDG | `stm32-iwdg` | modelled | +| SPI2 | `stm32-spi` | modelled | +| SPI3 | `stm32-spi` | modelled | +| USART2 | `stm32-usart-v2` | modelled | +| USART3 | `stm32-usart-v2` | modelled | +| UART4 | `stm32-usart-v2` | modelled | +| UART5 | `stm32-usart-v2` | modelled | +| I2C1 | โ€” | **missing** | +| I2C2 | โ€” | **missing** | +| USB_FS_device | โ€” | **missing** | +| FDCAN1 | โ€” | **missing** | +| FDCAN2 | โ€” | **missing** | +| FDCAN3 | โ€” | **missing** | +| PWR | `stm32g4-pwr` | modelled | +| I2C3 | โ€” | **missing** | +| LPTIM1 | โ€” | **missing** | +| LPUART1 | `stm32-usart-v2` | modelled | +| I2C4 | โ€” | **missing** | +| UCPD1 | โ€” | **missing** | +| SYSCFG | `stm32f4-syscfg` | modelled | +| VREFBUF | โ€” | **missing** | +| COMP | โ€” | **missing** | +| OPAMP | โ€” | **missing** | +| EXTI | `stm32-exti` | modelled | +| TIM1 | `stm32-tim` | modelled | +| SPI1 | `stm32-spi` | modelled | +| TIM8 | `stm32-tim` | modelled | +| USART1 | `stm32-usart-v2` | modelled | +| SPI4 | `stm32-spi` | modelled | +| TIM15 | `stm32-tim` | modelled | +| TIM16 | `stm32-tim` | modelled | +| TIM17 | `stm32-tim` | modelled | +| TIM20 | `stm32-tim` | modelled | +| SAI | โ€” | **missing** | +| HRTIM_Master | โ€” | **missing** | +| HRTIM_TIMA | โ€” | **missing** | +| HRTIM_TIMB | โ€” | **missing** | +| HRTIM_TIMC | โ€” | **missing** | +| HRTIM_TIMD | โ€” | **missing** | +| HRTIM_TIME | โ€” | **missing** | +| HRTIM_TIMF | โ€” | **missing** | +| HRTIM_Common | โ€” | **missing** | +| DMA1 | `stm32g4-dma` | modelled | +| DMA2 | `stm32g4-dma` | modelled | +| DMAMUX | `stm32g4-dmamux` | modelled | +| CORDIC | โ€” | **missing** | +| RCC | `stm32g4-rcc` | modelled | +| FMAC | โ€” | **missing** | +| FLASH | `stm32g4-flash` | modelled | +| CRC | `stm32-crc` | modelled | +| GPIOA | `stm32f4-gpio` | modelled | +| GPIOB | `stm32f4-gpio` | modelled | +| GPIOC | `stm32f4-gpio` | modelled | +| GPIOD | `stm32f4-gpio` | modelled | +| GPIOE | `stm32f4-gpio` | modelled | +| GPIOF | `stm32f4-gpio` | modelled | +| GPIOG | `stm32f4-gpio` | modelled | +| ADC1 | โ€” | **missing** | +| ADC2 | โ€” | **missing** | +| ADC12_Common | โ€” | **missing** | +| ADC3 | โ€” | **missing** | +| ADC4 | โ€” | **missing** | +| ADC5 | โ€” | **missing** | +| ADC345_Common | โ€” | **missing** | +| DAC1 | โ€” | **missing** | +| DAC2 | โ€” | **missing** | +| DAC3 | โ€” | **missing** | +| DAC4 | โ€” | **missing** | +| RNG | โ€” | **missing** | +| FMC | โ€” | **missing** | +| QUADSPI | โ€” | **missing** | +| DBGMCU | `stm32f4-dbgmcu` | modelled | + +Declared omissions: the peripherals coverage.md lists as missing keep their register values and raise mcu.unsupported_access: the ADCs, DACs, comparators, op-amps and VREFBUF, the I2Cs, RTC and TAMP, LPTIM1, RNG, CORDIC, FMAC, CRS, the FDCANs, USB, UCPD, HRTIM, QUADSPI, SAI and FMC; the timers' G4 additions: OCxM's fourth bit (retriggerable one-pulse, combined and asymmetric PWM), SMS's fourth bit (combined reset and trigger, the extended encoder modes), the internal trigger inputs ITR4 to ITR10 and TS's fifth bit, MMS's fourth bit, channels 5 and 6, dithering (DITHEN: ARR and CCRx read as their 16 integer bits), UIFREMAP, the encoder index (ECR), the asymmetric dead times (DTR2), break 2, the comparators on TISEL and AF1/AF2's break sources, the G4's ITR interconnection table (the F4's is used); the start-up times, flash times and PVD thresholds are DS12288 Rev 6's typical values (HSI16 0.8 us, an HSE crystal 2 ms, LSI 80 us, LSE 2 s, HSI48 2.5 us, the PLL's lock 15 us; a double word 81.7 us, a fast row 1.91 ms, a page erase 22.02 ms, a bank erase 22.13 ms; the PVD's thresholds), not their spread between parts or their dependence on temperature; RCC: the clock security systems (CSSON, LSECSSON: the oscillators never fail), LSEDRV, HSITRIM and HSI48CAL's effect on the frequencies, the CRS's trimming, a peripheral held in reset while its *RSTR bit stays set, the brownout reset (BORRSTF only at power-on), the sleep-mode enables (*SMENR), MCO and LSCO on their pins; PWR: the regulator's settling (VOSF never set) and the wake-up times, the supply currents, the PVMs (VDDA is VDD), UCPD's dead-battery bits, VBAT charging; FLASH: the option bytes' programming time, the read protection's levels and their mass erase, PCROP and the securable area, ECC, the bank swap (BFB2, FB_MODE), the boot from SRAM, the power-down modes, the caches' real line length; USART: noise detection (NE never sets, ONEBIT does nothing), auto baud rate detection, TXINV and RXINV, DE's assertion and deassertion times (DEAT, DEDT), the synchronous slave, smartcard and IrDA modes, TCBGT; SYSCFG: SWPR's write protection of the CCM SRAM, its erase time, the parity errors CFGR2 reports; EXTI: the internal lines' sources but PVD's; GPIO: EVENTOUT, the I/O compensation, the 5 V tolerant pins' clamps; the I/O thresholds are DS12288's typical characteristics (0.39 x VDD - 0.06 and 0.49 x VDD + 0.26, 200 mV of hysteresis, 40 kOhm pulls), not the guaranteed 0.3 and 0.7 x VDD; the output resistances and edge rates are the F446's; SPI: I2S (I2SCFGR keeps its value), the multimaster arbitration a MODF serves beyond the fault; DMA: the arbitration's delays and the bus matrix's timing (a request is served at once, a memory-to-memory item every two cycles), the DMAMUX inputs' two-cycle filter and the three cycles a CxCR or RGxCR write masks them for, the byte and half-word lanes duplicated for an APB peripheral that ignores the size, LPTIM1_OUT as a trigger and synchronisation input (LPTIM1 is not modelled); DBGMCU's REV_ID 0x2001 (revision Z: which revision a board carries varies, UM2505 10.1); a halted core draws its sleep current. diff --git a/docs/gallery/README.md b/docs/gallery/README.md index 115e2093f..f4e1a5054 100644 --- a/docs/gallery/README.md +++ b/docs/gallery/README.md @@ -213,6 +213,20 @@ probes (`output:PC.HOST.*`), checked by the vendor scenario. |---|---| | ![The USB project in the Design workspace: the board, the ST-LINK supply and the PC's port, the OTG nets listed](nucleo-f446ze/design-usb-hid.png) | ![It running past enumeration: the USB host's probes, OTG_VBUS at 5 V among the meters](nucleo-f446ze/run-usb-hid.png) | +## The NUCLEO-G474RE (2026-11-12) + +ST's Nucleo-64 board (MB1367) with its STM32G474RE, a second STM32 family, +running `examples/nucleo-g474re-blink-serial`: 170 MHz from the 24 MHz +crystal X3 in range 1 boost, LD2 blinking, the USER button on EXTI13's +falling edge, the virtual COM port on LPUART1. Its jumpers are controls: +JP5's four supply positions (STLK, VIN, E5V, CHGR), JP6 (IDD) and JP7. The +artwork is drawn for EmbSIM to the 70 x 82.5 mm outline, its positions +approximate until a dimensioned drawing gives `reference.json`. + +| Design | Run | Board | +|---|---|---| +| ![The NUCLEO-G474RE example in the Design workspace](nucleo-g474re/design-nucleo-g474re.png) | ![The example running: VDD on the oscilloscope, LD2 on the logic analyzer, JP5's positions and JP6 among the controls](nucleo-g474re/run-nucleo-g474re.png) | ![The board's 2D face on the bench: LD3 lit, LD2 between blinks, JP5 on STLK, JP8 on VREF, LD4 dark](nucleo-g474re/board-nucleo-g474re.png) | + ## The NUCLEO-F446ZE (2026-10-31) ST's Nucleo-144 board (MB1137) with its STM32F446ZE in LQFP144, running diff --git a/docs/gallery/nucleo-g474re/board-nucleo-g474re.png b/docs/gallery/nucleo-g474re/board-nucleo-g474re.png new file mode 100644 index 000000000..c7d4abfa3 Binary files /dev/null and b/docs/gallery/nucleo-g474re/board-nucleo-g474re.png differ diff --git a/docs/gallery/nucleo-g474re/design-nucleo-g474re.png b/docs/gallery/nucleo-g474re/design-nucleo-g474re.png new file mode 100644 index 000000000..782a47a51 Binary files /dev/null and b/docs/gallery/nucleo-g474re/design-nucleo-g474re.png differ diff --git a/docs/gallery/nucleo-g474re/run-nucleo-g474re.png b/docs/gallery/nucleo-g474re/run-nucleo-g474re.png new file mode 100644 index 000000000..95202a7c0 Binary files /dev/null and b/docs/gallery/nucleo-g474re/run-nucleo-g474re.png differ diff --git a/examples/nucleo-g474re-blink-serial/README.md b/examples/nucleo-g474re-blink-serial/README.md new file mode 100644 index 000000000..bdb40c848 --- /dev/null +++ b/examples/nucleo-g474re-blink-serial/README.md @@ -0,0 +1,36 @@ +# NUCLEO-G474RE: 170 MHz from the 24 MHz crystal, LD2, B1 and the virtual COM port (firmware) + +The bundled NUCLEO-G474RE board running [`firmware/main.c`](firmware/main.c) +on its STM32G474RE, a Cortex-M4F in an LQFP64. The firmware writes the +registers directly (no HAL), in the order STM32CubeG4's `SystemClock_Config` +does, and waits on each ready bit as the part needs: HSE (the board's +24 MHz crystal X3, its 2 ms start-up) and the PLL's lock. + +- Range 1 boost (PWR_CR5's R1MODE cleared), the PLL at 24 MHz / 6 x 85 / 2 + = 170 MHz, four flash wait states with the prefetch, the AHB at /2 for + the switch to the PLL and back to /1 (RM0440 7.2.7). +- SysTick interrupts every millisecond; every 500 ms it toggles LD2 (green, + PA5), so LD2 blinks at 1 Hz. +- The blue USER button B1 joins PC13 to VDD (MB1367's R26 holds it low + while B1 is released), so EXTI13 takes its rising edge; each press is + counted and reported on the console. +- LPUART1 on PA2/PA3 (AF12) at 115200 baud (BRR = 256 x 170 MHz / 115200) + is the STLINK-V3E's virtual COM port: the session's console, and a serial + port on the host with `embsim serve --serial B1`. What arrives comes back + in upper case. + +5 V comes in on the STLINK-V3E's USB (U5V) from a voltage source, as a +computer's port brings it: JP5 on STLK takes it to +5V, U12 makes 3.3 V and +JP6 (IDD) carries it to the STM32. + +The scenario checks the banner +(`nucleo-g474re: STM32G474RE, flash 512 KB, SYSCLK 170000 kHz, reset por`), +VDD, the blink, a press of B1, the echo, RCC's CFGR on the PLL and the +engineering bytes' FLASH_SIZE. + +```bash +embsim run examples/nucleo-g474re-blink-serial/project.json --scenario examples/nucleo-g474re-blink-serial/scenarios/blink.json +``` + +`firmware/build.sh` rebuilds the image with clang and lld; `embsim build` +does the same from the project. diff --git a/examples/nucleo-g474re-blink-serial/firmware/blink-serial.elf b/examples/nucleo-g474re-blink-serial/firmware/blink-serial.elf new file mode 100755 index 000000000..21e39a463 Binary files /dev/null and b/examples/nucleo-g474re-blink-serial/firmware/blink-serial.elf differ diff --git a/examples/nucleo-g474re-blink-serial/firmware/build.sh b/examples/nucleo-g474re-blink-serial/firmware/build.sh new file mode 100755 index 000000000..4c216e780 --- /dev/null +++ b/examples/nucleo-g474re-blink-serial/firmware/build.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Build the NUCLEO-G474RE example with clang and lld (embsim build does the +# same from project.json). +set -eu +cd "$(dirname "$0")" +clang --target=thumbv7em-none-eabihf -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -g -O2 \ + -ffreestanding -fno-builtin -nostdlib -fuse-ld=lld -Wl,--build-id=none -Wl,-T,stm32g474re.ld \ + startup.c main.c -o blink-serial.elf diff --git a/examples/nucleo-g474re-blink-serial/firmware/main.c b/examples/nucleo-g474re-blink-serial/firmware/main.c new file mode 100644 index 000000000..ce6106a5c --- /dev/null +++ b/examples/nucleo-g474re-blink-serial/firmware/main.c @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* main.c -- the NUCLEO-G474RE example: 170 MHz from the 24 MHz crystal X3 + * in range 1 boost, LD2 (PA5) blinking at 1 Hz from SysTick, B1 (PC13, + * active high: MB1367's B1 joins PC13 to VDD) counted through EXTI13's rising + * edges (an edge after 20 ms without one: B1's contacts bounce), and the STLINK-V3E's + * virtual COM port (LPUART1 on PA2/PA3 at 115200 baud) echoing in upper + * case. The registers are written directly, in the order STM32CubeG4's + * SystemClock_Config writes them (RM0440 7.2.7: the AHB at /2 for the + * switch above 80 MHz). */ +#include + +#define REG(a) (*(volatile uint32_t *)(a)) + +#define RCC_CR REG(0x40021000u) +#define RCC_CFGR REG(0x40021008u) +#define RCC_PLLCFGR REG(0x4002100Cu) +#define RCC_AHB2ENR REG(0x4002104Cu) +#define RCC_APB1ENR1 REG(0x40021058u) +#define RCC_APB1ENR2 REG(0x4002105Cu) +#define RCC_APB2ENR REG(0x40021060u) +#define RCC_CSR REG(0x40021094u) +#define PWR_CR5 REG(0x40007080u) +#define FLASH_ACR REG(0x40022000u) +#define GPIOA 0x48000000u +#define GPIOC 0x48000800u +#define MODER(p) REG((p) + 0x00u) +#define IDR(p) REG((p) + 0x10u) +#define ODR(p) REG((p) + 0x14u) +#define AFRL(p) REG((p) + 0x20u) +#define LPUART1 0x40008000u +#define LP_CR1 REG(LPUART1 + 0x00u) +#define LP_BRR REG(LPUART1 + 0x0Cu) +#define LP_ISR REG(LPUART1 + 0x1Cu) +#define LP_RDR REG(LPUART1 + 0x24u) +#define LP_TDR REG(LPUART1 + 0x28u) +#define SYSCFG_EXTICR4 REG(0x40010014u) +#define EXTI_IMR1 REG(0x40010400u) +#define EXTI_RTSR1 REG(0x40010408u) +#define EXTI_PR1 REG(0x40010414u) +#define SYST_CSR REG(0xE000E010u) +#define SYST_RVR REG(0xE000E014u) +#define SYST_CVR REG(0xE000E018u) +#define NVIC_ISER1 REG(0xE000E104u) +#define NVIC_ISER2 REG(0xE000E108u) +#define FLASH_SIZE (*(volatile uint16_t *)0x1FFF75E0u) + +static volatile uint32_t ticks, presses, reported, last_edge; + +static void putc_(char c) +{ + while (!(LP_ISR & (1u << 7))) /* TXE */ + ; + LP_TDR = (uint8_t)c; +} + +static void puts_(const char *s) +{ + while (*s) + putc_(*s++); +} + +static void putu(uint32_t v) +{ + char b[11]; + int n = 0; + do { + b[n++] = (char)('0' + v % 10u); + v /= 10u; + } while (v); + while (n) + putc_(b[--n]); +} + +/* range 1 boost, HSE (the crystal) through the PLL: 24 MHz / 6 x 85 / 2 = + * 170 MHz, four wait states */ +static void clock_170mhz(void) +{ + RCC_APB1ENR1 |= 1u << 28; /* PWREN */ + PWR_CR5 &= ~(1u << 8); /* R1MODE 0: range 1 boost */ + RCC_CR |= 1u << 16; /* HSEON */ + while (!(RCC_CR & (1u << 17))) /* HSERDY: the crystal's start-up */ + ; + RCC_PLLCFGR = 3u | (5u << 4) | (85u << 8) | (1u << 24); /* HSE, M /6, N 85, R /2, PLLREN */ + RCC_CR |= 1u << 24; /* PLLON */ + while (!(RCC_CR & (1u << 25))) + ; + FLASH_ACR = (FLASH_ACR & ~0xFu) | 4u | (1u << 8); /* LATENCY 4, PRFTEN */ + RCC_CFGR = (RCC_CFGR & ~0xF0u) | 0x80u; /* HPRE /2 for the switch */ + RCC_CFGR = (RCC_CFGR & ~3u) | 3u; /* SW PLL */ + while (((RCC_CFGR >> 2) & 3u) != 3u) + ; + for (volatile int i = 0; i < 100; i++) /* the 1 us the AHB stays at /2 */ + ; + RCC_CFGR &= ~0xF0u; /* HPRE /1 */ +} + +/* SYSCLK as the RCC's registers give it */ +static uint32_t sysclk_khz(void) +{ + uint32_t pll = RCC_PLLCFGR; + uint32_t m = ((pll >> 4) & 0xFu) + 1u, n = (pll >> 8) & 0x7Fu, r = 2u * (((pll >> 25) & 3u) + 1u); + return 24000u / m * n / r; +} + +void SysTick_Handler(void) +{ + if (++ticks % 500u == 0u) + ODR(GPIOA) ^= 1u << 5; /* LD2 */ +} + +void EXTI15_10_IRQHandler(void) +{ + if (EXTI_PR1 & (1u << 13)) { + uint32_t now = ticks; + EXTI_PR1 = 1u << 13; + /* B1's contacts bounce: a press is a rising edge after the line has + * been still for 20 ms */ + if ((IDR(GPIOC) & (1u << 13)) && now - last_edge >= 20u) + presses++; + last_edge = now; + } +} + +void LPUART1_IRQHandler(void) +{ + if (LP_ISR & (1u << 5)) { /* RXNE */ + char c = (char)LP_RDR; + if (c >= 'a' && c <= 'z') + c = (char)(c - 'a' + 'A'); + LP_TDR = (uint8_t)c; + } +} + +int main(void) +{ + uint32_t csr = RCC_CSR; + clock_170mhz(); + RCC_AHB2ENR |= (1u << 0) | (1u << 2); /* GPIOA, GPIOC */ + RCC_APB1ENR2 |= 1u << 0; /* LPUART1 */ + RCC_APB2ENR |= 1u << 0; /* SYSCFG */ + (void)RCC_APB2ENR; + /* PA5 an output (LD2); PA2, PA3 AF12 (LPUART1 to the STLINK-V3E); PC13 + * an input (B1, held low by the board's R26 while released) */ + MODER(GPIOA) = (MODER(GPIOA) & ~((3u << 10) | (0xFu << 4))) | (1u << 10) | (0xAu << 4); + AFRL(GPIOA) = (AFRL(GPIOA) & ~(0xFFu << 8)) | (0xCCu << 8); + MODER(GPIOC) &= ~(3u << 26); + /* 115200 baud from PCLK1 = 170 MHz: BRR = 256 x 170 MHz / 115200 */ + LP_BRR = 377778u; + LP_CR1 = (1u << 5) | (1u << 3) | (1u << 2); /* RXNEIE, TE, RE */ + LP_CR1 |= 1u; /* UE */ + while ((LP_ISR & (3u << 21)) != (3u << 21)) /* TEACK, REACK */ + ; + /* B1: EXTI13 on port C, rising edge (B1 joins PC13 to VDD) */ + SYSCFG_EXTICR4 = (SYSCFG_EXTICR4 & ~(0xFu << 4)) | (2u << 4); + EXTI_RTSR1 |= 1u << 13; + EXTI_IMR1 |= 1u << 13; + NVIC_ISER1 = 1u << (40 - 32); + NVIC_ISER2 = 1u << (91 - 64); + /* SysTick every millisecond from HCLK */ + SYST_RVR = sysclk_khz() - 1u; + SYST_CVR = 0; + SYST_CSR = 7u; + + puts_("nucleo-g474re: STM32G474RE, flash "); + putu(FLASH_SIZE); + puts_(" KB, SYSCLK "); + putu(sysclk_khz()); + puts_(" kHz, reset "); + puts_((csr & (1u << 27)) ? "por" : (csr & (1u << 28)) ? "software" : (csr & (1u << 26)) ? "pin" : "other"); + puts_("\r\n"); + for (;;) { + __asm volatile("wfi"); + if (presses != reported) { + reported = presses; + puts_("button "); + putu(reported); + puts_("\r\n"); + } + } +} diff --git a/examples/nucleo-g474re-blink-serial/firmware/startup.c b/examples/nucleo-g474re-blink-serial/firmware/startup.c new file mode 100644 index 000000000..87a38be0c --- /dev/null +++ b/examples/nucleo-g474re-blink-serial/firmware/startup.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* startup.c -- the example's start-up on the STM32G474RE: the vector table + * (the core's 16 entries and the part's 102 interrupts, each a weak alias of + * a handler that stops), the FPU enabled as CMSIS's SystemInit does, .data + * copied from flash, .bss cleared, then main. Freestanding: no C library. */ +#include + +extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss; +int main(void); + +void Reset_Handler(void); +void Default_Handler(void) +{ + for (;;) + ; +} + +#define WEAK(name) void name(void) __attribute__((weak, alias("Default_Handler"))) +WEAK(NMI_Handler); WEAK(HardFault_Handler); WEAK(MemManage_Handler); WEAK(BusFault_Handler); +WEAK(UsageFault_Handler); WEAK(SVC_Handler); WEAK(DebugMon_Handler); WEAK(PendSV_Handler); +WEAK(SysTick_Handler); WEAK(LPUART1_IRQHandler); WEAK(EXTI15_10_IRQHandler); + +#define IRQ(n) (16 + (n)) +__attribute__((section(".isr_vector"), used)) void (*const vectors[16 + 102])(void) = { + [0] = (void (*)(void))(uintptr_t)&_estack, + [1] = Reset_Handler, + [2] = NMI_Handler, + [3] = HardFault_Handler, + [4] = MemManage_Handler, + [5] = BusFault_Handler, + [6] = UsageFault_Handler, + [11] = SVC_Handler, + [12] = DebugMon_Handler, + [14] = PendSV_Handler, + [15] = SysTick_Handler, + [IRQ(40)] = EXTI15_10_IRQHandler, + [IRQ(91)] = LPUART1_IRQHandler, +}; + +void Reset_Handler(void) +{ + uint32_t *src = &_sidata, *dst = &_sdata; + /* CP10 and CP11 full access: the FPU, as SystemInit enables it */ + *(volatile uint32_t *)0xE000ED88u |= 0xFu << 20; + __asm volatile("dsb\n\tisb"); + while (dst < &_edata) + *dst++ = *src++; + for (dst = &_sbss; dst < &_ebss;) + *dst++ = 0; + main(); + for (;;) + ; +} diff --git a/examples/nucleo-g474re-blink-serial/firmware/stm32g474re.ld b/examples/nucleo-g474re-blink-serial/firmware/stm32g474re.ld new file mode 100644 index 000000000..e79fc0ffe --- /dev/null +++ b/examples/nucleo-g474re-blink-serial/firmware/stm32g474re.ld @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* STM32G474RE: 512 KiB of flash at 0x08000000, 128 KiB of SRAM at 0x20000000 (SRAM1 80 KiB, SRAM2 16 KiB, then the CCM SRAM's 32 KiB alias) */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} +ENTRY(Reset_Handler) +_estack = ORIGIN(RAM) + LENGTH(RAM); +SECTIONS +{ + .isr_vector : { KEEP(*(.isr_vector)) } > FLASH + .text : { *(.text*) *(.rodata*) . = ALIGN(4); } > FLASH + .ARM.exidx : { *(.ARM.exidx*) } > FLASH + _sidata = LOADADDR(.data); + .data : { _sdata = .; *(.data*) . = ALIGN(4); _edata = .; } > RAM AT > FLASH + .bss (NOLOAD) : { _sbss = .; *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; } > RAM +} diff --git a/examples/nucleo-g474re-blink-serial/project.json b/examples/nucleo-g474re-blink-serial/project.json new file mode 100644 index 000000000..d3350c106 --- /dev/null +++ b/examples/nucleo-g474re-blink-serial/project.json @@ -0,0 +1,105 @@ +{ + "schema_version": 1, + "kind": "project", + "name": "nucleo-g474re-blink-serial", + "description": "A NUCLEO-G474RE running firmware/main.c on its STM32G474RE (Cortex-M4F): the 24 MHz crystal X3 through the PLL to 170 MHz in range 1 boost, LD2 on PA5 blinking at 1 Hz from SysTick, the blue USER button B1 on PC13 (active high: MB1367 joins it to VDD) counted through EXTI13's rising edge, and the STLINK-V3E's virtual COM port (LPUART1 on PA2/PA3 at 115200 baud) echoing what it receives in upper case. The board runs from its STLINK-V3E USB connector's 5 V.", + "policy": "electrical", + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re", + "layout": { + "x": 360, + "y": 120 + }, + "firmware": { + "image": "firmware/blink-serial.elf", + "format": "elf", + "toolchain": "clang", + "sources": [ + "firmware/startup.c", + "firmware/main.c" + ], + "flags": [ + "-ffreestanding", + "-fno-builtin" + ], + "linker_script": "firmware/stm32g474re.ld" + } + } + ], + "components": [ + { + "id": "USB", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5 + }, + "layout": { + "x": 120, + "y": 160 + } + }, + { + "id": "GND1", + "component": "emblink/gnd", + "layout": { + "x": 120, + "y": 320 + } + } + ], + "nets": { + "USB5V": [ + "USB.+", + "B1.U5V" + ], + "GND": [ + "USB.-", + "GND1.GND", + "B1.GND" + ] + }, + "probes": [ + { + "id": "console", + "target": "serial:B1", + "kind": "serial" + }, + { + "id": "led", + "target": "net:B1.PA5", + "kind": "digital" + }, + { + "id": "btn", + "target": "net:B1.PC13", + "kind": "digital" + }, + { + "id": "vdd", + "target": "net:B1.VDD", + "kind": "analog", + "rate_hz": 1000 + }, + { + "id": "presses", + "target": "var:B1:presses", + "kind": "value" + }, + { + "id": "cfgr", + "target": "reg:B1.RCC.CFGR", + "kind": "value" + }, + { + "id": "flash_size", + "target": "mem:B1:0x1FFF75E0:2", + "kind": "value" + } + ], + "scenarios": [ + "scenarios/blink.json" + ] +} diff --git a/examples/nucleo-g474re-blink-serial/scenarios/blink.json b/examples/nucleo-g474re-blink-serial/scenarios/blink.json new file mode 100644 index 000000000..91c45c775 --- /dev/null +++ b/examples/nucleo-g474re-blink-serial/scenarios/blink.json @@ -0,0 +1,113 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "blink", + "until": "2.2s", + "description": "The banner with SYSCLK as the RCC's registers give it and the flash size from the engineering bytes' FLASH_SIZE; LD2's 1 Hz blink from SysTick; a press of B1 through EXTI13's rising edge; text sent to the virtual COM port echoed in upper case.", + "inputs": [ + { + "at": "1.2s", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "1.25s", + "target": "B1.B1", + "input": "pressed", + "value": false + }, + { + "at": "1.5s", + "target": "B1", + "input": "serial", + "value": "nucleo" + } + ], + "assertions": [ + { + "id": "banner", + "at": "30ms", + "probe": "console", + "expect": { + "contains": "nucleo-g474re: STM32G474RE, flash 512 KB, SYSCLK 170000 kHz, reset por" + } + }, + { + "id": "vdd", + "at": "20ms", + "probe": "vdd", + "expect": { + "min_v": 3.25, + "max_v": 3.35 + } + }, + { + "id": "led-off", + "at": "0.4s", + "probe": "led", + "expect": { + "logic": "0" + } + }, + { + "id": "led-on", + "at": "0.6s", + "probe": "led", + "expect": { + "logic": "1" + } + }, + { + "id": "blink", + "between": [ + "100ms", + "2.2s" + ], + "probe": "led", + "expect": { + "edges": 4 + } + }, + { + "id": "button", + "at": "1.3s", + "probe": "console", + "expect": { + "contains": "button 1" + } + }, + { + "id": "echo", + "at": "1.6s", + "probe": "console", + "expect": { + "contains": "NUCLEO" + } + }, + { + "id": "presses", + "at": "1.3s", + "probe": "presses", + "expect": { + "equals": 1 + } + }, + { + "id": "on-pll", + "at": "30ms", + "probe": "cfgr", + "expect": { + "equals": 15 + } + }, + { + "id": "flash-size", + "at": "30ms", + "probe": "flash_size", + "expect": { + "equals": 512 + } + } + ] +} diff --git a/schemas/board.schema.json b/schemas/board.schema.json index 922e42082..da44e86b6 100644 --- a/schemas/board.schema.json +++ b/schemas/board.schema.json @@ -24,7 +24,21 @@ "version": {"$ref": "common.schema.json#/$defs/version_range"}, "package": {"type": "string", "pattern": "^[a-z][a-z0-9_-]*$"}, "instance": {"$ref": "common.schema.json#/$defs/instance_id"}, - "fuses": {"$ref": "common.schema.json#/$defs/fuses"} + "fuses": {"$ref": "common.schema.json#/$defs/fuses"}, + "memory": { + "type": "array", + "description": "The MCU's memory as the board ships it, written over the MCU description's factory contents (the option bytes ST programs on a NUCLEO-G474RE): an address and its bytes", + "items": { + "type": "object", + "required": ["base", "bytes"], + "additionalProperties": false, + "properties": { + "base": {"$ref": "common.schema.json#/$defs/hex_or_size"}, + "bytes": {"type": "string", "pattern": "^([0-9A-Fa-f]{2})+$"}, + "doc": {"type": "string"} + } + } + } } }, "oscillators": { diff --git a/schemas/mcu.schema.json b/schemas/mcu.schema.json index ca9562da9..291688fb0 100644 --- a/schemas/mcu.schema.json +++ b/schemas/mcu.schema.json @@ -83,14 +83,14 @@ }, "dma_requests": { "type": "object", - "description": "A DMA controller's request mapping (an STM32's DMA1 and DMA2, RM0390 tables 28 and 29): controller -> stream -> the channel CHSEL selects -> the peripheral requests on it (USART2_RX, TIM1_UP, ADC1)", + "description": "A DMA controller's request mapping (an STM32's DMA1 and DMA2, RM0390 tables 28 and 29): controller -> stream -> the channel CHSEL selects -> the peripheral requests on it (USART2_RX, TIM1_UP, ADC1); an STM32G4's request multiplexer as controller DMAMUX, stream 0, its request inputs by number (RM0440 table 91)", "propertyNames": {"pattern": "^[A-Z][A-Z0-9_]*$"}, "additionalProperties": { "type": "object", "propertyNames": {"pattern": "^[0-9]{1,2}$"}, "additionalProperties": { "type": "object", - "propertyNames": {"pattern": "^[0-9]{1,2}$"}, + "propertyNames": {"pattern": "^[0-9]{1,3}$"}, "additionalProperties": {"type": "array", "minItems": 1, "items": {"type": "string", "pattern": "^[A-Z][A-Z0-9_]*$"}} } } diff --git a/tests/unit/test_analog.c b/tests/unit/test_analog.c index 69d922eaa..31784d73e 100644 --- a/tests/unit/test_analog.c +++ b/tests/unit/test_analog.c @@ -1445,6 +1445,10 @@ static void test_opamp_inverting(void) esk_engine_free(&e); } +/* the regulator's output resistance while it regulates (devices.c REG_ROUT): + * vout = vset - iout x ROUT */ +#define REG_ROUT_T 1e-3 + static void test_regulator(void) { esk_engine e; @@ -1454,9 +1458,9 @@ static void test_regulator(void) add_dev3(&e, "regulator", "U1", "{\"vout\": 3.3, \"dropout\": 0.3}", "vin", "vcc", "gnd"); add_dev2(&e, "resistor", "R1", "{\"r\": 33}", "vcc", "gnd"); engine_run(&e); - CHECK_NEAR(v_of(&e, "vcc"), 3.3, 1e-6); - CHECK_NEAR(obs_num(&e, "U1", "iout"), 0.1, 1e-6); - CHECK_NEAR(obs_num(&e, "V1", "i"), -0.1, 1e-6); /* the load current comes from the input */ + CHECK_NEAR(v_of(&e, "vcc"), 3.3 * 33.0 / (33.0 + REG_ROUT_T), 1e-6); + CHECK_NEAR(obs_num(&e, "U1", "iout"), 3.3 / (33.0 + REG_ROUT_T), 1e-6); + CHECK_NEAR(obs_num(&e, "V1", "i"), -3.3 / (33.0 + REG_ROUT_T), 1e-6); /* the load current comes from the input */ esk_engine_free(&e); /* dropout: 3 V in gives 2.7 V out */ engine_open(&e); @@ -1465,7 +1469,7 @@ static void test_regulator(void) add_dev3(&e, "regulator", "U1", "{\"vout\": 3.3, \"dropout\": 0.3}", "vin", "vcc", "gnd"); add_dev2(&e, "resistor", "R1", "{\"r\": 33}", "vcc", "gnd"); engine_run(&e); - CHECK_NEAR(v_of(&e, "vcc"), 2.7, 1e-6); + CHECK_NEAR(v_of(&e, "vcc"), 2.7 * 33.0 / (33.0 + REG_ROUT_T), 1e-6); CHECK_EQ(diag_errors, 0); esk_engine_free(&e); } @@ -1480,9 +1484,9 @@ static void test_regulator_negative(void) add_dev3(&e, "regulator", "U1", "{\"vout\": 5, \"dropout\": 1.1, \"polarity\": -1, \"quiescent\": 0.003}", "vin", "vee", "gnd"); add_dev2(&e, "resistor", "R1", "{\"r\": 50}", "vee", "gnd"); engine_run(&e); - CHECK_NEAR(v_of(&e, "vee"), -5.0, 1e-6); - CHECK_NEAR(obs_num(&e, "U1", "iout"), -0.1, 1e-6); - CHECK_NEAR(obs_num(&e, "V1", "i"), 0.103, 1e-6); /* the load and quiescent currents return through the input */ + CHECK_NEAR(v_of(&e, "vee"), -5.0 * 50.0 / (50.0 + REG_ROUT_T), 1e-6); + CHECK_NEAR(obs_num(&e, "U1", "iout"), -5.0 / (50.0 + REG_ROUT_T), 1e-6); + CHECK_NEAR(obs_num(&e, "V1", "i"), 5.0 / (50.0 + REG_ROUT_T) + 0.003, 1e-6); /* the load and quiescent currents return through the input */ esk_engine_free(&e); /* dropout: -5.5 V in gives -4.4 V out */ engine_open(&e); @@ -1491,7 +1495,7 @@ static void test_regulator_negative(void) add_dev3(&e, "regulator", "U1", "{\"vout\": 5, \"dropout\": 1.1, \"polarity\": -1}", "vin", "vee", "gnd"); add_dev2(&e, "resistor", "R1", "{\"r\": 50}", "vee", "gnd"); engine_run(&e); - CHECK_NEAR(v_of(&e, "vee"), -4.4, 1e-6); + CHECK_NEAR(v_of(&e, "vee"), -4.4 * 50.0 / (50.0 + REG_ROUT_T), 1e-6); /* an output pulled below its setting by another supply: the pass element cannot sink */ esk_engine_free(&e); engine_open(&e); @@ -1583,7 +1587,10 @@ static void test_quiet_island(void) CHECK_NEAR(v_of(&e, "out"), 5.0 * (1.0 - exp(-2.0)), 1e-4); CHECK_EQ(isl->quiet_steps, 0); CHECK(esk_engine_advance(&e, 40 * ES_PS_PER_MS) == ES_OK); - CHECK_NEAR(v_of(&e, "out"), 5.0, 1e-6); /* to vntol, the floor where an island is still */ + /* to the floor where an island is still: a trial step of 1 ms moving no + * node by vntol (1 uV) and no branch current by 1 nA, here the source's + * 1.5 nA into the capacitor, 1.5 uV short of 5 V */ + CHECK_NEAR(v_of(&e, "out"), 5.0, 2e-6); CHECK_EQ(diag_errors, 0); esk_engine_free(&e); } @@ -1676,7 +1683,7 @@ static void test_regulator_board_rails(void) w = add_watcher(&e, "MCU", "btn", ESK_PULL_NONE); engine_run(&e); CHECK_NEAR(v_of(&e, "5v"), 5.0, 1e-9); /* held by the ideal source whatever the load */ - CHECK_NEAR(v_of(&e, "3v3"), 3.3, 1e-6); + CHECK_NEAR(v_of(&e, "3v3"), 3.3 - obs_num(&e, "U2", "iout") * REG_ROUT_T, 1e-6); CHECK(v_of(&e, "leda") > 1.6 && v_of(&e, "leda") < 1.9); CHECK(v_of(&e, "btn") > 3.29); CHECK_EQ(w->pins[0].sampled, ESK_L1); @@ -1686,7 +1693,7 @@ static void test_regulator_board_rails(void) -(obs_num(&e, "U2", "iout") + 5e-3), 1e-6); CHECK(esk_engine_advance(&e, 2 * ES_PS_PER_MS) == ES_OK); CHECK_NEAR(v_of(&e, "5v"), 5.0, 1e-9); - CHECK_NEAR(v_of(&e, "3v3"), 3.3, 1e-6); + CHECK_NEAR(v_of(&e, "3v3"), 3.3 - obs_num(&e, "U2", "iout") * REG_ROUT_T, 1e-6); CHECK(esk_engine_net(&e, "3v3")->island->steps < 100); CHECK_EQ(diag_errors, 0); esk_engine_free(&e); diff --git a/tests/unit/test_stm32g4.c b/tests/unit/test_stm32g4.c new file mode 100644 index 000000000..21fe6b26a --- /dev/null +++ b/tests/unit/test_stm32g4.c @@ -0,0 +1,1028 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* test_stm32g4.c -- the STM32G474RE on the machine the catalog's + * description builds, with the NUCLEO-G474RE's clocks (a 24 MHz crystal on + * OSC_IN/OSC_OUT, the 32.768 kHz LSE crystal): its clock tree and power + * control (rcc_g4.c, pwr_g4.c), flash interface (flash_g4.c), GPIO, SYSCFG + * and EXTI (gpio_f4.c, syscfg_f4.c, exti.c), its USARTs and LPUART + * (usart_v2.c), the programmable CRC (crc.c) and the watchdogs (wdg.c). + * The program's accesses are made from here in the order STM32CubeG4's HAL + * makes them (RM0440). */ +#include "harness.h" +#include "mcu/build.h" +#include "mcu/cortexm/cortexm.h" +#include "mcu/stm32/stm32.h" +#include "util/json.h" + +#define RCC 0x40021000u +#define RCC_CR (RCC + 0x00u) +#define RCC_CFGR (RCC + 0x08u) +#define RCC_PLLCFGR (RCC + 0x0Cu) +#define RCC_CIER (RCC + 0x18u) +#define RCC_CIFR (RCC + 0x1Cu) +#define RCC_CICR (RCC + 0x20u) +#define RCC_AHB1ENR (RCC + 0x48u) +#define RCC_AHB2ENR (RCC + 0x4Cu) +#define RCC_APB1ENR1 (RCC + 0x58u) +#define RCC_APB1ENR2 (RCC + 0x5Cu) +#define RCC_APB2ENR (RCC + 0x60u) +#define RCC_CCIPR (RCC + 0x88u) +#define RCC_BDCR (RCC + 0x90u) +#define RCC_CSR (RCC + 0x94u) +#define RCC_CRRCR (RCC + 0x98u) +#define PWR 0x40007000u +#define PWR_CR1 (PWR + 0x00u) +#define PWR_CR3 (PWR + 0x08u) +#define PWR_SR1 (PWR + 0x10u) +#define PWR_SR2 (PWR + 0x14u) +#define PWR_SCR (PWR + 0x18u) +#define PWR_CR5 (PWR + 0x80u) +#define FLASH 0x40022000u +#define FLASH_ACR (FLASH + 0x00u) +#define FLASH_KEYR (FLASH + 0x08u) +#define FLASH_OPTKEYR (FLASH + 0x0Cu) +#define FLASH_SR (FLASH + 0x10u) +#define FLASH_CR (FLASH + 0x14u) +#define FLASH_OPTR (FLASH + 0x20u) +#define FLASH_WRP1AR (FLASH + 0x2Cu) +#define GPIOA 0x48000000u +#define GPIOC 0x48000800u +#define MODER 0x00u +#define PUPDR 0x0Cu +#define IDR 0x10u +#define ODR 0x14u +#define BSRR 0x18u +#define AFRL 0x20u +#define BRR 0x28u +#define SYSCFG 0x40010000u +#define EXTI 0x40010400u +#define LPUART1 0x40008000u +#define USART1 0x40013800u +#define U_CR1 0x00u +#define U_CR2 0x04u +#define U_CR3 0x08u +#define U_BRR 0x0Cu +#define U_RQR 0x18u +#define U_ISR 0x1Cu +#define U_ICR 0x20u +#define U_RDR 0x24u +#define U_TDR 0x28u +#define CRC 0x40023000u +#define IWDG 0x40003000u +#define WWDG 0x40002C00u +#define DBGMCU 0xE0042000u +#define NVIC_ISPR1 0xE000E204u +#define NVIC_ISPR2 0xE000E208u + +typedef struct g4 { + esk_alloc a; + esk_json *mcu, *regs; + struct esk_mach m; + int warnings; + char codes[256]; + esk_mach_pin pin[7][16]; + int ext[7][16]; + struct { int c, nbits, stop; u32 bits, bit_cycles; char unit[12]; } frame[32]; + int nframe; +} g4; + +static unsigned char *slurp(const char *rel, size_t *len) +{ + char path[1024]; + FILE *f; + unsigned char *buf; + long n; + snprintf(path, sizeof path, "%s/%s", EMBSIM_SOURCE_DIR, rel); + f = fopen(path, "rb"); + if (!f) + return NULL; + fseek(f, 0, SEEK_END); + n = ftell(f); + fseek(f, 0, SEEK_SET); + buf = (unsigned char *)malloc(n > 0 ? (size_t)n : 1); + if (buf && fread(buf, 1, (size_t)n, f) != (size_t)n) { + free(buf); + buf = NULL; + } + fclose(f); + *len = (size_t)n; + return buf; +} + +static esk_json *load_json(esk_alloc *a, const char *rel) +{ + size_t len = 0; + unsigned char *text = slurp(rel, &len); + esk_json *j; + int line = 0; + const char *err = NULL; + if (!text) + return NULL; + j = esk_json_parse(a, (const char *)text, len, &line, &err); + free(text); + return j; +} + +static void r_diag(void *ctx, int sev, const char *code, const char *msg) +{ + g4 *f = (g4 *)ctx; + size_t n = strlen(f->codes); + (void)msg; + if (sev < ES_SEV_WARNING) + return; + f->warnings++; + snprintf(f->codes + n, sizeof f->codes - n, "%s ", code); +} + +static void r_pin_cfg(void *ctx, int port, int bit, const esk_mach_pin *cfg) +{ + g4 *f = (g4 *)ctx; + if (port >= 0 && port < 7 && bit >= 0 && bit < 16) + f->pin[port][bit] = *cfg; +} + +static int r_pin_in(void *ctx, int port, int bit, int *level) +{ + g4 *f = (g4 *)ctx; + if (port < 0 || port >= 7 || bit < 0 || bit > 15 || f->ext[port][bit] < 0) + return 0; + *level = f->ext[port][bit]; + return 1; +} + +static void r_uart_frame(void *ctx, const char *unit, int c, u32 bits, int nbits, int stop, u32 bit_cycles) +{ + g4 *f = (g4 *)ctx; + if (f->nframe < 32) { + f->frame[f->nframe].c = c; + f->frame[f->nframe].bits = bits; + f->frame[f->nframe].nbits = nbits; + f->frame[f->nframe].stop = stop; + f->frame[f->nframe].bit_cycles = bit_cycles; + snprintf(f->frame[f->nframe].unit, sizeof f->frame[f->nframe].unit, "%s", unit); + f->nframe++; + } +} + +static int g4_open(g4 *f) +{ + char why[200]; + es_status st; + int i, j; + memset(f, 0, sizeof *f); + for (i = 0; i < 7; i++) + for (j = 0; j < 16; j++) + f->ext[i][j] = -1; + esk_alloc_init(&f->a, NULL); + f->mcu = load_json(&f->a, "catalog/mcus/st/stm32g474re/mcu.json"); + f->regs = load_json(&f->a, "catalog/mcus/st/stm32g474re/registers.json"); + CHECK(f->mcu != NULL && f->regs != NULL); + esk_mach_init(&f->m, &f->a); + f->m.host.ctx = f; + f->m.host.diag = r_diag; + f->m.host.pin_cfg = r_pin_cfg; + f->m.host.pin_in = r_pin_in; + f->m.host.uart_frame = r_uart_frame; + f->m.hse_clock = 0; /* X3: a 24 MHz crystal */ + f->m.lse_hz = 32768u; /* X2 */ + st = esk_mach_build(&f->m, f->mcu, f->regs, 24000000u, why, sizeof why); + if (st != ES_OK) { + FAIL(why); + return 0; + } + CHECK_EQ(esk_bus_debug_write(&f->m.bus, 0x08000000u, 4, 0x20001000u), 0); + CHECK_EQ(esk_bus_debug_write(&f->m.bus, 0x08000004u, 4, 0x08000101u), 0); + CHECK_EQ(esk_bus_debug_write(&f->m.bus, 0x08000100u, 4, 0xbf00e7feu), 0); /* b . */ + for (i = 0; i < f->m.bus.nrg; i++) /* as an image's load leaves them: stores reach the flash interface */ + f->m.bus.rg[i].rom = f->m.bus.rg[i].kind == ESK_MEM_FLASH || f->m.bus.rg[i].kind == ESK_MEM_ROM; + esk_mach_reset(&f->m); + return 1; +} + +static void g4_close(g4 *f) +{ + esk_mach_free(&f->m); + esk_json_free(&f->a, f->mcu); + esk_json_free(&f->a, f->regs); + CHECK_EQ(f->a.live_bytes, 0); +} + +static u32 rd(g4 *f, u32 a) +{ + u32 v = 0; + CHECK_EQ(esk_bus_read(&f->m.bus, a, 4, &v), 0); + return v; +} + +static void wr(g4 *f, u32 a, u32 v) { CHECK_EQ(esk_bus_write(&f->m.bus, a, 4, v), 0); } +static void wr8(g4 *f, u32 a, u32 v) { CHECK_EQ(esk_bus_write(&f->m.bus, a, 1, v), 0); } + +/* the core runs (its program a loop in place) for `us` microseconds */ +static void run_us(g4 *f, double us) +{ + u32 hz = esk_mach_core_hz(&f->m); + u64 end = f->m.cycles + (u64)((double)(hz ? hz : 16000000u) * us / 1e6); + while (f->m.cycles < end && !f->m.reset_req) + if (!esk_mach_run(&f->m, end - f->m.cycles, 0) && f->m.asleep) + esk_mach_idle(&f->m, end - f->m.cycles); +} + +/* the microseconds until the bits at `a` are all set (or all clear), or -1 */ +static long wait_bits(g4 *f, u32 a, u32 mask, int set, long max_us) +{ + double us = 0; + while (us <= (double)max_us) { + u32 hz = esk_mach_core_hz(&f->m); + u64 from = f->m.cycles; + u32 v = rd(f, a) & mask; + if (set ? v == mask : v == 0) + return (long)(us + 0.5); + run_us(f, max_us > 100000 ? 100.0 : 0.25); + us += (double)(f->m.cycles - from) * 1e6 / (double)(hz ? hz : 16000000u); + } + return -1; +} + +/* SystemClock_Config of CubeG4's NUCLEO-G474RE examples: range 1 boost, + * HSI16 through the PLL (M /4, N 85, R /2) to 170 MHz, four wait states, + * the AHB at /2 for the switch (RM0440 7.2.7) and back to /1 */ +static void clock_170(g4 *f, int from_hse) +{ + wr(f, RCC_APB1ENR1, rd(f, RCC_APB1ENR1) | 1u << 28); /* PWREN */ + wr(f, PWR_CR5, rd(f, PWR_CR5) & ~(1u << 8)); /* R1MODE 0: boost */ + if (from_hse) { + wr(f, RCC_CR, rd(f, RCC_CR) | 1u << 16); /* HSEON */ + CHECK(wait_bits(f, RCC_CR, 1u << 17, 1, 5000) > 1000); /* HSERDY: the crystal's 2 ms */ + /* M /6, N 85, R /2: 24 / 6 x 85 / 2 = 170 MHz */ + wr(f, RCC_PLLCFGR, 3u | 5u << 4 | 85u << 8 | 1u << 24); + } else { + wr(f, RCC_PLLCFGR, 2u | 3u << 4 | 85u << 8 | 1u << 24); /* HSI16 /4 x 85 /2, PLLREN */ + } + wr(f, RCC_CR, rd(f, RCC_CR) | 1u << 24); /* PLLON */ + CHECK(wait_bits(f, RCC_CR, 1u << 25, 1, 100) >= 10); /* PLLRDY: its 15 us lock */ + wr(f, FLASH_ACR, (rd(f, FLASH_ACR) & ~0xFu) | 4u); /* LATENCY 4 */ + wr(f, RCC_CFGR, (rd(f, RCC_CFGR) & ~0xF0u) | 0x80u); /* HPRE /2 */ + wr(f, RCC_CFGR, (rd(f, RCC_CFGR) & ~3u) | 3u); /* SW PLL */ + CHECK_EQ(rd(f, RCC_CFGR) >> 2 & 3u, 3u); /* SWS */ + run_us(f, 1.0); + wr(f, RCC_CFGR, rd(f, RCC_CFGR) & ~0xF0u); /* HPRE /1 */ +} + +/* ---- the tests -------------------------------------------------------------- */ + +static void test_reset(void) +{ + g4 f; + if (!g4_open(&f)) + return; + CHECK_STR(esk_json_get_str(f.mcu, "name", ""), "STM32G474RE"); + CHECK_EQ(rd(&f, RCC_CR), 0x00000500u); /* HSION, HSIRDY */ + CHECK_EQ(rd(&f, RCC_CFGR), 0x00000005u); /* SW, SWS: HSI16 */ + CHECK_EQ(rd(&f, RCC_PLLCFGR), 0x00001000u); + CHECK_EQ(rd(&f, RCC_CSR) & 0xFE000000u, 0x0C000000u); /* BORRSTF, PINRSTF */ + CHECK_EQ(rd(&f, RCC_AHB1ENR), 0x00000100u); /* FLASHEN */ + CHECK_EQ(esk_mach_core_hz(&f.m), 16000000u); + CHECK_EQ(esk_stm32_pclk(&f.m, 1), 16000000u); + CHECK_EQ(esk_stm32_timclk(&f.m, 2), 16000000u); + /* the option bytes as from the factory, their complements checked */ + CHECK_EQ(rd(&f, FLASH_OPTR), 0xFFEFF8AAu); + CHECK_EQ(rd(&f, FLASH_SR) & (1u << 15), 0u); /* no OPTVERR */ + CHECK_EQ(rd(&f, FLASH_CR), 0xC0000000u); /* LOCK, OPTLOCK */ + CHECK_EQ(rd(&f, DBGMCU) & 0xFFFu, 0x469u); /* DEV_ID */ + /* PWR's clock is off: its registers read 0 and say why once */ + CHECK_EQ(rd(&f, PWR_CR1), 0u); + CHECK(strstr(f.codes, "mcu.clock_gated") != NULL); + wr(&f, RCC_APB1ENR1, rd(&f, RCC_APB1ENR1) | 1u << 28); + CHECK_EQ(rd(&f, PWR_CR1), 0x00000200u); /* VOS range 1 */ + CHECK_EQ(rd(&f, PWR_CR5), 0x00000100u); /* R1MODE: normal */ + CHECK_EQ(rd(&f, PWR_SR2) & (1u << 8), 1u << 8); /* REGLPS */ + g4_close(&f); +} + +static void test_170mhz(void) +{ + g4 f; + if (!g4_open(&f)) + return; + f.warnings = 0; + clock_170(&f, 0); + CHECK_EQ(esk_mach_core_hz(&f.m), 170000000u); + CHECK_EQ(esk_stm32_pclk(&f.m, 2), 170000000u); + CHECK_EQ(esk_stm32_timclk(&f.m, 1), 170000000u); + CHECK_EQ(f.warnings, 0); + /* APB1 /2: the timers run at twice it */ + wr(&f, RCC_CFGR, (rd(&f, RCC_CFGR) & ~(7u << 8)) | 4u << 8); + CHECK_EQ(esk_stm32_pclk(&f.m, 1), 85000000u); + CHECK_EQ(esk_stm32_timclk(&f.m, 1), 170000000u); + /* the PLL used as SYSCLK cannot be turned off, nor HSI16 under it */ + wr(&f, RCC_CR, rd(&f, RCC_CR) & ~(1u << 24 | 1u << 8)); + CHECK_EQ(rd(&f, RCC_CR) & (1u << 24 | 1u << 8), 1u << 24 | 1u << 8); + g4_close(&f); + /* the same from the board's 24 MHz crystal */ + if (!g4_open(&f)) + return; + f.warnings = 0; + clock_170(&f, 1); + CHECK_EQ(esk_mach_core_hz(&f.m), 170000000u); + CHECK_EQ(f.warnings, 0); + g4_close(&f); +} + +static void test_out_of_spec(void) +{ + g4 f; + if (!g4_open(&f)) + return; + /* range 1 normal (R1MODE left 1): 170 MHz is above its 150 MHz */ + wr(&f, RCC_APB1ENR1, rd(&f, RCC_APB1ENR1) | 1u << 28); + wr(&f, RCC_PLLCFGR, 2u | 3u << 4 | 85u << 8 | 1u << 24); + wr(&f, RCC_CR, rd(&f, RCC_CR) | 1u << 24); + CHECK(wait_bits(&f, RCC_CR, 1u << 25, 1, 100) >= 0); + f.codes[0] = 0; + wr(&f, FLASH_ACR, (rd(&f, FLASH_ACR) & ~0xFu) | 2u); /* too few wait states too */ + wr(&f, RCC_CFGR, (rd(&f, RCC_CFGR) & ~3u) | 3u); + CHECK(strstr(f.codes, "mcu.clock_out_of_spec") != NULL); + CHECK(strstr(f.codes, "mcu.flash_wait_states") != NULL); + g4_close(&f); + /* a VCO input below 2.66 MHz */ + if (!g4_open(&f)) + return; + wr(&f, RCC_PLLCFGR, 2u | 15u << 4 | 85u << 8 | 1u << 24); /* 16 / 16 = 1 MHz */ + f.codes[0] = 0; + wr(&f, RCC_CR, rd(&f, RCC_CR) | 1u << 24); + CHECK(strstr(f.codes, "mcu.clock_out_of_spec") != NULL); + g4_close(&f); +} + +static void test_startup_and_irq(void) +{ + g4 f; + long t; + if (!g4_open(&f)) + return; + /* HSI48 ready after its start-up, LSI after 80 us, each flag with its + * interrupt */ + wr(&f, RCC_CIER, 1u << 10 | 1u << 0); + wr(&f, RCC_CRRCR, 1u); + t = wait_bits(&f, RCC_CRRCR, 2u, 1, 50); + CHECK(t >= 2 && t <= 4); + CHECK(rd(&f, RCC_CIFR) & 1u << 10); + CHECK(rd(&f, 0xE000E200u) & 1u << 5); /* RCC's interrupt, 5, pending */ + wr(&f, RCC_CICR, 1u << 10); + CHECK_EQ(rd(&f, RCC_CIFR) & 1u << 10, 0u); + wr(&f, RCC_CSR, 1u); + t = wait_bits(&f, RCC_CSR, 2u, 1, 500); + CHECK(t >= 75 && t <= 90); + /* LSE: two seconds, written only with PWR's DBP */ + wr(&f, RCC_APB1ENR1, rd(&f, RCC_APB1ENR1) | 1u << 28); + wr(&f, RCC_BDCR, 1u); + CHECK_EQ(rd(&f, RCC_BDCR) & 1u, 0u); + wr(&f, PWR_CR1, rd(&f, PWR_CR1) | 1u << 8); + wr(&f, RCC_BDCR, 1u); + t = wait_bits(&f, RCC_BDCR, 2u, 1, 3000000); + CHECK(t >= 1990000 && t <= 2010000); + g4_close(&f); +} + +static void test_reset_flags(void) +{ + g4 f; + if (!g4_open(&f)) + return; + wr(&f, RCC_CSR, rd(&f, RCC_CSR) | 1u << 23); /* RMVF */ + CHECK_EQ(rd(&f, RCC_CSR) & 0xFE000000u, 0u); + f.m.reset_cause = ESK_RESET_SOFTWARE; + esk_mach_reset(&f.m); + CHECK_EQ(rd(&f, RCC_CSR) & 0xFE000000u, 1u << 26 | 1u << 28); /* PINRSTF, SFTRSTF */ + f.m.reset_cause = ESK_RESET_WATCHDOG; + esk_mach_reset(&f.m); + CHECK_EQ(rd(&f, RCC_CSR) & 0xFE000000u, 1u << 26 | 1u << 28 | 1u << 29); + g4_close(&f); +} + +static void test_gpio_exti(void) +{ + g4 f; + if (!g4_open(&f)) + return; + CHECK_EQ(rd(&f, GPIOA + MODER), 0u); /* its clock off */ + wr(&f, RCC_AHB2ENR, 1u | 1u << 2); /* GPIOA, GPIOC */ + CHECK_EQ(rd(&f, GPIOA + MODER), 0xABFFFFFFu); + CHECK_EQ(rd(&f, GPIOA + PUPDR), 0x64000000u); + /* PA5 (LD2) an output: BSRR sets it, BRR clears it */ + wr(&f, GPIOA + MODER, (rd(&f, GPIOA + MODER) & ~(3u << 10)) | 1u << 10); + wr(&f, GPIOA + BSRR, 1u << 5); + CHECK_EQ(f.pin[0][5].drive, 1); + CHECK_EQ(rd(&f, GPIOA + ODR) & 0x20u, 0x20u); + wr(&f, GPIOA + BRR, 1u << 5); + CHECK_EQ(f.pin[0][5].drive, 0); + CHECK_EQ(rd(&f, GPIOA + BRR), 0u); + /* PC13 (B1) an input: EXTI13 on port C, rising edge, its interrupt + * EXTI15_10 (40) */ + wr(&f, RCC_APB2ENR, 1u); /* SYSCFGEN */ + wr(&f, GPIOC + MODER, rd(&f, GPIOC + MODER) & ~(3u << 26)); + wr(&f, SYSCFG + 0x14u, 2u << 4); /* EXTICR4: EXTI13 on PC */ + wr(&f, EXTI + 0x08u, 1u << 13); /* RTSR1 */ + wr(&f, EXTI + 0x00u, rd(&f, EXTI + 0x00u) | 1u << 13); /* IMR1 */ + CHECK_EQ(rd(&f, EXTI + 0x00u) & 0x1F840000u, 0x1F840000u); /* the direct lines' */ + f.ext[2][13] = 0; + esk_stm32f4_pins_changed(&f.m); + f.ext[2][13] = 1; + esk_stm32f4_pins_changed(&f.m); + CHECK(rd(&f, EXTI + 0x14u) & 1u << 13); /* PR1 */ + CHECK(rd(&f, NVIC_ISPR1) & 1u << 8); /* 40 */ + wr(&f, EXTI + 0x14u, 1u << 13); + CHECK_EQ(rd(&f, EXTI + 0x14u) & 1u << 13, 0u); + /* the second bank: SWIER2 sets PR2 (line 38, PVM1) */ + wr(&f, EXTI + 0x20u, 1u << 6); + wr(&f, EXTI + 0x30u, 1u << 6); + CHECK(rd(&f, EXTI + 0x34u) & 1u << 6); + g4_close(&f); +} + +/* LPUART1 on PA2/PA3 (AF12) at 115200 from PCLK1, the VCP's */ +static void lpuart_setup(g4 *f, u32 pclk) +{ + wr(f, RCC_AHB2ENR, rd(f, RCC_AHB2ENR) | 1u); + wr(f, RCC_APB1ENR2, rd(f, RCC_APB1ENR2) | 1u); + wr(f, GPIOA + MODER, (rd(f, GPIOA + MODER) & ~(0xFu << 4)) | 0xAu << 4); + wr(f, GPIOA + AFRL, (rd(f, GPIOA + AFRL) & ~(0xFFu << 8)) | 0xCCu << 8); + /* UART_SetConfig: BRR = 256 x PCLK / baud, rounded */ + wr(f, LPUART1 + U_BRR, (u32)(((u64)pclk * 256u + 115200u / 2) / 115200u)); + wr(f, LPUART1 + U_CR1, 1u << 3 | 1u << 2); /* TE, RE */ + wr(f, LPUART1 + U_CR1, rd(f, LPUART1 + U_CR1) | 1u); /* UE */ +} + +static void test_lpuart(void) +{ + g4 f; + struct esk_rx_port *rx; + if (!g4_open(&f)) + return; + clock_170(&f, 0); + lpuart_setup(&f, 170000000u); + /* UART_CheckIdleState waits for TEACK and REACK */ + CHECK_EQ(rd(&f, LPUART1 + U_ISR) & (3u << 21), 3u << 21); + CHECK_EQ(f.pin[0][2].drive, 1); /* TX idles high */ + f.nframe = 0; + wr(&f, LPUART1 + U_TDR, 'H'); + CHECK_EQ(rd(&f, LPUART1 + U_ISR) & (1u << 6), 0u); /* TC clear */ + CHECK(wait_bits(&f, LPUART1 + U_ISR, 1u << 6, 1, 1000) > 80); /* the idle frame, then 'H' */ + CHECK_EQ(f.nframe, 1); + CHECK_EQ(f.frame[0].c, 'H'); + CHECK_STR(f.frame[0].unit, "LPUART1"); + CHECK_NEAR(f.frame[0].bit_cycles, 170e6 / 115200.0, 1.0); + /* receiving: RXNE, then ORE once RDR holds a frame; ICR clears it */ + rx = esk_mach_rx_find(&f.m, "LPUART1"); + CHECK(rx != NULL); + if (rx) { + CHECK(rx->room(rx->ctx)); + rx->put(rx->ctx, 'a'); + CHECK(rd(&f, LPUART1 + U_ISR) & 1u << 5); + rx->put(rx->ctx, 'b'); + CHECK(rd(&f, LPUART1 + U_ISR) & 1u << 3); + CHECK_EQ(rd(&f, LPUART1 + U_RDR), (u32)'a'); + CHECK_EQ(rd(&f, LPUART1 + U_ISR) & 1u << 5, 0u); + wr(&f, LPUART1 + U_ICR, 1u << 3); + CHECK_EQ(rd(&f, LPUART1 + U_ISR) & 1u << 3, 0u); + /* the FIFO: eight frames held, then RXFF */ + wr(&f, LPUART1 + U_CR1, rd(&f, LPUART1 + U_CR1) & ~1u); + wr(&f, LPUART1 + U_CR1, rd(&f, LPUART1 + U_CR1) | 1u << 29 | 1u); + { + int k; + for (k = 0; k < 8; k++) + rx->put(rx->ctx, '0' + k); + CHECK(rd(&f, LPUART1 + U_ISR) & 1u << 24); /* RXFF */ + CHECK_EQ(rd(&f, LPUART1 + U_ISR) & 1u << 3, 0u); + for (k = 0; k < 8; k++) + CHECK_EQ(rd(&f, LPUART1 + U_RDR), (u32)('0' + k)); + CHECK_EQ(rd(&f, LPUART1 + U_ISR) & 1u << 5, 0u); + } + } + g4_close(&f); +} + +static void test_usart_formats(void) +{ + g4 f; + if (!g4_open(&f)) + return; + /* USART1 on PC4/PC5 (AF7), 16 MHz PCLK2, 9600 baud, 7 data bits with + * even parity, MSB first, its kernel clock from HSI16 */ + wr(&f, RCC_AHB2ENR, rd(&f, RCC_AHB2ENR) | 1u << 2); + wr(&f, RCC_APB2ENR, rd(&f, RCC_APB2ENR) | 1u << 14); + wr(&f, RCC_CCIPR, 2u); /* USART1SEL: HSI16 */ + wr(&f, GPIOC + MODER, (rd(&f, GPIOC + MODER) & ~(0xFu << 8)) | 0xAu << 8); + wr(&f, GPIOC + AFRL, (rd(&f, GPIOC + AFRL) & ~(0xFFu << 16)) | 0x77u << 16); + wr(&f, USART1 + U_BRR, 16000000u / 9600u); + wr(&f, USART1 + U_CR2, 1u << 19); /* MSBFIRST */ + wr(&f, USART1 + U_CR1, 1u << 28 | 1u << 10 | 1u << 3); /* M1 (7 bits), PCE, TE */ + wr(&f, USART1 + U_CR1, rd(&f, USART1 + U_CR1) | 1u); + f.nframe = 0; + wr(&f, USART1 + U_TDR, 0x41u); /* 'A' */ + CHECK(wait_bits(&f, USART1 + U_ISR, 1u << 6, 1, 3000) > 0); + CHECK_EQ(f.nframe, 1); + CHECK_EQ(f.frame[0].nbits, 7); + /* 6 data bits and the parity bit: 0x41's six (0b000001) MSB first are + * 0b100000 on the line, even parity over them 1 */ + CHECK_EQ(f.frame[0].bits & 0x7Fu, 0x60u); + CHECK_NEAR(f.frame[0].bit_cycles, 16e6 / 9600.0, 2.0); + g4_close(&f); +} + +static void test_crc(void) +{ + g4 f; + static const u8 d16[9] = { 0x4D, 0x3C, 0x2B, 0x1A, 0xBE, 0x71, 0xC9, 0x8A, 0x5E }; + int k; + if (!g4_open(&f)) + return; + wr(&f, RCC_AHB1ENR, rd(&f, RCC_AHB1ENR) | 1u << 12); /* CRCEN */ + /* the default unit: CRC-32 of one word */ + wr(&f, CRC + 0x08u, 1u); + wr(&f, CRC + 0x00u, 0x12345678u); + CHECK_EQ(rd(&f, CRC + 0x00u), 0xDF8A8A2Bu); + /* CubeG4's CRC_UserDefinedPolynomial: 8-bit polynomial 0x9B over the + * word 0x1234, INIT 0xFF: 0xEF */ + wr(&f, CRC + 0x14u, 0x9Bu); + wr(&f, CRC + 0x08u, 2u << 3 | 1u); + wr(&f, CRC + 0x00u, 0x1234u); + CHECK_EQ(rd(&f, CRC + 0x00u), 0xEFu); + /* CRC_Data_Reversing_16bit_CRC: CCITT's 0x1021, INIT 0x5ABE, the + * input reversed by words (a byte written reversed as a byte), the + * output reversed: RBIT(0xC20A) >> 16 */ + wr(&f, CRC + 0x14u, 0x1021u); + wr(&f, CRC + 0x10u, 0x5ABEu); + wr(&f, CRC + 0x08u, 1u << 7 | 3u << 5 | 1u << 3 | 1u); + for (k = 0; k < 8; k += 4) + wr(&f, CRC + 0x00u, (u32)d16[k] << 24 | (u32)d16[k + 1] << 16 | (u32)d16[k + 2] << 8 | d16[k + 3]); + wr8(&f, CRC + 0x00u, d16[8]); + CHECK_EQ(rd(&f, CRC + 0x00u) & 0xFFFFu, 0x5043u); + g4_close(&f); +} + +static void flash_unlock(g4 *f) +{ + wr(f, FLASH_KEYR, 0x45670123u); + wr(f, FLASH_KEYR, 0xCDEF89ABu); + CHECK_EQ(rd(f, FLASH_CR) & 1u << 31, 0u); +} + +static void test_flash(void) +{ + g4 f; + u32 v = 0; + long t; + if (!g4_open(&f)) + return; + flash_unlock(&f); + /* HAL_FLASH_Program's double word at 0x08040000 (bank 2, page 0): PG, + * the first word, the second; BSY for 81.7 us */ + wr(&f, FLASH_CR, 1u); + wr(&f, 0x08040000u, 0x11223344u); + CHECK_EQ(rd(&f, FLASH_SR) & 1u << 16, 0u); + wr(&f, 0x08040004u, 0x55667788u); + CHECK(rd(&f, FLASH_SR) & 1u << 16); + t = wait_bits(&f, FLASH_SR, 1u << 16, 0, 1000); + CHECK(t >= 80 && t <= 84); /* the program runs from bank 1: bank 2's work does not stall it */ + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x08040004u, 4, &v), 0); + CHECK_EQ(v, 0x55667788u); + /* a halfword is SIZERR, a double word not erased PROGERR */ + CHECK_EQ(esk_bus_write(&f.m.bus, 0x08040008u, 2, 0x1234u), 0); + CHECK(rd(&f, FLASH_SR) & 1u << 6); + wr(&f, FLASH_SR, 0xFFFFu); + wr(&f, 0x08040000u, 0x1u); + wr(&f, 0x08040004u, 0x1u); + CHECK(rd(&f, FLASH_SR) & 1u << 3); + wr(&f, FLASH_SR, 0xFFFFu); + /* a page erase: PER, PNB 0, BKER (bank 2), STRT; 22 ms */ + wr(&f, FLASH_CR, 1u << 1 | 1u << 11); + wr(&f, FLASH_CR, rd(&f, FLASH_CR) | 1u << 16); + t = wait_bits(&f, FLASH_SR, 1u << 16, 0, 100000); + CHECK(t >= 21000 && t <= 23000); + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x08040000u, 4, &v), 0); + CHECK_EQ(v, 0xFFFFFFFFu); + /* the option bytes: write protection of bank 1's pages 2 to 3 */ + wr(&f, FLASH_CR, 1u << 31); /* LOCK */ + flash_unlock(&f); + wr(&f, FLASH_OPTKEYR, 0x08192A3Bu); + wr(&f, FLASH_OPTKEYR, 0x4C5D6E7Fu); + CHECK_EQ(rd(&f, FLASH_CR) & 1u << 30, 0u); + wr(&f, FLASH_WRP1AR, 2u | 3u << 16); + wr(&f, FLASH_CR, rd(&f, FLASH_CR) | 1u << 17); /* OPTSTRT */ + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x1FFF7818u, 4, &v), 0); + CHECK_EQ(v & 0x007F007Fu, 0x00030002u); + wr(&f, FLASH_CR, rd(&f, FLASH_CR) | 1u << 27); /* OBL_LAUNCH: a reset */ + CHECK(f.m.reset_req); + f.m.reset_req = 0; + esk_mach_reset(&f.m); + CHECK(rd(&f, RCC_CSR) & 1u << 25); /* OBLRSTF */ + CHECK_EQ(rd(&f, FLASH_WRP1AR) & 0x007F007Fu, 0x00030002u); + CHECK_EQ(rd(&f, FLASH_SR) & 1u << 15, 0u); + flash_unlock(&f); + wr(&f, FLASH_CR, 1u); + wr(&f, 0x08001000u, 0u); /* page 2 */ + CHECK(rd(&f, FLASH_SR) & 1u << 4); /* WRPERR */ + g4_close(&f); +} + +static void test_iwdg_window(void) +{ + g4 f; + if (!g4_open(&f)) + return; + /* HAL_IWDG_Init with a window: start, access, PR /4, RLR 1000, WINR 500; + * refreshing above the window resets the part */ + wr(&f, IWDG + 0x00u, 0xCCCCu); + CHECK(rd(&f, RCC_CSR) & 1u << 1 || wait_bits(&f, RCC_CSR, 2u, 1, 200) >= 0); /* LSI forced on */ + wr(&f, IWDG + 0x00u, 0x5555u); + wr(&f, IWDG + 0x04u, 0u); + wr(&f, IWDG + 0x08u, 1000u); + wr(&f, IWDG + 0x10u, 500u); + CHECK(rd(&f, IWDG + 0x0Cu) & 4u); /* WVU */ + CHECK(wait_bits(&f, IWDG + 0x0Cu, 7u, 0, 1000) >= 0); + wr(&f, IWDG + 0x00u, 0xAAAAu); /* counter 1000 > 500: too early */ + CHECK(f.m.reset_req); + CHECK_EQ(f.m.reset_cause, ESK_RESET_WATCHDOG); + g4_close(&f); +} + +static void test_wwdg_prescaler(void) +{ + g4 f; + long t; + if (!g4_open(&f)) + return; + /* WDGTB at CFR[13:11]: /128 at 16 MHz, 4096 x 128 / 16 MHz = 32.77 ms a + * count; EWIF once 0x7F has counted down to 0x40 */ + wr(&f, RCC_APB1ENR1, rd(&f, RCC_APB1ENR1) | 1u << 11); + wr(&f, WWDG + 0x04u, 7u << 11 | 1u << 9 | 0x7Fu); + wr(&f, WWDG + 0x00u, 0x7Fu); + t = wait_bits(&f, WWDG + 0x08u, 1u, 1, 2500000); + CHECK(t > 0); + CHECK_NEAR((double)t, 63.0 * 4096.0 * 128.0 / 16.0, 33000.0); + g4_close(&f); +} + +static void test_stop(void) +{ + g4 f; + if (!g4_open(&f)) + return; + clock_170(&f, 0); + /* Stop 1 (LPMS 001) then a wake-up: the part runs on HSI16 again */ + wr(&f, PWR_CR1, (rd(&f, PWR_CR1) & ~7u) | 1u); + CHECK(f.m.deep_sleep != NULL); + if (f.m.deep_sleep) { + f.m.deep_sleep(&f.m); + CHECK(f.m.clocks_stopped); + CHECK_EQ(rd(&f, RCC_CR) & 1u << 24, 0u); + CHECK_EQ(esk_mach_core_hz(&f.m), 16000000u); + f.m.deep_wake(&f.m); + CHECK(!f.m.clocks_stopped); + } + /* Standby (011) with SRAM2 kept (RRS): SRAM1 lost, SBF after the reset */ + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x20000100u, 4, 0x12345678u), 0); + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x20014100u, 4, 0xCAFEF00Du), 0); + wr(&f, PWR_CR3, rd(&f, PWR_CR3) | 1u << 8 | 1u); /* RRS, EWUP1 (PA0) */ + wr(&f, PWR_CR1, (rd(&f, PWR_CR1) & ~7u) | 3u); + if (f.m.deep_sleep) { + u32 v = 0; + f.m.deep_sleep(&f.m); + CHECK(f.m.powered_down); + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x20014100u, 4, &v), 0); + CHECK_EQ(v, 0xCAFEF00Du); + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x20000100u, 4, &v), 0); + CHECK(v != 0x12345678u); + /* PA0 rises: WUF1, the part resets out of Standby */ + esk_stm32f4_pwr_pin_edge(&f.m, 0, 0, 0); + esk_stm32f4_pwr_pin_edge(&f.m, 0, 0, 1); + CHECK(f.m.reset_req); + CHECK_EQ(f.m.reset_cause, ESK_RESET_STANDBY); + f.m.reset_req = 0; + f.m.powered_down = 0; + esk_mach_reset(&f.m); + wr(&f, RCC_APB1ENR1, rd(&f, RCC_APB1ENR1) | 1u << 28); + CHECK_EQ(rd(&f, PWR_SR1) & (1u << 8 | 1u), 1u << 8 | 1u); /* SBF, WUF1 */ + wr(&f, PWR_SCR, 1u << 8 | 0x1Fu); + CHECK_EQ(rd(&f, PWR_SR1) & 0x11Fu, 0u); + } + g4_close(&f); +} + +/* halfwords from `a` (little-endian Thumb code) */ +static void code(g4 *f, u32 a, const u16 *h, int n) +{ + int k; + for (k = 0; k < n; k++) + CHECK_EQ(esk_bus_debug_write(&f->m.bus, a + 2u * (u32)k, 2, h[k]), 0); +} + +static u32 reg(g4 *f, int n) +{ + u8 b[4] = { 0, 0, 0, 0 }; + f->m.cpu->ops->reg_read(f->m.cpu, n, b); + return (u32)b[0] | (u32)b[1] << 8 | (u32)b[2] << 16 | (u32)b[3] << 24; +} + +/* ARMv7-M's ExceptionTaken clears CONTROL.SPSEL: a handler entered from a + * thread on the process stack reads it 0, and the thread reads it 1 again + * after the return (CubeG4's CORTEXM_ProcessStack checks both) */ +static void test_spsel_in_handler(void) +{ + static const u16 thread[] = { + 0xf242, 0x0000, 0xf2c2, 0x0000, /* movw r0, #0x2000; movt r0, #0x2000 */ + 0xf380, 0x8809, /* msr psp, r0 */ + 0x2002, /* movs r0, #2 */ + 0xf380, 0x8814, /* msr control, r0 */ + 0xf3bf, 0x8f6f, /* isb */ + 0xdf01, /* svc #1 */ + 0xf3ef, 0x8214, /* mrs r2, control */ + 0xe7fe, /* b . */ + }; + /* the handler stores CONTROL at 0x20003000 (its r0-r3 are the frame's again after the return) */ + static const u16 handler[] = { + 0xf243, 0x0000, 0xf2c2, 0x0000, /* movw r0, #0x3000; movt r0, #0x2000 */ + 0xf3ef, 0x8114, /* mrs r1, control */ + 0x6001, /* str r1, [r0] */ + 0x4770, /* bx lr */ + }; + u32 seen = 0; + g4 f; + if (!g4_open(&f)) + return; + code(&f, 0x08000100u, thread, (int)(sizeof thread / sizeof thread[0])); + code(&f, 0x08000200u, handler, (int)(sizeof handler / sizeof handler[0])); + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x0800002Cu, 4, 0x08000201u), 0); /* SVCall's vector */ + esk_mach_reset(&f.m); + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x20003000u, 4, 0xdeadbeefu), 0); + run_us(&f, 20.0); + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x20003000u, 4, &seen), 0); + CHECK_EQ(seen, 0u); /* in the handler: SPSEL 0, the main stack */ + CHECK_EQ(reg(&f, 2) & 2u, 2u); /* back in the thread: the process stack */ + CHECK_EQ(reg(&f, 13), 0x20002000u); /* PSP as it was, the frame popped */ + g4_close(&f); +} + +/* DMA1 and DMAMUX (RM0440 12, 13) */ +#define DMA1 0x40020000u +#define DMA_ISR (DMA1 + 0x00u) +#define DMA_IFCR (DMA1 + 0x04u) +#define DMA_CCR(k) (DMA1 + 0x08u + 0x14u * ((k) - 1u)) +#define DMA_CNDTR(k) (DMA1 + 0x0Cu + 0x14u * ((k) - 1u)) +#define DMA_CPAR(k) (DMA1 + 0x10u + 0x14u * ((k) - 1u)) +#define DMA_CMAR(k) (DMA1 + 0x14u + 0x14u * ((k) - 1u)) +#define DMAMUX 0x40020800u +#define MUX_CCR(c) (DMAMUX + 0x04u * (c)) +#define MUX_CSR (DMAMUX + 0x80u) +#define MUX_CFR (DMAMUX + 0x84u) +#define MUX_RGCR(c) (DMAMUX + 0x100u + 0x04u * (c)) +#define NVIC_ISPR0 0xE000E200u + +static void pc13(g4 *f, int level) +{ + f->ext[2][13] = level; + esk_stm32f4_pins_changed(&f->m); +} + +static void test_dma(void) +{ + g4 f; + u32 v, k; + if (!g4_open(&f)) + return; + wr(&f, RCC_AHB1ENR, rd(&f, RCC_AHB1ENR) | 1u | 1u << 2); /* DMA1EN, DMAMUX1EN */ + /* memory to memory: eight words, both addresses stepping, TCIE */ + for (k = 0; k < 8; k++) + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x20000100u + 4u * k, 4, 0x11110000u + k), 0); + wr(&f, DMA_CPAR(1), 0x20000100u); + wr(&f, DMA_CMAR(1), 0x20000200u); + wr(&f, DMA_CNDTR(1), 8u); + wr(&f, DMA_CCR(1), 1u << 14 | 2u << 10 | 2u << 8 | 1u << 7 | 1u << 6 | 1u << 1); /* MEM2MEM, 32-bit, MINC, PINC, TCIE */ + wr(&f, DMA_CCR(1), rd(&f, DMA_CCR(1)) | 1u); + /* while EN: the sizes and CNDTR keep their values */ + wr(&f, DMA_CCR(1), (rd(&f, DMA_CCR(1)) & ~(3u << 8)) | 0u << 8); + CHECK_EQ(rd(&f, DMA_CCR(1)) >> 8 & 3u, 2u); + run_us(&f, 20.0); + for (k = 0; k < 8; k++) { + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x20000200u + 4u * k, 4, &v), 0); + CHECK_EQ(v, 0x11110000u + k); + } + CHECK_EQ(rd(&f, DMA_CNDTR(1)), 0u); + CHECK_EQ(rd(&f, DMA_ISR) & 0xFu, 0x7u); /* GIF1, TCIF1, HTIF1 */ + CHECK_EQ(rd(&f, DMA_CCR(1)) & 1u, 1u); /* not circular: EN stays, nothing more is served */ + CHECK(rd(&f, NVIC_ISPR0) & 1u << 11); /* DMA1_CH1 */ + wr(&f, DMA_CNDTR(1), 5u); + CHECK_EQ(rd(&f, DMA_CNDTR(1)), 0u); /* read-only while EN */ + wr(&f, DMA_IFCR, 1u << 1); /* CTCIF1: HTIF1 is left, so GIF1 too */ + CHECK_EQ(rd(&f, DMA_ISR) & 0xFu, 0x5u); + wr(&f, DMA_IFCR, 1u); /* CGIF1 */ + CHECK_EQ(rd(&f, DMA_ISR) & 0xFu, 0u); + wr(&f, DMA_CCR(1), 0u); + /* table 89: bytes read, half-words written zero-extended */ + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x20000300u, 4, 0x44332211u), 0); + wr(&f, DMA_CPAR(1), 0x20000300u); + wr(&f, DMA_CMAR(1), 0x20000400u); + wr(&f, DMA_CNDTR(1), 4u); + wr(&f, DMA_CCR(1), 1u << 14 | 1u << 10 | 0u << 8 | 1u << 7 | 1u << 6 | 1u); + run_us(&f, 10.0); + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x20000400u, 4, &v), 0); + CHECK_EQ(v, 0x00220011u); + CHECK_EQ(esk_bus_debug_read(&f.m.bus, 0x20000404u, 4, &v), 0); + CHECK_EQ(v, 0x00440033u); + wr(&f, DMA_CCR(1), 0u); + wr(&f, DMA_IFCR, 0xFFFFFFFFu); + /* LPUART1_TX (request 35) through DMAMUX channel 0 to DMA1 channel 1 */ + lpuart_setup(&f, 16000000u); + CHECK(wait_bits(&f, LPUART1 + U_ISR, 1u << 21, 1, 100) >= 0); /* TEACK */ + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x20000500u, 4, 0x00214948u), 0); /* "HI!" */ + wr(&f, MUX_CCR(0), 35u); + wr(&f, DMA_CPAR(1), LPUART1 + U_TDR); + wr(&f, DMA_CMAR(1), 0x20000500u); + wr(&f, DMA_CNDTR(1), 3u); + wr(&f, DMA_CCR(1), 1u << 7 | 1u << 4 | 1u); /* MINC, DIR (from memory), EN */ + f.nframe = 0; + wr(&f, LPUART1 + U_CR3, rd(&f, LPUART1 + U_CR3) | 1u << 7); /* DMAT */ + run_us(&f, 400.0); + CHECK_EQ(f.nframe, 3); + CHECK_EQ(f.frame[0].c, 'H'); + CHECK_EQ(f.frame[2].c, '!'); + CHECK_EQ(rd(&f, DMA_CNDTR(1)), 0u); + wr(&f, DMA_CCR(1), 0u); + wr(&f, DMA_IFCR, 0xFFFFFFFFu); + /* synchronised on EXTI13 (PC13's rising edge): two requests (NBREQ 1) + * a sync event, an event each two; the event (input 16) triggers + * generator 0, whose request (1) DMA1 channel 2 serves */ + wr(&f, RCC_AHB2ENR, rd(&f, RCC_AHB2ENR) | 1u << 2); + wr(&f, RCC_APB2ENR, rd(&f, RCC_APB2ENR) | 1u); /* SYSCFG */ + wr(&f, SYSCFG + 0x14u, 2u << 4); /* EXTI13 on PC */ + wr(&f, GPIOC + MODER, rd(&f, GPIOC + MODER) & ~(3u << 26)); /* PC13 an input */ + pc13(&f, 0); + for (k = 0; k < 8; k++) + CHECK_EQ(esk_bus_debug_write(&f.m.bus, 0x20000600u + k, 1, 'a' + k), 0); + wr(&f, MUX_CCR(0), 35u | 1u << 9 | 1u << 16 | 1u << 17 | 1u << 19 | 13u << 24); /* EGE, SE, SPOL rising, NBREQ 1, SYNC_ID 13 */ + wr(&f, MUX_RGCR(0), 16u | 1u << 16 | 1u << 17); /* SIG_ID 16 (channel 0's event), GE, rising */ + wr(&f, MUX_CCR(1), 1u); /* DMAMUX_REQ_GEN0 to DMA1 channel 2 */ + wr(&f, DMA_CPAR(2), 0x20000700u); + wr(&f, DMA_CMAR(2), 0x20000800u); + wr(&f, DMA_CNDTR(2), 4u); + wr(&f, DMA_CCR(2), 2u << 10 | 2u << 8 | 1u << 7 | 1u); /* 32-bit, MINC: one word a generated request */ + wr(&f, DMA_CMAR(1), 0x20000600u); + wr(&f, DMA_CNDTR(1), 8u); + wr(&f, DMA_CCR(1), 1u << 7 | 1u << 4 | 1u); + f.nframe = 0; + run_us(&f, 400.0); + CHECK_EQ(f.nframe, 0); /* no sync event yet */ + CHECK_EQ(rd(&f, DMA_CNDTR(2)), 4u); + pc13(&f, 1); + run_us(&f, 400.0); + CHECK_EQ(f.nframe, 2); /* NBREQ + 1 */ + CHECK_EQ(f.frame[1].c, 'b'); + CHECK_EQ(rd(&f, DMA_CNDTR(2)), 3u); /* the event's generated request */ + pc13(&f, 0); + pc13(&f, 1); + run_us(&f, 400.0); + CHECK_EQ(f.nframe, 4); + CHECK_EQ(f.frame[3].c, 'd'); + CHECK_EQ(rd(&f, DMA_CNDTR(2)), 2u); + CHECK_EQ(rd(&f, MUX_CSR), 0u); + /* four requests a sync event (NBREQ 3, written with SE and EGE clear): + * an idle transmitter takes two at once, the others a frame apart, so + * a sync event right after the first is an overrun: SOF0, DMAMUX_OVR + * (94) with SOIE */ + wr(&f, MUX_CCR(0), 35u); + wr(&f, MUX_CCR(0), 35u | 3u << 19); + wr(&f, MUX_CCR(0), 35u | 3u << 19 | 1u << 8 | 1u << 16 | 1u << 17 | 13u << 24); + run_us(&f, 400.0); + pc13(&f, 0); + pc13(&f, 1); + pc13(&f, 0); + pc13(&f, 1); + CHECK_EQ(rd(&f, MUX_CSR), 1u); + CHECK(rd(&f, NVIC_ISPR2) & 1u << 30); + wr(&f, MUX_CFR, 1u); + CHECK_EQ(rd(&f, MUX_CSR), 0u); + wr(&f, MUX_CCR(0), 0u); + wr(&f, DMA_CCR(1), 0u); + wr(&f, DMA_CCR(2), 0u); + /* a bus error: TEIF, EN cleared and refused until TEIF is */ + wr(&f, DMA_IFCR, 0xFFFFFFFFu); + wr(&f, DMA_CPAR(1), 0x60000000u); /* no FMC bank fitted */ + wr(&f, DMA_CMAR(1), 0x20000900u); + wr(&f, DMA_CNDTR(1), 2u); + wr(&f, DMA_CCR(1), 1u << 14 | 1u << 3 | 1u); + run_us(&f, 5.0); + CHECK_EQ(rd(&f, DMA_ISR) & 0x9u, 0x9u); /* TEIF1, GIF1 */ + CHECK_EQ(rd(&f, DMA_CCR(1)) & 1u, 0u); + wr(&f, DMA_CCR(1), rd(&f, DMA_CCR(1)) | 1u); + CHECK_EQ(rd(&f, DMA_CCR(1)) & 1u, 0u); + wr(&f, DMA_IFCR, 1u << 3); + wr(&f, DMA_CCR(1), 0u); + g4_close(&f); +} + +/* SPI1, the FIFO SPI (RM0440 42): SCK PB3, MISO PB4, MOSI PB5 (AF5), NSS + * PA4 (AF5) */ +#define SPI1 0x40013000u +#define SPI_CR1 (SPI1 + 0x00u) +#define SPI_CR2 (SPI1 + 0x04u) +#define SPI_SR (SPI1 + 0x08u) +#define SPI_DR (SPI1 + 0x0Cu) +#define GPIOB 0x48000400u + +static u32 rd8(g4 *f, u32 a) +{ + u32 v = 0; + CHECK_EQ(esk_bus_read(&f->m.bus, a, 1, &v), 0); + return v; +} + +static void test_spi_fifo(void) +{ + g4 f; + u32 v; + int k; + if (!g4_open(&f)) + return; + wr(&f, RCC_AHB2ENR, rd(&f, RCC_AHB2ENR) | 1u | 2u); /* GPIOA, GPIOB */ + wr(&f, RCC_APB2ENR, rd(&f, RCC_APB2ENR) | 1u << 12); /* SPI1EN */ + wr(&f, GPIOB + MODER, (rd(&f, GPIOB + MODER) & ~(0x3Fu << 6)) | 0x2Au << 6); + wr(&f, GPIOB + AFRL, (rd(&f, GPIOB + AFRL) & ~(0xFFFu << 12)) | 0x555u << 12); + wr(&f, GPIOA + MODER, (rd(&f, GPIOA + MODER) & ~(3u << 8)) | 2u << 8); + wr(&f, GPIOA + AFRL, (rd(&f, GPIOA + AFRL) & ~(0xFu << 16)) | 5u << 16); + f.ext[1][4] = 1; /* MISO held high: every frame received is ones */ + esk_stm32f4_pins_changed(&f.m); + CHECK_EQ(rd(&f, SPI_CR2), 0x700u); /* DS 8 bits out of reset */ + wr(&f, SPI_CR2, 2u << 8); /* a DS not used: forced to 8 bits */ + CHECK_EQ(rd(&f, SPI_CR2) >> 8 & 15u, 7u); + wr(&f, SPI_CR2, 7u << 8 | 1u << 12); /* 8 bits, FRXTH: RXNE at a byte */ + wr(&f, SPI_CR1, 1u << 2 | 1u << 8 | 1u << 9); /* MSTR, SSI, SSM, PCLK / 2 */ + /* the transmit FIFO before SPE: TXE while it is at most half full */ + wr8(&f, SPI_DR, 0x11u); + CHECK_EQ(rd(&f, SPI_SR) & 0x1802u, 1u << 11 | 2u); /* FTLVL 1/4, TXE */ + wr8(&f, SPI_DR, 0x22u); + CHECK_EQ(rd(&f, SPI_SR) & 0x1802u, 2u << 11 | 2u); /* 1/2, TXE */ + wr8(&f, SPI_DR, 0x33u); + CHECK_EQ(rd(&f, SPI_SR) & 0x1802u, 3u << 11); /* 3/4 reads full, TXE clear */ + wr(&f, SPI_CR1, rd(&f, SPI_CR1) | 1u << 6); /* SPE: three frames go */ + run_us(&f, 20.0); + v = rd(&f, SPI_SR); + CHECK_EQ(v & 0x1880u, 0u); /* FTLVL empty, BSY clear */ + CHECK_EQ(v >> 9 & 3u, 3u); /* FRLVL: three bytes */ + CHECK(v & 1u); /* RXNE */ + CHECK_EQ(rd(&f, SPI_DR) & 0xFFFFu, 0xFFFFu); /* a word read: two frames packed */ + CHECK_EQ(rd(&f, SPI_SR) >> 9 & 3u, 1u); + CHECK_EQ(rd8(&f, SPI_DR), 0xFFu); + CHECK_EQ(rd(&f, SPI_SR) & 0x601u, 0u); /* empty, RXNE clear */ + /* FRXTH 0: RXNE at two bytes only */ + wr(&f, SPI_CR2, 7u << 8); + wr8(&f, SPI_DR, 0x44u); + run_us(&f, 10.0); + CHECK_EQ(rd(&f, SPI_SR) & 0x601u, 1u << 9); /* a byte in, no RXNE */ + wr8(&f, SPI_DR, 0x55u); + run_us(&f, 10.0); + CHECK_EQ(rd(&f, SPI_SR) & 0x601u, 2u << 9 | 1u); + /* five more frames unread: the FIFO full at four bytes, then OVR */ + for (k = 0; k < 3; k++) { + wr8(&f, SPI_DR, 0x66u); + run_us(&f, 10.0); + } + v = rd(&f, SPI_SR); + CHECK_EQ(v >> 9 & 3u, 3u); + CHECK(v & 1u << 6); /* OVR */ + (void)rd(&f, SPI_DR); + (void)rd(&f, SPI_DR); + v = rd(&f, SPI_SR); /* DR then SR: the read shows OVR and clears it */ + CHECK(v & 1u << 6); + v = rd(&f, SPI_SR); + CHECK_EQ(v & (1u << 6), 0u); + /* NSSP: NSS pulses between frames and stays high after the last */ + wr(&f, SPI_CR1, rd(&f, SPI_CR1) & ~(1u << 6)); + wr(&f, SPI_CR1, (rd(&f, SPI_CR1) & ~(1u << 9 | 1u << 8))); /* NSS by the hardware */ + wr(&f, SPI_CR2, 7u << 8 | 1u << 12 | 1u << 3 | 1u << 2); /* NSSP, SSOE */ + wr(&f, SPI_CR1, rd(&f, SPI_CR1) | 1u << 6); + CHECK_EQ(f.pin[0][4].drive, 0); /* enabled: NSS low */ + wr(&f, SPI_DR, 0x7788u); /* two frames back to back */ + run_us(&f, 20.0); + CHECK_EQ(f.pin[0][4].drive, 1); /* high after the transfer */ + g4_close(&f); +} + +TEST_MAIN_BEGIN +RUN(test_reset); +RUN(test_170mhz); +RUN(test_out_of_spec); +RUN(test_startup_and_irq); +RUN(test_reset_flags); +RUN(test_gpio_exti); +RUN(test_lpuart); +RUN(test_usart_formats); +RUN(test_crc); +RUN(test_flash); +RUN(test_iwdg_window); +RUN(test_wwdg_prescaler); +RUN(test_stop); +RUN(test_spsel_in_handler); +RUN(test_dma); +RUN(test_spi_fifo); +TEST_MAIN_END diff --git a/tests/vendor/README.md b/tests/vendor/README.md index 65cf3410c..306ebbb80 100644 --- a/tests/vendor/README.md +++ b/tests/vendor/README.md @@ -11,6 +11,7 @@ toolchains. | `arduino/` | ArduinoCore-avr (Blink, a tour of the core) | `emblink/arduino_uno` | | `stm32cube/` | ST's STM32F1 HAL and CMSIS device files | `emblink/bluepill` | | `stm32cubef4/` | STM32CubeF4's own examples for the NUCLEO-F446RE (GPIO, HAL time bases, RCC, RTC, timers, UART, PWR's low-power modes, I2C between two boards, EEPROM emulation in flash) and, with `--board nucleo_f446ze`, for the NUCLEO-F446ZE (ADC, CRC, Cortex, DMA, flash erase and program, GPIO, the watchdogs, RTC, seven timer examples, UART, the USB device HID mouse on a computer's port, the USB host HID and MSC demos with Adafruit's 1.8" TFT shield, a mouse and a flash drive; their middleware and components, stm32-mw-usb-device v2.11.4, stm32-mw-usb-host, stm32-mw-fatfs, stm32-st7735 and stm32-bsp-common at the commits CubeF4 pins, fetched like the rest and copied into CubeF4's tree, with its Adafruit_Shield BSP and Utilities' LCD log and fonts) | `emblink/nucleo_f446re`, `emblink/nucleo_f446ze` | +| `stm32cubeg4/` | STM32CubeG4's own examples for the NUCLEO-G474RE (GPIO, EXTI, the HAL's time base, RCC, UART on LPUART1, CRC, Cortex, flash erase, program and fast program, the IWDG and WWDG, Stop 0, TIM1's PWM and output compare, DMA memory to memory and with USART2 and LPUART1, SPI1 between two boards), built from a CubeG4 checkout with its HAL, CMSIS device and Nucleo BSP submodules | `emblink/nucleo_g474re` | | `pico-sdk/` | The Raspberry Pi Pico SDK | `emblink/pico` | | `micropython/` | MicroPython v1.24.1's rp2 port (RPI_PICO), built with its own Makefile and copied as firmware.uf2 onto the Pico's BOOTSEL drive; its prompt over its USB serial port: arithmetic, `machine.Pin` lighting the LED, a file in its flash filesystem | `emblink/pico` | | `freedom-metal/` | SiFive's freedom-metal and freedom-e-sdk's examples | `emblink/hifive1_revb` | diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_modeprivilege/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_modeprivilege/scenario.json new file mode 100644 index 000000000..c42527265 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_modeprivilege/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "cortexm_modeprivilege", + "until": "500ms", + "description": "CORTEXM_ModePrivilege: thread mode switched to unprivileged and to the process stack through CONTROL, back to privileged by an SVC; LD2 on when the sequence completes.", + "inputs": [], + "assertions": [ + { + "id": "pass", + "between": [ + "100ms", + "490ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_processstack/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_processstack/scenario.json new file mode 100644 index 000000000..9b37a5009 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_processstack/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "cortexm_processstack", + "until": "500ms", + "description": "CORTEXM_ProcessStack: the process stack selected through CONTROL and PSP, checked by an SVC handler; LD2 on in case of success.", + "inputs": [], + "assertions": [ + { + "id": "pass", + "between": [ + "100ms", + "490ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_systick/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_systick/scenario.json new file mode 100644 index 000000000..6a3bc8234 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/cortexm_systick/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "cortexm_systick", + "until": "1.2s", + "description": "CORTEXM_SysTick: LD2 toggled every HAL_Delay(50), SysTick's 1 ms at 170 MHz: 51 ms a toggle.", + "inputs": [], + "assertions": [ + { + "id": "blink", + "between": [ + "100ms", + "1.12s" + ], + "probe": "led", + "expect": { + "edges": 20 + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/crc_bytes_stream_7bit_crc/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_bytes_stream_7bit_crc/scenario.json new file mode 100644 index 000000000..a54637833 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_bytes_stream_7bit_crc/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "crc_bytes_stream_7bit_crc", + "until": "500ms", + "description": "CRC BYTES STREAM 7BIT CRC: 7-bit CRCs of polynomial 0x65 over byte streams of 5, 17, 1 and 2 bytes; LD2 on means each value matched, a 1 s blink an error.", + "inputs": [], + "assertions": [ + { + "id": "pass", + "between": [ + "50ms", + "490ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/crc_data_reversing_16bit_crc/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_data_reversing_16bit_crc/scenario.json new file mode 100644 index 000000000..01ad17622 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_data_reversing_16bit_crc/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "crc_data_reversing_16bit_crc", + "until": "500ms", + "description": "CRC DATA REVERSING 16BIT CRC: CCITT's 16-bit CRC with the input reversed by words (a last byte reversed as a byte) and the output reversed, against the same without reversal over the bytes reversed by hand; LD2 on means each value matched, a 1 s blink an error.", + "inputs": [], + "assertions": [ + { + "id": "pass", + "between": [ + "50ms", + "490ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/crc_example/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_example/scenario.json new file mode 100644 index 000000000..5d91fb9a0 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_example/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "crc_example", + "until": "500ms", + "description": "CRC EXAMPLE: the CRC-32 of 114 words with the default polynomial and initial value, 0x379E9F06; LD2 on means each value matched, a 1 s blink an error.", + "inputs": [], + "assertions": [ + { + "id": "pass", + "between": [ + "50ms", + "490ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/crc_userdefinedpolynomial/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_userdefinedpolynomial/scenario.json new file mode 100644 index 000000000..5ec434baa --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/crc_userdefinedpolynomial/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "crc_userdefinedpolynomial", + "until": "500ms", + "description": "CRC USERDEFINEDPOLYNOMIAL: an 8-bit CRC of polynomial 0x9B over the word 0x1234, 0xEF; LD2 on means each value matched, a 1 s blink an error.", + "inputs": [], + "assertions": [ + { + "id": "pass", + "between": [ + "50ms", + "490ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/dma_copyfromflashtomemory_init/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/dma_copyfromflashtomemory_init/scenario.json new file mode 100644 index 000000000..b13cd5207 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/dma_copyfromflashtomemory_init/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "dma_copyfromflashtomemory_init", + "until": "300ms", + "description": "DMA_CopyFromFlashToMemory_Init (LL): DMA1 channel 1 copies 32 words from the flash to the SRAM in memory-to-memory mode; once the transfer-complete interrupt has come, the program compares the two buffers and lights LD2 when they match (it blinks LD2 on a mismatch or a transfer error).", + "inputs": [], + "assertions": [ + { + "id": "done", + "between": [ + "50ms", + "290ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/dma_flashtoram/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/dma_flashtoram/scenario.json new file mode 100644 index 000000000..080ba284b --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/dma_flashtoram/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "dma_flashtoram", + "until": "300ms", + "description": "DMA_FLASHToRAM: DMA1 channel 1 in memory-to-memory mode copies 32 words from the flash to the SRAM, started by software; the transfer-complete interrupt's callback lights LD2 (a transfer error would blink it).", + "inputs": [], + "assertions": [ + { + "id": "done", + "between": [ + "50ms", + "290ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/flash_eraseprogram/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/flash_eraseprogram/scenario.json new file mode 100644 index 000000000..90d123a19 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/flash_eraseprogram/scenario.json @@ -0,0 +1,32 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "flash_eraseprogram", + "until": "6.5s", + "description": "FLASH_EraseProgram: bank 1's pages 4 to 127 erased (124 x 22.02 ms) then programmed by double words (31744 x 81.7 us) by a program running from the same bank, which stalls through each operation: about 5.3 s before LD2 comes on, as on the board.", + "inputs": [], + "assertions": [ + { + "id": "working", + "between": [ + "100ms", + "5.2s" + ], + "probe": "led", + "expect": { + "logic": "0" + } + }, + { + "id": "pass", + "between": [ + "5.6s", + "6.4s" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/flash_fastprogram/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/flash_fastprogram/scenario.json new file mode 100644 index 000000000..b78fc320a --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/flash_fastprogram/scenario.json @@ -0,0 +1,32 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "flash_fastprogram", + "until": "3s", + "description": "FLASH_FastProgram: bank 2 mass-erased (MER2, 22.13 ms), then programmed a 256-byte row at a time (FSTPG, 1024 x 1.91 ms, DS12288's fast row) by a program running from bank 1, which goes on meanwhile and polls BSY: about 2 s before LD2 comes on once every word reads back.", + "inputs": [], + "assertions": [ + { + "id": "working", + "between": [ + "100ms", + "1.9s" + ], + "probe": "led", + "expect": { + "logic": "0" + } + }, + { + "id": "pass", + "between": [ + "2.1s", + "2.9s" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/gpio_exti/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/gpio_exti/scenario.json new file mode 100644 index 000000000..1f977c463 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/gpio_exti/scenario.json @@ -0,0 +1,68 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "gpio_exti", + "until": "1.2s", + "description": "GPIO_EXTI: EXTI15_10 on PC13's falling edge toggles LD2 in its callback, once per press; on the NUCLEO-G474RE that edge is B1's release (B1 joins PC13 to VDD: active high, where the readme expects the press), so LD2 changes as B1 is let go.", + "inputs": [ + { + "at": "200ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "300ms", + "target": "B1.B1", + "input": "pressed", + "value": false + }, + { + "at": "700ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "800ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "dark", + "between": [ + "100ms", + "290ms" + ], + "probe": "led", + "expect": { + "logic": "0" + } + }, + { + "id": "first", + "between": [ + "350ms", + "790ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + }, + { + "id": "second", + "between": [ + "850ms", + "1.15s" + ], + "probe": "led", + "expect": { + "logic": "0" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/gpio_iotoggle/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/gpio_iotoggle/scenario.json new file mode 100644 index 000000000..9c3ea7b38 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/gpio_iotoggle/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "gpio_iotoggle", + "until": "1.2s", + "description": "GPIO_IOToggle on the NUCLEO-G474RE: LD2 on PA5 toggled by HAL_GPIO_TogglePin every HAL_Delay(100), 101 ms of SysTick at 170 MHz from HSI16 through the PLL.", + "inputs": [], + "assertions": [ + { + "id": "blink", + "between": [ + "150ms", + "1.16s" + ], + "probe": "led", + "expect": { + "edges": 10 + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/hal_timebase_tim/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/hal_timebase_tim/scenario.json new file mode 100644 index 000000000..348b50ac0 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/hal_timebase_tim/scenario.json @@ -0,0 +1,21 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "hal_timebase_tim", + "until": "3.5s", + "description": "HAL_TimeBase_TIM: the HAL's time base on TIM6's update interrupt instead of SysTick, LD2 toggled every HAL_Delay(1000).", + "inputs": [], + "assertions": [ + { + "id": "blink", + "between": [ + "500ms", + "3.4s" + ], + "probe": "led", + "expect": { + "edges": 3 + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/iwdg_reset/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/iwdg_reset/scenario.json new file mode 100644 index 000000000..e856831a9 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/iwdg_reset/scenario.json @@ -0,0 +1,47 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "iwdg_reset", + "until": "6s", + "description": "IWDG_Reset: LSI measured by TIM16's input capture (TISEL: LSI on TI1), the IWDG set to time out after 1 s and refreshed every 990 ms while LD2 toggles. B1's handler (on the press: the BSP takes B1's rising edge, and B1 is active high) turns LD2 off and stores a word at 0x00040001, which its comment calls unmapped; on the G474RE's 512 KiB that address is inside the flash's boot alias, so the store reaches the flash interface with PG clear and sets PGSERR without a fault (RM0440 5.3.9), and the program goes on refreshing the IWDG: no reset. (On a 128 KiB part, the example's first target, the address is unmapped and the hard fault lets the IWDG reset it.)", + "inputs": [ + { + "at": "2500ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "2600ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "running", + "between": [ + "300ms", + "2.45s" + ], + "probe": "led", + "expect": { + "edges": 2 + } + }, + { + "id": "no-reset", + "between": [ + "3s", + "5.9s" + ], + "probe": "led", + "expect": { + "min": 0.3, + "max": 0.7 + }, + "measure": "duty_cycle" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/iwdg_windowmode/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/iwdg_windowmode/scenario.json new file mode 100644 index 000000000..0fd9066e9 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/iwdg_windowmode/scenario.json @@ -0,0 +1,47 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "iwdg_windowmode", + "until": "6.5s", + "description": "IWDG_WindowMode: the IWDG at LSI / 16 with a reload of 1561 (780 ms) and a window of 800, refreshed every 450 ms, after the window opens, while LD2 toggles; B1's callback shortens the wait to 200 ms, so the next refresh comes while the counter is still above the window and the IWDG resets the part (IWDG_WINR), which then holds LD2 on for 4 s (RCC_CSR's IWDGRSTF).", + "inputs": [ + { + "at": "2000ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "2100ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "running", + "between": [ + "300ms", + "1.95s" + ], + "probe": "led", + "expect": { + "min": 0.3, + "max": 0.7 + }, + "measure": "duty_cycle" + }, + { + "id": "reset", + "between": [ + "3.2s", + "6s" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/project.json b/tests/vendor/stm32cubeg4/nucleo_g474re/project.json new file mode 100644 index 000000000..559278927 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/project.json @@ -0,0 +1,71 @@ +{ + "schema_version": 1, + "kind": "project", + "name": "stm32cubeg4-nucleo-g474re", + "description": "A NUCLEO-G474RE running one of STM32CubeG4's examples for it, built from ST's unmodified sources (tests/vendor/stm32cubeg4/run.py puts the image beside this file as sketch.elf), on its STLINK-V3E's USB power. The console is the STLINK-V3E's virtual COM port on LPUART1; LD2 is on PA5, B1 on PC13 (active high: B1 joins it to VDD).", + "policy": "electrical", + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re", + "layout": { + "x": 360, + "y": 120 + }, + "firmware": { + "image": "sketch.elf", + "format": "elf" + } + } + ], + "components": [ + { + "id": "USB", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5 + }, + "layout": { + "x": 120, + "y": 160 + } + }, + { + "id": "GND1", + "component": "emblink/gnd", + "layout": { + "x": 120, + "y": 320 + } + } + ], + "nets": { + "USB5V": [ + "USB.+", + "B1.U5V" + ], + "GND": [ + "USB.-", + "GND1.GND", + "B1.GND" + ] + }, + "probes": [ + { + "id": "console", + "target": "serial:B1", + "kind": "serial" + }, + { + "id": "led", + "target": "net:B1.PA5", + "kind": "digital" + }, + { + "id": "button", + "target": "net:B1.PC13", + "kind": "digital" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/pwr_stop0/project.json b/tests/vendor/stm32cubeg4/nucleo_g474re/pwr_stop0/project.json new file mode 100644 index 000000000..a0e4e8639 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/pwr_stop0/project.json @@ -0,0 +1,76 @@ +{ + "schema_version": 1, + "kind": "project", + "name": "stm32cubeg4-nucleo-g474re-pwr-stop0", + "description": "A NUCLEO-G474RE running one of STM32CubeG4's examples for it, built from ST's unmodified sources (tests/vendor/stm32cubeg4/run.py puts the image beside this file as sketch.elf), on its STLINK-V3E's USB power. The console is the STLINK-V3E's virtual COM port on LPUART1; LD2 is on PA5, B1 on PC13 (active low). An analog probe on PA5, which the example leaves floating (analog mode) in Stop 0.", + "policy": "electrical", + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re", + "layout": { + "x": 360, + "y": 120 + }, + "firmware": { + "image": "sketch.elf", + "format": "elf" + } + } + ], + "components": [ + { + "id": "USB", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5 + }, + "layout": { + "x": 120, + "y": 160 + } + }, + { + "id": "GND1", + "component": "emblink/gnd", + "layout": { + "x": 120, + "y": 320 + } + } + ], + "nets": { + "USB5V": [ + "USB.+", + "B1.U5V" + ], + "GND": [ + "USB.-", + "GND1.GND", + "B1.GND" + ] + }, + "probes": [ + { + "id": "console", + "target": "serial:B1", + "kind": "serial" + }, + { + "id": "led", + "target": "net:B1.PA5", + "kind": "digital" + }, + { + "id": "button", + "target": "net:B1.PC13", + "kind": "digital" + }, + { + "id": "pa5v", + "target": "net:B1.PA5", + "kind": "analog" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/pwr_stop0/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/pwr_stop0/scenario.json new file mode 100644 index 000000000..2826bcbdf --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/pwr_stop0/scenario.json @@ -0,0 +1,60 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "pwr_stop0", + "until": "11s", + "description": "PWR_STOP0: LD2 toggled from SysTick for 5 s at 170 MHz, then every port but C put in analog mode (LD2 dark) and Stop 0 entered by WFI with SysTick suspended; B1's press (a rising edge on EXTI13: the example sets it, and B1 is active high) wakes the part on HSI16, SYSCLKConfig_STOP brings the PLL back and LD2 toggles for 5 s more.", + "inputs": [ + { + "at": "7500ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "7600ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "run", + "between": [ + "500ms", + "4.8s" + ], + "probe": "led", + "expect": { + "min": 0.3, + "max": 0.7 + }, + "measure": "duty_cycle" + }, + { + "id": "stop", + "between": [ + "5.3s", + "7.4s" + ], + "probe": "pa5v", + "expect": { + "max_v": 0.5 + } + }, + { + "id": "woken", + "between": [ + "8s", + "10.9s" + ], + "probe": "led", + "expect": { + "min": 0.3, + "max": 0.7 + }, + "measure": "duty_cycle" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/rcc_clockconfig/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/rcc_clockconfig/scenario.json new file mode 100644 index 000000000..7db9ead13 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/rcc_clockconfig/scenario.json @@ -0,0 +1,71 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "rcc_clockconfig", + "until": "2s", + "description": "RCC_ClockConfig: SYSCLK at 170 MHz from the PLL on HSI16, LD2 toggled every HAL_Delay(100); each press of B1 moves the PLL to the other source (the 24 MHz crystal X3, ready after its 2 ms start-up, then back to HSI16) through SYSCLK on the source it leaves, and LD2 keeps its rate.", + "inputs": [ + { + "at": "600ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "650ms", + "target": "B1.B1", + "input": "pressed", + "value": false + }, + { + "at": "1300ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "1350ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "hsi", + "between": [ + "100ms", + "590ms" + ], + "probe": "led", + "expect": { + "frequency_hz": 4.95 + }, + "tolerance": 0.06 + }, + { + "id": "hse", + "between": [ + "750ms", + "1.24s" + ], + "probe": "led", + "expect": { + "frequency_hz": 4.95 + }, + "tolerance": 0.06 + }, + { + "id": "hsi-again", + "between": [ + "1.45s", + "1.95s" + ], + "probe": "led", + "expect": { + "frequency_hz": 4.95 + }, + "tolerance": 0.06 + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/spi_fullduplex_comdma/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/spi_fullduplex_comdma/scenario.json new file mode 100644 index 000000000..afd528ac7 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/spi_fullduplex_comdma/scenario.json @@ -0,0 +1,58 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "spi_fullduplex_comdma", + "until": "600ms", + "description": "SPI_FullDuplex_ComDMA: SPI1 of B1 (the master) and B2 (the slave) exchange their buffers full duplex by DMA (DMA1 through DMAMUX) once B1's USER button is pressed; each board compares what it received with what it expected and lights LD2 when they match (LD2 blinks on the master while it waits for the button).", + "inputs": [ + { + "at": "200ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "300ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "waiting", + "between": [ + "20ms", + "190ms" + ], + "probe": "led1", + "expect": { + "min": 0.2, + "max": 0.8 + }, + "measure": "duty_cycle" + }, + { + "id": "master-ok", + "between": [ + "400ms", + "590ms" + ], + "probe": "led1", + "expect": { + "logic": "1" + } + }, + { + "id": "slave-ok", + "between": [ + "400ms", + "590ms" + ], + "probe": "led2", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/spi_fullduplex_compolling/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/spi_fullduplex_compolling/scenario.json new file mode 100644 index 000000000..7dec00f3c --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/spi_fullduplex_compolling/scenario.json @@ -0,0 +1,58 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "spi_fullduplex_compolling", + "until": "600ms", + "description": "SPI_FullDuplex_ComPolling: SPI1 of B1 (the master) and B2 (the slave) exchange their buffers full duplex by polling once B1's USER button is pressed; each board compares what it received with what it expected and lights LD2 when they match (LD2 blinks on the master while it waits for the button).", + "inputs": [ + { + "at": "200ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "300ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "waiting", + "between": [ + "20ms", + "190ms" + ], + "probe": "led1", + "expect": { + "min": 0.2, + "max": 0.8 + }, + "measure": "duty_cycle" + }, + { + "id": "master-ok", + "between": [ + "400ms", + "590ms" + ], + "probe": "led1", + "expect": { + "logic": "1" + } + }, + { + "id": "slave-ok", + "between": [ + "400ms", + "590ms" + ], + "probe": "led2", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/tim_octoggle/project.json b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_octoggle/project.json new file mode 100644 index 000000000..748c64496 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_octoggle/project.json @@ -0,0 +1,91 @@ +{ + "schema_version": 1, + "kind": "project", + "name": "stm32cubeg4-nucleo-g474re-tim-octoggle", + "description": "A NUCLEO-G474RE running one of STM32CubeG4's examples for it, built from ST's unmodified sources (tests/vendor/stm32cubeg4/run.py puts the image beside this file as sketch.elf), on its STLINK-V3E's USB power. The console is the STLINK-V3E's virtual COM port on LPUART1; LD2 is on PA5, B1 on PC13 (active low). Probes on TIM1's channels, PA8 to PA11.", + "policy": "electrical", + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re", + "layout": { + "x": 360, + "y": 120 + }, + "firmware": { + "image": "sketch.elf", + "format": "elf" + } + } + ], + "components": [ + { + "id": "USB", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5 + }, + "layout": { + "x": 120, + "y": 160 + } + }, + { + "id": "GND1", + "component": "emblink/gnd", + "layout": { + "x": 120, + "y": 320 + } + } + ], + "nets": { + "USB5V": [ + "USB.+", + "B1.U5V" + ], + "GND": [ + "USB.-", + "GND1.GND", + "B1.GND" + ] + }, + "probes": [ + { + "id": "console", + "target": "serial:B1", + "kind": "serial" + }, + { + "id": "led", + "target": "net:B1.PA5", + "kind": "digital" + }, + { + "id": "button", + "target": "net:B1.PC13", + "kind": "digital" + }, + { + "id": "pa8", + "target": "net:B1.PA8", + "kind": "digital" + }, + { + "id": "pa9", + "target": "net:B1.PA9", + "kind": "digital" + }, + { + "id": "pa10", + "target": "net:B1.PA10", + "kind": "digital" + }, + { + "id": "pa11", + "target": "net:B1.PA11", + "kind": "digital" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/tim_octoggle/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_octoggle/scenario.json new file mode 100644 index 000000000..4f8c9c1c3 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_octoggle/scenario.json @@ -0,0 +1,71 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "tim_octoggle", + "until": "100ms", + "description": "TIM_OCToggle: TIM1 at 17 MHz, its channels in toggle mode, each CC interrupt moving CCRx on by its value: 2125 Hz on PA8, 4250 Hz on PA9, 8500 Hz on PA10, 17 kHz on PA11, each at 50 %.", + "inputs": [], + "assertions": [ + { + "id": "pa8-f", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa8", + "expect": { + "frequency_hz": 2125 + }, + "tolerance": 0.01 + }, + { + "id": "pa9-f", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa9", + "expect": { + "frequency_hz": 4250 + }, + "tolerance": 0.01 + }, + { + "id": "pa10-f", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa10", + "expect": { + "frequency_hz": 8500 + }, + "tolerance": 0.01 + }, + { + "id": "pa11-f", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa11", + "expect": { + "frequency_hz": 17000 + }, + "tolerance": 0.01 + }, + { + "id": "pa8-duty", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa8", + "expect": { + "min": 0.49, + "max": 0.51 + }, + "measure": "duty_cycle" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/tim_pwmoutput/project.json b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_pwmoutput/project.json new file mode 100644 index 000000000..d0f8e9b26 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_pwmoutput/project.json @@ -0,0 +1,91 @@ +{ + "schema_version": 1, + "kind": "project", + "name": "stm32cubeg4-nucleo-g474re-tim-pwmoutput", + "description": "A NUCLEO-G474RE running one of STM32CubeG4's examples for it, built from ST's unmodified sources (tests/vendor/stm32cubeg4/run.py puts the image beside this file as sketch.elf), on its STLINK-V3E's USB power. The console is the STLINK-V3E's virtual COM port on LPUART1; LD2 is on PA5, B1 on PC13 (active low). Probes on TIM1's channels, PA8 to PA11.", + "policy": "electrical", + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re", + "layout": { + "x": 360, + "y": 120 + }, + "firmware": { + "image": "sketch.elf", + "format": "elf" + } + } + ], + "components": [ + { + "id": "USB", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5 + }, + "layout": { + "x": 120, + "y": 160 + } + }, + { + "id": "GND1", + "component": "emblink/gnd", + "layout": { + "x": 120, + "y": 320 + } + } + ], + "nets": { + "USB5V": [ + "USB.+", + "B1.U5V" + ], + "GND": [ + "USB.-", + "GND1.GND", + "B1.GND" + ] + }, + "probes": [ + { + "id": "console", + "target": "serial:B1", + "kind": "serial" + }, + { + "id": "led", + "target": "net:B1.PA5", + "kind": "digital" + }, + { + "id": "button", + "target": "net:B1.PC13", + "kind": "digital" + }, + { + "id": "pa8", + "target": "net:B1.PA8", + "kind": "digital" + }, + { + "id": "pa9", + "target": "net:B1.PA9", + "kind": "digital" + }, + { + "id": "pa10", + "target": "net:B1.PA10", + "kind": "digital" + }, + { + "id": "pa11", + "target": "net:B1.PA11", + "kind": "digital" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/tim_pwmoutput/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_pwmoutput/scenario.json new file mode 100644 index 000000000..b57bdc61d --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/tim_pwmoutput/scenario.json @@ -0,0 +1,86 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "tim_pwmoutput", + "until": "100ms", + "description": "TIM_PWMOutput: TIM1 at 85 MHz (PSC from 170 MHz), ARR 999: four 85 kHz PWM channels, CH1 on PA8 at 50 %, CH2 on PA9 at 37.5 %, CH3 on PA10 at 25 %, CH4 on PA11 at 12.5 % (TIM1's MOE through BDTR).", + "inputs": [], + "assertions": [ + { + "id": "pa8-f", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa8", + "expect": { + "frequency_hz": 85000 + }, + "tolerance": 0.01 + }, + { + "id": "pa11-f", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa11", + "expect": { + "frequency_hz": 85000 + }, + "tolerance": 0.01 + }, + { + "id": "pa8-duty", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa8", + "expect": { + "min": 0.495, + "max": 0.505 + }, + "measure": "duty_cycle" + }, + { + "id": "pa9-duty", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa9", + "expect": { + "min": 0.37, + "max": 0.38 + }, + "measure": "duty_cycle" + }, + { + "id": "pa10-duty", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa10", + "expect": { + "min": 0.245, + "max": 0.255 + }, + "measure": "duty_cycle" + }, + { + "id": "pa11-duty", + "between": [ + "20ms", + "90ms" + ], + "probe": "pa11", + "expect": { + "min": 0.12, + "max": 0.13 + }, + "measure": "duty_cycle" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/two_boards.json b/tests/vendor/stm32cubeg4/nucleo_g474re/two_boards.json new file mode 100644 index 000000000..79245b71a --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/two_boards.json @@ -0,0 +1,133 @@ +{ + "schema_version": 1, + "kind": "project", + "name": "stm32cubeg4-two-boards", + "description": "Two NUCLEO-G474RE boards running one of STM32CubeG4's examples for a pair of boards, built from ST's unmodified sources: B1 the master (sketch.elf, the example's _Master project), B2 the slave (slave.elf, its _Slave project). As the readme's figure wires them, SPI1's SCK (PB3, CN10 pin 31), MISO (PB4, CN10 pin 27) and MOSI (PB5, CN10 pin 29) join, with the grounds. Each board is plugged into its own USB port; the master waits for its USER button.", + "policy": "electrical", + "boards": [ + { + "id": "B1", + "board": "emblink/nucleo_g474re", + "layout": { + "x": 360, + "y": 120 + }, + "firmware": { + "image": "sketch.elf", + "format": "elf" + } + }, + { + "id": "B2", + "board": "emblink/nucleo_g474re", + "layout": { + "x": 900, + "y": 120 + }, + "firmware": { + "image": "slave.elf", + "format": "elf" + } + } + ], + "components": [ + { + "id": "USB1", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5 + }, + "layout": { + "x": 120, + "y": 160 + } + }, + { + "id": "USB2", + "component": "emblink/vsource", + "params": { + "kind": "dc", + "dc": 5 + }, + "layout": { + "x": 1300, + "y": 160 + } + }, + { + "id": "GND1", + "component": "emblink/gnd", + "layout": { + "x": 120, + "y": 320 + } + } + ], + "nets": { + "USB5V": [ + "USB1.+", + "B1.U5V" + ], + "GND": [ + "USB1.-", + "USB2.-", + "GND1.GND", + "B1.GND", + "B2.GND" + ], + "SCK": [ + "B1.CN10_31", + "B2.CN10_31" + ], + "MISO": [ + "B1.CN10_27", + "B2.CN10_27" + ], + "MOSI": [ + "B1.CN10_29", + "B2.CN10_29" + ], + "USB5V_2": [ + "USB2.+", + "B2.U5V" + ] + }, + "probes": [ + { + "id": "led1", + "target": "net:B1.PA5", + "kind": "digital" + }, + { + "id": "led2", + "target": "net:B2.PA5", + "kind": "digital" + }, + { + "id": "sck", + "target": "net:B1.PB3", + "kind": "digital" + }, + { + "id": "mosi", + "target": "net:B1.PB5", + "kind": "digital" + }, + { + "id": "miso", + "target": "net:B1.PB4", + "kind": "digital" + }, + { + "id": "master_rx", + "target": "var:B1:aRxBuffer", + "kind": "value" + }, + { + "id": "slave_rx", + "target": "var:B2:aRxBuffer", + "kind": "value" + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/uart_hyperterminal_dma/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/uart_hyperterminal_dma/scenario.json new file mode 100644 index 000000000..cef1d11e2 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/uart_hyperterminal_dma/scenario.json @@ -0,0 +1,52 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "uart_hyperterminal_dma", + "until": "400ms", + "description": "UART_HyperTerminal_DMA: USART2 on PA2/PA3, the pins the STLINK-V3E's virtual COM port is wired to, at 9600 baud with 7 data bits and odd parity; the start message goes out by DMA, ten characters typed come in by DMA and go back out by DMA, then the end message, and LD2 lights.", + "inputs": [ + { + "at": "150ms", + "target": "B1", + "input": "serial", + "value": "0123456789" + } + ], + "assertions": [ + { + "id": "start", + "at": "140ms", + "probe": "console", + "expect": { + "contains": "Enter 10 characters using keyboard :" + } + }, + { + "id": "echo", + "at": "390ms", + "probe": "console", + "expect": { + "contains": "keyboard :\n\r0123456789" + } + }, + { + "id": "end", + "at": "390ms", + "probe": "console", + "expect": { + "contains": "Example Finished" + } + }, + { + "id": "done", + "between": [ + "350ms", + "395ms" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/uart_printf/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/uart_printf/scenario.json new file mode 100644 index 000000000..112821ed6 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/uart_printf/scenario.json @@ -0,0 +1,37 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "uart_printf", + "until": "100ms", + "description": "UART_Printf: printf retargeted to LPUART1 (PA2/PA3), the STLINK-V3E's virtual COM port, at 115200 baud with 8 bits, odd parity (7 data bits and the parity bit).", + "inputs": [], + "assertions": [ + { + "id": "banner", + "at": "60ms", + "probe": "console", + "expect": { + "contains": "UART Printf Example: retarget the C library printf function to the UART" + } + }, + { + "id": "done", + "at": "95ms", + "probe": "console", + "expect": { + "contains": "** Test finished successfully. **" + } + }, + { + "id": "no-error", + "between": [ + "20ms", + "95ms" + ], + "probe": "led", + "expect": { + "logic": "0" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/uart_receptiontoidle_circulardma/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/uart_receptiontoidle_circulardma/scenario.json new file mode 100644 index 000000000..e6b81a0c5 --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/uart_receptiontoidle_circulardma/scenario.json @@ -0,0 +1,47 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "uart_receptiontoidle_circulardma", + "until": "200ms", + "description": "UART_ReceptionToIdle_CircularDMA: LPUART1 receives into a 20-byte buffer by circular DMA, the HAL calling back on the half-transfer, the transfer-complete and the line going idle; each chunk is echoed. Text typed on the STLINK-V3E's virtual COM port comes back whole, also when it wraps the buffer.", + "inputs": [ + { + "at": "50ms", + "target": "B1", + "input": "serial", + "value": "hello" + }, + { + "at": "100ms", + "target": "B1", + "input": "serial", + "value": "The quick brown fox jumps over the lazy dog" + } + ], + "assertions": [ + { + "id": "banner", + "at": "40ms", + "probe": "console", + "expect": { + "contains": "USART Example : Enter characters to fill reception buffers." + } + }, + { + "id": "idle-echo", + "at": "90ms", + "probe": "console", + "expect": { + "contains": "reception buffers.\r\n\u0000hello" + } + }, + { + "id": "wrapping-echo", + "at": "190ms", + "probe": "console", + "expect": { + "contains": "helloThe quick brown fox jumps over the lazy dog" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/nucleo_g474re/wwdg_example/scenario.json b/tests/vendor/stm32cubeg4/nucleo_g474re/wwdg_example/scenario.json new file mode 100644 index 000000000..714f39e1e --- /dev/null +++ b/tests/vendor/stm32cubeg4/nucleo_g474re/wwdg_example/scenario.json @@ -0,0 +1,47 @@ +{ + "schema_version": 1, + "kind": "scenario", + "name": "wwdg_example", + "until": "6s", + "description": "WWDG_Example: the WWDG at PCLK1 / 4096 / 128, counter 127 and window 80, refreshed in its window while LD2 toggles; B1's press makes the EXTI handler write to an invalid address, the hard fault's loop stops the refreshes and the WWDG resets the part as its counter passes 0x40, which then holds LD2 on for 4 s (RCC_CSR's WWDGRSTF).", + "inputs": [ + { + "at": "1500ms", + "target": "B1.B1", + "input": "pressed", + "value": true + }, + { + "at": "1600ms", + "target": "B1.B1", + "input": "pressed", + "value": false + } + ], + "assertions": [ + { + "id": "running", + "between": [ + "300ms", + "1.45s" + ], + "probe": "led", + "expect": { + "min": 0.3, + "max": 0.7 + }, + "measure": "duty_cycle" + }, + { + "id": "reset", + "between": [ + "2.2s", + "5.3s" + ], + "probe": "led", + "expect": { + "logic": "1" + } + } + ] +} diff --git a/tests/vendor/stm32cubeg4/run.py b/tests/vendor/stm32cubeg4/run.py new file mode 100644 index 000000000..11162f475 --- /dev/null +++ b/tests/vendor/stm32cubeg4/run.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Junior Deogracias +"""STM32CubeG4's own examples for the NUCLEO-G474RE, built unmodified and +run on EmbSIM's board (01 ยง8.2). + +ST's files are not vendored. --cube names a checkout of STM32CubeG4 with +its submodules (Drivers/STM32G4xx_HAL_Driver, Drivers/CMSIS/Device/ST/ +STM32G4xx, Drivers/BSP/STM32G4xx_Nucleo; its Drivers/CMSIS/Include). +CI fetches it at the commit the workflow pins. + +Each example under nucleo_g474re/ is one of CubeG4's for the board (the +EXAMPLES table names its directory). It is built as its STM32CubeIDE +project builds it: +- the sources its .project links; +- the defines and include paths of its .cproject's Debug configuration, + at -Os; +- its own startup file, syscalls.c, sysmem.c and linker script + (STM32G474RETX_FLASH.ld); +- newlib-nano. +The image then runs nucleo_g474re/project.json (or /project.json) +under the example's scenario.json, whose assertions must all pass. An +example for two boards (SPI_FullDuplex_*) is a pair of projects: the +_Master one is B1's sketch.elf, the _Slave one B2's slave.elf, in +nucleo_g474re/two_boards.json. + + run.py --cube DIR [--embsim PATH] [--keep DIR] [EXAMPLE...] + +Without arm-none-eabi-gcc, or without --cube (or STM32CUBE_G4), it skips.""" +import argparse +import os +import re +import shutil +import sys +import tempfile +from pathlib import Path + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[2] +sys.path.insert(0, str(HERE.parent)) +from vendor_run import run_scenario, sh # noqa: E402 + +NUCLEO = "Projects/NUCLEO-G474RE/" +SPI = NUCLEO + "Examples/SPI/SPI_FullDuplex_" + + +def two(master: str) -> dict: + """a pair of projects for two boards: the master's and the slave's""" + return {"dir": master + "_Master", "slave": master + "_Slave", "project": "two_boards.json"} + + +EXAMPLES = { + "cortexm_modeprivilege": NUCLEO + "Examples/Cortex/CORTEXM_ModePrivilege", + "cortexm_processstack": NUCLEO + "Examples/Cortex/CORTEXM_ProcessStack", + "cortexm_systick": NUCLEO + "Examples/Cortex/CORTEXM_SysTick", + "crc_bytes_stream_7bit_crc": NUCLEO + "Examples/CRC/CRC_Bytes_Stream_7bit_CRC", + "crc_data_reversing_16bit_crc": NUCLEO + "Examples/CRC/CRC_Data_Reversing_16bit_CRC", + "crc_example": NUCLEO + "Examples/CRC/CRC_Example", + "crc_userdefinedpolynomial": NUCLEO + "Examples/CRC/CRC_UserDefinedPolynomial", + "dma_copyfromflashtomemory_init": NUCLEO + "Examples_LL/DMA/DMA_CopyFromFlashToMemory_Init", + "dma_flashtoram": NUCLEO + "Examples/DMA/DMA_FLASHToRAM", + "flash_eraseprogram": NUCLEO + "Examples/FLASH/FLASH_EraseProgram", + "flash_fastprogram": NUCLEO + "Examples/FLASH/FLASH_FastProgram", + "gpio_exti": NUCLEO + "Examples/GPIO/GPIO_EXTI", + "gpio_iotoggle": NUCLEO + "Examples/GPIO/GPIO_IOToggle", + "hal_timebase_tim": NUCLEO + "Examples/HAL/HAL_TimeBase_TIM", + "iwdg_reset": NUCLEO + "Examples/IWDG/IWDG_Reset", + "iwdg_windowmode": NUCLEO + "Examples/IWDG/IWDG_WindowMode", + "pwr_stop0": NUCLEO + "Examples/PWR/PWR_STOP0", + "rcc_clockconfig": NUCLEO + "Examples/RCC/RCC_ClockConfig", + "spi_fullduplex_comdma": two(SPI + "ComDMA"), + # SPI_FullDuplex_ComIT: the master's fourth received byte loses a bit (the + # slave's MISO change, made in its TXE interrupt, reaches the line after + # the master's next sample); not in the suite until that is solved + "spi_fullduplex_compolling": two(SPI + "ComPolling"), + "tim_octoggle": NUCLEO + "Examples/TIM/TIM_OCToggle", + "tim_pwmoutput": NUCLEO + "Examples/TIM/TIM_PWMOutput", + "uart_hyperterminal_dma": NUCLEO + "Examples/UART/UART_HyperTerminal_DMA", + "uart_printf": NUCLEO + "Examples/UART/UART_Printf", + "uart_receptiontoidle_circulardma": NUCLEO + "Examples/UART/UART_ReceptionToIdle_CircularDMA", + "wwdg_example": NUCLEO + "Examples/WWDG/WWDG_Example", +} +BOARD_DIR = HERE / "nucleo_g474re" +LD = "STM32G474RETX_FLASH.ld" +MCU = ["-mcpu=cortex-m4", "-mfpu=fpv4-sp-d16", "-mfloat-abi=hard", "-mthumb"] +CFLAGS = ["-std=gnu11", "-g3", "-Os", "-ffunction-sections", "-fdata-sections", "-Wall", "--specs=nano.specs"] +LDFLAGS = ["--specs=nosys.specs", "--specs=nano.specs", "-Wl,--gc-sections", "-static", + "-Wl,--start-group", "-lc", "-lm", "-Wl,--end-group"] + + +def debug_config(cproject: str) -> str: + for m in re.finditer(r"", cproject, re.S): + if 'name="Debug"' in m.group(0): + return m.group(0) + raise SystemExit("no Debug configuration in .cproject") + + +def option_values(config: str, key: str) -> list: + out = [] + for m in re.finditer(r']*superClass="[^"]*c\.compiler\.option\.' + key + r'"[^>]*>(.*?)', + config, re.S): + out += re.findall(r' list: + """the .project's linked C and assembly sources (CubeG4 writes them as + ${PARENT-n-PROJECT_LOC}/..., URL-encoded), then the files the project + directory holds (its startup, syscalls.c, sysmem.c)""" + text = (ide / ".project").read_text(encoding="utf-8") + out = [] + for loc in re.findall(r"([^<]*)", text): + loc = loc.replace("$%7B", "").replace("%7D", "") + m = re.match(r"PARENT-(\d+)-PROJECT_LOC/(.*)", loc) + if not m: + continue + base = ide + for _ in range(int(m.group(1))): + base = base.parent + p = base / m.group(2) + if p.suffix in (".c", ".s"): + out.append(p) + for p in sorted(ide.rglob("*")): + if p.suffix in (".c", ".s") and p.is_file(): + out.append(p) + return out + + +def record(name: str) -> dict: + e = EXAMPLES[name] + return dict({"defines": [], "patches": {}, "slave": None, "project": None}, **(e if isinstance(e, dict) else {"dir": e})) + + +def build(cube: Path, name: str, out: Path, slave: bool = False) -> Path: + """the example's image; `slave`: the slave board's project of a pair""" + rec = record(name) + ex = cube / (rec["slave"] if slave else rec["dir"]) + if slave: + name += "_slave" + ide = ex / "STM32CubeIDE" + config = debug_config((ide / ".cproject").read_text(encoding="utf-8")) + defs = ["-D" + d for d in option_values(config, "definedsymbols") + rec["defines"]] + incs = [] + for i in option_values(config, "includepaths"): + incs += ["-I", (ide / "Debug" / i).resolve()] # relative to the IDE's build directory + d = out / name + d.mkdir(parents=True, exist_ok=True) + objs = [] + for n, src in enumerate(project_sources(ide)): + o = d / f"{n:03d}_{src.stem}.o" + if src.suffix == ".s": + sh(["arm-none-eabi-gcc", "-x", "assembler-with-cpp", "-c", *MCU, "-g3", *defs, src, "-o", o]) + else: + sh(["arm-none-eabi-gcc", "-c", *MCU, *CFLAGS, *defs, *incs, src, "-o", o]) + objs.append(o) + elf = out / (name + ".elf") + sh(["arm-none-eabi-gcc", *objs, *MCU, "-T", ide / LD, *LDFLAGS, f"-Wl,-Map={out / (name + '.map')}", "-o", elf]) + return elf + + +def project_of(name: str) -> Path: + own = BOARD_DIR / name / "project.json" + if own.exists(): + return own + return BOARD_DIR / (record(name)["project"] or "project.json") + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument("--cube", default=os.environ.get("STM32CUBE_G4"), help="an STM32CubeG4 checkout with its submodules") + ap.add_argument("--embsim", default=str(ROOT / "build" / "dev" / "bin" / "embsim")) + ap.add_argument("--keep", help="build here, and keep it, instead of a temporary directory") + ap.add_argument("examples", nargs="*") + args = ap.parse_args() + if not shutil.which("arm-none-eabi-gcc") or not args.cube: + print(f"SKIP: {'needs arm-none-eabi-gcc' if args.cube else 'no --cube (an STM32CubeG4 checkout)'}") + return 0 + cube = Path(args.cube).resolve() + for need in (NUCLEO, "Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h", + "Drivers/CMSIS/Device/ST/STM32G4xx/Include/stm32g4xx.h", "Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.h", + "Drivers/CMSIS/Include/core_cm4.h"): + if not (cube / need).exists(): + print(f"error: {cube} has no {need}") + return 2 + names = args.examples or sorted(d.name for d in BOARD_DIR.iterdir() if d.is_dir()) + with tempfile.TemporaryDirectory() as tmp: + work = Path(args.keep).resolve() if args.keep else Path(tmp) + work.mkdir(parents=True, exist_ok=True) + bad = 0 + for name in names: + elf = build(cube, name, work) + extra = {"slave.elf": build(cube, name, work, slave=True)} if record(name)["slave"] else {} + bad += not run_scenario(Path(args.embsim), project_of(name), name, elf, BOARD_DIR / name / "scenario.json", + work, extra) + return 1 if bad else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/importers/stm32g474_regs.sh b/tools/importers/stm32g474_regs.sh new file mode 100755 index 000000000..4a5f37549 --- /dev/null +++ b/tools/importers/stm32g474_regs.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Junior Deogracias +# STMicroelectronics STM32G474.svd v3.0 (the STM32G4 SVD pack, Apache-2.0) to +# catalog/mcus/st/stm32g474re/registers.json, with the corrections RM0440 and +# STM32CubeG4 (stm32g474xx.h, the HAL) give; run from the repository root +SVD=${1:?usage: stm32g474_regs.sh STM32G474.svd [registers.json]} +OUT=${2:-catalog/mcus/st/stm32g474re/registers.json} +python3 tools/importers/svd2regs.py "$SVD" -o "$OUT" --id st/stm32g474re/registers \ + --strip-prefixes \ + --drop "FDCAN=its address is the FDCAN message RAM's (SRAMCAN, RM0440 2.2.2); FDCAN1 to FDCAN3 keep its registers" \ + --rename TIM15.CCMR1_Output=CCMR1 \ + --field PWR.SR2=PVMO1:12:1:r --field PWR.SR2=PVMO2:13:1:r --field PWR.SR2=PVMO3:14:1:r --field PWR.SR2=PVMO4:15:1:r \ + --field QUADSPI.CR=FTHRES:8:4 \ + --field TIM2.CNT=CNT:0:32 \ + --field DBGMCU.IDCODE=DEV_ID:0:12:r \ + --field TIM1.CCMR1=OC1M_3:16:1 --field TIM1.CCMR1=OC2M_3:24:1 \ + --field TIM1.CCMR2=OC3M_3:16:1 --field TIM1.CCMR2=OC4M_3:24:1 \ + --field TIM2.CCMR1=OC1M_3:16:1 --field TIM2.CCMR1=OC2M_3:24:1 \ + --field TIM2.CCMR2=OC3M_3:16:1 --field TIM2.CCMR2=OC4M_3:24:1 \ + --field TIM3.CCMR1=OC1M_3:16:1 --field TIM3.CCMR1=OC2M_3:24:1 \ + --field TIM3.CCMR2=OC3M_3:16:1 --field TIM3.CCMR2=OC4M_3:24:1 \ + --field TIM16.CCMR1=OC1M_3:16:1 \ + --reset USART1.ISR=0x008000C0 --reset UART4.ISR=0x008000C0 --reset LPUART1.ISR=0x008000C0 \ + --reset FLASH.OPTR=0xFFEFF8AA \ + --reset RCC.CR=0x00000500 \ + --reset DBGMCU.IDCODE=0x20016469 \ + --reset EXTI.IMR1=0x1F840000 --reset EXTI.IMR2=0x00000C3C \ + --interrupts TAMP=RTC_TAMP_CSS_LSE --interrupts PWR=PVD_PVM \ + --interrupts EXTI=EXTI0,EXTI1,EXTI2,EXTI3,EXTI4,EXTI9_5,EXTI15_10 \ + --interrupts HRTIM_TIME=HRTIM_TIME_IRQn --interrupts HRTIM_TIMF=HRTIM_TIMF_IRQn \ + --interrupts TIM15=TIM1_BRK_TIM15 --interrupts TIM16=TIM1_UP_TIM16 --interrupts TIM17=TIM1_TRG_COM \ + --interrupts ADC2=ADC1_2 \ + --interrupts DAC1=TIM6_DACUNDER --interrupts DAC3=TIM6_DACUNDER --interrupts DAC2=TIM7 --interrupts DAC4=TIM7 +# the SVD's version in the description's source, as ST's pack names it +python3 - "$OUT" <<'PY' +import json, sys +p = sys.argv[1] +d = json.load(open(p, encoding="utf-8")) +d["source"] = d["source"].replace("converted from STM32G474.svd by", "converted from STMicroelectronics STM32G474.svd v3.0 by", 1) +open(p, "w", encoding="utf-8").write(json.dumps(d, indent=1) + "\n") +PY diff --git a/tools/importers/stm32pins.py b/tools/importers/stm32pins.py index 224a0e413..a76a3a241 100644 --- a/tools/importers/stm32pins.py +++ b/tools/importers/stm32pins.py @@ -13,7 +13,8 @@ (PA0, from "PA0-WKUP"), the rest of its name becoming the pin's doc; power, reset and boot pins keep their names (VCAP_1, NRST, BOOT0). The analog map names each port pin's ADC inputs as the reference manual does, the ADCs -sharing a channel joined (ADC123_IN0). The alternate-function map, from +sharing a channel joined (ADC123_IN0), and the groups listed when its ADCs +number it differently ("ADC1_IN15, ADC3_IN12"). The alternate-function map, from the family's GPIO modes file (GPIO-_Modes.xml), gives each of the package's port pins the signals of each AF number (RM0390 7.3.2's table), AF15 being EVENTOUT on every pin; the debug port's signals lose their SYS_ @@ -78,8 +79,11 @@ def analog_of(pins: list) -> dict: if a: chans.setdefault(int(a.group(2)), []).append(a.group(1)) if chans: - ch = min(chans) - out[m.group(1)] = f"ADC{''.join(sorted(chans[ch]))}_IN{ch}" + # the ADCs sharing a channel number joined (ADC123_IN0); a pin + # whose ADCs number it differently lists each (an STM32G4's + # PB0: "ADC1_IN15, ADC3_IN12") + out[m.group(1)] = ", ".join(f"ADC{''.join(sorted(chans[ch]))}_IN{ch}" + for ch in sorted(chans, key=lambda c: (min(chans[c]), c))) return dict(sorted(out.items(), key=lambda kv: (kv[0][:2], int(kv[0][2:])))) diff --git a/tools/importers/svd2regs.py b/tools/importers/svd2regs.py index 1585941c2..93b2ce325 100644 --- a/tools/importers/svd2regs.py +++ b/tools/importers/svd2regs.py @@ -31,7 +31,11 @@ (RCC PLLCFGR's PLLM0..PLLM5) --drop PERIPH=WHY (repeatable) a peripheral the SVD lists that is another's registers at the same address - (Espressif's RNG, APB_CTRL's RND_DATA) + (Espressif's RNG, APB_CTRL's RND_DATA), or + at an address where no registers are (ST's + STM32G4 FDCAN, its message RAM's address): + the peripherals derived from it keep its + registers --fill PERIPH=FROM:WHY (repeatable) the registers of FROM at offsets PERIPH lacks, where the two share one layout and the SVD lists only part of PERIPH's @@ -41,6 +45,14 @@ the SVD leaves out, as WORDS 32-bit registers NAME0, NAME1, ... (the ESP32-C3's RMT RAM); recorded likewise + --strip-prefixes register names that repeat their + peripheral's (TIM2_CR1 in TIM2, RCC_CR in + RCC, DAC_CR in DAC1, as ST's STM32G4 file + names them) lose that prefix, the name the + reference manual gives them; recorded + --rename PERIPH.REG=NEW (repeatable) a register renamed as the + reference manual names it (TIM15's + CCMR1_Output: CCMR1); recorded --resolve-overlaps fields that share bits, which some SVDs list as alternative views of one register (Espressif's: a whole-register STATUS @@ -171,6 +183,8 @@ def convert(svd: Path, ident: str) -> dict: periphs, irqs = [], {} for p in root.iter("peripheral"): entry = {"name": p.findtext("name"), "base": "0x%08X" % num(p.findtext("baseAddress"))} + if p.findtext("groupName"): + entry["_group"] = p.findtext("groupName") names = [] for i in p.findall("interrupt"): irqs[i.findtext("name")] = num(i.findtext("value")) @@ -375,14 +389,77 @@ def apply_drops(doc: dict, specs: list[str]) -> None: done = [] for spec in specs: name, _, why = spec.partition("=") - if not any(p["name"] == name for p in doc["peripherals"]): + gone = next((p for p in doc["peripherals"] if p["name"] == name), None) + if gone is None: sys.exit(f"svd2regs: --drop {spec}: no peripheral {name}") + heir = None + for p in doc["peripherals"]: + if p.get("derived_from") != name: + continue + if heir is None and "registers" in gone: + # the first derived from it takes its registers, the others + # derive from that one + p.pop("derived_from") + p["registers"] = [dict(r) for r in gone["registers"]] + heir = p["name"] + elif heir is not None: + p["derived_from"] = heir doc["peripherals"] = [p for p in doc["peripherals"] if p["name"] != name] done.append(f"{name} ({why})" if why else name) if done: doc["source"] += "; peripherals left out: " + "; ".join(done) +def strip_prefixes(doc: dict) -> None: + """register names PREFIX_NAME in a peripheral whose name, name without + its number, or group is PREFIX become NAME (unless NAME is taken); a + field named after the whole register is renamed with it""" + done = [] + for p in doc["peripherals"]: + regs = p.get("registers") + if not regs: + continue + prefixes = {p["name"], re.sub(r"\d+$", "", p["name"])} + if p.get("_group"): + prefixes.add(p["_group"]) + taken = {r["name"] for r in regs} + n = 0 + for r in regs: + for pre in sorted(prefixes, key=len, reverse=True): + if r["name"].startswith(pre + "_") and len(r["name"]) > len(pre) + 1: + new = r["name"][len(pre) + 1:] + if new in taken: + break + for f in r.get("fields", []): + if f[0] == r["name"]: + f[0] = new + taken.discard(r["name"]) + taken.add(new) + r["name"] = new + n += 1 + break + if n: + done.append(f"{p['name']} ({n})") + if done: + doc["source"] += "; register names' peripheral prefixes taken off: " + ", ".join(done) + + +def apply_renames(doc: dict, specs: list[str]) -> None: + """registers PERIPH.REG=NEW renamed, recorded in source""" + done = [] + for spec in specs: + target, _, new = spec.partition("=") + reg = find_reg(doc, target, "--rename") + pname = target.partition(".")[0] + p = next(q for q in doc["peripherals"] if q["name"] == pname) + if not new or any(r["name"] == new for r in p["registers"]): + raise SystemExit(f"--rename {spec}: no new name, or {pname} already has {new}") + reg["name"] = new + done.append(spec) + if done: + doc["source"] += "; registers renamed as the reference manual names them: " + ", ".join(done) + + def apply_fills(doc: dict, specs: list[str]) -> None: """to each PERIPH of `specs` (PERIPH=FROM:WHY), FROM's registers at the offsets it lacks, recorded in source""" @@ -450,11 +527,18 @@ def main(argv: Optional[list[str]] = None) -> int: help="one-bit fields NAME0..NAMEn joined into NAME") ap.add_argument("--reserve", action="append", default=[], metavar="PERIPH.REG.NAME", help="a field whose bits the reference manual reserves, taken out") + ap.add_argument("--strip-prefixes", action="store_true", + help="register names that repeat their peripheral's lose that prefix") + ap.add_argument("--rename", action="append", default=[], metavar="PERIPH.REG=NEW", + help="a register renamed as the reference manual names it") ap.add_argument("--resolve-overlaps", action="store_true", help="fields containing another, or repeating its bits, taken out") args = ap.parse_args(argv) doc = convert(args.svd, args.id or (args.svd.stem.lower() + "/registers")) apply_drops(doc, args.drop) + if args.strip_prefixes: + strip_prefixes(doc) + apply_renames(doc, args.rename) apply_fills(doc, args.fill) apply_memories(doc, args.memory) apply_merges(doc, args.merge) @@ -465,6 +549,8 @@ def main(argv: Optional[list[str]] = None) -> int: resolve_overlaps(doc) apply_resets(doc, args.reset) apply_interrupts(doc, args.interrupts) + for p in doc["peripherals"]: + p.pop("_group", None) args.output.write_text(json.dumps(doc, indent=1) + "\n", encoding="utf-8") nregs = sum(len(p.get("registers", [])) for p in doc["peripherals"]) print(f"{args.output}: {len(doc['peripherals'])} peripherals, {nregs} registers, {len(doc['interrupts'])} interrupts") diff --git a/tools/test_stm32pins.py b/tools/test_stm32pins.py index b9bbe11c2..1bc04e067 100644 --- a/tools/test_stm32pins.py +++ b/tools/test_stm32pins.py @@ -20,6 +20,7 @@ + """ @@ -36,7 +37,9 @@ def test_package_and_analog(self): self.assertEqual(pkg["pins"][0], {"number": 1, "signal": "VBAT"}) self.assertEqual(pkg["pins"][1], {"number": 2, "signal": "PA0", "doc": "PA0-WKUP"}) self.assertEqual(pkg["pins"][4], {"number": 5, "signal": "NRST"}) - self.assertEqual(stm32pins.analog_of(pins), {"PA0": "ADC123_IN0", "PC4": "ADC12_IN14"}) + # an STM32G4's PB0: its ADCs number it differently, both listed + self.assertEqual(stm32pins.analog_of(pins), + {"PA0": "ADC123_IN0", "PB0": "ADC1_IN15, ADC3_IN12", "PC4": "ADC12_IN14"}) def test_alternate(self): modes = """ diff --git a/tools/test_svd2regs.py b/tools/test_svd2regs.py index bc9145c98..cad24a911 100644 --- a/tools/test_svd2regs.py +++ b/tools/test_svd2regs.py @@ -182,5 +182,60 @@ def test_memory(self): svd2regs.apply_memories(doc, ["UART0.RAM=0x404:2:again"]) +PREFIXED = """ + + TOYG4 + 32 + + + TIM2TIM0x40000000 + + TIM2_CR10x0 + TIM2_SR0x10 + UIF01 + + + + DAC1DAC0x50000800 + + DAC_CR0x0 + OPAMP1_CSR0x4 + + + + FDCAN0x4000A400 + FDCAN_CREL0x00x32141218 + + FDCAN10x40006400 + FDCAN20x40006800 + + +""" + + +class Svd2RegsPrefixed(unittest.TestCase): + """ST's STM32G4 file: register names prefixed with their peripheral's, + and the FDCAN registers listed at the message RAM's address""" + + def test_strip_and_drop(self): + with tempfile.TemporaryDirectory() as tmp: + p = Path(tmp) / "toy.svd" + o = Path(tmp) / "out.json" + p.write_text(PREFIXED) + svd2regs.main([str(p), "-o", str(o), "--strip-prefixes", "--drop", "FDCAN=the message RAM's address"]) + doc = json.loads(o.read_text(encoding="utf-8")) + by = {q["name"]: q for q in doc["peripherals"]} + self.assertEqual([r["name"] for r in by["TIM2"]["registers"]], ["CR1", "SR"]) + # the group's prefix too; another peripheral's name is kept + self.assertEqual([r["name"] for r in by["DAC1"]["registers"]], ["CR", "OPAMP1_CSR"]) + # the first derived from the dropped one takes its registers + self.assertNotIn("FDCAN", by) + self.assertEqual(by["FDCAN1"]["registers"][0]["name"], "CREL") + self.assertEqual(by["FDCAN1"]["registers"][0]["reset"], "0x32141218") + self.assertEqual(by["FDCAN2"]["derived_from"], "FDCAN1") + self.assertIn("prefixes taken off", doc["source"]) + self.assertNotIn("_group", json.dumps(doc)) + + if __name__ == "__main__": unittest.main() diff --git a/ui/apps/workbench/scripts/screenshots.mjs b/ui/apps/workbench/scripts/screenshots.mjs index 87832df26..073043894 100644 --- a/ui/apps/workbench/scripts/screenshots.mjs +++ b/ui/apps/workbench/scripts/screenshots.mjs @@ -98,6 +98,7 @@ const explorer24 = 'examples/explorer16-pic24/project.json'; const picoDual = 'examples/pico-dual-core/project.json'; const nucleo = 'examples/nucleo-f446re-blink-serial/project.json'; const nucleo144 = 'examples/nucleo-f446ze-blink-serial/project.json'; +const nucleoG4 = 'examples/nucleo-g474re-blink-serial/project.json'; const faulting = 'tests/firmware/fault/project.json'; /** the Debug perspective stopped at a breakpoint on `symbol` */ @@ -222,6 +223,18 @@ try { await perspective(page, 2); await run(page, 2700); }); + // the NUCLEO-G474RE (STM32G474RE, the Nucleo-64 MB1367): a second STM32 family + await shot(browser, 'design-nucleo-g474re', nucleoG4, async (page) => run(page, 1500)); + await shot(browser, 'run-nucleo-g474re', nucleoG4, async (page) => { + await perspective(page, 2); + await run(page, 2700); + }); + await shot(browser, 'board-nucleo-g474re', nucleoG4, async (page) => { + await page.getByRole('radio', { name: 'Bench' }).click(); + await wait(800); + await page.getByRole('radio', { name: '2D', exact: true }).click(); + await run(page, 2700); + }, { scale: 2, element: '.es-board' }); // M5: verification. A scenario opened, edited in place and run; coverage of // the Blue Pill's firmware with its source; a recording replayed const verifyRegion = (page, name) => page.getByRole('region', { name });