├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── build.rs ├── devices ├── common.yaml ├── hpm6750.yaml └── peripheral │ ├── dma.yaml │ ├── dmamux.yaml │ ├── gpio.yaml │ ├── ioc.yaml │ ├── otp.yaml │ ├── rtc.yaml │ ├── spi.yaml │ ├── sysctl.yaml │ ├── tmr.yaml │ └── uart.yaml ├── doc.md ├── raltool-cfg.yml ├── raltool ├── .gitignore ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── combine.rs │ ├── generate │ ├── block.rs │ ├── device.rs │ ├── fieldset.rs │ └── mod.rs │ ├── ir.rs │ ├── lib.rs │ ├── main.rs │ ├── svd2ir.rs │ ├── transform │ ├── common.rs │ ├── delete.rs │ ├── delete_enums.rs │ ├── delete_fieldsets.rs │ ├── expand_extends.rs │ ├── find_duplicate_enums.rs │ ├── find_duplicate_fieldsets.rs │ ├── make_block.rs │ ├── make_field_array.rs │ ├── make_register_array.rs │ ├── merge_blocks.rs │ ├── merge_enums.rs │ ├── merge_fieldsets.rs │ ├── mod.rs │ ├── modify_byte_offset.rs │ ├── rename.rs │ ├── rename_fields.rs │ ├── rename_registers.rs │ └── sort.rs │ └── util.rs ├── script ├── check_latest.sh └── group_value.py ├── src ├── blocks │ └── hpm6750 │ │ ├── acmp.rs │ │ ├── adc.rs │ │ ├── adc3.rs │ │ ├── bcfg.rs │ │ ├── bgpr.rs │ │ ├── bkey.rs │ │ ├── bmon.rs │ │ ├── bpor.rs │ │ ├── bsec.rs │ │ ├── butn.rs │ │ ├── cam.rs │ │ ├── can.rs │ │ ├── conctl.rs │ │ ├── dao.rs │ │ ├── dma.rs │ │ ├── dmamux.rs │ │ ├── dram.rs │ │ ├── enet.rs │ │ ├── gpio.rs │ │ ├── gpiom.rs │ │ ├── gptmr.rs │ │ ├── hall.rs │ │ ├── hdma.rs │ │ ├── i2c.rs │ │ ├── i2s.rs │ │ ├── ioc.rs │ │ ├── jpeg.rs │ │ ├── keym.rs │ │ ├── lcdc.rs │ │ ├── mbx0a.rs │ │ ├── mchtmr.rs │ │ ├── mono.rs │ │ ├── ntmr.rs │ │ ├── otp.rs │ │ ├── otpshw.rs │ │ ├── pcfg.rs │ │ ├── pdm.rs │ │ ├── pdma.rs │ │ ├── pgpr.rs │ │ ├── plic.rs │ │ ├── plicsw.rs │ │ ├── pllctl.rs │ │ ├── pmon.rs │ │ ├── ppor.rs │ │ ├── psec.rs │ │ ├── ptpc.rs │ │ ├── pwm.rs │ │ ├── qei.rs │ │ ├── rng.rs │ │ ├── rtc.rs │ │ ├── rtcshw.rs │ │ ├── sdp.rs │ │ ├── sdxc.rs │ │ ├── spi.rs │ │ ├── synt.rs │ │ ├── sysctl.rs │ │ ├── tamp.rs │ │ ├── trgm.rs │ │ ├── uart.rs │ │ ├── usb.rs │ │ ├── vad.rs │ │ └── wdg.rs ├── hpm6750.rs ├── hpm6750.x └── lib.rs └── svd ├── HPM6360.svd.ignored └── HPM6750.svd /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [ main ] 4 | pull_request: 5 | 6 | name: Continuous integration 7 | 8 | jobs: 9 | ci-linux: 10 | runs-on: ubuntu-latest 11 | continue-on-error: ${{ matrix.experimental || false }} 12 | strategy: 13 | matrix: 14 | # All generated code should be running on stable now, MSRV is 1.62.0 15 | rust: [1.62.0, stable, nightly] 16 | include: 17 | - rust: nightly 18 | experimental: true 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | - uses: actions-rs/toolchain@v1 23 | with: 24 | profile: minimal 25 | toolchain: ${{ matrix.rust }} 26 | target: riscv32imac-unknown-none-elf 27 | components: rustfmt 28 | override: true 29 | - name: Install Python 30 | uses: actions/setup-python@v4 31 | with: 32 | python-version: "3.10" 33 | - name: Install svdtools for patch svds 34 | run: pip install svdtools 35 | - name: Run make and check under ${{ matrix.rust }} 36 | run: make TARGET=riscv32imac-unknown-none-elf 37 | - name: Check if the commit is latest 38 | run: bash script/check_latest.sh 39 | - name: Collect cache for rustup and Cargo 40 | if: always() 41 | uses: actions/cache@v3 42 | with: 43 | path: | 44 | ~/.rustup/ 45 | ~/.cargo/bin/ 46 | ~/.cargo/registry/index/ 47 | ~/.cargo/registry/cache/ 48 | ~/.cargo/git/db/ 49 | target/ 50 | key: ${{ runner.os }}-${{ env.RUSTC_HASH }}-${{ hashFiles('**/Cargo.lock') }} 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | *.patched 3 | *.lock 4 | .vscode/ 5 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hpm-ral" 3 | authors = ["tfx2001 "] 4 | description = "Register access layer for all HPMicro microcontrollers" 5 | repository = "https://github.com/hpm-rs/hpm-ral" 6 | readme = "README.md" 7 | keywords = ["hpmicro", "embedded", "no_std"] 8 | categories = ["embedded", "no-std"] 9 | license = "MIT" 10 | edition = "2021" 11 | include = ["src/*", "build.rs", "Cargo.toml", "doc.md"] 12 | version = "0.0.1" 13 | 14 | [dependencies] 15 | ral-registers = "0.1" 16 | plic = { version = "0.0.2", features = ["primitive-id"] } 17 | 18 | [lib] 19 | bench = false 20 | test = false 21 | 22 | [features] 23 | rt = [] 24 | hpm6750 = [] 25 | 26 | [workspace] 27 | members = ["raltool"] 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 tfx2001 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(TARGET),) 2 | TARGET := riscv32imac-unknown-none-elf 3 | endif 4 | 5 | .PHONY: all patch 6 | 7 | all: patch 8 | cargo run --package raltool -- generate svd/HPM6750.svd.patched --transform raltool-cfg.yml 9 | cargo fmt 10 | cargo check --features hpm6750 --target ${TARGET} 11 | 12 | patch: devices/hpm6750.yaml 13 | svd patch devices/hpm6750.yaml 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hpm-ral 2 | 3 | [![Crate.io](https://img.shields.io/crates/v/hpm-ral)](https://crates.io/crates/hpm-ral) 4 | [![Crate.io](https://img.shields.io/crates/d/hpm-ral)](https://crates.io/crates/hpm-ral) 5 | [![Stars](https://img.shields.io/github/stars/hpm-rs/hpm-ral)](https://github.com/hpm-rs/hpm-ral) 6 | [![LICENSE](https://img.shields.io/github/license/hpm-rs/hpm-ral)](https://github.com/hpm-rs/hpm-ral/blob/main/LICENSE) 7 | [![Build](https://github.com/hpm-rs/hpm-ral/actions/workflows/ci.yaml/badge.svg)](https://github.com/hpm-rs/hpm-ral/actions/workflows/ci.yaml) 8 | 9 | Register Access Layer for HPMicro MCUs. 10 | 11 | ## Use 12 | 13 | ```shell 14 | cargo add --git https://github.com/hpm-rs/hpm-ral hpm-ral 15 | ``` 16 | 17 | ## Example 18 | 19 | See [/examples](/examples). 20 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs; 3 | use std::path::PathBuf; 4 | fn main() { 5 | if env::var_os("CARGO_FEATURE_RT").is_some() { 6 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 7 | println!("cargo:rustc-link-search={}", out.display()); 8 | let device_file = if env::var_os("CARGO_FEATURE_HPM6750").is_some() { 9 | "src/hpm6750.x" 10 | } else { 11 | panic!("No device features selected"); 12 | }; 13 | fs::copy(device_file, out.join("device.x")).unwrap(); 14 | println!("cargo:rerun-if-changed={}", device_file); 15 | } 16 | println!("cargo:rerun-if-changed=build.rs"); 17 | } 18 | -------------------------------------------------------------------------------- /devices/common.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | cpu: 3 | name: riscv32imafdc 4 | 5 | "*": 6 | "*": 7 | _delete: 8 | - RESERVED 9 | - RESERVE 10 | - RSV 11 | 12 | _delete: 13 | - PLIC 14 | -------------------------------------------------------------------------------- /devices/hpm6750.yaml: -------------------------------------------------------------------------------- 1 | _svd: ../svd/HPM6750.svd 2 | 3 | _include: 4 | - common.yaml 5 | - peripheral/dma.yaml 6 | - peripheral/dmamux.yaml 7 | - peripheral/gpio.yaml 8 | - peripheral/ioc.yaml 9 | - peripheral/otp.yaml 10 | - peripheral/rtc.yaml 11 | - peripheral/spi.yaml 12 | - peripheral/sysctl.yaml 13 | - peripheral/tmr.yaml 14 | - peripheral/uart.yaml 15 | 16 | # Interrupt vector 17 | GPIO0: 18 | _add: 19 | _interrupts: 20 | Gpio0PortA: 21 | description: GPIO0 port A interrupt 22 | value: 1 23 | Gpio0PortB: 24 | description: GPIO0 port B interrupt 25 | value: 2 26 | Gpio0PortC: 27 | description: GPIO0 port C interrupt 28 | value: 3 29 | Gpio0PortD: 30 | description: GPIO0 port D interrupt 31 | value: 4 32 | Gpio0PortE: 33 | description: GPIO0 port E interrupt 34 | value: 5 35 | Gpio0PortF: 36 | description: GPIO0 port F interrupt 37 | value: 6 38 | Gpio0PortX: 39 | description: GPIO0 port X interrupt 40 | value: 7 41 | Gpio0PortY: 42 | description: GPIO0 port Y interrupt 43 | value: 8 44 | Gpio0PortZ: 45 | description: GPIO0 port Z interrupt 46 | value: 9 47 | GPIO1: 48 | _add: 49 | _interrupts: 50 | Gpio1PortA: 51 | description: GPIO1 port A interrupt 52 | value: 10 53 | Gpio1PortB: 54 | description: GPIO1 port B interrupt 55 | value: 11 56 | Gpio1PortC: 57 | description: GPIO1 port C interrupt 58 | value: 12 59 | Gpio1PortD: 60 | description: GPIO1 port D interrupt 61 | value: 13 62 | Gpio1PortE: 63 | description: GPIO1 port E interrupt 64 | value: 14 65 | Gpio1PortF: 66 | description: GPIO1 port F interrupt 67 | value: 15 68 | Gpio1PortX: 69 | description: GPIO1 port X interrupt 70 | value: 16 71 | Gpio1PortY: 72 | description: GPIO1 port Y interrupt 73 | value: 17 74 | Gpio1PortZ: 75 | description: GPIO1 port Z interrupt 76 | value: 18 77 | 78 | _delete: 79 | - "MBX*" 80 | - "*WDG*" 81 | -------------------------------------------------------------------------------- /devices/peripheral/dma.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | HDMA: 3 | name: HDMA0 4 | XDMA: 5 | name: XDMA1 6 | 7 | HDMA0: 8 | "CHCTRL_CH?_CTRL": 9 | ENABLE: 10 | Disable: [0, "Disable"] 11 | Enable: [1, "Enable"] 12 | INTTCMASK: 13 | Enable: [0, "Allow the terminal count interrupt to be triggered"] 14 | Disable: [1, "Disable the terminal count interrupt"] 15 | INTERRMASK: 16 | Enable: [0, "Allow the error interrupt to be triggered"] 17 | Disable: [1, "Disable the error interrupt interrupt"] 18 | INTABTMASK: 19 | Enable: [0, "Allow the abort interrupt to be triggered"] 20 | Disable: [1, "Disable the abort interrupt interrupt"] 21 | DSTADDRCTRL,SRCADDRCTRL: 22 | Increment: [0, "Increment address"] 23 | Decrement: [1, "Decrement address"] 24 | Fixed: [2, "Fixed address"] 25 | DSTMODE,SRCMODE: 26 | Normal: [0, "Normal mode"] 27 | Handshake: [1, "Handshake mode"] 28 | DSTWIDTH,SRCWIDTH: 29 | Byte: [0, "Byte transfer"] 30 | HalfWord: [1, "Half-word transfer"] 31 | Word: [2, "Word transfer"] 32 | DoubleWord: [3, "Double word transfer"] 33 | QuadWord: [4, "Quad word transfer"] 34 | EightWord: [5, "Eight word transfer"] 35 | SRCBURSTSIZE: 36 | Transfer1: [0, "1 transfer"] 37 | Transfers2: [1, "2 transfers"] 38 | Transfers4: [2, "4 transfers"] 39 | Transfers8: [3, "8 transfers"] 40 | Transfers16: [4, "16 transfers"] 41 | Transfers32: [5, "32 transfers"] 42 | Transfers64: [6, "64 transfers"] 43 | Transfers128: [7, "128 transfers"] 44 | Transfers256: [8, "256 transfers"] 45 | Transfers512: [9, "512 transfers"] 46 | Transfers1024: [10, "1024 transfers"] 47 | PRIORITY: 48 | Lower: [0, "Lower priority"] 49 | Higher: [1, "Higher priority"] 50 | -------------------------------------------------------------------------------- /devices/peripheral/dmamux.yaml: -------------------------------------------------------------------------------- 1 | DMAMUX: 2 | "MUXCFG_?DMA_MUX?": 3 | ENABLE: 4 | Disable: [0, "DMA Mux channel is disabled"] 5 | Enable: [1, "DMA Mux channel is enabled"] 6 | -------------------------------------------------------------------------------- /devices/peripheral/gpio.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | FGPIO: 3 | name: FGPIO10 4 | PGPIO: 5 | name: PGPIO11 6 | BGPIO: 7 | name: BGPIO12 8 | 9 | _rebase: 10 | GPIO0: FGPIO10 # rebase after modify, so use the new name 11 | -------------------------------------------------------------------------------- /devices/peripheral/ioc.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | IOC: 3 | name: IOC0 4 | PIOC: 5 | name: PIOC10 # Hack for raltool 6 | BIOC: 7 | name: BIOC11 # Hack for raltool 8 | 9 | "IOC?,?IOC??": 10 | "*FUNC_CTL": 11 | LOOP_BACK: 12 | Disable: [0, "Output look back disable"] 13 | Enable: [1, "Output look back enable"] 14 | ANALOG: 15 | Disable: [0, "Analog input disable"] 16 | Enable: [1, "Analog input enable"] 17 | "*PAD_CTL": 18 | OD: 19 | Disable: [0, "Open drain disable"] 20 | Enable: [1, "Open drain enable"] 21 | MS: 22 | Volt3V3: [0, "3.3V"] 23 | Volt1V8: [1, "1.8V"] 24 | SMT: 25 | Disable: [0, "Schmitt trigger disable"] 26 | Enable: [1, "Schmitt trigger enable"] 27 | PS: 28 | Down: [0, "Pull down selected"] 29 | Up: [1, "Pull up selected"] 30 | PE: 31 | Disable: [0, "Pull disable"] 32 | Enable: [1, "Pull enable"] 33 | -------------------------------------------------------------------------------- /devices/peripheral/otp.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | OTP: 3 | name: OTP0 4 | OTPSHW: 5 | name: OTPSHW1 6 | 7 | _rebase: 8 | OTP0: OTPSHW1 9 | -------------------------------------------------------------------------------- /devices/peripheral/rtc.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | RTC: 3 | name: RTC0 4 | RTCSHW: 5 | name: RTCSHW1 6 | 7 | _rebase: 8 | RTC0: RTCSHW1 9 | -------------------------------------------------------------------------------- /devices/peripheral/spi.yaml: -------------------------------------------------------------------------------- 1 | SPI0: 2 | TRANSFMT: 3 | CPHA: 4 | Odd: [0, "Sampling data at odd SCLK edges"] 5 | Even: [1, "Sampling data at even SCLK edges"] 6 | CPOL: 7 | Low: [0, "SCLK is low in the idle states"] 8 | High: [1, "SCLK is high in the idle states"] 9 | SLVMODE: 10 | Master: [0, "Master mode"] 11 | Slave: [1, "Slave mode"] 12 | LSB: 13 | MSB: [0, "Most significant bit first"] 14 | LSB: [1, "Least significant bit first"] 15 | MOSIBIDIR: 16 | UniDirectional: [0, "MOSI is uni-directional signal in regular mode"] 17 | BiDirectional: [1, "MOSI is bi-directional signal in regular mode"] 18 | DATAMERGE: 19 | Disable: [0, "Disable data merge"] 20 | Enable: [1, "Enable data merge"] 21 | ADDRLEN: 22 | Byte1: [0, "1 byte"] 23 | Bytes2: [1, "2 byte"] 24 | Bytes3: [2, "3 byte"] 25 | Bytes4: [3, "4 byte"] 26 | DIRECTIO: 27 | DIRECTIOEN: 28 | Disable: [0, "Disable Direct IO"] 29 | Enable: [1, "Enable Direct IO"] 30 | TRANSCTRL: 31 | TOKENVALUE: 32 | Token0x00: [0, "Token value is 0x00"] 33 | Token0x69: [1, "Token value is 0x69"] 34 | TOKENEN: 35 | Disable: [0, "Disable the one-byte special token"] 36 | Enable: [1, "Enable the one-byte special token"] 37 | DUALQUAD: 38 | Single: [0, "Regular(single) mode"] 39 | Dual: [1, "Dual I/O mode"] 40 | Quad: [3, "Quad I/O mode"] 41 | TRANSMODE: 42 | ReadWhileWrite: [0, "Write and read at the same time"] 43 | WriteOnly: [1, "Write only"] 44 | ReadOnly: [2, "Read only"] 45 | ReadAfterWrite: [3, "Write, Read"] 46 | WriteAfterRead: [4, "Read, Write"] 47 | WriteDummyRead: [5, "Write, Dummy, Read"] 48 | ReadDummyWrite: [6, "Read, Dummy, Write"] 49 | NoneData: [7, "None data (must enable CmdEn or AddrEn in master mode)"] 50 | DummyWrite: [8, "Dummy, Write"] 51 | DummyRead: [9, "Dummy, Read"] 52 | ADDRFMT: 53 | Single: [0, "Address phase is the regular (single) mode"] 54 | DataPhase: [1, "The format of the address phase is the same as the data phase (DualQuad)"] 55 | ADDREN: 56 | Disable: [0, "Disable the address phase"] 57 | Enable: [1, "Enable the address phase"] 58 | CMDEN: 59 | Disable: [0, "Disable the command phase"] 60 | Enable: [1, "Enable the command phase"] 61 | SLVDATAONLY: 62 | Disable: [0, "Disable the data-only mode"] 63 | Enable: [1, "Enable the data-only mode"] 64 | CTRL: 65 | SPIRST: 66 | Reset: [1, "Reset SPI controller. It is automatically cleared to 0 afer the reset operation completes."] 67 | RXFIFORST: 68 | Reset: [1, "Reset receive FIFO. It is automatically cleared to 0 afer the reset operation completes."] 69 | TXFIFORST: 70 | Reset: [1, "Reset transmit FIFO. It is automatically cleared to 0 afer the reset operation completes."] 71 | RXDMAEN: 72 | Disable: [0, "Disable RX DMA"] 73 | Enable: [1, "Enable RX DMA"] 74 | TXDMAEN: 75 | Disable: [0, "Disable TX DMA"] 76 | Enable: [1, "Enable TX DMA"] 77 | -------------------------------------------------------------------------------- /devices/peripheral/sysctl.yaml: -------------------------------------------------------------------------------- 1 | SYSCTL: 2 | GROUP0_0_VALUE: 3 | _delete: 4 | - LINK 5 | _add: 6 | AHB_APB: 7 | bitOffset: 0 8 | bitWidth: 1 9 | AXI: 10 | bitOffset: 1 11 | bitWidth: 1 12 | CONN: 13 | bitOffset: 2 14 | bitWidth: 1 15 | VIS: 16 | bitOffset: 3 17 | bitWidth: 1 18 | DRAM: 19 | bitOffset: 4 20 | bitWidth: 1 21 | ROM: 22 | bitOffset: 5 23 | bitWidth: 1 24 | ILM_DLM0: 25 | bitOffset: 6 26 | bitWidth: 1 27 | ILM_DLM1: 28 | bitOffset: 7 29 | bitWidth: 1 30 | MCHTMR0: 31 | bitOffset: 8 32 | bitWidth: 1 33 | MCHTMR1: 34 | bitOffset: 9 35 | bitWidth: 1 36 | AXI_SRAMO: 37 | bitOffset: 10 38 | bitWidth: 1 39 | AXI_SRAM1: 40 | bitOffset: 11 41 | bitWidth: 1 42 | XPI0: 43 | bitOffset: 12 44 | bitWidth: 1 45 | XPI1: 46 | bitOffset: 13 47 | bitWidth: 1 48 | SDP: 49 | bitOffset: 14 50 | bitWidth: 1 51 | RNG: 52 | bitOffset: 15 53 | bitWidth: 1 54 | KEYM: 55 | bitOffset: 16 56 | bitWidth: 1 57 | HDMA: 58 | bitOffset: 17 59 | bitWidth: 1 60 | XDMA: 61 | bitOffset: 18 62 | bitWidth: 1 63 | GPIO0_1: 64 | bitOffset: 19 65 | bitWidth: 1 66 | MBX0: 67 | bitOffset: 20 68 | bitWidth: 1 69 | MBX1: 70 | bitOffset: 21 71 | bitWidth: 1 72 | WDG0: 73 | bitOffset: 22 74 | bitWidth: 1 75 | WDG1: 76 | bitOffset: 23 77 | bitWidth: 1 78 | WDG2: 79 | bitOffset: 24 80 | bitWidth: 1 81 | WDG3: 82 | bitOffset: 25 83 | bitWidth: 1 84 | GPTMRO: 85 | bitOffset: 26 86 | bitWidth: 1 87 | GPTMR1: 88 | bitOffset: 27 89 | bitWidth: 1 90 | GPTMR2: 91 | bitOffset: 28 92 | bitWidth: 1 93 | GPTMR3: 94 | bitOffset: 29 95 | bitWidth: 1 96 | GPTMR4: 97 | bitOffset: 30 98 | bitWidth: 1 99 | GPTMR5: 100 | bitOffset: 31 101 | bitWidth: 1 102 | GROUP0_1_VALUE: 103 | _delete: 104 | - LINK 105 | _add: 106 | GPTMR6: 107 | bitOffset: 0 108 | bitWidth: 1 109 | GPTMR7: 110 | bitOffset: 1 111 | bitWidth: 1 112 | UARTO: 113 | bitOffset: 2 114 | bitWidth: 1 115 | UART1: 116 | bitOffset: 3 117 | bitWidth: 1 118 | UART2: 119 | bitOffset: 4 120 | bitWidth: 1 121 | UART3: 122 | bitOffset: 5 123 | bitWidth: 1 124 | UART4: 125 | bitOffset: 6 126 | bitWidth: 1 127 | UART5: 128 | bitOffset: 7 129 | bitWidth: 1 130 | UART6: 131 | bitOffset: 8 132 | bitWidth: 1 133 | UART7: 134 | bitOffset: 9 135 | bitWidth: 1 136 | UART8: 137 | bitOffset: 10 138 | bitWidth: 1 139 | UART9: 140 | bitOffset: 11 141 | bitWidth: 1 142 | UART10: 143 | bitOffset: 12 144 | bitWidth: 1 145 | UART11: 146 | bitOffset: 13 147 | bitWidth: 1 148 | UART12: 149 | bitOffset: 14 150 | bitWidth: 1 151 | UART13: 152 | bitOffset: 15 153 | bitWidth: 1 154 | UART14: 155 | bitOffset: 16 156 | bitWidth: 1 157 | UART15: 158 | bitOffset: 17 159 | bitWidth: 1 160 | I2C0: 161 | bitOffset: 18 162 | bitWidth: 1 163 | I2C1: 164 | bitOffset: 19 165 | bitWidth: 1 166 | l2C2: 167 | bitOffset: 20 168 | bitWidth: 1 169 | I2C3: 170 | bitOffset: 21 171 | bitWidth: 1 172 | SPI0: 173 | bitOffset: 22 174 | bitWidth: 1 175 | SPI1: 176 | bitOffset: 23 177 | bitWidth: 1 178 | SPI2: 179 | bitOffset: 24 180 | bitWidth: 1 181 | SPI3: 182 | bitOffset: 25 183 | bitWidth: 1 184 | CANO: 185 | bitOffset: 26 186 | bitWidth: 1 187 | CAN1: 188 | bitOffset: 27 189 | bitWidth: 1 190 | CAN2: 191 | bitOffset: 28 192 | bitWidth: 1 193 | CAN3: 194 | bitOffset: 29 195 | bitWidth: 1 196 | PTPC: 197 | bitOffset: 30 198 | bitWidth: 1 199 | ADC0: 200 | bitOffset: 31 201 | bitWidth: 1 202 | GROUP0_2_VALUE: 203 | _delete: 204 | - LINK 205 | _add: 206 | ADC1: 207 | bitOffset: 0 208 | bitWidth: 1 209 | ADC2: 210 | bitOffset: 1 211 | bitWidth: 1 212 | ADC3: 213 | bitOffset: 2 214 | bitWidth: 1 215 | ACMP: 216 | bitOffset: 3 217 | bitWidth: 1 218 | I2S0: 219 | bitOffset: 4 220 | bitWidth: 1 221 | I2S1: 222 | bitOffset: 5 223 | bitWidth: 1 224 | I2S2: 225 | bitOffset: 6 226 | bitWidth: 1 227 | I2S3: 228 | bitOffset: 7 229 | bitWidth: 1 230 | PDM: 231 | bitOffset: 8 232 | bitWidth: 1 233 | DAO: 234 | bitOffset: 9 235 | bitWidth: 1 236 | SYNT: 237 | bitOffset: 10 238 | bitWidth: 1 239 | MOTO: 240 | bitOffset: 11 241 | bitWidth: 1 242 | MOT1: 243 | bitOffset: 12 244 | bitWidth: 1 245 | MOT2: 246 | bitOffset: 13 247 | bitWidth: 1 248 | MOT3: 249 | bitOffset: 14 250 | bitWidth: 1 251 | LCDC: 252 | bitOffset: 15 253 | bitWidth: 1 254 | CAMO: 255 | bitOffset: 16 256 | bitWidth: 1 257 | CAM1: 258 | bitOffset: 17 259 | bitWidth: 1 260 | JPEG: 261 | bitOffset: 18 262 | bitWidth: 1 263 | PDMA: 264 | bitOffset: 19 265 | bitWidth: 1 266 | ENETO: 267 | bitOffset: 20 268 | bitWidth: 1 269 | ENET1: 270 | bitOffset: 21 271 | bitWidth: 1 272 | NTMRO: 273 | bitOffset: 22 274 | bitWidth: 1 275 | NTMR1: 276 | bitOffset: 23 277 | bitWidth: 1 278 | SDXC0: 279 | bitOffset: 24 280 | bitWidth: 1 281 | SDXC1: 282 | bitOffset: 25 283 | bitWidth: 1 284 | USBO: 285 | bitOffset: 26 286 | bitWidth: 1 287 | USB1: 288 | bitOffset: 27 289 | bitWidth: 1 290 | 291 | "GROUP?_?_VALUE": 292 | "*": 293 | Unlinked: [0, "Unlink from group"] 294 | Linked: [1, "Link to group"] 295 | -------------------------------------------------------------------------------- /devices/peripheral/tmr.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | PTMR: 3 | name: PTMR2 # Hack for raltool limitation 4 | 5 | _rebase: 6 | GPTMR0: NTMR0 7 | -------------------------------------------------------------------------------- /devices/peripheral/uart.yaml: -------------------------------------------------------------------------------- 1 | _modify: 2 | PUART: 3 | name: PUART20 # Hack for raltool limitation 4 | 5 | UART0: 6 | CFG: 7 | FIFOSIZE: 8 | Bytes16: [0, "16-byte FIFO"] 9 | Bytes32: [1, "32-byte FIFO"] 10 | Bytes64: [2, "64-byte FIFO"] 11 | Bytes128: [3, "128-byte FIFO"] 12 | IER: 13 | "*": 14 | Disable: [0, "Interrupt disable"] 15 | Enable: [1, "Interrupt enable"] 16 | LCR: 17 | SPS: 18 | Free: [0, "Disable the sticky bit parity"] 19 | Sticky: [1, "Parity bit is constant 0 or 1, depending on bit4 (EPS)"] 20 | EPS: 21 | Odd: [0, "Old parity"] 22 | Even: [1, "Even parity (an even number of logic-1 is in the data and parity bits)"] 23 | PEN: 24 | Disable: [0, "Disable parity check"] 25 | Enable: [1, "Enable parity check"] 26 | STB: 27 | Stop1Bit: [0, "1 bit"] 28 | Stop1p5Bit: [1, "The number of STOP bit is based on the WLS setting. When WLS = 0, STOP bit is 1.5 bits. When WLS = 1, 2, 3, STOP bit is 2 bits"] 29 | WLS: 30 | Bits5: [0, "5 bits"] 31 | Bits6: [1, "6 bits"] 32 | Bits7: [2, "7 bits"] 33 | Bits8: [3, "8 bits"] 34 | -------------------------------------------------------------------------------- /raltool-cfg.yml: -------------------------------------------------------------------------------- 1 | transforms: 2 | - Rename: 3 | from: Hpm6750 4 | to: hpm6750 5 | - Rename: 6 | from: gpio::Gpio0 7 | to: gpio::Gpio 8 | - Rename: 9 | from: gptmr::Gptmr0 10 | to: gptmr::Gptmr 11 | - Rename: 12 | from: (N|P)TMR(\d) 13 | to: ${1}TMR1${2} 14 | - Rename: 15 | from: otp::Otp0 16 | to: otp::Otp 17 | - Rename: 18 | from: rtc::Rtc0 19 | to: rtc::Rtc 20 | - Rename: 21 | from: uart::Uart0 22 | to: uart::uart 23 | - Rename: 24 | from: hdma::Hdma0 25 | to: dma::Dma 26 | -------------------------------------------------------------------------------- /raltool/.gitignore: -------------------------------------------------------------------------------- 1 | [._]*.sw[a-p] 2 | *.org 3 | *.rs.bk 4 | target -------------------------------------------------------------------------------- /raltool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "raltool" 3 | license = "MIT OR Apache-2.0" 4 | version = "0.1.0" 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | clap = { version = "3.1.6", features = ["derive"] } 10 | env_logger = "0.9.0" 11 | inflections = "1.1" 12 | log = { version = "~0.4", features = ["std"] } 13 | quote = "1.0" 14 | proc-macro2 = "1.0" 15 | anyhow = "1.0.19" 16 | rayon = "1.5" 17 | regex = "1.4.3" 18 | serde = { version = "1.0.123", features = [ "derive" ]} 19 | serde_yaml = "0.8.15" 20 | svd-parser = { version = "0.10.2", features = ["derive-from"] } 21 | -------------------------------------------------------------------------------- /raltool/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /raltool/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Jorge Aparicio 2 | Copyright (c) 2021 Embassy project contributors 3 | Copyright (c) 2022 imxrt-rs project contributors 4 | 5 | Permission is hereby granted, free of charge, to any 6 | person obtaining a copy of this software and associated 7 | documentation files (the "Software"), to deal in the 8 | Software without restriction, including without 9 | limitation the rights to use, copy, modify, merge, 10 | publish, distribute, sublicense, and/or sell copies of 11 | the Software, and to permit persons to whom the Software 12 | is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice 16 | shall be included in all copies or substantial portions 17 | of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 20 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 21 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 22 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 23 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 26 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 | DEALINGS IN THE SOFTWARE. 28 | -------------------------------------------------------------------------------- /raltool/README.md: -------------------------------------------------------------------------------- 1 | raltool 2 | ======= 3 | 4 | `raltool` is a fork of [`chiptool`][], which is itself a fork of [`svd2rust`][]. 5 | The register access layer (RAL) generated by `raltool` strives to compile faster 6 | than anything generated by `chiptool` or `svd2rust`, supporting the needs of 7 | Rust projects that work with very large SVDs. 8 | 9 | `raltool` is an experiment to support the [`imxrt-ral`][] project. The 10 | tool's interface and features do not vary much from [`chiptool`][], so see 11 | that project's documentation for more information. However, the 12 | `raltool`-generated code is different than both `chiptool`- and 13 | `svd2rust`-generated code. For more information on the `raltool`-generated API, 14 | see the [`imxrt-ral`][] project. 15 | 16 | [`chiptool`]: https://github.com/embassy-rs/chiptool 17 | [`svd2rust`]: https://github.com/rust-embedded/svd2rust 18 | [`imxrt-ral`]: https://github.com/imxrt-rs/imxrt-ral 19 | 20 | Benchmarks 21 | ---------- 22 | 23 | `svd2rust`, `chiptool`, and `raltool` ingested a patched SVD for an i.MX RT 1062 24 | MCU and generated a Rust crate. The table below shows the `cargo build` build 25 | times for each crate. Each build succeeded without warnings. 26 | 27 | | Codegen tool | Build time | 28 | |:------------------------|:-----------| 29 | | `svd2rust` | 1m 30s | 30 | | `chiptool` 1 | 47s | 31 | | **`raltool`** | **9s** | 32 | 33 | 1 Lightly modified the generated crate to suppress warnings. 34 | 35 | `svd2rust` version 0.24.1. `chiptool` built at revision `73b33d9`. rustc 1.63.0. 36 | 37 | `chiptool` enhancements 38 | ----------------------- 39 | 40 | ┌───────┐ IR_A ┌───────────┐ IR_A' ┏━━━━━━━━━┓ 41 | SVD_A -> │ Parse │ ---> │ Transform │ ----> ┃ ┃ 42 | └───────┘ └───────────┘ ┃ ┃ 43 | ┌───────┐ IR_B ┌───────────┐ IR_B' ┃ ┃ IR ┌─────────┐ 44 | SVD_B -> │ Parse │ ---> │ Transform │ ----> ┃ Combine ┃ -> │ Codegen │ -> RAL Crate 45 | └───────┘ └───────────┘ ┃ ┃ └─────────┘ 46 | ┌───────┐ IR_C ┌───────────┐ IR_C' ┃ ┃ 47 | SVD_C -> │ Parse │ ---> │ Transform │ ----> ┃ ┃ 48 | └───────┘ └───────────┘ ┗━━━━━━━━━┛ 49 | 50 | `raltool` changes more than just the generated code. `raltool` accepts multiple 51 | SVD files, and introduces a new "combine" phase to the process. The 52 | combine phase consolidates blocks, fieldsets, and enums *across* devices. The 53 | combine pass runs after the transform pass(es), consuming one or more `chiptool` 54 | intermediate representations (IR) to create a new IR. This single, combined IR 55 | represents all the peripherals, blocks, fieldsets, and enums for all devices. 56 | The codegen phase generates modules to represent that combined IR. 57 | 58 | In practice, the combine phase can automatically reduce `N` UART peripherals 59 | from `N` SVDs down to 1 UART peripheral. This works even if the input SVDs have 60 | different names for blocks, fieldsets, or enums. 61 | 62 | The combine phase is conservative, and it won't combine device elements if 63 | they don't seem equivalent. If you know that blocks, fieldsets, or enums 64 | should be equivalent, you can use transforms to coax the IR into a combine-able 65 | form, or you can patch your SVD(s). 66 | 67 | Limitations 68 | ----------- 69 | 70 | Aliased registers are not supported. To control codegen, use a transform to 71 | remove aliased registers / fields. The codegen phase will select an arbitrary 72 | register alias for codegen, though it prefers an alias that's both 73 | read-write. 74 | 75 | Aliased cluster arrays are also not supported. The recommendation is to either 76 | remove the peripherals, or describe the peripherals differently, using 77 | `chiptool` YAML. Surprisingly, aliased cluster arrays appear in practice; see 78 | the i.MX RT 11xx SVDs. 79 | 80 | The transform phase(s) run before the combine phase, not after. It's 81 | trivial to introduce a transform phase on the combined IR, but there 82 | hasn't been a need for this. 83 | 84 | `raltool` simply generates a tree of Rust source files. It does not generate a 85 | `Cargo.toml` to define the package. You're responsible for defining this 86 | manifest, adding all dependencies, and defining the features expected in the 87 | generated code. `cargo init` and `cargo add` can help with this: 88 | 89 | ``` bash 90 | cd path/to/output 91 | 92 | cargo init 93 | cargo add cortex-m ral-registers 94 | 95 | # Edit Cargo.toml, add feature flags for devices. 96 | # See lib.rs for expected features. 97 | ``` 98 | 99 | License 100 | ------- 101 | 102 | Licensed under either of 103 | 104 | - Apache License, Version 2.0 ([LICENSE-APACHE][] or 105 | http://www.apache.org/licenses/LICENSE-2.0) 106 | - MIT license ([LICENSE-MIT][] or http://opensource.org/licenses/MIT) 107 | 108 | at your option. 109 | 110 | [LICENSE-APACHE]: LICENSE-APACHE 111 | [LICENSE-MIT]: LICENSE-MIT 112 | 113 | **Contribution** 114 | 115 | Unless you explicitly state otherwise, any contribution intentionally submitted 116 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 117 | dual licensed as above, without any additional terms or conditions. 118 | -------------------------------------------------------------------------------- /raltool/src/generate/fieldset.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use proc_macro2::TokenStream; 3 | use proc_macro2::{Ident, Span}; 4 | use quote::quote; 5 | 6 | use crate::ir::*; 7 | use crate::util; 8 | 9 | pub fn render(ir: &IR, fs: &FieldSet) -> Result { 10 | let span = Span::call_site(); 11 | let mut items = TokenStream::new(); 12 | 13 | let ty = match fs.bit_size { 14 | BitSize(1..=8) => quote!(u8), 15 | BitSize(9..=16) => quote!(u16), 16 | BitSize(17..=32) => quote!(u32), 17 | BitSize(33..=64) => quote!(u64), 18 | BitSize(invalid) => anyhow::bail!("Invalid bit_size {invalid}"), 19 | }; 20 | 21 | for f in &fs.fields { 22 | anyhow::ensure!( 23 | f.array.is_none(), 24 | "Field {} is an array, and that's not supported", 25 | f.name 26 | ); 27 | 28 | let name = Ident::new(&f.name, span); 29 | let bit_offset = proc_macro2::Literal::u32_unsuffixed(f.bit_offset); 30 | let mask = util::hex(1u64.wrapping_shl(f.bit_size.0).wrapping_sub(1)); 31 | let doc = util::doc(&f.description); 32 | 33 | let enum_tokenize = |enm: &Option| -> TokenStream { 34 | enm.as_ref() 35 | .and_then(|path| ir.enums.get(path)) 36 | .map(|enm| { 37 | let mut items = TokenStream::new(); 38 | for e in &enm.variants { 39 | let name = Ident::new(&e.name, span); 40 | let value = util::hex(e.value); 41 | let doc = util::doc(&e.description); 42 | items.extend(quote!( 43 | #doc 44 | pub const #name: #ty = #value; 45 | )); 46 | } 47 | items 48 | }) 49 | .unwrap_or_else(TokenStream::new) 50 | }; 51 | 52 | let reads = enum_tokenize(&f.enum_read); 53 | let writes = enum_tokenize(&f.enum_write); 54 | let reads_writes = enum_tokenize(&f.enum_readwrite); 55 | 56 | items.extend(quote! { 57 | #doc 58 | pub mod #name { 59 | pub const offset: #ty = #bit_offset; 60 | pub const mask: #ty = #mask << offset; 61 | pub mod R { #reads } 62 | pub mod W { #writes } 63 | pub mod RW { #reads_writes } 64 | } 65 | }); 66 | } 67 | 68 | Ok(quote! { #items }) 69 | } 70 | -------------------------------------------------------------------------------- /raltool/src/ir.rs: -------------------------------------------------------------------------------- 1 | use de::MapAccess; 2 | use serde::{de, de::Visitor, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; 3 | use std::collections::{BTreeMap, HashMap}; 4 | use std::fmt; 5 | 6 | #[derive(Clone, Debug, Eq, PartialEq)] 7 | pub struct IR { 8 | pub devices: HashMap, 9 | pub blocks: HashMap, 10 | pub fieldsets: HashMap, 11 | pub enums: HashMap, 12 | } 13 | 14 | impl IR { 15 | pub fn new() -> Self { 16 | Self { 17 | devices: HashMap::new(), 18 | blocks: HashMap::new(), 19 | fieldsets: HashMap::new(), 20 | enums: HashMap::new(), 21 | } 22 | } 23 | 24 | pub fn merge(&mut self, other: IR) { 25 | self.devices.extend(other.devices); 26 | self.blocks.extend(other.blocks); 27 | self.fieldsets.extend(other.fieldsets); 28 | self.enums.extend(other.enums); 29 | } 30 | } 31 | 32 | impl Default for IR { 33 | fn default() -> Self { 34 | Self::new() 35 | } 36 | } 37 | 38 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 39 | pub struct Cpu { 40 | pub name: String, 41 | pub nvic_priority_bits: u32, 42 | } 43 | 44 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 45 | pub struct Device { 46 | pub peripherals: Vec, 47 | pub interrupts: Vec, 48 | #[serde(default, skip_serializing_if = "Option::is_none")] 49 | pub cpu: Option, 50 | } 51 | 52 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 53 | pub struct Peripheral { 54 | pub name: String, 55 | #[serde(default, skip_serializing_if = "Option::is_none")] 56 | pub description: Option, 57 | pub base_address: u64, 58 | #[serde(default, skip_serializing_if = "Option::is_none")] 59 | pub array: Option, 60 | 61 | #[serde(default, skip_serializing_if = "Option::is_none")] 62 | pub block: Option, 63 | 64 | #[serde( 65 | default, 66 | skip_serializing_if = "HashMap::is_empty", 67 | serialize_with = "ordered_map" 68 | )] 69 | pub interrupts: HashMap, 70 | } 71 | 72 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 73 | pub struct Interrupt { 74 | pub name: String, 75 | #[serde(default, skip_serializing_if = "Option::is_none")] 76 | pub description: Option, 77 | pub value: u32, 78 | } 79 | 80 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 81 | pub struct Block { 82 | #[serde(default, skip_serializing_if = "Option::is_none")] 83 | pub extends: Option, 84 | 85 | #[serde(default, skip_serializing_if = "Option::is_none")] 86 | pub description: Option, 87 | pub items: Vec, 88 | } 89 | 90 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 91 | pub struct BlockItem { 92 | pub name: String, 93 | #[serde(default, skip_serializing_if = "Option::is_none")] 94 | pub description: Option, 95 | 96 | #[serde(default, skip_serializing_if = "Option::is_none")] 97 | pub array: Option, 98 | pub byte_offset: u32, 99 | 100 | #[serde(flatten)] 101 | pub inner: BlockItemInner, 102 | } 103 | 104 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 105 | #[serde(untagged)] 106 | pub enum BlockItemInner { 107 | Block(BlockItemBlock), 108 | Register(Register), 109 | } 110 | 111 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 112 | #[serde(untagged)] 113 | pub enum Array { 114 | Regular(RegularArray), 115 | Cursed(CursedArray), 116 | } 117 | 118 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 119 | pub struct RegularArray { 120 | pub len: u32, 121 | pub stride: u32, 122 | } 123 | 124 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 125 | pub struct CursedArray { 126 | pub offsets: Vec, 127 | } 128 | 129 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] 130 | pub struct BitSize(pub u32); 131 | 132 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 133 | pub struct Register { 134 | #[serde(default = "default_readwrite", skip_serializing_if = "is_readwrite")] 135 | pub access: Access, 136 | pub bit_size: BitSize, 137 | #[serde(default, skip_serializing_if = "Option::is_none")] 138 | pub fieldset: Option, 139 | } 140 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 141 | pub struct BlockItemBlock { 142 | pub block: String, 143 | } 144 | 145 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] 146 | pub enum Access { 147 | ReadWrite, 148 | Read, 149 | Write, 150 | } 151 | 152 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 153 | pub struct FieldSet { 154 | #[serde(default, skip_serializing_if = "Option::is_none")] 155 | pub extends: Option, 156 | 157 | #[serde(default, skip_serializing_if = "Option::is_none")] 158 | pub description: Option, 159 | pub bit_size: BitSize, 160 | pub fields: Vec, 161 | } 162 | 163 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 164 | pub struct Field { 165 | pub name: String, 166 | #[serde(default, skip_serializing_if = "Option::is_none")] 167 | pub description: Option, 168 | 169 | pub bit_offset: u32, 170 | pub bit_size: BitSize, 171 | #[serde(default, skip_serializing_if = "Option::is_none")] 172 | pub array: Option, 173 | #[serde(default, skip_serializing_if = "Option::is_none")] 174 | pub enum_read: Option, 175 | #[serde(default, skip_serializing_if = "Option::is_none")] 176 | pub enum_write: Option, 177 | #[serde(default, skip_serializing_if = "Option::is_none", rename = "enum")] 178 | pub enum_readwrite: Option, 179 | } 180 | 181 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 182 | pub struct Enum { 183 | #[serde(default, skip_serializing_if = "Option::is_none")] 184 | pub description: Option, 185 | pub bit_size: BitSize, 186 | pub variants: Vec, 187 | } 188 | 189 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 190 | pub struct EnumVariant { 191 | pub name: String, 192 | #[serde(default, skip_serializing_if = "Option::is_none")] 193 | pub description: Option, 194 | pub value: u64, 195 | } 196 | 197 | fn default_readwrite() -> Access { 198 | Access::ReadWrite 199 | } 200 | fn is_readwrite(x: &Access) -> bool { 201 | *x == Access::ReadWrite 202 | } 203 | 204 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] 205 | enum Kind { 206 | Block, 207 | Fieldset, 208 | Enum, 209 | } 210 | 211 | impl Serialize for IR { 212 | fn serialize(&self, serializer: S) -> Result 213 | where 214 | S: Serializer, 215 | { 216 | // Sort by block/fieldset/enum, then alphabetically. 217 | // This ensures the output's order is deterministic. 218 | // - Easier diffing between yamls 219 | // - No spurious changes when roundtripping 220 | let mut entries = Vec::new(); 221 | for name in self.blocks.keys() { 222 | entries.push((Kind::Block, name)); 223 | } 224 | for name in self.fieldsets.keys() { 225 | entries.push((Kind::Fieldset, name)); 226 | } 227 | for name in self.enums.keys() { 228 | entries.push((Kind::Enum, name)); 229 | } 230 | 231 | entries.sort(); 232 | 233 | let mut map = serializer.serialize_map(Some(entries.len()))?; 234 | for (kind, name) in entries { 235 | match kind { 236 | Kind::Block => { 237 | map.serialize_entry( 238 | &format!("block/{}", name), 239 | self.blocks.get(name).unwrap(), 240 | )?; 241 | } 242 | Kind::Fieldset => { 243 | map.serialize_entry( 244 | &format!("fieldset/{}", name), 245 | self.fieldsets.get(name).unwrap(), 246 | )?; 247 | } 248 | Kind::Enum => { 249 | map.serialize_entry(&format!("enum/{}", name), self.enums.get(name).unwrap())?; 250 | } 251 | } 252 | } 253 | map.end() 254 | } 255 | } 256 | 257 | struct IRVisitor; 258 | 259 | impl<'de> Visitor<'de> for IRVisitor { 260 | type Value = IR; 261 | 262 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 263 | formatter.write_str("an IR") 264 | } 265 | 266 | fn visit_map(self, mut access: M) -> Result 267 | where 268 | M: MapAccess<'de>, 269 | { 270 | let mut ir = IR::new(); 271 | 272 | // While there are entries remaining in the input, add them 273 | // into our map. 274 | while let Some(key) = access.next_key()? { 275 | let key: String = key; 276 | let (kind, name) = key.split_once('/').ok_or_else(|| de::Error::custom("item names must be in form `kind/name`, where kind is `block`, `fieldset` or `enum`"))?; 277 | match kind { 278 | "block" => { 279 | let val: Block = access.next_value()?; 280 | if ir.blocks.insert(name.to_string(), val).is_some() { 281 | return Err(de::Error::custom(format!("Duplicate item {:?}", key))); 282 | } 283 | } 284 | "fieldset" => { 285 | let val: FieldSet = access.next_value()?; 286 | if ir.fieldsets.insert(name.to_string(), val).is_some() { 287 | return Err(de::Error::custom(format!("Duplicate item {:?}", key))); 288 | } 289 | } 290 | "enum" => { 291 | let val: Enum = access.next_value()?; 292 | if ir.enums.insert(name.to_string(), val).is_some() { 293 | return Err(de::Error::custom(format!("Duplicate item {:?}", key))); 294 | } 295 | } 296 | _ => return Err(de::Error::custom(format!("Unknown kind {:?}", kind))), 297 | } 298 | } 299 | 300 | Ok(ir) 301 | } 302 | } 303 | 304 | impl<'de> Deserialize<'de> for IR { 305 | fn deserialize(deserializer: D) -> Result 306 | where 307 | D: Deserializer<'de>, 308 | { 309 | deserializer.deserialize_map(IRVisitor) 310 | } 311 | } 312 | 313 | fn ordered_map(value: &HashMap, serializer: S) -> Result 314 | where 315 | S: Serializer, 316 | { 317 | let ordered: BTreeMap<_, _> = value.iter().collect(); 318 | ordered.serialize(serializer) 319 | } 320 | -------------------------------------------------------------------------------- /raltool/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod combine; 2 | pub mod generate; 3 | pub mod ir; 4 | pub mod svd2ir; 5 | pub mod transform; 6 | pub mod util; 7 | -------------------------------------------------------------------------------- /raltool/src/transform/common.rs: -------------------------------------------------------------------------------- 1 | use anyhow::bail; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::{HashMap, HashSet}; 4 | 5 | use crate::ir::*; 6 | 7 | pub(crate) fn make_regex(r: &str) -> Result { 8 | regex::Regex::new(&format!("^{}$", r)) 9 | } 10 | 11 | #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Serialize, Deserialize)] 12 | pub enum CheckLevel { 13 | NoCheck, 14 | Layout, 15 | Names, 16 | Descriptions, 17 | } 18 | 19 | pub(crate) fn check_mergeable_enums(a: &Enum, b: &Enum, level: CheckLevel) -> anyhow::Result<()> { 20 | if let Err(e) = check_mergeable_enums_inner(a, b, level) { 21 | bail!( 22 | "Cannot merge enums.\nfirst: {:#?}\nsecond: {:#?}\ncause: {:?}", 23 | a, 24 | b, 25 | e 26 | ) 27 | } 28 | Ok(()) 29 | } 30 | pub(crate) fn check_mergeable_enums_inner( 31 | a: &Enum, 32 | b: &Enum, 33 | level: CheckLevel, 34 | ) -> anyhow::Result<()> { 35 | if a.bit_size != b.bit_size { 36 | bail!("Different bit size: {} vs {}", a.bit_size.0, b.bit_size.0) 37 | } 38 | 39 | if level >= CheckLevel::Layout { 40 | if a.variants.len() != b.variants.len() { 41 | bail!("Different variant count") 42 | } 43 | 44 | let mut aok = [false; 128]; 45 | let mut bok = [false; 128]; 46 | 47 | for (ia, fa) in a.variants.iter().enumerate() { 48 | if let Some((ib, _fb)) = b 49 | .variants 50 | .iter() 51 | .enumerate() 52 | .find(|(ib, fb)| !bok[*ib] && mergeable_variants(fa, fb, level)) 53 | { 54 | aok[ia] = true; 55 | bok[ib] = true; 56 | } else { 57 | bail!("Variant in first enum has no match: {:?}", fa); 58 | } 59 | } 60 | } 61 | 62 | Ok(()) 63 | } 64 | 65 | pub(crate) fn mergeable_variants(a: &EnumVariant, b: &EnumVariant, level: CheckLevel) -> bool { 66 | let mut res = true; 67 | if level >= CheckLevel::Layout { 68 | res &= a.value == b.value; 69 | } 70 | if level >= CheckLevel::Names { 71 | res &= a.name == b.name; 72 | } 73 | if level >= CheckLevel::Descriptions { 74 | res &= a.description == b.description; 75 | } 76 | res 77 | } 78 | 79 | impl Default for CheckLevel { 80 | fn default() -> Self { 81 | Self::Names 82 | } 83 | } 84 | 85 | pub(crate) fn check_mergeable_fieldsets( 86 | a: &FieldSet, 87 | b: &FieldSet, 88 | level: CheckLevel, 89 | ) -> anyhow::Result<()> { 90 | if let Err(e) = check_mergeable_fieldsets_inner(a, b, level) { 91 | bail!( 92 | "Cannot merge fieldsets.\nfirst: {:#?}\nsecond: {:#?}\ncause: {:?}", 93 | a, 94 | b, 95 | e 96 | ) 97 | } 98 | Ok(()) 99 | } 100 | 101 | pub(crate) fn mergeable_fields(a: &Field, b: &Field, level: CheckLevel) -> bool { 102 | let mut res = true; 103 | if level >= CheckLevel::Layout { 104 | res &= a.bit_size == b.bit_size 105 | && a.bit_offset == b.bit_offset 106 | && a.enum_read == b.enum_read 107 | && a.enum_write == b.enum_write 108 | && a.enum_readwrite == b.enum_readwrite 109 | && a.array == b.array; 110 | } 111 | if level >= CheckLevel::Names { 112 | res &= a.name == b.name; 113 | } 114 | if level >= CheckLevel::Descriptions { 115 | res &= a.description == b.description; 116 | } 117 | res 118 | } 119 | 120 | pub(crate) fn check_mergeable_fieldsets_inner( 121 | a: &FieldSet, 122 | b: &FieldSet, 123 | level: CheckLevel, 124 | ) -> anyhow::Result<()> { 125 | if a.bit_size != b.bit_size { 126 | bail!("Different bit size: {} vs {}", a.bit_size.0, b.bit_size.0) 127 | } 128 | 129 | if level >= CheckLevel::Layout { 130 | if a.fields.len() != b.fields.len() { 131 | bail!("Different field count") 132 | } 133 | 134 | let mut aok = [false; 128]; 135 | let mut bok = [false; 128]; 136 | 137 | for (ia, fa) in a.fields.iter().enumerate() { 138 | if let Some((ib, _fb)) = b 139 | .fields 140 | .iter() 141 | .enumerate() 142 | .find(|(ib, fb)| !bok[*ib] && mergeable_fields(fa, fb, level)) 143 | { 144 | aok[ia] = true; 145 | bok[ib] = true; 146 | } else { 147 | bail!("Field in first fieldset has no match: {:?}", fa); 148 | } 149 | } 150 | } 151 | 152 | Ok(()) 153 | } 154 | 155 | pub(crate) fn match_all(set: impl Iterator, re: ®ex::Regex) -> HashSet { 156 | let mut ids: HashSet = HashSet::new(); 157 | for id in set { 158 | if re.is_match(&id) { 159 | ids.insert(id); 160 | } 161 | } 162 | ids 163 | } 164 | 165 | pub(crate) fn match_groups( 166 | set: impl Iterator, 167 | re: ®ex::Regex, 168 | to: &str, 169 | ) -> HashMap> { 170 | let mut groups: HashMap> = HashMap::new(); 171 | for s in set { 172 | if let Some(to) = match_expand(&s, re, to) { 173 | if let Some(v) = groups.get_mut(&to) { 174 | v.insert(s); 175 | } else { 176 | let mut v = HashSet::new(); 177 | v.insert(s); 178 | groups.insert(to, v); 179 | } 180 | } 181 | } 182 | groups 183 | } 184 | 185 | pub(crate) fn match_expand(s: &str, regex: ®ex::Regex, res: &str) -> Option { 186 | let m = regex.captures(s)?; 187 | let mut dst = String::new(); 188 | m.expand(res, &mut dst); 189 | Some(dst) 190 | } 191 | 192 | pub(crate) fn replace_enum_ids(ir: &mut IR, from: &HashSet, to: String) { 193 | for (_, fs) in ir.fieldsets.iter_mut() { 194 | for f in fs.fields.iter_mut() { 195 | for id in [&mut f.enum_read, &mut f.enum_write, &mut f.enum_readwrite] 196 | .into_iter() 197 | .flatten() 198 | { 199 | if from.contains(id) { 200 | *id = to.clone() 201 | } 202 | } 203 | } 204 | } 205 | } 206 | 207 | pub(crate) fn replace_fieldset_ids(ir: &mut IR, from: &HashSet, to: String) { 208 | for (_, b) in ir.blocks.iter_mut() { 209 | for i in b.items.iter_mut() { 210 | if let BlockItemInner::Register(r) = &mut i.inner { 211 | if let Some(id) = &r.fieldset { 212 | if from.contains(id) { 213 | r.fieldset = Some(to.clone()) 214 | } 215 | } 216 | } 217 | } 218 | } 219 | } 220 | 221 | pub(crate) fn replace_block_ids(ir: &mut IR, from: &HashSet, to: String) { 222 | for (_, d) in ir.devices.iter_mut() { 223 | for p in d.peripherals.iter_mut() { 224 | if let Some(block) = &mut p.block { 225 | if from.contains(block) { 226 | *block = to.clone() 227 | } 228 | } 229 | } 230 | } 231 | 232 | for (_, b) in ir.blocks.iter_mut() { 233 | for i in b.items.iter_mut() { 234 | if let BlockItemInner::Block(bi) = &mut i.inner { 235 | if from.contains(&bi.block) { 236 | bi.block = to.clone() 237 | } 238 | } 239 | } 240 | } 241 | } 242 | 243 | pub(crate) fn calc_array(mut offsets: Vec) -> (u32, Array) { 244 | offsets.sort_unstable(); 245 | 246 | // Guess stride. 247 | let start_offset = offsets[0]; 248 | let len = offsets.len() as u32; 249 | let stride = if len == 1 { 250 | // If there's only 1 item, we can't know the stride, but it 251 | // doesn't really matter! 252 | 0 253 | } else { 254 | offsets[1] - offsets[0] 255 | }; 256 | 257 | // Check the stride guess is OK 258 | 259 | if offsets 260 | .iter() 261 | .enumerate() 262 | .all(|(n, &i)| i == start_offset + (n as u32) * stride) 263 | { 264 | // Array is regular, 265 | ( 266 | start_offset, 267 | Array::Regular(RegularArray { 268 | len: offsets.len() as _, 269 | stride, 270 | }), 271 | ) 272 | } else { 273 | // Array is irregular, 274 | for o in &mut offsets { 275 | *o -= start_offset 276 | } 277 | (start_offset, Array::Cursed(CursedArray { offsets })) 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /raltool/src/transform/delete.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::HashSet; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct Delete { 10 | pub from: String, 11 | } 12 | 13 | impl Delete { 14 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 15 | let re = make_regex(&self.from)?; 16 | 17 | let mut ids: HashSet = HashSet::new(); 18 | for (id, _fs) in ir.fieldsets.iter() { 19 | if re.is_match(id) { 20 | info!("deleting fieldset {}", id); 21 | ids.insert(id.clone()); 22 | } 23 | } 24 | 25 | super::delete_fieldsets::remove_fieldset_ids(ir, &ids); 26 | 27 | for id in ids { 28 | ir.fieldsets.remove(&id); 29 | } 30 | 31 | let mut ids: HashSet = HashSet::new(); 32 | for (id, _e) in ir.enums.iter() { 33 | if re.is_match(id) { 34 | info!("deleting enum {}", id); 35 | ids.insert(id.clone()); 36 | } 37 | } 38 | 39 | super::delete_enums::remove_enum_ids(ir, &ids); 40 | 41 | for id in ids { 42 | ir.enums.remove(&id); 43 | } 44 | 45 | let mut ids: HashSet = HashSet::new(); 46 | for (id, _b) in ir.blocks.iter() { 47 | if re.is_match(id) { 48 | info!("deleting block {}", id); 49 | ids.insert(id.clone()); 50 | } 51 | } 52 | 53 | remove_block_ids(ir, &ids); 54 | 55 | for id in ids { 56 | ir.blocks.remove(&id); 57 | } 58 | 59 | Ok(()) 60 | } 61 | } 62 | 63 | pub(crate) fn remove_block_ids(ir: &mut IR, from: &HashSet) { 64 | for (_, b) in ir.blocks.iter_mut() { 65 | b.items.retain(|i| { 66 | if let BlockItemInner::Block(bi) = &i.inner { 67 | !from.contains(&bi.block) 68 | } else { 69 | true 70 | } 71 | }); 72 | } 73 | 74 | for (_, d) in ir.devices.iter_mut() { 75 | d.peripherals.retain(|p| match &p.block { 76 | Some(block) => !from.contains(block), 77 | None => true, 78 | }); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /raltool/src/transform/delete_enums.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::HashSet; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct DeleteEnums { 10 | pub from: String, 11 | pub bit_size: Option, 12 | #[serde(default)] 13 | pub soft: bool, 14 | } 15 | 16 | impl DeleteEnums { 17 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 18 | let re = make_regex(&self.from)?; 19 | 20 | let mut ids: HashSet = HashSet::new(); 21 | for (id, e) in ir.enums.iter() { 22 | let bit_size_matches = self.bit_size.map_or(true, |s| s == e.bit_size); 23 | if re.is_match(id) && bit_size_matches { 24 | info!("deleting enum {}", id); 25 | ids.insert(id.clone()); 26 | } 27 | } 28 | 29 | remove_enum_ids(ir, &ids); 30 | 31 | if !self.soft { 32 | for id in ids { 33 | ir.enums.remove(&id); 34 | } 35 | } 36 | 37 | Ok(()) 38 | } 39 | } 40 | 41 | pub(crate) fn remove_enum_ids(ir: &mut IR, from: &HashSet) { 42 | for (_, fs) in ir.fieldsets.iter_mut() { 43 | for f in fs.fields.iter_mut() { 44 | for e in [&mut f.enum_read, &mut f.enum_write, &mut f.enum_readwrite].into_iter() { 45 | if let Some(id) = e { 46 | if from.contains(id) { 47 | *e = None 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /raltool/src/transform/delete_fieldsets.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::HashSet; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct DeleteFieldsets { 10 | pub from: String, 11 | #[serde(default)] 12 | pub useless: bool, 13 | #[serde(default)] 14 | pub soft: bool, 15 | } 16 | 17 | impl DeleteFieldsets { 18 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 19 | let re = make_regex(&self.from)?; 20 | 21 | let mut ids: HashSet = HashSet::new(); 22 | for (id, fs) in ir.fieldsets.iter() { 23 | if re.is_match(id) && (!self.useless | is_useless(fs)) { 24 | info!("deleting fieldset {}", id); 25 | ids.insert(id.clone()); 26 | } 27 | } 28 | 29 | remove_fieldset_ids(ir, &ids); 30 | 31 | if !self.soft { 32 | for id in ids { 33 | ir.fieldsets.remove(&id); 34 | } 35 | } 36 | 37 | Ok(()) 38 | } 39 | } 40 | 41 | fn is_useless(fs: &FieldSet) -> bool { 42 | match &fs.fields[..] { 43 | [] => true, 44 | [f] => { 45 | fs.bit_size == f.bit_size 46 | && f.bit_offset == 0 47 | && f.enum_read.is_none() 48 | && f.enum_write.is_none() 49 | && f.enum_readwrite.is_none() 50 | } 51 | _ => false, 52 | } 53 | } 54 | 55 | pub(crate) fn remove_fieldset_ids(ir: &mut IR, from: &HashSet) { 56 | for (_, b) in ir.blocks.iter_mut() { 57 | for i in b.items.iter_mut() { 58 | if let BlockItemInner::Register(reg) = &mut i.inner { 59 | if let Some(id) = ®.fieldset { 60 | if from.contains(id) { 61 | reg.fieldset = None 62 | } 63 | } 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /raltool/src/transform/expand_extends.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::{HashMap, HashSet}; 4 | 5 | use crate::ir::*; 6 | 7 | #[derive(Debug, Serialize, Deserialize)] 8 | pub struct ExpandExtends {} 9 | 10 | impl ExpandExtends { 11 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 12 | // Expand blocks 13 | let deps = ir 14 | .blocks 15 | .iter() 16 | .map(|(k, v)| (k.clone(), v.extends.clone())) 17 | .collect(); 18 | for name in topological_sort(deps) { 19 | let block = ir.blocks.get(&name).unwrap(); 20 | if let Some(parent_name) = &block.extends { 21 | let parent = ir.blocks.get(parent_name).unwrap(); 22 | 23 | let items = parent.items.clone(); 24 | let block = ir.blocks.get_mut(&name).unwrap(); 25 | 26 | for i in items { 27 | if !block.items.iter().any(|j| j.name == i.name) { 28 | block.items.push(i); 29 | } 30 | } 31 | } 32 | } 33 | // Expand fiedsets 34 | let deps = ir 35 | .fieldsets 36 | .iter() 37 | .map(|(k, v)| (k.clone(), v.extends.clone())) 38 | .collect(); 39 | for name in topological_sort(deps) { 40 | let fieldset = ir.fieldsets.get(&name).unwrap(); 41 | if let Some(parent_name) = &fieldset.extends { 42 | let parent = ir.fieldsets.get(parent_name).unwrap(); 43 | 44 | let items = parent.fields.clone(); 45 | let fieldset = ir.fieldsets.get_mut(&name).unwrap(); 46 | 47 | for i in items { 48 | if !fieldset.fields.iter().any(|j| j.name == i.name) { 49 | fieldset.fields.push(i); 50 | } 51 | } 52 | } 53 | } 54 | 55 | Ok(()) 56 | } 57 | } 58 | 59 | fn topological_sort(vals: HashMap>) -> Vec { 60 | for (name, dep) in &vals { 61 | info!("{:?} => {:?}", name, dep); 62 | } 63 | 64 | let mut done = HashSet::new(); 65 | let mut res = Vec::new(); 66 | while done.len() != vals.len() { 67 | for (name, dep) in &vals { 68 | if done.contains(name) { 69 | continue; 70 | } 71 | if let Some(dep) = dep { 72 | if !done.contains(dep) { 73 | continue; 74 | } 75 | } 76 | info!("doing {:?} ", name); 77 | done.insert(name.clone()); 78 | res.push(name.clone()); 79 | } 80 | } 81 | res 82 | } 83 | -------------------------------------------------------------------------------- /raltool/src/transform/find_duplicate_enums.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::{HashMap, HashSet}; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct FindDuplicateEnums {} 10 | impl FindDuplicateEnums { 11 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 12 | let mut suggested = HashSet::new(); 13 | 14 | for (id1, e1) in ir.enums.iter() { 15 | if suggested.contains(&id1) { 16 | continue; 17 | } 18 | 19 | let mut ids = Vec::new(); 20 | for (id2, e2) in ir.enums.iter() { 21 | if id1 != id2 && mergeable_enums(e1, e2) { 22 | ids.push(id2) 23 | } 24 | } 25 | 26 | if !ids.is_empty() { 27 | ids.push(id1); 28 | info!("Duplicated enums:"); 29 | for id in ids { 30 | suggested.insert(id); 31 | info!(" {}", ir.enums.get(id).path); 32 | } 33 | } 34 | } 35 | 36 | Ok(()) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /raltool/src/transform/find_duplicate_fieldsets.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::{HashMap, HashSet}; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct FindDuplicateFieldsets {} 10 | impl FindDuplicateFieldsets { 11 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 12 | let mut suggested = HashSet::new(); 13 | 14 | for (id1, fs1) in ir.fieldsets.iter() { 15 | if suggested.contains(&id1) { 16 | continue; 17 | } 18 | 19 | let mut ids = Vec::new(); 20 | for (id2, fs2) in ir.fieldsets.iter() { 21 | if id1 != id2 && check_mergeable_fieldsets(fs1, fs2, CheckLevel::Names).is_ok() { 22 | ids.push(id2) 23 | } 24 | } 25 | 26 | if !ids.is_empty() { 27 | ids.push(id1); 28 | info!("Duplicated fieldsets:"); 29 | for id in ids { 30 | suggested.insert(id); 31 | info!(" {}", ir.fieldsets.get(id).path); 32 | } 33 | } 34 | } 35 | 36 | Ok(()) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /raltool/src/transform/make_block.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use super::common::*; 5 | use crate::ir::*; 6 | 7 | #[derive(Debug, Serialize, Deserialize)] 8 | pub struct MakeBlock { 9 | pub blocks: String, 10 | pub from: String, 11 | pub to_outer: String, 12 | pub to_block: String, 13 | pub to_inner: String, 14 | } 15 | 16 | impl MakeBlock { 17 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 18 | let path_re = make_regex(&self.blocks)?; 19 | let re = make_regex(&self.from)?; 20 | for id in match_all(ir.blocks.keys().cloned(), &path_re) { 21 | let b = ir.blocks.get_mut(&id).unwrap(); 22 | let groups = match_groups(b.items.iter().map(|f| f.name.clone()), &re, &self.to_outer); 23 | for (to, group) in groups { 24 | let b = ir.blocks.get_mut(&id).unwrap(); 25 | info!("blockifizing to {}", to); 26 | 27 | // Grab all items into a vec 28 | let mut items = Vec::new(); 29 | for i in b.items.iter().filter(|i| group.contains(&i.name)) { 30 | items.push(i); 31 | } 32 | 33 | // Sort by offs 34 | items.sort_by_key(|i| i.byte_offset); 35 | for i in &items { 36 | info!(" {}", i.name); 37 | } 38 | 39 | // todo check they're mergeable 40 | // todo check they're not arrays (arrays of arrays not supported) 41 | 42 | let byte_offset = items[0].byte_offset; 43 | 44 | let b2 = Block { 45 | extends: None, 46 | description: None, 47 | items: items 48 | .iter() 49 | .map(|&i| { 50 | let mut i = i.clone(); 51 | i.name = match_expand(&i.name, &re, &self.to_inner).unwrap(); 52 | i.byte_offset -= byte_offset; 53 | i 54 | }) 55 | .collect(), 56 | }; 57 | 58 | // TODO if destination block exists, check mergeable 59 | let dest = self.to_block.clone(); // todo regex 60 | ir.blocks.insert(dest.clone(), b2); 61 | 62 | // Remove all items 63 | let b = ir.blocks.get_mut(&id).unwrap(); 64 | b.items.retain(|i| !group.contains(&i.name)); 65 | 66 | // Create the new block item 67 | b.items.push(BlockItem { 68 | name: to, 69 | description: None, 70 | array: None, 71 | byte_offset, 72 | inner: BlockItemInner::Block(BlockItemBlock { block: dest }), 73 | }); 74 | } 75 | } 76 | Ok(()) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /raltool/src/transform/make_field_array.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use super::common::*; 5 | use crate::ir::*; 6 | 7 | #[derive(Debug, Serialize, Deserialize)] 8 | pub struct MakeFieldArray { 9 | pub fieldsets: String, 10 | pub from: String, 11 | pub to: String, 12 | #[serde(default)] 13 | pub allow_cursed: bool, 14 | } 15 | 16 | impl MakeFieldArray { 17 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 18 | let path_re = make_regex(&self.fieldsets)?; 19 | let re = make_regex(&self.from)?; 20 | for id in match_all(ir.fieldsets.keys().cloned(), &path_re) { 21 | let b = ir.fieldsets.get_mut(&id).unwrap(); 22 | let groups = match_groups(b.fields.iter().map(|f| f.name.clone()), &re, &self.to); 23 | for (to, group) in groups { 24 | info!("arrayizing to {}", to); 25 | 26 | // Grab all items into a vec 27 | let mut items = Vec::new(); 28 | for i in b.fields.iter().filter(|i| group.contains(&i.name)) { 29 | items.push(i); 30 | } 31 | 32 | // todo check they're mergeable 33 | // todo check they're not arrays (arrays of arrays not supported) 34 | 35 | // Sort by offs 36 | items.sort_by_key(|i| i.bit_offset); 37 | for i in &items { 38 | info!(" {}", i.name); 39 | } 40 | 41 | let (offset, array) = calc_array(items.iter().map(|x| x.bit_offset).collect()); 42 | if let Array::Cursed(_) = &array { 43 | if !self.allow_cursed { 44 | panic!("arrayize: items are not evenly spaced. Set `allow_cursed: true` to allow this.") 45 | } 46 | } 47 | 48 | let mut item = items[0].clone(); 49 | 50 | // Remove all 51 | b.fields.retain(|i| !group.contains(&i.name)); 52 | 53 | // Create the new array item 54 | item.name = to; 55 | item.array = Some(array); 56 | item.bit_offset = offset; 57 | b.fields.push(item); 58 | } 59 | } 60 | Ok(()) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /raltool/src/transform/make_register_array.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use super::common::*; 5 | use crate::ir::*; 6 | 7 | #[derive(Debug, Serialize, Deserialize)] 8 | pub struct MakeRegisterArray { 9 | pub blocks: String, 10 | pub from: String, 11 | pub to: String, 12 | #[serde(default)] 13 | pub allow_cursed: bool, 14 | } 15 | 16 | impl MakeRegisterArray { 17 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 18 | let path_re = make_regex(&self.blocks)?; 19 | let re = make_regex(&self.from)?; 20 | for id in match_all(ir.blocks.keys().cloned(), &path_re) { 21 | let b = ir.blocks.get_mut(&id).unwrap(); 22 | let groups = match_groups(b.items.iter().map(|f| f.name.clone()), &re, &self.to); 23 | for (to, group) in groups { 24 | info!("arrayizing to {}", to); 25 | 26 | // Grab all items into a vec 27 | let mut items = Vec::new(); 28 | for i in b.items.iter().filter(|i| group.contains(&i.name)) { 29 | items.push(i); 30 | } 31 | 32 | // todo check they're mergeable 33 | // todo check they're not arrays (arrays of arrays not supported) 34 | 35 | // Sort by offs 36 | items.sort_by_key(|i| i.byte_offset); 37 | for i in &items { 38 | info!(" {}", i.name); 39 | } 40 | 41 | let (offset, array) = calc_array(items.iter().map(|x| x.byte_offset).collect()); 42 | if let Array::Cursed(_) = &array { 43 | if !self.allow_cursed { 44 | panic!("arrayize: items are not evenly spaced. Set `allow_cursed: true` to allow this.") 45 | } 46 | } 47 | 48 | let mut item = items[0].clone(); 49 | 50 | // Remove all 51 | b.items.retain(|i| !group.contains(&i.name)); 52 | 53 | // Create the new array item 54 | item.name = to; 55 | item.array = Some(array); 56 | item.byte_offset = offset; 57 | b.items.push(item); 58 | } 59 | } 60 | Ok(()) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /raltool/src/transform/merge_blocks.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::HashSet; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct MergeBlocks { 10 | pub from: String, 11 | pub to: String, 12 | pub main: Option, 13 | #[serde(default)] 14 | pub check: CheckLevel, 15 | } 16 | 17 | impl MergeBlocks { 18 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 19 | let re = make_regex(&self.from)?; 20 | let groups = match_groups(ir.blocks.keys().cloned(), &re, &self.to); 21 | 22 | for (to, group) in groups { 23 | info!("Merging blocks, dest: {}", to); 24 | for id in &group { 25 | info!(" {}", id); 26 | } 27 | self.merge_blocks(ir, group, to, self.main.as_ref())?; 28 | } 29 | 30 | Ok(()) 31 | } 32 | 33 | fn merge_blocks( 34 | &self, 35 | ir: &mut IR, 36 | ids: HashSet, 37 | to: String, 38 | main: Option<&String>, 39 | ) -> anyhow::Result<()> { 40 | let mut main_id = ids.iter().next().unwrap().clone(); 41 | if let Some(main) = main { 42 | let re = make_regex(main)?; 43 | for id in ids.iter() { 44 | if re.is_match(id) { 45 | main_id = id.clone(); 46 | break; 47 | } 48 | } 49 | } 50 | let b = ir.blocks.get(&main_id).unwrap().clone(); 51 | 52 | // todo 53 | //for id in &ids { 54 | // let b2 = ir.blocks.get(id).unwrap(); 55 | // check_mergeable_blocks(&b, b2, self.check)?; 56 | //} 57 | 58 | replace_block_ids(ir, &ids, to.clone()); 59 | for id in &ids { 60 | ir.blocks.remove(id); 61 | } 62 | ir.blocks.insert(to, b); 63 | 64 | Ok(()) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /raltool/src/transform/merge_enums.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::HashSet; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct MergeEnums { 10 | pub from: String, 11 | pub to: String, 12 | #[serde(default)] 13 | pub check: CheckLevel, 14 | #[serde(default)] 15 | pub skip_unmergeable: bool, 16 | } 17 | 18 | impl MergeEnums { 19 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 20 | let re = make_regex(&self.from)?; 21 | let groups = match_groups(ir.enums.keys().cloned(), &re, &self.to); 22 | 23 | for (to, group) in groups { 24 | info!("Merging enums, dest: {}", to); 25 | for id in &group { 26 | info!(" {}", id); 27 | } 28 | self.merge_enums(ir, group, to)?; 29 | } 30 | 31 | Ok(()) 32 | } 33 | 34 | fn merge_enums(&self, ir: &mut IR, ids: HashSet, to: String) -> anyhow::Result<()> { 35 | let e = ir.enums.get(ids.iter().next().unwrap()).unwrap().clone(); 36 | 37 | for id in &ids { 38 | let e2 = ir.enums.get(id).unwrap(); 39 | if let Err(e) = check_mergeable_enums(&e, e2, self.check) { 40 | if self.skip_unmergeable { 41 | info!("skipping: {:?}", to); 42 | return Ok(()); 43 | } else { 44 | return Err(e); 45 | } 46 | } 47 | } 48 | for id in &ids { 49 | ir.enums.remove(id); 50 | } 51 | 52 | assert!(ir.enums.insert(to.clone(), e).is_none()); 53 | replace_enum_ids(ir, &ids, to); 54 | 55 | Ok(()) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /raltool/src/transform/merge_fieldsets.rs: -------------------------------------------------------------------------------- 1 | use log::*; 2 | use serde::{Deserialize, Serialize}; 3 | use std::collections::HashSet; 4 | 5 | use super::common::*; 6 | use crate::ir::*; 7 | 8 | #[derive(Debug, Serialize, Deserialize)] 9 | pub struct MergeFieldsets { 10 | pub from: String, 11 | pub to: String, 12 | pub main: Option, 13 | #[serde(default)] 14 | pub check: CheckLevel, 15 | } 16 | 17 | impl MergeFieldsets { 18 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 19 | let re = make_regex(&self.from)?; 20 | let groups = match_groups(ir.fieldsets.keys().cloned(), &re, &self.to); 21 | 22 | for (to, group) in groups { 23 | info!("Merging fieldsets, dest: {}", to); 24 | for id in &group { 25 | info!(" {}", id); 26 | } 27 | self.merge_fieldsets(ir, group, to, self.main.as_ref())?; 28 | } 29 | 30 | Ok(()) 31 | } 32 | 33 | fn merge_fieldsets( 34 | &self, 35 | ir: &mut IR, 36 | ids: HashSet, 37 | to: String, 38 | main: Option<&String>, 39 | ) -> anyhow::Result<()> { 40 | let mut main_id = ids.iter().next().unwrap().clone(); 41 | if let Some(main) = main { 42 | let re = make_regex(main)?; 43 | for id in ids.iter() { 44 | if re.is_match(id) { 45 | main_id = id.clone(); 46 | break; 47 | } 48 | } 49 | } 50 | let fs = ir.fieldsets.get(&main_id).unwrap().clone(); 51 | 52 | for id in &ids { 53 | let fs2 = ir.fieldsets.get(id).unwrap(); 54 | check_mergeable_fieldsets(&fs, fs2, self.check)?; 55 | } 56 | 57 | for id in &ids { 58 | ir.fieldsets.remove(id); 59 | } 60 | 61 | assert!(ir.fieldsets.insert(to.clone(), fs).is_none()); 62 | replace_fieldset_ids(ir, &ids, to); 63 | 64 | Ok(()) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /raltool/src/transform/mod.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use std::collections::{HashMap, HashSet}; 3 | 4 | use crate::ir::*; 5 | use crate::util::{ToSanitizedPascalCase, ToSanitizedSnakeCase, ToSanitizedUpperCase}; 6 | 7 | #[derive(Debug, Serialize, Deserialize)] 8 | pub struct Sanitize {} 9 | 10 | impl Sanitize { 11 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 12 | map_names(ir, |k, p| match k { 13 | NameKind::Device => *p = sanitize_path(p), 14 | NameKind::DevicePeripheral => *p = p.to_sanitized_upper_case().to_string(), 15 | NameKind::DeviceInterrupt => *p = p.to_string(), 16 | NameKind::Block => *p = sanitize_path(p), 17 | NameKind::Fieldset => *p = sanitize_path(p), 18 | NameKind::Enum => *p = sanitize_path(p), 19 | NameKind::BlockItem => *p = p.to_sanitized_upper_case().to_string(), 20 | NameKind::Field => *p = p.to_sanitized_upper_case().to_string(), 21 | NameKind::EnumVariant => *p = p.to_sanitized_pascal_case().to_string(), 22 | }); 23 | Ok(()) 24 | } 25 | } 26 | 27 | #[derive(PartialEq, Eq)] 28 | pub enum NameKind { 29 | Device, 30 | DevicePeripheral, 31 | DeviceInterrupt, 32 | Block, 33 | BlockItem, 34 | Fieldset, 35 | Field, 36 | Enum, 37 | EnumVariant, 38 | } 39 | 40 | fn rename_opt(s: &mut Option, f: impl Fn(&mut String)) { 41 | if let Some(s) = s { 42 | f(s) 43 | } 44 | } 45 | 46 | pub fn map_block_names(ir: &mut IR, f: impl Fn(&mut String)) { 47 | remap_names(&mut ir.blocks, &f); 48 | 49 | for (_, d) in ir.devices.iter_mut() { 50 | for p in &mut d.peripherals { 51 | rename_opt(&mut p.block, &f); 52 | } 53 | } 54 | 55 | for (_, b) in ir.blocks.iter_mut() { 56 | for i in b.items.iter_mut() { 57 | match &mut i.inner { 58 | BlockItemInner::Block(p) => f(&mut p.block), 59 | BlockItemInner::Register(_r) => {} 60 | } 61 | } 62 | } 63 | } 64 | 65 | pub fn map_fieldset_names(ir: &mut IR, f: impl Fn(&mut String)) { 66 | remap_names(&mut ir.fieldsets, &f); 67 | 68 | for (_, b) in ir.blocks.iter_mut() { 69 | for i in b.items.iter_mut() { 70 | match &mut i.inner { 71 | BlockItemInner::Block(_p) => {} 72 | BlockItemInner::Register(r) => rename_opt(&mut r.fieldset, &f), 73 | } 74 | } 75 | } 76 | } 77 | 78 | pub fn map_enum_names(ir: &mut IR, f: impl Fn(&mut String)) { 79 | remap_names(&mut ir.enums, &f); 80 | 81 | for (_, fs) in ir.fieldsets.iter_mut() { 82 | for ff in fs.fields.iter_mut() { 83 | rename_opt(&mut ff.enum_read, &f); 84 | rename_opt(&mut ff.enum_write, &f); 85 | rename_opt(&mut ff.enum_readwrite, &f); 86 | } 87 | } 88 | } 89 | 90 | pub fn map_device_names(ir: &mut IR, f: impl Fn(&mut String)) { 91 | remap_names(&mut ir.devices, &f); 92 | } 93 | 94 | pub fn map_device_interrupt_names(ir: &mut IR, f: impl Fn(&mut String)) { 95 | for (_, d) in ir.devices.iter_mut() { 96 | for i in &mut d.interrupts { 97 | f(&mut i.name); 98 | } 99 | } 100 | } 101 | 102 | pub fn map_device_peripheral_names(ir: &mut IR, f: impl Fn(&mut String)) { 103 | for (_, d) in ir.devices.iter_mut() { 104 | for p in &mut d.peripherals { 105 | f(&mut p.name); 106 | } 107 | } 108 | } 109 | 110 | pub fn map_block_item_names(ir: &mut IR, f: impl Fn(&mut String)) { 111 | for (_, b) in ir.blocks.iter_mut() { 112 | for i in b.items.iter_mut() { 113 | f(&mut i.name) 114 | } 115 | } 116 | } 117 | 118 | pub fn map_field_names(ir: &mut IR, f: impl Fn(&mut String)) { 119 | for (_, fs) in ir.fieldsets.iter_mut() { 120 | for ff in fs.fields.iter_mut() { 121 | f(&mut ff.name) 122 | } 123 | } 124 | } 125 | 126 | pub fn map_enum_variant_names(ir: &mut IR, f: impl Fn(&mut String)) { 127 | for (_, e) in ir.enums.iter_mut() { 128 | for v in e.variants.iter_mut() { 129 | f(&mut v.name) 130 | } 131 | } 132 | } 133 | 134 | pub fn map_names(ir: &mut IR, f: impl Fn(NameKind, &mut String)) { 135 | map_device_names(ir, |s| f(NameKind::Device, s)); 136 | map_device_peripheral_names(ir, |s| f(NameKind::DevicePeripheral, s)); 137 | map_device_interrupt_names(ir, |s| f(NameKind::DeviceInterrupt, s)); 138 | map_block_names(ir, |s| f(NameKind::Block, s)); 139 | map_block_item_names(ir, |s| f(NameKind::BlockItem, s)); 140 | map_fieldset_names(ir, |s| f(NameKind::Fieldset, s)); 141 | map_field_names(ir, |s| f(NameKind::Field, s)); 142 | map_enum_names(ir, |s| f(NameKind::Enum, s)); 143 | map_enum_variant_names(ir, |s| f(NameKind::EnumVariant, s)); 144 | } 145 | 146 | pub fn map_descriptions(ir: &mut IR, mut ff: impl FnMut(&str) -> String) -> anyhow::Result<()> { 147 | let mut mapit = |d: &mut Option| { 148 | *d = d.as_ref().map(|p| ff(p)); 149 | }; 150 | 151 | for (_, b) in ir.blocks.iter_mut() { 152 | mapit(&mut b.description); 153 | for i in b.items.iter_mut() { 154 | mapit(&mut i.description); 155 | } 156 | } 157 | 158 | for (_, fs) in ir.fieldsets.iter_mut() { 159 | mapit(&mut fs.description); 160 | for f in fs.fields.iter_mut() { 161 | mapit(&mut f.description); 162 | } 163 | } 164 | 165 | for (_, e) in ir.enums.iter_mut() { 166 | mapit(&mut e.description); 167 | for v in e.variants.iter_mut() { 168 | mapit(&mut v.description); 169 | } 170 | } 171 | 172 | Ok(()) 173 | } 174 | 175 | fn remap_names(x: &mut HashMap, f: impl Fn(&mut String)) { 176 | let mut res = HashMap::new(); 177 | for (mut name, val) in x.drain() { 178 | f(&mut name); 179 | assert!(res.insert(name, val).is_none()) 180 | } 181 | *x = res 182 | } 183 | 184 | fn sanitize_path(p: &str) -> String { 185 | let v = p.split("::").collect::>(); 186 | let len = v.len(); 187 | v.into_iter() 188 | .enumerate() 189 | .map(|(i, s)| { 190 | if i == len - 1 { 191 | s.to_sanitized_pascal_case() 192 | } else { 193 | s.to_sanitized_snake_case() 194 | } 195 | }) 196 | .collect::>() 197 | .join("::") 198 | } 199 | 200 | mod common; 201 | 202 | pub mod delete; 203 | pub mod delete_enums; 204 | pub mod delete_fieldsets; 205 | //pub mod find_duplicate_enums; 206 | //pub mod find_duplicate_fieldsets; 207 | pub mod expand_extends; 208 | pub mod make_block; 209 | pub mod make_field_array; 210 | pub mod make_register_array; 211 | pub mod merge_blocks; 212 | pub mod merge_enums; 213 | pub mod merge_fieldsets; 214 | pub mod modify_byte_offset; 215 | pub mod rename; 216 | pub mod rename_fields; 217 | pub mod rename_registers; 218 | pub mod sort; 219 | 220 | #[derive(Debug, Serialize, Deserialize)] 221 | pub enum Transform { 222 | Sanitize(Sanitize), 223 | Sort(sort::Sort), 224 | Delete(delete::Delete), 225 | DeleteEnums(delete_enums::DeleteEnums), 226 | DeleteFieldsets(delete_fieldsets::DeleteFieldsets), 227 | MergeBlocks(merge_blocks::MergeBlocks), 228 | MergeEnums(merge_enums::MergeEnums), 229 | MergeFieldsets(merge_fieldsets::MergeFieldsets), 230 | Rename(rename::Rename), 231 | RenameFields(rename_fields::RenameFields), 232 | RenameRegisters(rename_registers::RenameRegisters), 233 | MakeRegisterArray(make_register_array::MakeRegisterArray), 234 | MakeFieldArray(make_field_array::MakeFieldArray), 235 | MakeBlock(make_block::MakeBlock), 236 | ModifyByteOffset(modify_byte_offset::ModifyByteOffset), 237 | //FindDuplicateEnums(find_duplicate_enums::FindDuplicateEnums), 238 | //FindDuplicateFieldsets(find_duplicate_fieldsets::FindDuplicateFieldsets), 239 | } 240 | 241 | impl Transform { 242 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 243 | match self { 244 | Self::Sanitize(t) => t.run(ir), 245 | Self::Sort(t) => t.run(ir), 246 | Self::Delete(t) => t.run(ir), 247 | Self::DeleteEnums(t) => t.run(ir), 248 | Self::DeleteFieldsets(t) => t.run(ir), 249 | Self::MergeBlocks(t) => t.run(ir), 250 | Self::MergeEnums(t) => t.run(ir), 251 | Self::MergeFieldsets(t) => t.run(ir), 252 | Self::Rename(t) => t.run(ir), 253 | Self::RenameFields(t) => t.run(ir), 254 | Self::RenameRegisters(t) => t.run(ir), 255 | Self::MakeRegisterArray(t) => t.run(ir), 256 | Self::MakeFieldArray(t) => t.run(ir), 257 | Self::MakeBlock(t) => t.run(ir), 258 | Self::ModifyByteOffset(t) => t.run(ir), 259 | //Self::FindDuplicateEnums(t) => t.run(ir), 260 | //Self::FindDuplicateFieldsets(t) => t.run(ir), 261 | } 262 | } 263 | } 264 | 265 | /// A transform that removes extraneous numbers 266 | /// from block paths that have multiple instances. 267 | /// 268 | /// If the IR uses paths that look like 269 | /// 270 | /// - `lpuart1::Lpuart2` 271 | /// - `lpuart1::Lpuart7` 272 | /// - etc. 273 | /// 274 | /// this transformer changes `lpuart1` to `lpuart`, 275 | /// dropping the '1'. 276 | pub struct SimplifyPaths(()); 277 | impl SimplifyPaths { 278 | pub fn new() -> Self { 279 | SimplifyPaths(()) 280 | } 281 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 282 | let re = regex::Regex::new(r"\d+$")?; 283 | 284 | let mut block_to_peripherals: HashMap<&str, usize> = HashMap::new(); 285 | for device in ir.devices.values() { 286 | for peripheral in &device.peripherals { 287 | *block_to_peripherals 288 | .entry(peripheral.block.as_ref().unwrap()) 289 | .or_insert(0) += 1; 290 | } 291 | } 292 | 293 | let renames: HashSet = block_to_peripherals 294 | .into_iter() 295 | .filter(|(_, count)| *count > 1) 296 | .filter(|(path, _)| { 297 | let root = path.split("::").next().unwrap(); 298 | re.is_match(root) 299 | }) 300 | .map(|(path, _)| path.split("::").next().unwrap().into()) 301 | .collect(); 302 | 303 | map_names(ir, |_, name| { 304 | let mut parts = name.split("::"); 305 | if let Some(root) = parts.next() { 306 | if renames.contains(root) { 307 | let new_root = re.replace(root, ""); 308 | *name = std::iter::once(&*new_root) 309 | .chain(parts) 310 | .collect::>() 311 | .join("::"); 312 | } 313 | } 314 | }); 315 | 316 | Ok(()) 317 | } 318 | } 319 | 320 | impl Default for SimplifyPaths { 321 | fn default() -> Self { 322 | Self::new() 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /raltool/src/transform/modify_byte_offset.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use super::common::*; 4 | use crate::ir::*; 5 | 6 | #[derive(Debug, Serialize, Deserialize)] 7 | pub struct ModifyByteOffset { 8 | pub block: String, 9 | pub add_offset: u32, 10 | } 11 | 12 | impl ModifyByteOffset { 13 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 14 | let path_re = make_regex(&self.block)?; 15 | for id in match_all(ir.blocks.keys().cloned(), &path_re) { 16 | let b = ir.blocks.get_mut(&id).unwrap(); 17 | for i in &mut b.items { 18 | i.byte_offset += self.add_offset; 19 | } 20 | } 21 | Ok(()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /raltool/src/transform/rename.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use super::common::*; 4 | use crate::ir::*; 5 | 6 | #[derive(Debug, Serialize, Deserialize)] 7 | pub struct Rename { 8 | pub from: String, 9 | pub to: String, 10 | } 11 | 12 | impl Rename { 13 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 14 | let re = make_regex(&self.from)?; 15 | 16 | let renamer = |name: &mut String| { 17 | if let Some(res) = match_expand(name, &re, &self.to) { 18 | *name = res 19 | } 20 | }; 21 | 22 | super::map_device_names(ir, &renamer); 23 | super::map_block_names(ir, &renamer); 24 | super::map_fieldset_names(ir, &renamer); 25 | super::map_enum_names(ir, &renamer); 26 | super::map_device_peripheral_names(ir, &renamer); 27 | 28 | Ok(()) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /raltool/src/transform/rename_fields.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use super::common::*; 4 | use crate::ir::*; 5 | 6 | #[derive(Debug, Serialize, Deserialize)] 7 | pub struct RenameFields { 8 | pub fieldset: String, 9 | pub from: String, 10 | pub to: String, 11 | } 12 | 13 | impl RenameFields { 14 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 15 | let path_re = make_regex(&self.fieldset)?; 16 | let re = make_regex(&self.from)?; 17 | for id in match_all(ir.fieldsets.keys().cloned(), &path_re) { 18 | let fs = ir.fieldsets.get_mut(&id).unwrap(); 19 | for f in &mut fs.fields { 20 | if let Some(name) = match_expand(&f.name, &re, &self.to) { 21 | f.name = name; 22 | } 23 | } 24 | } 25 | Ok(()) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /raltool/src/transform/rename_registers.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use super::common::*; 4 | use crate::ir::*; 5 | 6 | #[derive(Debug, Serialize, Deserialize)] 7 | pub struct RenameRegisters { 8 | pub block: String, 9 | pub from: String, 10 | pub to: String, 11 | } 12 | 13 | impl RenameRegisters { 14 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 15 | let path_re = make_regex(&self.block)?; 16 | let re = make_regex(&self.from)?; 17 | for id in match_all(ir.blocks.keys().cloned(), &path_re) { 18 | let b = ir.blocks.get_mut(&id).unwrap(); 19 | for i in &mut b.items { 20 | if let Some(name) = match_expand(&i.name, &re, &self.to) { 21 | i.name = name; 22 | } 23 | } 24 | } 25 | Ok(()) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /raltool/src/transform/sort.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use crate::ir::*; 4 | 5 | #[derive(Debug, Serialize, Deserialize)] 6 | pub struct Sort {} 7 | 8 | impl Sort { 9 | pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { 10 | for z in ir.blocks.values_mut() { 11 | z.items.sort_by_key(|i| (i.byte_offset, i.name.clone())) 12 | } 13 | for z in ir.fieldsets.values_mut() { 14 | z.fields.sort_by_key(|i| (i.bit_offset, i.name.clone())) 15 | } 16 | for z in ir.enums.values_mut() { 17 | z.variants.sort_by_key(|i| (i.value, i.name.clone())) 18 | } 19 | 20 | Ok(()) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /raltool/src/util.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{anyhow, Result}; 2 | use inflections::Inflect; 3 | use proc_macro2::{Ident, Literal, Span, TokenStream}; 4 | use quote::{quote, ToTokens}; 5 | use std::{borrow::Cow, str::FromStr}; 6 | 7 | pub const BITS_PER_BYTE: u32 = 8; 8 | 9 | /// List of chars that some vendors use in their peripheral/field names but 10 | /// that are not valid in Rust ident 11 | const BLACKLIST_CHARS: &[char] = &['(', ')', '[', ']', '/', ' ', '-']; 12 | 13 | pub trait ToSanitizedPascalCase { 14 | fn to_sanitized_pascal_case(&self) -> Cow; 15 | } 16 | 17 | pub trait ToSanitizedUpperCase { 18 | fn to_sanitized_upper_case(&self) -> Cow; 19 | } 20 | 21 | pub trait ToSanitizedSnakeCase { 22 | fn to_sanitized_snake_case(&self) -> Cow; 23 | } 24 | 25 | impl ToSanitizedSnakeCase for str { 26 | fn to_sanitized_snake_case(&self) -> Cow { 27 | macro_rules! keywords { 28 | ($s:expr, $($kw:ident),+,) => { 29 | Cow::from(match &$s.to_lowercase()[..] { 30 | $(stringify!($kw) => concat!(stringify!($kw), "_")),+, 31 | _ => return Cow::from($s.to_snake_case()) 32 | }) 33 | } 34 | } 35 | 36 | let s = self.replace(BLACKLIST_CHARS, ""); 37 | 38 | match s.chars().next().unwrap_or('\0') { 39 | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => { 40 | Cow::from(format!("_{}", s.to_snake_case())) 41 | } 42 | _ => { 43 | keywords! { 44 | s, 45 | abstract, 46 | alignof, 47 | as, 48 | async, 49 | await, 50 | become, 51 | box, 52 | break, 53 | const, 54 | continue, 55 | crate, 56 | do, 57 | else, 58 | enum, 59 | extern, 60 | false, 61 | final, 62 | fn, 63 | for, 64 | if, 65 | impl, 66 | in, 67 | let, 68 | loop, 69 | macro, 70 | match, 71 | mod, 72 | move, 73 | mut, 74 | offsetof, 75 | override, 76 | priv, 77 | proc, 78 | pub, 79 | pure, 80 | ref, 81 | return, 82 | self, 83 | sizeof, 84 | static, 85 | struct, 86 | super, 87 | trait, 88 | true, 89 | try, 90 | type, 91 | typeof, 92 | unsafe, 93 | unsized, 94 | use, 95 | virtual, 96 | where, 97 | while, 98 | yield, 99 | set_bit, 100 | clear_bit, 101 | bit, 102 | bits, 103 | } 104 | } 105 | } 106 | } 107 | } 108 | 109 | impl ToSanitizedUpperCase for str { 110 | fn to_sanitized_upper_case(&self) -> Cow { 111 | let s = self.replace(BLACKLIST_CHARS, ""); 112 | 113 | match s.chars().next().unwrap_or('\0') { 114 | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => { 115 | Cow::from(format!("_{}", s.to_upper_case())) 116 | } 117 | _ => Cow::from(s.to_upper_case()), 118 | } 119 | } 120 | } 121 | 122 | impl ToSanitizedPascalCase for str { 123 | fn to_sanitized_pascal_case(&self) -> Cow { 124 | let s = self.replace(BLACKLIST_CHARS, ""); 125 | 126 | match s.chars().next().unwrap_or('\0') { 127 | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => { 128 | Cow::from(format!("_{}", s.to_pascal_case())) 129 | } 130 | _ => Cow::from(s.to_pascal_case()), 131 | } 132 | } 133 | } 134 | 135 | pub fn respace(s: &str) -> String { 136 | s.split_whitespace().collect::>().join(" ") 137 | } 138 | 139 | pub fn escape_brackets(s: &str) -> String { 140 | s.split('[') 141 | .fold("".to_string(), |acc, x| { 142 | if acc.is_empty() { 143 | x.to_string() 144 | } else if acc.ends_with('\\') { 145 | acc + "[" + x 146 | } else { 147 | acc + "\\[" + x 148 | } 149 | }) 150 | .split(']') 151 | .fold("".to_string(), |acc, x| { 152 | if acc.is_empty() { 153 | x.to_string() 154 | } else if acc.ends_with('\\') { 155 | acc + "]" + x 156 | } else { 157 | acc + "\\]" + x 158 | } 159 | }) 160 | } 161 | 162 | pub fn replace_suffix(name: &str, suffix: &str) -> String { 163 | if name.contains("[%s]") { 164 | name.replace("[%s]", suffix) 165 | } else { 166 | name.replace("%s", suffix) 167 | } 168 | } 169 | 170 | /// Turns `n` into an unsuffixed separated hex token 171 | pub fn hex(n: u64) -> TokenStream { 172 | let (h4, h3, h2, h1) = ( 173 | (n >> 48) & 0xffff, 174 | (n >> 32) & 0xffff, 175 | (n >> 16) & 0xffff, 176 | n & 0xffff, 177 | ); 178 | TokenStream::from_str( 179 | &(if h4 != 0 { 180 | format!("0x{:04x}_{:04x}_{:04x}_{:04x}", h4, h3, h2, h1) 181 | } else if h3 != 0 { 182 | format!("0x{:04x}_{:04x}_{:04x}", h3, h2, h1) 183 | } else if h2 != 0 { 184 | format!("0x{:04x}_{:04x}", h2, h1) 185 | } else if h1 & 0xff00 != 0 { 186 | format!("0x{:04x}", h1) 187 | } else if h1 != 0 { 188 | format!("0x{:02x}", h1 & 0xff) 189 | } else { 190 | "0".to_string() 191 | }), 192 | ) 193 | .unwrap() 194 | } 195 | 196 | /// Turns `n` into an unsuffixed token 197 | pub fn unsuffixed(n: u64) -> TokenStream { 198 | Literal::u64_unsuffixed(n).into_token_stream() 199 | } 200 | 201 | pub fn unsuffixed_or_bool(n: u64, width: u32) -> TokenStream { 202 | if width == 1 { 203 | Ident::new(if n == 0 { "false" } else { "true" }, Span::call_site()).into_token_stream() 204 | } else { 205 | unsuffixed(n) 206 | } 207 | } 208 | 209 | pub trait U32Ext { 210 | fn to_ty(&self) -> Result; 211 | fn to_ty_width(&self) -> Result; 212 | } 213 | 214 | impl U32Ext for u32 { 215 | fn to_ty(&self) -> Result { 216 | Ok(Ident::new( 217 | match *self { 218 | 1 => "bool", 219 | 2..=8 => "u8", 220 | 9..=16 => "u16", 221 | 17..=32 => "u32", 222 | 33..=64 => "u64", 223 | _ => { 224 | return Err(anyhow!( 225 | "can't convert {} bits into a Rust integral type", 226 | *self 227 | )) 228 | } 229 | }, 230 | Span::call_site(), 231 | )) 232 | } 233 | 234 | fn to_ty_width(&self) -> Result { 235 | Ok(match *self { 236 | 1 => 1, 237 | 2..=8 => 8, 238 | 9..=16 => 16, 239 | 17..=32 => 32, 240 | 33..=64 => 64, 241 | _ => { 242 | return Err(anyhow!( 243 | "can't convert {} bits into a Rust integral type width", 244 | *self 245 | )) 246 | } 247 | }) 248 | } 249 | } 250 | 251 | pub fn build_rs() -> TokenStream { 252 | quote! { 253 | use std::env; 254 | use std::fs::File; 255 | use std::io::Write; 256 | use std::path::PathBuf; 257 | 258 | fn main() { 259 | if env::var_os("CARGO_FEATURE_RT").is_some() { 260 | // Put the linker script somewhere the linker can find it 261 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 262 | File::create(out.join("device.x")) 263 | .unwrap() 264 | .write_all(include_bytes!("device.x")) 265 | .unwrap(); 266 | println!("cargo:rustc-link-search={}", out.display()); 267 | 268 | println!("cargo:rerun-if-changed=device.x"); 269 | } 270 | 271 | println!("cargo:rerun-if-changed=build.rs"); 272 | } 273 | } 274 | } 275 | /// Return a relative path to access a from b. 276 | pub fn relative_path(a: &str, b: &str) -> TokenStream { 277 | let a: Vec<&str> = a.split("::").collect(); 278 | let b: Vec<&str> = b.split("::").collect(); 279 | 280 | let mut ma = &a[..a.len() - 1]; 281 | let mut mb = &b[..b.len() - 1]; 282 | while !ma.is_empty() && !mb.is_empty() && ma[0] == mb[0] { 283 | ma = &ma[1..]; 284 | mb = &mb[1..]; 285 | } 286 | 287 | let mut res = TokenStream::new(); 288 | 289 | // for each item left in b, append a `super` 290 | for _ in mb { 291 | res.extend(quote!(super::)); 292 | } 293 | 294 | // for each item in a, append it 295 | for ident in ma { 296 | let ident = Ident::new(ident, Span::call_site()); 297 | res.extend(quote!(#ident::)); 298 | } 299 | 300 | let ident = Ident::new(a[a.len() - 1], Span::call_site()); 301 | res.extend(quote!(#ident)); 302 | 303 | res 304 | } 305 | 306 | pub fn absolute_path(path: &str) -> TokenStream { 307 | path.split("::") 308 | .map(|part| Ident::new(part, Span::call_site())) 309 | .fold(quote!(crate), |mut path, ident| { 310 | path.extend(quote!(::#ident)); 311 | path 312 | }) 313 | } 314 | 315 | pub fn doc(doc: &Option) -> TokenStream { 316 | if let Some(doc) = doc { 317 | let doc = doc.replace("\\n", "\n"); 318 | let doc = respace(&doc); 319 | let doc = escape_brackets(&doc); 320 | quote!(#[doc=#doc]) 321 | } else { 322 | quote!() 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /script/check_latest.sh: -------------------------------------------------------------------------------- 1 | git diff > ./diff 2 | file_size=$(stat --printf="%s" ./diff) 3 | 4 | if [ $file_size == 0 ]; then 5 | echo "No difference found" 6 | exit 0 7 | else 8 | echo "Found difference" 9 | git --no-pager diff 10 | exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /script/group_value.py: -------------------------------------------------------------------------------- 1 | FILED = [ 2 | "ADC1", 3 | "ADC2", 4 | "ADC3", 5 | "ACMP", 6 | "I2S0", 7 | "I2S1", 8 | "I2S2", 9 | "I2S3", 10 | "PDM", 11 | "DAO", 12 | "SYNT", 13 | "MOTO", 14 | "MOT1", 15 | "MOT2", 16 | "MOT3", 17 | "LCDC", 18 | "CAMO", 19 | "CAM1", 20 | "JPEG", 21 | "PDMA", 22 | "ENETO", 23 | "ENET1", 24 | "NTMRO", 25 | "NTMR1", 26 | "SDXC0", 27 | "SDXC1", 28 | "USBO", 29 | "USB1", 30 | ] 31 | 32 | 33 | def print_field(name: str, offset: int): 34 | print( 35 | f"""{name}: 36 | bitOffset: {offset} 37 | bitWidth: 1""" 38 | ) 39 | 40 | 41 | def main(): 42 | for index, name in enumerate(FILED): 43 | print_field(name, index) 44 | 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/bcfg.rs: -------------------------------------------------------------------------------- 1 | #[doc = "BCFG"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Bandgap config"] 5 | pub VBG_CFG: crate::RWRegister, 6 | #[doc = "LDO config"] 7 | pub LDO_CFG: crate::RWRegister, 8 | #[doc = "On-chip 32k oscillator config"] 9 | pub IRC32K_CFG: crate::RWRegister, 10 | #[doc = "XTAL 32K config"] 11 | pub XTAL32K_CFG: crate::RWRegister, 12 | #[doc = "Clock config"] 13 | pub CLK_CFG: crate::RWRegister, 14 | } 15 | #[doc = "Bandgap config"] 16 | pub mod VBG_CFG { 17 | #[doc = "Bandgap 0.50V output trim"] 18 | pub mod VBG_P50 { 19 | pub const offset: u32 = 0; 20 | pub const mask: u32 = 0x1f << offset; 21 | pub mod R {} 22 | pub mod W {} 23 | pub mod RW {} 24 | } 25 | #[doc = "Bandgap 0.65V output trim"] 26 | pub mod VBG_P65 { 27 | pub const offset: u32 = 8; 28 | pub const mask: u32 = 0x1f << offset; 29 | pub mod R {} 30 | pub mod W {} 31 | pub mod RW {} 32 | } 33 | #[doc = "Bandgap 1.0V output trim"] 34 | pub mod VBG_1P0 { 35 | pub const offset: u32 = 16; 36 | pub const mask: u32 = 0x1f << offset; 37 | pub mod R {} 38 | pub mod W {} 39 | pub mod RW {} 40 | } 41 | #[doc = "Bandgap works in power save mode 0: not in power save mode 1: bandgap work in power save mode"] 42 | pub mod POWER_SAVE { 43 | pub const offset: u32 = 24; 44 | pub const mask: u32 = 0x01 << offset; 45 | pub mod R {} 46 | pub mod W {} 47 | pub mod RW {} 48 | } 49 | #[doc = "Bandgap works in low power mode 0: not in low power mode 1: bandgap work in low power mode"] 50 | pub mod LP_MODE { 51 | pub const offset: u32 = 25; 52 | pub const mask: u32 = 0x01 << offset; 53 | pub mod R {} 54 | pub mod W {} 55 | pub mod RW {} 56 | } 57 | #[doc = "Bandgap trim happened, this bit set by hardware after trim value loaded, and stop load, write 0 will clear this bit and reload trim value 0: bandgap is not trimmed 1: bandgap is trimmed"] 58 | pub mod VBG_TRIMMED { 59 | pub const offset: u32 = 31; 60 | pub const mask: u32 = 0x01 << offset; 61 | pub mod R {} 62 | pub mod W {} 63 | pub mod RW {} 64 | } 65 | } 66 | #[doc = "LDO config"] 67 | pub mod LDO_CFG { 68 | #[doc = "LDO voltage setting in mV, valid range through 600mV to 1100mV, step 20mV. Hardware select voltage no less than target if not on valid steps, with maximum 1100mV. 600: 600mV 620: 620mV . . . 1100:1100mV"] 69 | pub mod VOLT { 70 | pub const offset: u32 = 0; 71 | pub const mask: u32 = 0x0fff << offset; 72 | pub mod R {} 73 | pub mod W {} 74 | pub mod RW {} 75 | } 76 | #[doc = "LDO enable 0: LDO is disabled 1: LDO is enabled"] 77 | pub mod ENABLE { 78 | pub const offset: u32 = 16; 79 | pub const mask: u32 = 0x01 << offset; 80 | pub mod R {} 81 | pub mod W {} 82 | pub mod RW {} 83 | } 84 | #[doc = "disable pull down resistor, enable pull down may lead to more power but better response 0: pulldown resistor enabled 1: pulldown resistor disabled"] 85 | pub mod DIS_PD { 86 | pub const offset: u32 = 17; 87 | pub const mask: u32 = 0x01 << offset; 88 | pub mod R {} 89 | pub mod W {} 90 | pub mod RW {} 91 | } 92 | #[doc = "enable selfload, this bit helps improve LDO performance when current less than 200nA 0: self load disabled 1: selfload enabled"] 93 | pub mod EN_SL { 94 | pub const offset: u32 = 18; 95 | pub const mask: u32 = 0x01 << offset; 96 | pub mod R {} 97 | pub mod W {} 98 | pub mod RW {} 99 | } 100 | #[doc = "Capacitor trim"] 101 | pub mod CP_TRIM { 102 | pub const offset: u32 = 20; 103 | pub const mask: u32 = 0x03 << offset; 104 | pub mod R {} 105 | pub mod W {} 106 | pub mod RW {} 107 | } 108 | #[doc = "Resistor trim"] 109 | pub mod RES_TRIM { 110 | pub const offset: u32 = 24; 111 | pub const mask: u32 = 0x03 << offset; 112 | pub mod R {} 113 | pub mod W {} 114 | pub mod RW {} 115 | } 116 | } 117 | #[doc = "On-chip 32k oscillator config"] 118 | pub mod IRC32K_CFG { 119 | #[doc = "capacitor trim bits"] 120 | pub mod CAP_TRIM { 121 | pub const offset: u32 = 0; 122 | pub const mask: u32 = 0x01ff << offset; 123 | pub mod R {} 124 | pub mod W {} 125 | pub mod RW {} 126 | } 127 | #[doc = "IRC32K bit 6"] 128 | pub mod CAPEX6_TRIM { 129 | pub const offset: u32 = 22; 130 | pub const mask: u32 = 0x01 << offset; 131 | pub mod R {} 132 | pub mod W {} 133 | pub mod RW {} 134 | } 135 | #[doc = "IRC32K bit 7"] 136 | pub mod CAPEX7_TRIM { 137 | pub const offset: u32 = 23; 138 | pub const mask: u32 = 0x01 << offset; 139 | pub mod R {} 140 | pub mod W {} 141 | pub mod RW {} 142 | } 143 | #[doc = "IRC32K trim happened, this bit set by hardware after trim value loaded, and stop load, write 0 will clear this bit and reload trim value 0: irc is not trimmed 1: irc is trimmed"] 144 | pub mod IRC_TRIMMED { 145 | pub const offset: u32 = 31; 146 | pub const mask: u32 = 0x01 << offset; 147 | pub mod R {} 148 | pub mod W {} 149 | pub mod RW {} 150 | } 151 | } 152 | #[doc = "XTAL 32K config"] 153 | pub mod XTAL32K_CFG { 154 | #[doc = "crystal 32k amplifier"] 155 | pub mod AMP { 156 | pub const offset: u32 = 0; 157 | pub const mask: u32 = 0x03 << offset; 158 | pub mod R {} 159 | pub mod W {} 160 | pub mod RW {} 161 | } 162 | #[doc = "crystal 32k config"] 163 | pub mod CFG { 164 | pub const offset: u32 = 4; 165 | pub const mask: u32 = 0x01 << offset; 166 | pub mod R {} 167 | pub mod W {} 168 | pub mod RW {} 169 | } 170 | #[doc = "crystal 32k gm selection"] 171 | pub mod GMSEL { 172 | pub const offset: u32 = 8; 173 | pub const mask: u32 = 0x03 << offset; 174 | pub mod R {} 175 | pub mod W {} 176 | pub mod RW {} 177 | } 178 | #[doc = "crystal 32k hysteres enable"] 179 | pub mod HYST_EN { 180 | pub const offset: u32 = 12; 181 | pub const mask: u32 = 0x01 << offset; 182 | pub mod R {} 183 | pub mod W {} 184 | pub mod RW {} 185 | } 186 | } 187 | #[doc = "Clock config"] 188 | pub mod CLK_CFG { 189 | #[doc = "force switch to crystal"] 190 | pub mod FORCE_XTAL { 191 | pub const offset: u32 = 4; 192 | pub const mask: u32 = 0x01 << offset; 193 | pub mod R {} 194 | pub mod W {} 195 | pub mod RW {} 196 | } 197 | #[doc = "force irc32k run"] 198 | pub mod KEEP_IRC { 199 | pub const offset: u32 = 16; 200 | pub const mask: u32 = 0x01 << offset; 201 | pub mod R {} 202 | pub mod W {} 203 | pub mod RW {} 204 | } 205 | #[doc = "crystal selected"] 206 | pub mod XTAL_SEL { 207 | pub const offset: u32 = 28; 208 | pub const mask: u32 = 0x01 << offset; 209 | pub mod R {} 210 | pub mod W {} 211 | pub mod RW {} 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/bgpr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "BGPR"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Generic control"] 5 | pub BATT_GPR0: crate::RWRegister, 6 | #[doc = "Generic control"] 7 | pub BATT_GPR1: crate::RWRegister, 8 | #[doc = "Generic control"] 9 | pub BATT_GPR2: crate::RWRegister, 10 | #[doc = "Generic control"] 11 | pub BATT_GPR3: crate::RWRegister, 12 | #[doc = "Generic control"] 13 | pub BATT_GPR4: crate::RWRegister, 14 | #[doc = "Generic control"] 15 | pub BATT_GPR5: crate::RWRegister, 16 | #[doc = "Generic control"] 17 | pub BATT_GPR6: crate::RWRegister, 18 | #[doc = "Generic control"] 19 | pub BATT_GPR7: crate::RWRegister, 20 | } 21 | #[doc = "Generic control"] 22 | pub mod BATT_GPR0 { 23 | #[doc = "Generic control"] 24 | pub mod GPR { 25 | pub const offset: u32 = 0; 26 | pub const mask: u32 = 0xffff_ffff << offset; 27 | pub mod R {} 28 | pub mod W {} 29 | pub mod RW {} 30 | } 31 | } 32 | #[doc = "Generic control"] 33 | pub mod BATT_GPR1 { 34 | #[doc = "Generic control"] 35 | pub mod GPR { 36 | pub const offset: u32 = 0; 37 | pub const mask: u32 = 0xffff_ffff << offset; 38 | pub mod R {} 39 | pub mod W {} 40 | pub mod RW {} 41 | } 42 | } 43 | #[doc = "Generic control"] 44 | pub mod BATT_GPR2 { 45 | #[doc = "Generic control"] 46 | pub mod GPR { 47 | pub const offset: u32 = 0; 48 | pub const mask: u32 = 0xffff_ffff << offset; 49 | pub mod R {} 50 | pub mod W {} 51 | pub mod RW {} 52 | } 53 | } 54 | #[doc = "Generic control"] 55 | pub mod BATT_GPR3 { 56 | #[doc = "Generic control"] 57 | pub mod GPR { 58 | pub const offset: u32 = 0; 59 | pub const mask: u32 = 0xffff_ffff << offset; 60 | pub mod R {} 61 | pub mod W {} 62 | pub mod RW {} 63 | } 64 | } 65 | #[doc = "Generic control"] 66 | pub mod BATT_GPR4 { 67 | #[doc = "Generic control"] 68 | pub mod GPR { 69 | pub const offset: u32 = 0; 70 | pub const mask: u32 = 0xffff_ffff << offset; 71 | pub mod R {} 72 | pub mod W {} 73 | pub mod RW {} 74 | } 75 | } 76 | #[doc = "Generic control"] 77 | pub mod BATT_GPR5 { 78 | #[doc = "Generic control"] 79 | pub mod GPR { 80 | pub const offset: u32 = 0; 81 | pub const mask: u32 = 0xffff_ffff << offset; 82 | pub mod R {} 83 | pub mod W {} 84 | pub mod RW {} 85 | } 86 | } 87 | #[doc = "Generic control"] 88 | pub mod BATT_GPR6 { 89 | #[doc = "Generic control"] 90 | pub mod GPR { 91 | pub const offset: u32 = 0; 92 | pub const mask: u32 = 0xffff_ffff << offset; 93 | pub mod R {} 94 | pub mod W {} 95 | pub mod RW {} 96 | } 97 | } 98 | #[doc = "Generic control"] 99 | pub mod BATT_GPR7 { 100 | #[doc = "Generic control"] 101 | pub mod GPR { 102 | pub const offset: u32 = 0; 103 | pub const mask: u32 = 0xffff_ffff << offset; 104 | pub mod R {} 105 | pub mod W {} 106 | pub mod RW {} 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/bkey.rs: -------------------------------------------------------------------------------- 1 | #[doc = "BKEY"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Key data"] 5 | pub KEY_0_DATA_0: crate::RWRegister, 6 | #[doc = "Key data"] 7 | pub KEY_0_DATA_1: crate::RWRegister, 8 | #[doc = "Key data"] 9 | pub KEY_0_DATA_2: crate::RWRegister, 10 | #[doc = "Key data"] 11 | pub KEY_0_DATA_3: crate::RWRegister, 12 | #[doc = "Key data"] 13 | pub KEY_0_DATA_4: crate::RWRegister, 14 | #[doc = "Key data"] 15 | pub KEY_0_DATA_5: crate::RWRegister, 16 | #[doc = "Key data"] 17 | pub KEY_0_DATA_6: crate::RWRegister, 18 | #[doc = "Key data"] 19 | pub KEY_0_DATA_7: crate::RWRegister, 20 | #[doc = "Key data"] 21 | pub KEY_1_DATA_0: crate::RWRegister, 22 | #[doc = "Key data"] 23 | pub KEY_1_DATA_1: crate::RWRegister, 24 | #[doc = "Key data"] 25 | pub KEY_1_DATA_2: crate::RWRegister, 26 | #[doc = "Key data"] 27 | pub KEY_1_DATA_3: crate::RWRegister, 28 | #[doc = "Key data"] 29 | pub KEY_1_DATA_4: crate::RWRegister, 30 | #[doc = "Key data"] 31 | pub KEY_1_DATA_5: crate::RWRegister, 32 | #[doc = "Key data"] 33 | pub KEY_1_DATA_6: crate::RWRegister, 34 | #[doc = "Key data"] 35 | pub KEY_1_DATA_7: crate::RWRegister, 36 | #[doc = "Key ECC and access control"] 37 | pub ECC_KEY0: crate::RWRegister, 38 | #[doc = "Key 1 ECC and access control"] 39 | pub ECC_KEY1: crate::RWRegister, 40 | #[doc = "Key selection"] 41 | pub SELECT: crate::RWRegister, 42 | } 43 | #[doc = "Key data"] 44 | pub mod KEY_0_DATA_0 { 45 | #[doc = "security key data"] 46 | pub mod DATA { 47 | pub const offset: u32 = 0; 48 | pub const mask: u32 = 0xffff_ffff << offset; 49 | pub mod R {} 50 | pub mod W {} 51 | pub mod RW {} 52 | } 53 | } 54 | #[doc = "Key data"] 55 | pub mod KEY_0_DATA_1 { 56 | #[doc = "security key data"] 57 | pub mod DATA { 58 | pub const offset: u32 = 0; 59 | pub const mask: u32 = 0xffff_ffff << offset; 60 | pub mod R {} 61 | pub mod W {} 62 | pub mod RW {} 63 | } 64 | } 65 | #[doc = "Key data"] 66 | pub mod KEY_0_DATA_2 { 67 | #[doc = "security key data"] 68 | pub mod DATA { 69 | pub const offset: u32 = 0; 70 | pub const mask: u32 = 0xffff_ffff << offset; 71 | pub mod R {} 72 | pub mod W {} 73 | pub mod RW {} 74 | } 75 | } 76 | #[doc = "Key data"] 77 | pub mod KEY_0_DATA_3 { 78 | #[doc = "security key data"] 79 | pub mod DATA { 80 | pub const offset: u32 = 0; 81 | pub const mask: u32 = 0xffff_ffff << offset; 82 | pub mod R {} 83 | pub mod W {} 84 | pub mod RW {} 85 | } 86 | } 87 | #[doc = "Key data"] 88 | pub mod KEY_0_DATA_4 { 89 | #[doc = "security key data"] 90 | pub mod DATA { 91 | pub const offset: u32 = 0; 92 | pub const mask: u32 = 0xffff_ffff << offset; 93 | pub mod R {} 94 | pub mod W {} 95 | pub mod RW {} 96 | } 97 | } 98 | #[doc = "Key data"] 99 | pub mod KEY_0_DATA_5 { 100 | #[doc = "security key data"] 101 | pub mod DATA { 102 | pub const offset: u32 = 0; 103 | pub const mask: u32 = 0xffff_ffff << offset; 104 | pub mod R {} 105 | pub mod W {} 106 | pub mod RW {} 107 | } 108 | } 109 | #[doc = "Key data"] 110 | pub mod KEY_0_DATA_6 { 111 | #[doc = "security key data"] 112 | pub mod DATA { 113 | pub const offset: u32 = 0; 114 | pub const mask: u32 = 0xffff_ffff << offset; 115 | pub mod R {} 116 | pub mod W {} 117 | pub mod RW {} 118 | } 119 | } 120 | #[doc = "Key data"] 121 | pub mod KEY_0_DATA_7 { 122 | #[doc = "security key data"] 123 | pub mod DATA { 124 | pub const offset: u32 = 0; 125 | pub const mask: u32 = 0xffff_ffff << offset; 126 | pub mod R {} 127 | pub mod W {} 128 | pub mod RW {} 129 | } 130 | } 131 | #[doc = "Key data"] 132 | pub mod KEY_1_DATA_0 { 133 | #[doc = "security key data"] 134 | pub mod DATA { 135 | pub const offset: u32 = 0; 136 | pub const mask: u32 = 0xffff_ffff << offset; 137 | pub mod R {} 138 | pub mod W {} 139 | pub mod RW {} 140 | } 141 | } 142 | #[doc = "Key data"] 143 | pub mod KEY_1_DATA_1 { 144 | #[doc = "security key data"] 145 | pub mod DATA { 146 | pub const offset: u32 = 0; 147 | pub const mask: u32 = 0xffff_ffff << offset; 148 | pub mod R {} 149 | pub mod W {} 150 | pub mod RW {} 151 | } 152 | } 153 | #[doc = "Key data"] 154 | pub mod KEY_1_DATA_2 { 155 | #[doc = "security key data"] 156 | pub mod DATA { 157 | pub const offset: u32 = 0; 158 | pub const mask: u32 = 0xffff_ffff << offset; 159 | pub mod R {} 160 | pub mod W {} 161 | pub mod RW {} 162 | } 163 | } 164 | #[doc = "Key data"] 165 | pub mod KEY_1_DATA_3 { 166 | #[doc = "security key data"] 167 | pub mod DATA { 168 | pub const offset: u32 = 0; 169 | pub const mask: u32 = 0xffff_ffff << offset; 170 | pub mod R {} 171 | pub mod W {} 172 | pub mod RW {} 173 | } 174 | } 175 | #[doc = "Key data"] 176 | pub mod KEY_1_DATA_4 { 177 | #[doc = "security key data"] 178 | pub mod DATA { 179 | pub const offset: u32 = 0; 180 | pub const mask: u32 = 0xffff_ffff << offset; 181 | pub mod R {} 182 | pub mod W {} 183 | pub mod RW {} 184 | } 185 | } 186 | #[doc = "Key data"] 187 | pub mod KEY_1_DATA_5 { 188 | #[doc = "security key data"] 189 | pub mod DATA { 190 | pub const offset: u32 = 0; 191 | pub const mask: u32 = 0xffff_ffff << offset; 192 | pub mod R {} 193 | pub mod W {} 194 | pub mod RW {} 195 | } 196 | } 197 | #[doc = "Key data"] 198 | pub mod KEY_1_DATA_6 { 199 | #[doc = "security key data"] 200 | pub mod DATA { 201 | pub const offset: u32 = 0; 202 | pub const mask: u32 = 0xffff_ffff << offset; 203 | pub mod R {} 204 | pub mod W {} 205 | pub mod RW {} 206 | } 207 | } 208 | #[doc = "Key data"] 209 | pub mod KEY_1_DATA_7 { 210 | #[doc = "security key data"] 211 | pub mod DATA { 212 | pub const offset: u32 = 0; 213 | pub const mask: u32 = 0xffff_ffff << offset; 214 | pub mod R {} 215 | pub mod W {} 216 | pub mod RW {} 217 | } 218 | } 219 | #[doc = "Key ECC and access control"] 220 | pub mod ECC_KEY0 { 221 | #[doc = "Parity check bits for key0"] 222 | pub mod ECC { 223 | pub const offset: u32 = 0; 224 | pub const mask: u32 = 0xffff << offset; 225 | pub mod R {} 226 | pub mod W {} 227 | pub mod RW {} 228 | } 229 | #[doc = "read lock to key0 0: key read enable 1: key always read as 0"] 230 | pub mod RLOCK { 231 | pub const offset: u32 = 30; 232 | pub const mask: u32 = 0x01 << offset; 233 | pub mod R {} 234 | pub mod W {} 235 | pub mod RW {} 236 | } 237 | #[doc = "write lock to key0 0: write enable 1: write ignored"] 238 | pub mod WLOCK { 239 | pub const offset: u32 = 31; 240 | pub const mask: u32 = 0x01 << offset; 241 | pub mod R {} 242 | pub mod W {} 243 | pub mod RW {} 244 | } 245 | } 246 | #[doc = "Key 1 ECC and access control"] 247 | pub mod ECC_KEY1 { 248 | #[doc = "Parity check bits for key0"] 249 | pub mod ECC { 250 | pub const offset: u32 = 0; 251 | pub const mask: u32 = 0xffff << offset; 252 | pub mod R {} 253 | pub mod W {} 254 | pub mod RW {} 255 | } 256 | #[doc = "read lock to key0 0: key read enable 1: key always read as 0"] 257 | pub mod RLOCK { 258 | pub const offset: u32 = 30; 259 | pub const mask: u32 = 0x01 << offset; 260 | pub mod R {} 261 | pub mod W {} 262 | pub mod RW {} 263 | } 264 | #[doc = "write lock to key0 0: write enable 1: write ignored"] 265 | pub mod WLOCK { 266 | pub const offset: u32 = 31; 267 | pub const mask: u32 = 0x01 << offset; 268 | pub mod R {} 269 | pub mod W {} 270 | pub mod RW {} 271 | } 272 | } 273 | #[doc = "Key selection"] 274 | pub mod SELECT { 275 | #[doc = "select key, key0 treated as secure key, in non-scure mode, only key1 can be selected 0: select key0 in secure mode, key1 in non-secure mode 1: select key1 in secure or nonsecure mode"] 276 | pub mod SELECT { 277 | pub const offset: u32 = 0; 278 | pub const mask: u32 = 0x01 << offset; 279 | pub mod R {} 280 | pub mod W {} 281 | pub mod RW {} 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/bmon.rs: -------------------------------------------------------------------------------- 1 | #[doc = "BMON"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Glitch and clock monitor control"] 5 | pub MONITOR_GLITCH0_CONTROL: crate::RWRegister, 6 | #[doc = "Glitch and clock monitor status"] 7 | pub MONITOR_GLITCH0_STATUS: crate::RWRegister, 8 | _reserved0: [u8; 0x08], 9 | #[doc = "Glitch and clock monitor control"] 10 | pub MONITOR_CLOCK0_CONTROL: crate::RWRegister, 11 | #[doc = "Glitch and clock monitor status"] 12 | pub MONITOR_CLOCK0_STATUS: crate::RWRegister, 13 | } 14 | #[doc = "Glitch and clock monitor control"] 15 | pub mod MONITOR_GLITCH0_CONTROL { 16 | #[doc = "enable glitch detector 0: detector disabled 1: detector enabled"] 17 | pub mod ENABLE { 18 | pub const offset: u32 = 0; 19 | pub const mask: u32 = 0x01 << offset; 20 | pub mod R {} 21 | pub mod W {} 22 | pub mod RW {} 23 | } 24 | #[doc = "select glitch works in active mode or passve mode. 0: passive mode, depends on power glitch destory DFF value 1: active mode, check glitch by DFF chain"] 25 | pub mod ACTIVE { 26 | pub const offset: u32 = 4; 27 | pub const mask: u32 = 0x01 << offset; 28 | pub mod R {} 29 | pub mod W {} 30 | pub mod RW {} 31 | } 32 | } 33 | #[doc = "Glitch and clock monitor status"] 34 | pub mod MONITOR_GLITCH0_STATUS { 35 | #[doc = "flag for glitch detected, write 1 to clear this flag 0: glitch not detected 1: glitch detected"] 36 | pub mod FLAG { 37 | pub const offset: u32 = 0; 38 | pub const mask: u32 = 0x01 << offset; 39 | pub mod R {} 40 | pub mod W {} 41 | pub mod RW {} 42 | } 43 | } 44 | #[doc = "Glitch and clock monitor control"] 45 | pub mod MONITOR_CLOCK0_CONTROL { 46 | #[doc = "enable glitch detector 0: detector disabled 1: detector enabled"] 47 | pub mod ENABLE { 48 | pub const offset: u32 = 0; 49 | pub const mask: u32 = 0x01 << offset; 50 | pub mod R {} 51 | pub mod W {} 52 | pub mod RW {} 53 | } 54 | #[doc = "select glitch works in active mode or passve mode. 0: passive mode, depends on power glitch destory DFF value 1: active mode, check glitch by DFF chain"] 55 | pub mod ACTIVE { 56 | pub const offset: u32 = 4; 57 | pub const mask: u32 = 0x01 << offset; 58 | pub mod R {} 59 | pub mod W {} 60 | pub mod RW {} 61 | } 62 | } 63 | #[doc = "Glitch and clock monitor status"] 64 | pub mod MONITOR_CLOCK0_STATUS { 65 | #[doc = "flag for glitch detected, write 1 to clear this flag 0: glitch not detected 1: glitch detected"] 66 | pub mod FLAG { 67 | pub const offset: u32 = 0; 68 | pub const mask: u32 = 0x01 << offset; 69 | pub mod R {} 70 | pub mod W {} 71 | pub mod RW {} 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/bpor.rs: -------------------------------------------------------------------------------- 1 | #[doc = "BPOR"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Power on cause"] 5 | pub POR_CAUSE: crate::RWRegister, 6 | #[doc = "Power on select"] 7 | pub POR_SELECT: crate::RWRegister, 8 | #[doc = "Power on reset config"] 9 | pub POR_CONFIG: crate::RWRegister, 10 | #[doc = "Power down control"] 11 | pub POR_CONTROL: crate::RWRegister, 12 | } 13 | #[doc = "Power on cause"] 14 | pub mod POR_CAUSE { 15 | #[doc = "Power on cause, each bit represnts one cause, write 1 to clear each bit bit0: wakeup button bit1: security violation bit2: RTC alarm 0 bit3: RTC alarm 1 bit4: GPIO"] 16 | pub mod CAUSE { 17 | pub const offset: u32 = 0; 18 | pub const mask: u32 = 0x1f << offset; 19 | pub mod R {} 20 | pub mod W {} 21 | pub mod RW {} 22 | } 23 | } 24 | #[doc = "Power on select"] 25 | pub mod POR_SELECT { 26 | #[doc = "Power on cause select, each bit represnts one cause, value 1 enables corresponding cause bit0: wakeup button bit1: security violation bit2: RTC alarm 0 bit3: RTC alarm 1 bit4: GPIO"] 27 | pub mod SELECT { 28 | pub const offset: u32 = 0; 29 | pub const mask: u32 = 0x1f << offset; 30 | pub mod R {} 31 | pub mod W {} 32 | pub mod RW {} 33 | } 34 | } 35 | #[doc = "Power on reset config"] 36 | pub mod POR_CONFIG { 37 | #[doc = "retention battery domain setting 0: battery reset on reset pin reset happen 1: battery domain retention when reset pin reset happen"] 38 | pub mod RETENTION { 39 | pub const offset: u32 = 0; 40 | pub const mask: u32 = 0x01 << offset; 41 | pub mod R {} 42 | pub mod W {} 43 | pub mod RW {} 44 | } 45 | } 46 | #[doc = "Power down control"] 47 | pub mod POR_CONTROL { 48 | #[doc = "Chip power down counter, counter decreasing if value is not 0, power down of chip happens on counter value is 1"] 49 | pub mod COUNTER { 50 | pub const offset: u32 = 0; 51 | pub const mask: u32 = 0xffff << offset; 52 | pub mod R {} 53 | pub mod W {} 54 | pub mod RW {} 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/bsec.rs: -------------------------------------------------------------------------------- 1 | #[doc = "BSEC"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Secure state"] 5 | pub SECURE_STATE: crate::RWRegister, 6 | #[doc = "secure state configuration"] 7 | pub SECURE_STATE_CONFIG: crate::RWRegister, 8 | #[doc = "Security violation config"] 9 | pub VIOLATION_CONFIG: crate::RWRegister, 10 | #[doc = "Escalate behavior on security event"] 11 | pub ESCALATE_CONFIG: crate::RWRegister, 12 | #[doc = "Event and escalate status"] 13 | pub EVENT: crate::RWRegister, 14 | } 15 | #[doc = "Secure state"] 16 | pub mod SECURE_STATE { 17 | #[doc = "BATT secure state one hot indicator 0: secure state is not in inspect state 1: secure state is in inspect state"] 18 | pub mod BATT_INS { 19 | pub const offset: u32 = 0; 20 | pub const mask: u32 = 0x01 << offset; 21 | pub mod R {} 22 | pub mod W {} 23 | pub mod RW {} 24 | } 25 | #[doc = "BATT secure state one hot indicator 0: secure state is not in secure state 1: secure state is in secure state"] 26 | pub mod BATT_SEC { 27 | pub const offset: u32 = 1; 28 | pub const mask: u32 = 0x01 << offset; 29 | pub mod R {} 30 | pub mod W {} 31 | pub mod RW {} 32 | } 33 | #[doc = "BATT secure state one hot indicator 0: secure state is not in non-secure state 1: secure state is in non-secure state"] 34 | pub mod BATT_NSC { 35 | pub const offset: u32 = 2; 36 | pub const mask: u32 = 0x01 << offset; 37 | pub mod R {} 38 | pub mod W {} 39 | pub mod RW {} 40 | } 41 | #[doc = "BATT secure state one hot indicator 0: secure state is not in fail state 1: secure state is in fail state"] 42 | pub mod BATT_FAIL { 43 | pub const offset: u32 = 3; 44 | pub const mask: u32 = 0x01 << offset; 45 | pub mod R {} 46 | pub mod W {} 47 | pub mod RW {} 48 | } 49 | #[doc = "Secure state allow 0: system is not healthy to enter secure state, request to enter non-secure state will cause a fail state 1: system is healthy to enter secure state"] 50 | pub mod ALLOW_SEC { 51 | pub const offset: u32 = 16; 52 | pub const mask: u32 = 0x01 << offset; 53 | pub mod R {} 54 | pub mod W {} 55 | pub mod RW {} 56 | } 57 | #[doc = "Non-secure state allow 0: system is not healthy to enter non-secure state, request to enter non-secure state will cause a fail state 1: system is healthy to enter non-secure state"] 58 | pub mod ALLOW_NSC { 59 | pub const offset: u32 = 17; 60 | pub const mask: u32 = 0x01 << offset; 61 | pub mod R {} 62 | pub mod W {} 63 | pub mod RW {} 64 | } 65 | } 66 | #[doc = "secure state configuration"] 67 | pub mod SECURE_STATE_CONFIG { 68 | #[doc = "allow secure state restart from fail state 0: restart is not allowed, only hardware reset can recover secure state 1: software is allowed to switch to inspect state from fail state"] 69 | pub mod ALLOW_RESTART { 70 | pub const offset: u32 = 0; 71 | pub const mask: u32 = 0x01 << offset; 72 | pub mod R {} 73 | pub mod W {} 74 | pub mod RW {} 75 | } 76 | #[doc = "Lock bit of allow restart setting, once locked, lock bit itself and configuration register will keep value until next reset 0: not locked, register can be modified 1: register locked, write access to the register is ignored"] 77 | pub mod LOCK { 78 | pub const offset: u32 = 3; 79 | pub const mask: u32 = 0x01 << offset; 80 | pub mod R {} 81 | pub mod W {} 82 | pub mod RW {} 83 | } 84 | } 85 | #[doc = "Security violation config"] 86 | pub mod VIOLATION_CONFIG { 87 | #[doc = "configuration of secure state violations, each bit represents one security event 0: event is not a security violation 1: event is a security violation"] 88 | pub mod SEC_VIO_CFG { 89 | pub const offset: u32 = 0; 90 | pub const mask: u32 = 0x7fff << offset; 91 | pub mod R {} 92 | pub mod W {} 93 | pub mod RW {} 94 | } 95 | #[doc = "Lock bit secure violation setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified 1: register locked, write access to the configuration is ignored"] 96 | pub mod LOCK_SEC { 97 | pub const offset: u32 = 15; 98 | pub const mask: u32 = 0x01 << offset; 99 | pub mod R {} 100 | pub mod W {} 101 | pub mod RW {} 102 | } 103 | #[doc = "configuration of non-secure state violations, each bit represents one security event 0: event is not a security violation 1: event is a security violation"] 104 | pub mod NSC_VIO_CFG { 105 | pub const offset: u32 = 16; 106 | pub const mask: u32 = 0x7fff << offset; 107 | pub mod R {} 108 | pub mod W {} 109 | pub mod RW {} 110 | } 111 | #[doc = "Lock bit non-secure violation setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified 1: register locked, write access to the configuration is ignored"] 112 | pub mod LOCK_NSC { 113 | pub const offset: u32 = 31; 114 | pub const mask: u32 = 0x01 << offset; 115 | pub mod R {} 116 | pub mod W {} 117 | pub mod RW {} 118 | } 119 | } 120 | #[doc = "Escalate behavior on security event"] 121 | pub mod ESCALATE_CONFIG { 122 | #[doc = "configuration of secure state escalates, each bit represents one security event 0: event is not a security escalate 1: event is a security escalate"] 123 | pub mod SEC_VIO_CFG { 124 | pub const offset: u32 = 0; 125 | pub const mask: u32 = 0x7fff << offset; 126 | pub mod R {} 127 | pub mod W {} 128 | pub mod RW {} 129 | } 130 | #[doc = "Lock bit secure escalate setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified1: register locked, write access to the configuration is ignored"] 131 | pub mod LOCK_SEC { 132 | pub const offset: u32 = 15; 133 | pub const mask: u32 = 0x01 << offset; 134 | pub mod R {} 135 | pub mod W {} 136 | pub mod RW {} 137 | } 138 | #[doc = "configuration of non-secure state escalates, each bit represents one security event 0: event is not a security escalate 1: event is a security escalate"] 139 | pub mod NSC_VIO_CFG { 140 | pub const offset: u32 = 16; 141 | pub const mask: u32 = 0x7fff << offset; 142 | pub mod R {} 143 | pub mod W {} 144 | pub mod RW {} 145 | } 146 | #[doc = "Lock bit non-secure escalate setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified 1: register locked, write access to the configuration is ignored"] 147 | pub mod LOCK_NSC { 148 | pub const offset: u32 = 31; 149 | pub const mask: u32 = 0x01 << offset; 150 | pub mod R {} 151 | pub mod W {} 152 | pub mod RW {} 153 | } 154 | } 155 | #[doc = "Event and escalate status"] 156 | pub mod EVENT { 157 | #[doc = "BATT is escalting ssecure event"] 158 | pub mod BATT_ESC_SEC { 159 | pub const offset: u32 = 0; 160 | pub const mask: u32 = 0x01 << offset; 161 | pub mod R {} 162 | pub mod W {} 163 | pub mod RW {} 164 | } 165 | #[doc = "BATT is escalating non-secure event"] 166 | pub mod BATT_ESC_NSC { 167 | pub const offset: u32 = 1; 168 | pub const mask: u32 = 0x01 << offset; 169 | pub mod R {} 170 | pub mod W {} 171 | pub mod RW {} 172 | } 173 | #[doc = "local event statue, each bit represents one security event"] 174 | pub mod EVENT { 175 | pub const offset: u32 = 16; 176 | pub const mask: u32 = 0xffff << offset; 177 | pub mod R {} 178 | pub mod W {} 179 | pub mod RW {} 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/butn.rs: -------------------------------------------------------------------------------- 1 | #[doc = "BUTN"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Button status"] 5 | pub BTN_STATUS: crate::RWRegister, 6 | #[doc = "Button interrupt mask"] 7 | pub BTN_IRQ_MASK: crate::RWRegister, 8 | #[doc = "Debounce setting"] 9 | pub LED_INTENSE: crate::RWRegister, 10 | } 11 | #[doc = "Button status"] 12 | pub mod BTN_STATUS { 13 | #[doc = "Power button press status, write 1 to clear flag bit0: button pressed bit1: button confirmd bit2: button long pressed bit3: button long long pressed"] 14 | pub mod PBTN { 15 | pub const offset: u32 = 0; 16 | pub const mask: u32 = 0x0f << offset; 17 | pub mod R {} 18 | pub mod W {} 19 | pub mod RW {} 20 | } 21 | #[doc = "Wake button press status, write 1 to clear flag bit0: button pressed bit1: button confirmd bit2: button long pressed bit3: button long long pressed"] 22 | pub mod WBTN { 23 | pub const offset: u32 = 4; 24 | pub const mask: u32 = 0x0f << offset; 25 | pub mod R {} 26 | pub mod W {} 27 | pub mod RW {} 28 | } 29 | #[doc = "Dual button press status, write 1 to clear flag bit0: button pressed bit1: button confirmd bit2: button long pressed bit3: button long long pressed"] 30 | pub mod DBTN { 31 | pub const offset: u32 = 8; 32 | pub const mask: u32 = 0x0f << offset; 33 | pub mod R {} 34 | pub mod W {} 35 | pub mod RW {} 36 | } 37 | #[doc = "power button click status, write 1 to clear flag bit0: clicked bit1: double clicked bit2: tripple clicked"] 38 | pub mod PCLICK { 39 | pub const offset: u32 = 16; 40 | pub const mask: u32 = 0x07 << offset; 41 | pub mod R {} 42 | pub mod W {} 43 | pub mod RW {} 44 | } 45 | #[doc = "power button click status when wake button held, write 1 to clear flag bit0: clicked bit1: double clicked bit2: tripple clicked"] 46 | pub mod XPCLICK { 47 | pub const offset: u32 = 20; 48 | pub const mask: u32 = 0x07 << offset; 49 | pub mod R {} 50 | pub mod W {} 51 | pub mod RW {} 52 | } 53 | #[doc = "wake button click status, write 1 to clear flag bit0: clicked bit1: double clicked bit2: tripple clicked"] 54 | pub mod WCLICK { 55 | pub const offset: u32 = 24; 56 | pub const mask: u32 = 0x07 << offset; 57 | pub mod R {} 58 | pub mod W {} 59 | pub mod RW {} 60 | } 61 | #[doc = "wake button click status when power button held, write 1 to clear flag bit0: clicked bit1: double clicked bit2: tripple clicked"] 62 | pub mod XWCLICK { 63 | pub const offset: u32 = 28; 64 | pub const mask: u32 = 0x07 << offset; 65 | pub mod R {} 66 | pub mod W {} 67 | pub mod RW {} 68 | } 69 | } 70 | #[doc = "Button interrupt mask"] 71 | pub mod BTN_IRQ_MASK { 72 | #[doc = "Power button press interrupt enable bit0: button pressed bit1: button confirmd bit2: button long pressed bit3: button long long pressed"] 73 | pub mod PBTN { 74 | pub const offset: u32 = 0; 75 | pub const mask: u32 = 0x0f << offset; 76 | pub mod R {} 77 | pub mod W {} 78 | pub mod RW {} 79 | } 80 | #[doc = "Wake button press interrupt enable bit0: button pressed bit1: button confirmd bit2: button long pressed bit3: button long long pressed"] 81 | pub mod WBTN { 82 | pub const offset: u32 = 4; 83 | pub const mask: u32 = 0x0f << offset; 84 | pub mod R {} 85 | pub mod W {} 86 | pub mod RW {} 87 | } 88 | #[doc = "Dual button press interrupt enable bit0: button pressed bit1: button confirmd bit2: button long pressed bit3: button long long pressed"] 89 | pub mod DBTN { 90 | pub const offset: u32 = 8; 91 | pub const mask: u32 = 0x0f << offset; 92 | pub mod R {} 93 | pub mod W {} 94 | pub mod RW {} 95 | } 96 | #[doc = "power button click interrupt enable bit0: clicked bit1: double clicked bit2: tripple clicked"] 97 | pub mod PCLICK { 98 | pub const offset: u32 = 16; 99 | pub const mask: u32 = 0x07 << offset; 100 | pub mod R {} 101 | pub mod W {} 102 | pub mod RW {} 103 | } 104 | #[doc = "power button click status when wake button held interrupt enable bit0: clicked bit1: double clicked bit2: tripple clicked"] 105 | pub mod XPCLICK { 106 | pub const offset: u32 = 20; 107 | pub const mask: u32 = 0x07 << offset; 108 | pub mod R {} 109 | pub mod W {} 110 | pub mod RW {} 111 | } 112 | #[doc = "wake button click interrupt enable bit0: clicked bit1: double clicked bit2: tripple clicked"] 113 | pub mod WCLICK { 114 | pub const offset: u32 = 24; 115 | pub const mask: u32 = 0x07 << offset; 116 | pub mod R {} 117 | pub mod W {} 118 | pub mod RW {} 119 | } 120 | #[doc = "wake button click status when power button held interrupt enable bit0: clicked bit1: double clicked bit2: tripple clicked"] 121 | pub mod XWCLICK { 122 | pub const offset: u32 = 28; 123 | pub const mask: u32 = 0x07 << offset; 124 | pub mod R {} 125 | pub mod W {} 126 | pub mod RW {} 127 | } 128 | } 129 | #[doc = "Debounce setting"] 130 | pub mod LED_INTENSE { 131 | #[doc = "Pbutton brightness 0"] 132 | pub mod PLED { 133 | pub const offset: u32 = 0; 134 | pub const mask: u32 = 0x0f << offset; 135 | pub mod R {} 136 | pub mod W {} 137 | pub mod RW {} 138 | } 139 | #[doc = "Rbutton brightness 0"] 140 | pub mod RLED { 141 | pub const offset: u32 = 16; 142 | pub const mask: u32 = 0x0f << offset; 143 | pub mod R {} 144 | pub mod W {} 145 | pub mod RW {} 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/conctl.rs: -------------------------------------------------------------------------------- 1 | #[doc = "CONCTL"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "No description avaiable"] 5 | pub CTRL0: crate::RWRegister, 6 | _reserved0: [u8; 0x04], 7 | #[doc = "No description avaiable"] 8 | pub CTRL2: crate::RWRegister, 9 | #[doc = "No description avaiable"] 10 | pub CTRL3: crate::RWRegister, 11 | #[doc = "No description avaiable"] 12 | pub CTRL4: crate::RWRegister, 13 | #[doc = "No description avaiable"] 14 | pub CTRL5: crate::RWRegister, 15 | } 16 | #[doc = "No description avaiable"] 17 | pub mod CTRL0 { 18 | #[doc = "No description avaiable"] 19 | pub mod ENET0_TXCLK_DLY_SEL { 20 | pub const offset: u32 = 0; 21 | pub const mask: u32 = 0x1f << offset; 22 | pub mod R {} 23 | pub mod W {} 24 | pub mod RW {} 25 | } 26 | #[doc = "No description avaiable"] 27 | pub mod ENET0_RXCLK_DLY_SEL { 28 | pub const offset: u32 = 5; 29 | pub const mask: u32 = 0x1f << offset; 30 | pub mod R {} 31 | pub mod W {} 32 | pub mod RW {} 33 | } 34 | #[doc = "No description avaiable"] 35 | pub mod ENET1_TXCLK_DLY_SEL { 36 | pub const offset: u32 = 10; 37 | pub const mask: u32 = 0x1f << offset; 38 | pub mod R {} 39 | pub mod W {} 40 | pub mod RW {} 41 | } 42 | #[doc = "No description avaiable"] 43 | pub mod ENET1_RXCLK_DLY_SEL { 44 | pub const offset: u32 = 15; 45 | pub const mask: u32 = 0x1f << offset; 46 | pub mod R {} 47 | pub mod W {} 48 | pub mod RW {} 49 | } 50 | } 51 | #[doc = "No description avaiable"] 52 | pub mod CTRL2 { 53 | #[doc = "default to use internal clk. set from pad, two option here: internal 50MHz clock out to pad then in; use external clock;"] 54 | pub mod ENET0_RMII_TXCLK_SEL { 55 | pub const offset: u32 = 10; 56 | pub const mask: u32 = 0x01 << offset; 57 | pub mod R {} 58 | pub mod W {} 59 | pub mod RW {} 60 | } 61 | #[doc = "No description avaiable"] 62 | pub mod ENET0_FLOWCTRL { 63 | pub const offset: u32 = 12; 64 | pub const mask: u32 = 0x01 << offset; 65 | pub mod R {} 66 | pub mod W {} 67 | pub mod RW {} 68 | } 69 | #[doc = "000:Reserved 001:RGMII 100:RMII 111:Reserved"] 70 | pub mod ENET0_PHY_INTF_SEL { 71 | pub const offset: u32 = 13; 72 | pub const mask: u32 = 0x07 << offset; 73 | pub mod R {} 74 | pub mod W {} 75 | pub mod RW {} 76 | } 77 | #[doc = "No description avaiable"] 78 | pub mod ENET0_REFCLK_OE { 79 | pub const offset: u32 = 19; 80 | pub const mask: u32 = 0x01 << offset; 81 | pub mod R {} 82 | pub mod W {} 83 | pub mod RW {} 84 | } 85 | } 86 | #[doc = "No description avaiable"] 87 | pub mod CTRL3 { 88 | #[doc = "No description avaiable"] 89 | pub mod ENET1_RMII_TXCLK_SEL { 90 | pub const offset: u32 = 10; 91 | pub const mask: u32 = 0x01 << offset; 92 | pub mod R {} 93 | pub mod W {} 94 | pub mod RW {} 95 | } 96 | #[doc = "No description avaiable"] 97 | pub mod ENET1_FLOWCTRL { 98 | pub const offset: u32 = 12; 99 | pub const mask: u32 = 0x01 << offset; 100 | pub mod R {} 101 | pub mod W {} 102 | pub mod RW {} 103 | } 104 | #[doc = "No description avaiable"] 105 | pub mod ENET1_PHY_INTF_SEL { 106 | pub const offset: u32 = 13; 107 | pub const mask: u32 = 0x07 << offset; 108 | pub mod R {} 109 | pub mod W {} 110 | pub mod RW {} 111 | } 112 | #[doc = "No description avaiable"] 113 | pub mod ENET1_REFCLK_OE { 114 | pub const offset: u32 = 19; 115 | pub const mask: u32 = 0x01 << offset; 116 | pub mod R {} 117 | pub mod W {} 118 | pub mod RW {} 119 | } 120 | } 121 | #[doc = "No description avaiable"] 122 | pub mod CTRL4 { 123 | #[doc = "enable strobe clock, maybe used when update strobe DLL"] 124 | pub mod SDXC0_GPR_STROBE_IN_ENABLE { 125 | pub const offset: u32 = 17; 126 | pub const mask: u32 = 0x01 << offset; 127 | pub mod R {} 128 | pub mod W {} 129 | pub mod RW {} 130 | } 131 | #[doc = "for strobe DLL, default 7taps(1ns)"] 132 | pub mod SDXC0_GPR_TUNING_STROBE_SEL { 133 | pub const offset: u32 = 18; 134 | pub const mask: u32 = 0x1f << offset; 135 | pub mod R {} 136 | pub mod W {} 137 | pub mod RW {} 138 | } 139 | #[doc = "for card clock DLL, default 0"] 140 | pub mod SDXC0_GPR_TUNING_CARD_CLK_SEL { 141 | pub const offset: u32 = 23; 142 | pub const mask: u32 = 0x1f << offset; 143 | pub mod R {} 144 | pub mod W {} 145 | pub mod RW {} 146 | } 147 | #[doc = "card clock inverter enable"] 148 | pub mod SDXC0_CARDCLK_INV_EN { 149 | pub const offset: u32 = 28; 150 | pub const mask: u32 = 0x01 << offset; 151 | pub mod R {} 152 | pub mod W {} 153 | pub mod RW {} 154 | } 155 | #[doc = "wakeup irq enable"] 156 | pub mod SDXC0_WKP_IRQ_EN { 157 | pub const offset: u32 = 30; 158 | pub const mask: u32 = 0x01 << offset; 159 | pub mod R {} 160 | pub mod W {} 161 | pub mod RW {} 162 | } 163 | #[doc = "system irq enable"] 164 | pub mod SDXC0_SYS_IRQ_EN { 165 | pub const offset: u32 = 31; 166 | pub const mask: u32 = 0x01 << offset; 167 | pub mod R {} 168 | pub mod W {} 169 | pub mod RW {} 170 | } 171 | } 172 | #[doc = "No description avaiable"] 173 | pub mod CTRL5 { 174 | #[doc = "No description avaiable"] 175 | pub mod SDXC1_GPR_STROBE_IN_ENABLE { 176 | pub const offset: u32 = 17; 177 | pub const mask: u32 = 0x01 << offset; 178 | pub mod R {} 179 | pub mod W {} 180 | pub mod RW {} 181 | } 182 | #[doc = "No description avaiable"] 183 | pub mod SDXC1_GPR_TUNING_STROBE_SEL { 184 | pub const offset: u32 = 18; 185 | pub const mask: u32 = 0x1f << offset; 186 | pub mod R {} 187 | pub mod W {} 188 | pub mod RW {} 189 | } 190 | #[doc = "No description avaiable"] 191 | pub mod SDXC1_GPR_TUNING_CARD_CLK_SEL { 192 | pub const offset: u32 = 23; 193 | pub const mask: u32 = 0x1f << offset; 194 | pub mod R {} 195 | pub mod W {} 196 | pub mod RW {} 197 | } 198 | #[doc = "card clock inverter enable"] 199 | pub mod SDXC1_CARDCLK_INV_EN { 200 | pub const offset: u32 = 28; 201 | pub const mask: u32 = 0x01 << offset; 202 | pub mod R {} 203 | pub mod W {} 204 | pub mod RW {} 205 | } 206 | #[doc = "wakeup irq enable"] 207 | pub mod SDXC1_WKP_IRQ_EN { 208 | pub const offset: u32 = 30; 209 | pub const mask: u32 = 0x01 << offset; 210 | pub mod R {} 211 | pub mod W {} 212 | pub mod RW {} 213 | } 214 | #[doc = "system irq enable"] 215 | pub mod SDXC1_SYS_IRQ_EN { 216 | pub const offset: u32 = 31; 217 | pub const mask: u32 = 0x01 << offset; 218 | pub mod R {} 219 | pub mod W {} 220 | pub mod RW {} 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/dao.rs: -------------------------------------------------------------------------------- 1 | #[doc = "DAO"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Control Register"] 5 | pub CTRL: crate::RWRegister, 6 | _reserved0: [u8; 0x04], 7 | #[doc = "Command Register"] 8 | pub CMD: crate::RWRegister, 9 | #[doc = "Configuration Register"] 10 | pub RX_CFGR: crate::RWRegister, 11 | #[doc = "RX Slot Control Register"] 12 | pub RXSLT: crate::RWRegister, 13 | #[doc = "HPF A Coef Register"] 14 | pub HPF_MA: crate::RWRegister, 15 | #[doc = "HPF B Coef Register"] 16 | pub HPF_B: crate::RWRegister, 17 | } 18 | #[doc = "Control Register"] 19 | pub mod CTRL { 20 | #[doc = "the module continues to comsume data, but all the pads are constant, thus no audio out"] 21 | pub mod FALSE_RUN { 22 | pub const offset: u32 = 0; 23 | pub const mask: u32 = 0x01 << offset; 24 | pub mod R {} 25 | pub mod W {} 26 | pub mod RW {} 27 | } 28 | #[doc = "the pad output in False run mode, or when the module is disabled 0: all low 1: all high 2: P-high, N-low 3. output is not enabled"] 29 | pub mod FALSE_LEVEL { 30 | pub const offset: u32 = 1; 31 | pub const mask: u32 = 0x03 << offset; 32 | pub mod R {} 33 | pub mod W {} 34 | pub mod RW {} 35 | } 36 | #[doc = "all the outputs are inverted before sending to pad"] 37 | pub mod INVERT { 38 | pub const offset: u32 = 3; 39 | pub const mask: u32 = 0x01 << offset; 40 | pub mod R {} 41 | pub mod W {} 42 | pub mod RW {} 43 | } 44 | #[doc = "1: Use remap pwm version. The remap version is a version that one pwm output is tied to zero when the input pcm signal is positive or negative 0: Don't use remap pwm version"] 45 | pub mod REMAP { 46 | pub const offset: u32 = 4; 47 | pub const mask: u32 = 0x01 << offset; 48 | pub mod R {} 49 | pub mod W {} 50 | pub mod RW {} 51 | } 52 | #[doc = "Asserted to enable the left channel"] 53 | pub mod LEFT_EN { 54 | pub const offset: u32 = 5; 55 | pub const mask: u32 = 0x01 << offset; 56 | pub mod R {} 57 | pub mod W {} 58 | pub mod RW {} 59 | } 60 | #[doc = "Asserted to enable the right channel"] 61 | pub mod RIGHT_EN { 62 | pub const offset: u32 = 6; 63 | pub const mask: u32 = 0x01 << offset; 64 | pub mod R {} 65 | pub mod W {} 66 | pub mod RW {} 67 | } 68 | #[doc = "Asserted to let the left and right channel output the same value."] 69 | pub mod MONO { 70 | pub const offset: u32 = 7; 71 | pub const mask: u32 = 0x01 << offset; 72 | pub mod R {} 73 | pub mod W {} 74 | pub mod RW {} 75 | } 76 | #[doc = "Error interrupt enable This bit controls the generation of an interrupt when an error condition (saturation) occurs. 0: Error interrupt is masked 1: Error interrupt is enabled"] 77 | pub mod SAT_ERR_IE { 78 | pub const offset: u32 = 16; 79 | pub const mask: u32 = 0x01 << offset; 80 | pub mod R {} 81 | pub mod W {} 82 | pub mod RW {} 83 | } 84 | #[doc = "Whether HPF is enabled. This HPF is used to filter out the DC part."] 85 | pub mod HPF_EN { 86 | pub const offset: u32 = 17; 87 | pub const mask: u32 = 0x01 << offset; 88 | pub mod R {} 89 | pub mod W {} 90 | pub mod RW {} 91 | } 92 | } 93 | #[doc = "Command Register"] 94 | pub mod CMD { 95 | #[doc = "Enable this module to run."] 96 | pub mod RUN { 97 | pub const offset: u32 = 0; 98 | pub const mask: u32 = 0x01 << offset; 99 | pub mod R {} 100 | pub mod W {} 101 | pub mod RW {} 102 | } 103 | #[doc = "Self-clear"] 104 | pub mod SFTRST { 105 | pub const offset: u32 = 1; 106 | pub const mask: u32 = 0x01 << offset; 107 | pub mod R {} 108 | pub mod W {} 109 | pub mod RW {} 110 | } 111 | } 112 | #[doc = "Configuration Register"] 113 | pub mod RX_CFGR { 114 | #[doc = "CH_MAX\\[3:0\\] is the number if channels supported in TDM mode. When not in TDM mode, it must be set as 2. It must be an even number, so CH_MAX\\[0\\] is always 0. 4'h2: 2 channels 4'h4: 4 channels etc"] 115 | pub mod CH_MAX { 116 | pub const offset: u32 = 6; 117 | pub const mask: u32 = 0x1f << offset; 118 | pub mod R {} 119 | pub mod W {} 120 | pub mod RW {} 121 | } 122 | } 123 | #[doc = "RX Slot Control Register"] 124 | pub mod RXSLT { 125 | #[doc = "Slot enable for the channels."] 126 | pub mod EN { 127 | pub const offset: u32 = 0; 128 | pub const mask: u32 = 0xffff_ffff << offset; 129 | pub mod R {} 130 | pub mod W {} 131 | pub mod RW {} 132 | } 133 | } 134 | #[doc = "HPF A Coef Register"] 135 | pub mod HPF_MA { 136 | #[doc = "Composite value of coef A of the Order-1 HPF"] 137 | pub mod COEF { 138 | pub const offset: u32 = 0; 139 | pub const mask: u32 = 0xffff_ffff << offset; 140 | pub mod R {} 141 | pub mod W {} 142 | pub mod RW {} 143 | } 144 | } 145 | #[doc = "HPF B Coef Register"] 146 | pub mod HPF_B { 147 | #[doc = "coef B of the Order-1 HPF"] 148 | pub mod COEF { 149 | pub const offset: u32 = 0; 150 | pub const mask: u32 = 0xffff_ffff << offset; 151 | pub mod R {} 152 | pub mod W {} 153 | pub mod RW {} 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/mchtmr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "MCHTMR"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Machine Time"] 5 | pub MTIME: crate::RWRegister, 6 | #[doc = "Machine Time Compare"] 7 | pub MTIMECMP: crate::RWRegister, 8 | } 9 | #[doc = "Machine Time"] 10 | pub mod MTIME { 11 | #[doc = "Machine time"] 12 | pub mod MTIME { 13 | pub const offset: u64 = 0; 14 | pub const mask: u64 = 0 << offset; 15 | pub mod R {} 16 | pub mod W {} 17 | pub mod RW {} 18 | } 19 | } 20 | #[doc = "Machine Time Compare"] 21 | pub mod MTIMECMP { 22 | #[doc = "Machine time compare"] 23 | pub mod MTIMECMP { 24 | pub const offset: u64 = 0; 25 | pub const mask: u64 = 0 << offset; 26 | pub mod R {} 27 | pub mod W {} 28 | pub mod RW {} 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/mono.rs: -------------------------------------------------------------------------------- 1 | #[doc = "MONO"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Low part of monotonic counter"] 5 | pub MONOL: crate::RWRegister, 6 | #[doc = "High part of monotonic counter"] 7 | pub MONOH: crate::RWRegister, 8 | } 9 | #[doc = "Low part of monotonic counter"] 10 | pub mod MONOL { 11 | #[doc = "low part of monotonica counter, write to this counter will cause counter increase by 1"] 12 | pub mod COUNTER { 13 | pub const offset: u32 = 0; 14 | pub const mask: u32 = 0xffff_ffff << offset; 15 | pub mod R {} 16 | pub mod W {} 17 | pub mod RW {} 18 | } 19 | } 20 | #[doc = "High part of monotonic counter"] 21 | pub mod MONOH { 22 | #[doc = "high part of monotonica counter, write to this counter will cause counter increase by 1 if low part overflow"] 23 | pub mod COUNTER { 24 | pub const offset: u32 = 0; 25 | pub const mask: u32 = 0xffff << offset; 26 | pub mod R {} 27 | pub mod W {} 28 | pub mod RW {} 29 | } 30 | #[doc = "Fuse value for high part of monotonica"] 31 | pub mod EPOCH { 32 | pub const offset: u32 = 16; 33 | pub const mask: u32 = 0xffff << offset; 34 | pub mod R {} 35 | pub mod W {} 36 | pub mod RW {} 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/pgpr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "PGPR"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Generic control"] 5 | pub PMIC_GPR00: crate::RWRegister, 6 | #[doc = "Generic control"] 7 | pub PMIC_GPR01: crate::RWRegister, 8 | #[doc = "Generic control"] 9 | pub PMIC_GPR02: crate::RWRegister, 10 | #[doc = "Generic control"] 11 | pub PMIC_GPR03: crate::RWRegister, 12 | #[doc = "Generic control"] 13 | pub PMIC_GPR04: crate::RWRegister, 14 | #[doc = "Generic control"] 15 | pub PMIC_GPR05: crate::RWRegister, 16 | #[doc = "Generic control"] 17 | pub PMIC_GPR06: crate::RWRegister, 18 | #[doc = "Generic control"] 19 | pub PMIC_GPR07: crate::RWRegister, 20 | #[doc = "Generic control"] 21 | pub PMIC_GPR08: crate::RWRegister, 22 | #[doc = "Generic control"] 23 | pub PMIC_GPR09: crate::RWRegister, 24 | #[doc = "Generic control"] 25 | pub PMIC_GPR10: crate::RWRegister, 26 | #[doc = "Generic control"] 27 | pub PMIC_GPR11: crate::RWRegister, 28 | #[doc = "Generic control"] 29 | pub PMIC_GPR12: crate::RWRegister, 30 | #[doc = "Generic control"] 31 | pub PMIC_GPR13: crate::RWRegister, 32 | #[doc = "Generic control"] 33 | pub PMIC_GPR14: crate::RWRegister, 34 | #[doc = "Generic control"] 35 | pub PMIC_GPR15: crate::RWRegister, 36 | } 37 | #[doc = "Generic control"] 38 | pub mod PMIC_GPR00 { 39 | #[doc = "Generic control"] 40 | pub mod GPR { 41 | pub const offset: u32 = 0; 42 | pub const mask: u32 = 0xffff_ffff << offset; 43 | pub mod R {} 44 | pub mod W {} 45 | pub mod RW {} 46 | } 47 | } 48 | #[doc = "Generic control"] 49 | pub mod PMIC_GPR01 { 50 | #[doc = "Generic control"] 51 | pub mod GPR { 52 | pub const offset: u32 = 0; 53 | pub const mask: u32 = 0xffff_ffff << offset; 54 | pub mod R {} 55 | pub mod W {} 56 | pub mod RW {} 57 | } 58 | } 59 | #[doc = "Generic control"] 60 | pub mod PMIC_GPR02 { 61 | #[doc = "Generic control"] 62 | pub mod GPR { 63 | pub const offset: u32 = 0; 64 | pub const mask: u32 = 0xffff_ffff << offset; 65 | pub mod R {} 66 | pub mod W {} 67 | pub mod RW {} 68 | } 69 | } 70 | #[doc = "Generic control"] 71 | pub mod PMIC_GPR03 { 72 | #[doc = "Generic control"] 73 | pub mod GPR { 74 | pub const offset: u32 = 0; 75 | pub const mask: u32 = 0xffff_ffff << offset; 76 | pub mod R {} 77 | pub mod W {} 78 | pub mod RW {} 79 | } 80 | } 81 | #[doc = "Generic control"] 82 | pub mod PMIC_GPR04 { 83 | #[doc = "Generic control"] 84 | pub mod GPR { 85 | pub const offset: u32 = 0; 86 | pub const mask: u32 = 0xffff_ffff << offset; 87 | pub mod R {} 88 | pub mod W {} 89 | pub mod RW {} 90 | } 91 | } 92 | #[doc = "Generic control"] 93 | pub mod PMIC_GPR05 { 94 | #[doc = "Generic control"] 95 | pub mod GPR { 96 | pub const offset: u32 = 0; 97 | pub const mask: u32 = 0xffff_ffff << offset; 98 | pub mod R {} 99 | pub mod W {} 100 | pub mod RW {} 101 | } 102 | } 103 | #[doc = "Generic control"] 104 | pub mod PMIC_GPR06 { 105 | #[doc = "Generic control"] 106 | pub mod GPR { 107 | pub const offset: u32 = 0; 108 | pub const mask: u32 = 0xffff_ffff << offset; 109 | pub mod R {} 110 | pub mod W {} 111 | pub mod RW {} 112 | } 113 | } 114 | #[doc = "Generic control"] 115 | pub mod PMIC_GPR07 { 116 | #[doc = "Generic control"] 117 | pub mod GPR { 118 | pub const offset: u32 = 0; 119 | pub const mask: u32 = 0xffff_ffff << offset; 120 | pub mod R {} 121 | pub mod W {} 122 | pub mod RW {} 123 | } 124 | } 125 | #[doc = "Generic control"] 126 | pub mod PMIC_GPR08 { 127 | #[doc = "Generic control"] 128 | pub mod GPR { 129 | pub const offset: u32 = 0; 130 | pub const mask: u32 = 0xffff_ffff << offset; 131 | pub mod R {} 132 | pub mod W {} 133 | pub mod RW {} 134 | } 135 | } 136 | #[doc = "Generic control"] 137 | pub mod PMIC_GPR09 { 138 | #[doc = "Generic control"] 139 | pub mod GPR { 140 | pub const offset: u32 = 0; 141 | pub const mask: u32 = 0xffff_ffff << offset; 142 | pub mod R {} 143 | pub mod W {} 144 | pub mod RW {} 145 | } 146 | } 147 | #[doc = "Generic control"] 148 | pub mod PMIC_GPR10 { 149 | #[doc = "Generic control"] 150 | pub mod GPR { 151 | pub const offset: u32 = 0; 152 | pub const mask: u32 = 0xffff_ffff << offset; 153 | pub mod R {} 154 | pub mod W {} 155 | pub mod RW {} 156 | } 157 | } 158 | #[doc = "Generic control"] 159 | pub mod PMIC_GPR11 { 160 | #[doc = "Generic control"] 161 | pub mod GPR { 162 | pub const offset: u32 = 0; 163 | pub const mask: u32 = 0xffff_ffff << offset; 164 | pub mod R {} 165 | pub mod W {} 166 | pub mod RW {} 167 | } 168 | } 169 | #[doc = "Generic control"] 170 | pub mod PMIC_GPR12 { 171 | #[doc = "Generic control"] 172 | pub mod GPR { 173 | pub const offset: u32 = 0; 174 | pub const mask: u32 = 0xffff_ffff << offset; 175 | pub mod R {} 176 | pub mod W {} 177 | pub mod RW {} 178 | } 179 | } 180 | #[doc = "Generic control"] 181 | pub mod PMIC_GPR13 { 182 | #[doc = "Generic control"] 183 | pub mod GPR { 184 | pub const offset: u32 = 0; 185 | pub const mask: u32 = 0xffff_ffff << offset; 186 | pub mod R {} 187 | pub mod W {} 188 | pub mod RW {} 189 | } 190 | } 191 | #[doc = "Generic control"] 192 | pub mod PMIC_GPR14 { 193 | #[doc = "Generic control"] 194 | pub mod GPR { 195 | pub const offset: u32 = 0; 196 | pub const mask: u32 = 0xffff_ffff << offset; 197 | pub mod R {} 198 | pub mod W {} 199 | pub mod RW {} 200 | } 201 | } 202 | #[doc = "Generic control"] 203 | pub mod PMIC_GPR15 { 204 | #[doc = "Generic control"] 205 | pub mod GPR { 206 | pub const offset: u32 = 0; 207 | pub const mask: u32 = 0xffff_ffff << offset; 208 | pub mod R {} 209 | pub mod W {} 210 | pub mod RW {} 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/plicsw.rs: -------------------------------------------------------------------------------- 1 | #[doc = "PLICSW"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | _reserved0: [u8; 0x1000], 5 | #[doc = "Pending status"] 6 | pub PENDING: crate::RWRegister, 7 | _reserved1: [u8; 0x0ffc], 8 | #[doc = "Interrupt enable"] 9 | pub INTEN: crate::RWRegister, 10 | _reserved2: [u8; 0x001f_e000], 11 | #[doc = "Claim and complete."] 12 | pub CLAIM: crate::RWRegister, 13 | } 14 | #[doc = "Pending status"] 15 | pub mod PENDING { 16 | #[doc = "writing 1 to trigger software interrupt"] 17 | pub mod INTERRUPT { 18 | pub const offset: u32 = 1; 19 | pub const mask: u32 = 0x01 << offset; 20 | pub mod R {} 21 | pub mod W {} 22 | pub mod RW {} 23 | } 24 | } 25 | #[doc = "Interrupt enable"] 26 | pub mod INTEN { 27 | #[doc = "enable software interrupt"] 28 | pub mod INTERRUPT { 29 | pub const offset: u32 = 0; 30 | pub const mask: u32 = 0x01 << offset; 31 | pub mod R {} 32 | pub mod W {} 33 | pub mod RW {} 34 | } 35 | } 36 | #[doc = "Claim and complete."] 37 | pub mod CLAIM { 38 | #[doc = "On reads, indicating the interrupt source that has being claimed. On writes, indicating the interrupt source that has been handled (completed)."] 39 | pub mod INTERRUPT_ID { 40 | pub const offset: u32 = 0; 41 | pub const mask: u32 = 0x01 << offset; 42 | pub mod R {} 43 | pub mod W {} 44 | pub mod RW {} 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/pmon.rs: -------------------------------------------------------------------------------- 1 | #[doc = "PMON"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Glitch and clock monitor control"] 5 | pub MONITOR_GLITCH0_CONTROL: crate::RWRegister, 6 | #[doc = "Glitch and clock monitor status"] 7 | pub MONITOR_GLITCH0_STATUS: crate::RWRegister, 8 | #[doc = "Glitch and clock monitor control"] 9 | pub MONITOR_GLITCH1_CONTROL: crate::RWRegister, 10 | #[doc = "Glitch and clock monitor status"] 11 | pub MONITOR_GLITCH1_STATUS: crate::RWRegister, 12 | #[doc = "Glitch and clock monitor control"] 13 | pub MONITOR_CLOCK0_CONTROL: crate::RWRegister, 14 | #[doc = "Glitch and clock monitor status"] 15 | pub MONITOR_CLOCK0_STATUS: crate::RWRegister, 16 | #[doc = "Glitch and clock monitor control"] 17 | pub MONITOR_CLOCK1_CONTROL: crate::RWRegister, 18 | #[doc = "Glitch and clock monitor status"] 19 | pub MONITOR_CLOCK1_STATUS: crate::RWRegister, 20 | _reserved0: [u8; 0x20], 21 | #[doc = "No description avaiable"] 22 | pub IRQ_FLAG: crate::RWRegister, 23 | #[doc = "No description avaiable"] 24 | pub IRQ_ENABLE: crate::RWRegister, 25 | } 26 | #[doc = "Glitch and clock monitor control"] 27 | pub mod MONITOR_GLITCH0_CONTROL { 28 | #[doc = "enable glitch detector 0: detector disabled 1: detector enabled"] 29 | pub mod ENABLE { 30 | pub const offset: u32 = 0; 31 | pub const mask: u32 = 0x01 << offset; 32 | pub mod R {} 33 | pub mod W {} 34 | pub mod RW {} 35 | } 36 | #[doc = "select glitch works in active mode or passve mode. 0: passive mode, depends on power glitch destory DFF value 1: active mode, check glitch by DFF chain"] 37 | pub mod ACTIVE { 38 | pub const offset: u32 = 4; 39 | pub const mask: u32 = 0x01 << offset; 40 | pub mod R {} 41 | pub mod W {} 42 | pub mod RW {} 43 | } 44 | } 45 | #[doc = "Glitch and clock monitor status"] 46 | pub mod MONITOR_GLITCH0_STATUS { 47 | #[doc = "flag for glitch detected, write 1 to clear this flag 0: glitch not detected 1: glitch detected"] 48 | pub mod FLAG { 49 | pub const offset: u32 = 0; 50 | pub const mask: u32 = 0x01 << offset; 51 | pub mod R {} 52 | pub mod W {} 53 | pub mod RW {} 54 | } 55 | } 56 | #[doc = "Glitch and clock monitor control"] 57 | pub mod MONITOR_GLITCH1_CONTROL { 58 | #[doc = "enable glitch detector 0: detector disabled 1: detector enabled"] 59 | pub mod ENABLE { 60 | pub const offset: u32 = 0; 61 | pub const mask: u32 = 0x01 << offset; 62 | pub mod R {} 63 | pub mod W {} 64 | pub mod RW {} 65 | } 66 | #[doc = "select glitch works in active mode or passve mode. 0: passive mode, depends on power glitch destory DFF value 1: active mode, check glitch by DFF chain"] 67 | pub mod ACTIVE { 68 | pub const offset: u32 = 4; 69 | pub const mask: u32 = 0x01 << offset; 70 | pub mod R {} 71 | pub mod W {} 72 | pub mod RW {} 73 | } 74 | } 75 | #[doc = "Glitch and clock monitor status"] 76 | pub mod MONITOR_GLITCH1_STATUS { 77 | #[doc = "flag for glitch detected, write 1 to clear this flag 0: glitch not detected 1: glitch detected"] 78 | pub mod FLAG { 79 | pub const offset: u32 = 0; 80 | pub const mask: u32 = 0x01 << offset; 81 | pub mod R {} 82 | pub mod W {} 83 | pub mod RW {} 84 | } 85 | } 86 | #[doc = "Glitch and clock monitor control"] 87 | pub mod MONITOR_CLOCK0_CONTROL { 88 | #[doc = "enable glitch detector 0: detector disabled 1: detector enabled"] 89 | pub mod ENABLE { 90 | pub const offset: u32 = 0; 91 | pub const mask: u32 = 0x01 << offset; 92 | pub mod R {} 93 | pub mod W {} 94 | pub mod RW {} 95 | } 96 | #[doc = "select glitch works in active mode or passve mode. 0: passive mode, depends on power glitch destory DFF value 1: active mode, check glitch by DFF chain"] 97 | pub mod ACTIVE { 98 | pub const offset: u32 = 4; 99 | pub const mask: u32 = 0x01 << offset; 100 | pub mod R {} 101 | pub mod W {} 102 | pub mod RW {} 103 | } 104 | } 105 | #[doc = "Glitch and clock monitor status"] 106 | pub mod MONITOR_CLOCK0_STATUS { 107 | #[doc = "flag for glitch detected, write 1 to clear this flag 0: glitch not detected 1: glitch detected"] 108 | pub mod FLAG { 109 | pub const offset: u32 = 0; 110 | pub const mask: u32 = 0x01 << offset; 111 | pub mod R {} 112 | pub mod W {} 113 | pub mod RW {} 114 | } 115 | } 116 | #[doc = "Glitch and clock monitor control"] 117 | pub mod MONITOR_CLOCK1_CONTROL { 118 | #[doc = "enable glitch detector 0: detector disabled 1: detector enabled"] 119 | pub mod ENABLE { 120 | pub const offset: u32 = 0; 121 | pub const mask: u32 = 0x01 << offset; 122 | pub mod R {} 123 | pub mod W {} 124 | pub mod RW {} 125 | } 126 | #[doc = "select glitch works in active mode or passve mode. 0: passive mode, depends on power glitch destory DFF value 1: active mode, check glitch by DFF chain"] 127 | pub mod ACTIVE { 128 | pub const offset: u32 = 4; 129 | pub const mask: u32 = 0x01 << offset; 130 | pub mod R {} 131 | pub mod W {} 132 | pub mod RW {} 133 | } 134 | } 135 | #[doc = "Glitch and clock monitor status"] 136 | pub mod MONITOR_CLOCK1_STATUS { 137 | #[doc = "flag for glitch detected, write 1 to clear this flag 0: glitch not detected 1: glitch detected"] 138 | pub mod FLAG { 139 | pub const offset: u32 = 0; 140 | pub const mask: u32 = 0x01 << offset; 141 | pub mod R {} 142 | pub mod W {} 143 | pub mod RW {} 144 | } 145 | } 146 | #[doc = "No description avaiable"] 147 | pub mod IRQ_FLAG { 148 | #[doc = "interrupt flag, each bit represents for one monitor, write 1 to clear interrupt flag 0: no monitor interrupt 1: monitor interrupt happened"] 149 | pub mod FLAG { 150 | pub const offset: u32 = 0; 151 | pub const mask: u32 = 0x0f << offset; 152 | pub mod R {} 153 | pub mod W {} 154 | pub mod RW {} 155 | } 156 | } 157 | #[doc = "No description avaiable"] 158 | pub mod IRQ_ENABLE { 159 | #[doc = "interrupt enable, each bit represents for one monitor 0: monitor interrupt disabled 1: monitor interrupt enabled"] 160 | pub mod ENABLE { 161 | pub const offset: u32 = 0; 162 | pub const mask: u32 = 0x0f << offset; 163 | pub mod R {} 164 | pub mod W {} 165 | pub mod RW {} 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/ppor.rs: -------------------------------------------------------------------------------- 1 | #[doc = "PPOR"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "flag indicate reset source"] 5 | pub RESET_FLAG: crate::RWRegister, 6 | #[doc = "reset source status"] 7 | pub RESET_STATUS: crate::RWRegister, 8 | #[doc = "reset hold attribute"] 9 | pub RESET_HOLD: crate::RWRegister, 10 | #[doc = "reset source enable"] 11 | pub RESET_ENABLE: crate::RWRegister, 12 | #[doc = "reset type triggered by reset"] 13 | pub RESET_HOT: crate::RWRegister, 14 | #[doc = "reset type attribute"] 15 | pub RESET_COLD: crate::RWRegister, 16 | _reserved0: [u8; 0x04], 17 | #[doc = "Software reset counter"] 18 | pub SOFTWARE_RESET: crate::RWRegister, 19 | } 20 | #[doc = "flag indicate reset source"] 21 | pub mod RESET_FLAG { 22 | #[doc = "reset reason of last hard reset, write 1 to clear each bit 0: brownout 1: temperature(not available) 2: resetpin(not available) 4: debug reset 5: jtag reset 8: cpu0 lockup(not available) 9: cpu1 lockup(not available) 10: cpu0 request(not available) 11: cpu1 request(not available) 16: watch dog 0 17: watch dog 1 18: watch dog 2 19: watch dog 3 20: pmic watch dog 31: software"] 23 | pub mod FLAG { 24 | pub const offset: u32 = 0; 25 | pub const mask: u32 = 0xffff_ffff << offset; 26 | pub mod R {} 27 | pub mod W {} 28 | pub mod RW {} 29 | } 30 | } 31 | #[doc = "reset source status"] 32 | pub mod RESET_STATUS { 33 | #[doc = "current status of reset sources 0: brownout 1: temperature(not available) 2: resetpin(not available) 4: debug reset 5: jtag reset 8: cpu0 lockup(not available) 9: cpu1 lockup(not available) 10: cpu0 request(not available) 11: cpu1 request(not available) 16: watch dog 0 17: watch dog 1 18: watch dog 2 19: watch dog 3 20: pmic watch dog 31: software"] 34 | pub mod STATUS { 35 | pub const offset: u32 = 0; 36 | pub const mask: u32 = 0xffff_ffff << offset; 37 | pub mod R {} 38 | pub mod W {} 39 | pub mod RW {} 40 | } 41 | } 42 | #[doc = "reset hold attribute"] 43 | pub mod RESET_HOLD { 44 | #[doc = "hold arrtibute, when set, SOC keep in reset status until reset source release, or, reset will be released after SOC enter reset status 0: brownout 1: temperature(not available) 2: resetpin(not available) 4: debug reset 5: jtag reset 8: cpu0 lockup(not available) 9: cpu1 lockup(not available) 10: cpu0 request(not available) 11: cpu1 request(not available) 16: watch dog 0 17: watch dog 1 18: watch dog 2 19: watch dog 3 20: pmic watch dog 31: software"] 45 | pub mod STATUS { 46 | pub const offset: u32 = 0; 47 | pub const mask: u32 = 0xffff_ffff << offset; 48 | pub mod R {} 49 | pub mod W {} 50 | pub mod RW {} 51 | } 52 | } 53 | #[doc = "reset source enable"] 54 | pub mod RESET_ENABLE { 55 | #[doc = "enable of reset sources 0: brownout 1: temperature(not available) 2: resetpin(not available) 4: debug reset 5: jtag reset 8: cpu0 lockup(not available) 9: cpu1 lockup(not available) 10: cpu0 request(not available) 11: cpu1 request(not available) 16: watch dog 0 17: watch dog 1 18: watch dog 2 19: watch dog 3 20: pmic watch dog 31: software"] 56 | pub mod ENABLE { 57 | pub const offset: u32 = 0; 58 | pub const mask: u32 = 0xffff_ffff << offset; 59 | pub mod R {} 60 | pub mod W {} 61 | pub mod RW {} 62 | } 63 | } 64 | #[doc = "reset type triggered by reset"] 65 | pub mod RESET_HOT { 66 | #[doc = "reset type of reset sources, 0 for cold/warm reset, all system control setting cleared including clock, ioc; 1 for hot reset, system control, ioc setting kept, peripheral setting cleared. 0: brownout 1: temperature(not available) 2: resetpin(not available) 4: debug reset 5: jtag reset 8: cpu0 lockup(not available) 9: cpu1 lockup(not available) 10: cpu0 request(not available) 11: cpu1 request(not available) 16: watch dog 0 17: watch dog 1 18: watch dog 2 19: watch dog 3 20: pmic watch dog 31: software"] 67 | pub mod TYPE { 68 | pub const offset: u32 = 0; 69 | pub const mask: u32 = 0xffff_ffff << offset; 70 | pub mod R {} 71 | pub mod W {} 72 | pub mod RW {} 73 | } 74 | } 75 | #[doc = "reset type attribute"] 76 | pub mod RESET_COLD { 77 | #[doc = "perform cold or warm reset of chip, 0 for warm reset, fuse value and debug connection preserved; 1 for cold reset, fuse value reloaded and debug connection corrupted. This bit is ignored when hot reset selected 0: brownout 1: temperature(not available) 2: resetpin(not available) 4: debug reset 5: jtag reset 8: cpu0 lockup(not available) 9: cpu1 lockup(not available) 10: cpu0 request(not available) 11: cpu1 request(not available) 16: watch dog 0 17: watch dog 1 18: watch dog 2 19: watch dog 3 20: pmic watch dog 31: software"] 78 | pub mod FLAG { 79 | pub const offset: u32 = 0; 80 | pub const mask: u32 = 0xffff_ffff << offset; 81 | pub mod R {} 82 | pub mod W {} 83 | pub mod RW {} 84 | } 85 | } 86 | #[doc = "Software reset counter"] 87 | pub mod SOFTWARE_RESET { 88 | #[doc = "counter decrease in 24MHz and stop at 0, trigger reset when value reach 2, software can write 0 to cancel reset"] 89 | pub mod COUNTER { 90 | pub const offset: u32 = 0; 91 | pub const mask: u32 = 0xffff_ffff << offset; 92 | pub mod R {} 93 | pub mod W {} 94 | pub mod RW {} 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/psec.rs: -------------------------------------------------------------------------------- 1 | #[doc = "PSEC"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Secure state"] 5 | pub SECURE_STATE: crate::RWRegister, 6 | #[doc = "secure state configuration"] 7 | pub SECURE_STATE_CONFIG: crate::RWRegister, 8 | #[doc = "Security violation config"] 9 | pub VIOLATION_CONFIG: crate::RWRegister, 10 | #[doc = "Escalate behavior on security event"] 11 | pub ESCALATE_CONFIG: crate::RWRegister, 12 | #[doc = "Event and escalate status"] 13 | pub EVENT: crate::RWRegister, 14 | #[doc = "Lifecycle"] 15 | pub LIFECYCLE: crate::RWRegister, 16 | } 17 | #[doc = "Secure state"] 18 | pub mod SECURE_STATE { 19 | #[doc = "PMIC secure state one hot indicator 0: secure state is not in inspect state 1: secure state is in inspect state"] 20 | pub mod PMIC_INS { 21 | pub const offset: u32 = 4; 22 | pub const mask: u32 = 0x01 << offset; 23 | pub mod R {} 24 | pub mod W {} 25 | pub mod RW {} 26 | } 27 | #[doc = "PMIC secure state one hot indicator 0: secure state is not in secure state 1: secure state is in secure state"] 28 | pub mod PMIC_SEC { 29 | pub const offset: u32 = 5; 30 | pub const mask: u32 = 0x01 << offset; 31 | pub mod R {} 32 | pub mod W {} 33 | pub mod RW {} 34 | } 35 | #[doc = "PMIC secure state one hot indicator 0: secure state is not in non-secure state 1: secure state is in non-secure state"] 36 | pub mod PMIC_NSC { 37 | pub const offset: u32 = 6; 38 | pub const mask: u32 = 0x01 << offset; 39 | pub mod R {} 40 | pub mod W {} 41 | pub mod RW {} 42 | } 43 | #[doc = "PMIC secure state one hot indicator 0: secure state is not in fail state 1: secure state is in fail state"] 44 | pub mod PMIC_FAIL { 45 | pub const offset: u32 = 7; 46 | pub const mask: u32 = 0x01 << offset; 47 | pub mod R {} 48 | pub mod W {} 49 | pub mod RW {} 50 | } 51 | #[doc = "Secure state allow 0: system is not healthy to enter secure state, request to enter non-secure state will cause a fail state 1: system is healthy to enter secure state"] 52 | pub mod ALLOW_SEC { 53 | pub const offset: u32 = 16; 54 | pub const mask: u32 = 0x01 << offset; 55 | pub mod R {} 56 | pub mod W {} 57 | pub mod RW {} 58 | } 59 | #[doc = "Non-secure state allow 0: system is not healthy to enter non-secure state, request to enter non-secure state will cause a fail state 1: system is healthy to enter non-secure state"] 60 | pub mod ALLOW_NSC { 61 | pub const offset: u32 = 17; 62 | pub const mask: u32 = 0x01 << offset; 63 | pub mod R {} 64 | pub mod W {} 65 | pub mod RW {} 66 | } 67 | } 68 | #[doc = "secure state configuration"] 69 | pub mod SECURE_STATE_CONFIG { 70 | #[doc = "allow secure state restart from fail state 0: restart is not allowed, only hardware reset can recover secure state 1: software is allowed to switch to inspect state from fail state"] 71 | pub mod ALLOW_RESTART { 72 | pub const offset: u32 = 0; 73 | pub const mask: u32 = 0x01 << offset; 74 | pub mod R {} 75 | pub mod W {} 76 | pub mod RW {} 77 | } 78 | #[doc = "Lock bit of allow restart setting, once locked, lock bit itself and configuration register will keep value until next reset 0: not locked, register can be modified 1: register locked, write access to the register is ignored"] 79 | pub mod LOCK { 80 | pub const offset: u32 = 3; 81 | pub const mask: u32 = 0x01 << offset; 82 | pub mod R {} 83 | pub mod W {} 84 | pub mod RW {} 85 | } 86 | } 87 | #[doc = "Security violation config"] 88 | pub mod VIOLATION_CONFIG { 89 | #[doc = "configuration of secure state violations, each bit represents one security event 0: event is not a security violation 1: event is a security violation"] 90 | pub mod SEC_VIO_CFG { 91 | pub const offset: u32 = 0; 92 | pub const mask: u32 = 0x7fff << offset; 93 | pub mod R {} 94 | pub mod W {} 95 | pub mod RW {} 96 | } 97 | #[doc = "Lock bit secure violation setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified 1: register locked, write access to the configuration is ignored"] 98 | pub mod LOCK_SEC { 99 | pub const offset: u32 = 15; 100 | pub const mask: u32 = 0x01 << offset; 101 | pub mod R {} 102 | pub mod W {} 103 | pub mod RW {} 104 | } 105 | #[doc = "configuration of non-secure state violations, each bit represents one security event 0: event is not a security violation 1: event is a security violation"] 106 | pub mod NSC_VIO_CFG { 107 | pub const offset: u32 = 16; 108 | pub const mask: u32 = 0x7fff << offset; 109 | pub mod R {} 110 | pub mod W {} 111 | pub mod RW {} 112 | } 113 | #[doc = "Lock bit non-secure violation setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified 1: register locked, write access to the configuration is ignored"] 114 | pub mod LOCK_NSC { 115 | pub const offset: u32 = 31; 116 | pub const mask: u32 = 0x01 << offset; 117 | pub mod R {} 118 | pub mod W {} 119 | pub mod RW {} 120 | } 121 | } 122 | #[doc = "Escalate behavior on security event"] 123 | pub mod ESCALATE_CONFIG { 124 | #[doc = "configuration of secure state escalates, each bit represents one security event 0: event is not a security escalate 1: event is a security escalate"] 125 | pub mod SEC_VIO_CFG { 126 | pub const offset: u32 = 0; 127 | pub const mask: u32 = 0x7fff << offset; 128 | pub mod R {} 129 | pub mod W {} 130 | pub mod RW {} 131 | } 132 | #[doc = "Lock bit secure escalate setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified 1: register locked, write access to the configuration is ignored"] 133 | pub mod LOCK_SEC { 134 | pub const offset: u32 = 15; 135 | pub const mask: u32 = 0x01 << offset; 136 | pub mod R {} 137 | pub mod W {} 138 | pub mod RW {} 139 | } 140 | #[doc = "configuration of non-secure state escalates, each bit represents one security event 0: event is not a security escalate 1: event is a security escalate"] 141 | pub mod NSC_VIO_CFG { 142 | pub const offset: u32 = 16; 143 | pub const mask: u32 = 0x7fff << offset; 144 | pub mod R {} 145 | pub mod W {} 146 | pub mod RW {} 147 | } 148 | #[doc = "Lock bit non-secure escalate setting, once locked, lock bit itself and configuration will keep value until next reset 0: not locked, configuration can be modified 1: register locked, write access to the configuration is ignored"] 149 | pub mod LOCK_NSC { 150 | pub const offset: u32 = 31; 151 | pub const mask: u32 = 0x01 << offset; 152 | pub mod R {} 153 | pub mod W {} 154 | pub mod RW {} 155 | } 156 | } 157 | #[doc = "Event and escalate status"] 158 | pub mod EVENT { 159 | #[doc = "PMIC is escalting secure event"] 160 | pub mod PMIC_ESC_SEC { 161 | pub const offset: u32 = 2; 162 | pub const mask: u32 = 0x01 << offset; 163 | pub mod R {} 164 | pub mod W {} 165 | pub mod RW {} 166 | } 167 | #[doc = "PMIC is escalating non-secure event"] 168 | pub mod PMIC_ESC_NSC { 169 | pub const offset: u32 = 3; 170 | pub const mask: u32 = 0x01 << offset; 171 | pub mod R {} 172 | pub mod W {} 173 | pub mod RW {} 174 | } 175 | #[doc = "local event statue, each bit represents one security event"] 176 | pub mod EVENT { 177 | pub const offset: u32 = 16; 178 | pub const mask: u32 = 0xffff << offset; 179 | pub mod R {} 180 | pub mod W {} 181 | pub mod RW {} 182 | } 183 | } 184 | #[doc = "Lifecycle"] 185 | pub mod LIFECYCLE { 186 | #[doc = "lifecycle status, bit7: lifecycle_debate, bit6: lifecycle_scribe, bit5: lifecycle_no_ret, bit4: lifecycle_return, bit3: lifecycle_secure, bit2: lifecycle_nonsec, bit1: lifecycle_create, bit0: lifecycle_unknow"] 187 | pub mod LIFECYCLE { 188 | pub const offset: u32 = 0; 189 | pub const mask: u32 = 0xff << offset; 190 | pub mod R {} 191 | pub mod W {} 192 | pub mod RW {} 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/rtc.rs: -------------------------------------------------------------------------------- 1 | #[doc = "RTC"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Second counter"] 5 | pub SECOND: crate::RWRegister, 6 | #[doc = "Sub-second counter"] 7 | pub SUBSEC: crate::RWRegister, 8 | #[doc = "Second counter snap shot"] 9 | pub SEC_SNAP: crate::RWRegister, 10 | #[doc = "Sub-second counter snap shot"] 11 | pub SUB_SNAP: crate::RWRegister, 12 | #[doc = "RTC alarm0"] 13 | pub ALARM0: crate::RWRegister, 14 | #[doc = "Alarm0 incremental"] 15 | pub ALARM0_INC: crate::RWRegister, 16 | #[doc = "RTC alarm1"] 17 | pub ALARM1: crate::RWRegister, 18 | #[doc = "Alarm1 incremental"] 19 | pub ALARM1_INC: crate::RWRegister, 20 | #[doc = "RTC alarm flag"] 21 | pub ALARM_FLAG: crate::RWRegister, 22 | #[doc = "RTC alarm enable"] 23 | pub ALARM_EN: crate::RWRegister, 24 | } 25 | #[doc = "Second counter"] 26 | pub mod SECOND { 27 | #[doc = "second counter"] 28 | pub mod SECOND { 29 | pub const offset: u32 = 0; 30 | pub const mask: u32 = 0xffff_ffff << offset; 31 | pub mod R {} 32 | pub mod W {} 33 | pub mod RW {} 34 | } 35 | } 36 | #[doc = "Sub-second counter"] 37 | pub mod SUBSEC { 38 | #[doc = "sub second counter"] 39 | pub mod SUBSEC { 40 | pub const offset: u32 = 0; 41 | pub const mask: u32 = 0xffff_ffff << offset; 42 | pub mod R {} 43 | pub mod W {} 44 | pub mod RW {} 45 | } 46 | } 47 | #[doc = "Second counter snap shot"] 48 | pub mod SEC_SNAP { 49 | #[doc = "second snap shot, write to take snap shot"] 50 | pub mod SEC_SNAP { 51 | pub const offset: u32 = 0; 52 | pub const mask: u32 = 0xffff_ffff << offset; 53 | pub mod R {} 54 | pub mod W {} 55 | pub mod RW {} 56 | } 57 | } 58 | #[doc = "Sub-second counter snap shot"] 59 | pub mod SUB_SNAP { 60 | #[doc = "sub second snap shot, write to take snap shot"] 61 | pub mod SUB_SNAP { 62 | pub const offset: u32 = 0; 63 | pub const mask: u32 = 0xffff_ffff << offset; 64 | pub mod R {} 65 | pub mod W {} 66 | pub mod RW {} 67 | } 68 | } 69 | #[doc = "RTC alarm0"] 70 | pub mod ALARM0 { 71 | #[doc = "Alarm time for second counter, on each alarm match, alarm increase ALARM0_INC"] 72 | pub mod ALARM { 73 | pub const offset: u32 = 0; 74 | pub const mask: u32 = 0xffff_ffff << offset; 75 | pub mod R {} 76 | pub mod W {} 77 | pub mod RW {} 78 | } 79 | } 80 | #[doc = "Alarm0 incremental"] 81 | pub mod ALARM0_INC { 82 | #[doc = "adder when ARLAM0 happen, helps to create periodical alarm"] 83 | pub mod INCREASE { 84 | pub const offset: u32 = 0; 85 | pub const mask: u32 = 0xffff_ffff << offset; 86 | pub mod R {} 87 | pub mod W {} 88 | pub mod RW {} 89 | } 90 | } 91 | #[doc = "RTC alarm1"] 92 | pub mod ALARM1 { 93 | #[doc = "Alarm time for second counter, on each alarm match, alarm increase ALARM0_INC"] 94 | pub mod ALARM { 95 | pub const offset: u32 = 0; 96 | pub const mask: u32 = 0xffff_ffff << offset; 97 | pub mod R {} 98 | pub mod W {} 99 | pub mod RW {} 100 | } 101 | } 102 | #[doc = "Alarm1 incremental"] 103 | pub mod ALARM1_INC { 104 | #[doc = "adder when ARLAM0 happen, helps to create periodical alarm"] 105 | pub mod INCREASE { 106 | pub const offset: u32 = 0; 107 | pub const mask: u32 = 0xffff_ffff << offset; 108 | pub mod R {} 109 | pub mod W {} 110 | pub mod RW {} 111 | } 112 | } 113 | #[doc = "RTC alarm flag"] 114 | pub mod ALARM_FLAG { 115 | #[doc = "alarm0 happen"] 116 | pub mod ALARM0 { 117 | pub const offset: u32 = 0; 118 | pub const mask: u32 = 0x01 << offset; 119 | pub mod R {} 120 | pub mod W {} 121 | pub mod RW {} 122 | } 123 | #[doc = "alarm1 happen"] 124 | pub mod ALARM1 { 125 | pub const offset: u32 = 1; 126 | pub const mask: u32 = 0x01 << offset; 127 | pub mod R {} 128 | pub mod W {} 129 | pub mod RW {} 130 | } 131 | } 132 | #[doc = "RTC alarm enable"] 133 | pub mod ALARM_EN { 134 | #[doc = "alarm0 mask 0: alarm0 disabled 1: alarm0 enabled"] 135 | pub mod ENABLE0 { 136 | pub const offset: u32 = 0; 137 | pub const mask: u32 = 0x01 << offset; 138 | pub mod R {} 139 | pub mod W {} 140 | pub mod RW {} 141 | } 142 | #[doc = "alarm1 mask 0: alarm1 disabled 1: alarm1 enabled"] 143 | pub mod ENABLE1 { 144 | pub const offset: u32 = 1; 145 | pub const mask: u32 = 0x01 << offset; 146 | pub mod R {} 147 | pub mod W {} 148 | pub mod RW {} 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/rtcshw.rs: -------------------------------------------------------------------------------- 1 | #[doc = "RTCSHW"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Second counter"] 5 | pub SECOND: crate::RWRegister, 6 | #[doc = "Sub-second counter"] 7 | pub SUBSEC: crate::RWRegister, 8 | #[doc = "Second counter snap shot"] 9 | pub SEC_SNAP: crate::RWRegister, 10 | #[doc = "Sub-second counter snap shot"] 11 | pub SUB_SNAP: crate::RWRegister, 12 | #[doc = "RTC alarm0"] 13 | pub ALARM0: crate::RWRegister, 14 | #[doc = "Alarm0 incremental"] 15 | pub ALARM0_INC: crate::RWRegister, 16 | #[doc = "RTC alarm1"] 17 | pub ALARM1: crate::RWRegister, 18 | #[doc = "Alarm1 incremental"] 19 | pub ALARM1_INC: crate::RWRegister, 20 | #[doc = "RTC alarm flag"] 21 | pub ALARM_FLAG: crate::RWRegister, 22 | #[doc = "RTC alarm enable"] 23 | pub ALARM_EN: crate::RWRegister, 24 | } 25 | #[doc = "Second counter"] 26 | pub mod SECOND { 27 | #[doc = "second counter"] 28 | pub mod SECOND { 29 | pub const offset: u32 = 0; 30 | pub const mask: u32 = 0xffff_ffff << offset; 31 | pub mod R {} 32 | pub mod W {} 33 | pub mod RW {} 34 | } 35 | } 36 | #[doc = "Sub-second counter"] 37 | pub mod SUBSEC { 38 | #[doc = "sub second counter"] 39 | pub mod SUBSEC { 40 | pub const offset: u32 = 0; 41 | pub const mask: u32 = 0xffff_ffff << offset; 42 | pub mod R {} 43 | pub mod W {} 44 | pub mod RW {} 45 | } 46 | } 47 | #[doc = "Second counter snap shot"] 48 | pub mod SEC_SNAP { 49 | #[doc = "second snap shot, write to take snap shot"] 50 | pub mod SEC_SNAP { 51 | pub const offset: u32 = 0; 52 | pub const mask: u32 = 0xffff_ffff << offset; 53 | pub mod R {} 54 | pub mod W {} 55 | pub mod RW {} 56 | } 57 | } 58 | #[doc = "Sub-second counter snap shot"] 59 | pub mod SUB_SNAP { 60 | #[doc = "sub second snap shot, write to take snap shot"] 61 | pub mod SUB_SNAP { 62 | pub const offset: u32 = 0; 63 | pub const mask: u32 = 0xffff_ffff << offset; 64 | pub mod R {} 65 | pub mod W {} 66 | pub mod RW {} 67 | } 68 | } 69 | #[doc = "RTC alarm0"] 70 | pub mod ALARM0 { 71 | #[doc = "Alarm time for second counter, on each alarm match, alarm increase ALARM0_INC"] 72 | pub mod ALARM { 73 | pub const offset: u32 = 0; 74 | pub const mask: u32 = 0xffff_ffff << offset; 75 | pub mod R {} 76 | pub mod W {} 77 | pub mod RW {} 78 | } 79 | } 80 | #[doc = "Alarm0 incremental"] 81 | pub mod ALARM0_INC { 82 | #[doc = "adder when ARLAM0 happen, helps to create periodical alarm"] 83 | pub mod INCREASE { 84 | pub const offset: u32 = 0; 85 | pub const mask: u32 = 0xffff_ffff << offset; 86 | pub mod R {} 87 | pub mod W {} 88 | pub mod RW {} 89 | } 90 | } 91 | #[doc = "RTC alarm1"] 92 | pub mod ALARM1 { 93 | #[doc = "Alarm time for second counter, on each alarm match, alarm increase ALARM0_INC"] 94 | pub mod ALARM { 95 | pub const offset: u32 = 0; 96 | pub const mask: u32 = 0xffff_ffff << offset; 97 | pub mod R {} 98 | pub mod W {} 99 | pub mod RW {} 100 | } 101 | } 102 | #[doc = "Alarm1 incremental"] 103 | pub mod ALARM1_INC { 104 | #[doc = "adder when ARLAM0 happen, helps to create periodical alarm"] 105 | pub mod INCREASE { 106 | pub const offset: u32 = 0; 107 | pub const mask: u32 = 0xffff_ffff << offset; 108 | pub mod R {} 109 | pub mod W {} 110 | pub mod RW {} 111 | } 112 | } 113 | #[doc = "RTC alarm flag"] 114 | pub mod ALARM_FLAG { 115 | #[doc = "alarm0 happen"] 116 | pub mod ALARM0 { 117 | pub const offset: u32 = 0; 118 | pub const mask: u32 = 0x01 << offset; 119 | pub mod R {} 120 | pub mod W {} 121 | pub mod RW {} 122 | } 123 | #[doc = "alarm1 happen"] 124 | pub mod ALARM1 { 125 | pub const offset: u32 = 1; 126 | pub const mask: u32 = 0x01 << offset; 127 | pub mod R {} 128 | pub mod W {} 129 | pub mod RW {} 130 | } 131 | } 132 | #[doc = "RTC alarm enable"] 133 | pub mod ALARM_EN { 134 | #[doc = "alarm0 mask 0: alarm0 disabled 1: alarm0 enabled"] 135 | pub mod ENABLE0 { 136 | pub const offset: u32 = 0; 137 | pub const mask: u32 = 0x01 << offset; 138 | pub mod R {} 139 | pub mod W {} 140 | pub mod RW {} 141 | } 142 | #[doc = "alarm1 mask 0: alarm1 disabled 1: alarm1 enabled"] 143 | pub mod ENABLE1 { 144 | pub const offset: u32 = 1; 145 | pub const mask: u32 = 0x01 << offset; 146 | pub mod R {} 147 | pub mod W {} 148 | pub mod RW {} 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/synt.rs: -------------------------------------------------------------------------------- 1 | #[doc = "SYNT"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | #[doc = "Global control register"] 5 | pub GCR: crate::RWRegister, 6 | #[doc = "Counter reload register"] 7 | pub RLD: crate::RWRegister, 8 | _reserved0: [u8; 0x04], 9 | #[doc = "Counter"] 10 | pub CNT: crate::RWRegister, 11 | _reserved1: [u8; 0x10], 12 | #[doc = "Comparator"] 13 | pub CMP_0: crate::RWRegister, 14 | #[doc = "Comparator"] 15 | pub CMP_1: crate::RWRegister, 16 | #[doc = "Comparator"] 17 | pub CMP_2: crate::RWRegister, 18 | #[doc = "Comparator"] 19 | pub CMP_3: crate::RWRegister, 20 | } 21 | #[doc = "Global control register"] 22 | pub mod GCR { 23 | #[doc = "1- Enable counter"] 24 | pub mod CEN { 25 | pub const offset: u32 = 0; 26 | pub const mask: u32 = 0x01 << offset; 27 | pub mod R {} 28 | pub mod W {} 29 | pub mod RW {} 30 | } 31 | #[doc = "1- Reset counter"] 32 | pub mod CRST { 33 | pub const offset: u32 = 1; 34 | pub const mask: u32 = 0x01 << offset; 35 | pub mod R {} 36 | pub mod W {} 37 | pub mod RW {} 38 | } 39 | } 40 | #[doc = "Counter reload register"] 41 | pub mod RLD { 42 | #[doc = "counter reload value"] 43 | pub mod RLD { 44 | pub const offset: u32 = 0; 45 | pub const mask: u32 = 0xffff_ffff << offset; 46 | pub mod R {} 47 | pub mod W {} 48 | pub mod RW {} 49 | } 50 | } 51 | #[doc = "Counter"] 52 | pub mod CNT { 53 | #[doc = "counter"] 54 | pub mod CNT { 55 | pub const offset: u32 = 0; 56 | pub const mask: u32 = 0xffff_ffff << offset; 57 | pub mod R {} 58 | pub mod W {} 59 | pub mod RW {} 60 | } 61 | } 62 | #[doc = "Comparator"] 63 | pub mod CMP_0 { 64 | #[doc = "comparator value, the output will assert when counter count to this value"] 65 | pub mod CMP { 66 | pub const offset: u32 = 0; 67 | pub const mask: u32 = 0xffff_ffff << offset; 68 | pub mod R {} 69 | pub mod W {} 70 | pub mod RW {} 71 | } 72 | } 73 | #[doc = "Comparator"] 74 | pub mod CMP_1 { 75 | #[doc = "comparator value, the output will assert when counter count to this value"] 76 | pub mod CMP { 77 | pub const offset: u32 = 0; 78 | pub const mask: u32 = 0xffff_ffff << offset; 79 | pub mod R {} 80 | pub mod W {} 81 | pub mod RW {} 82 | } 83 | } 84 | #[doc = "Comparator"] 85 | pub mod CMP_2 { 86 | #[doc = "comparator value, the output will assert when counter count to this value"] 87 | pub mod CMP { 88 | pub const offset: u32 = 0; 89 | pub const mask: u32 = 0xffff_ffff << offset; 90 | pub mod R {} 91 | pub mod W {} 92 | pub mod RW {} 93 | } 94 | } 95 | #[doc = "Comparator"] 96 | pub mod CMP_3 { 97 | #[doc = "comparator value, the output will assert when counter count to this value"] 98 | pub mod CMP { 99 | pub const offset: u32 = 0; 100 | pub const mask: u32 = 0xffff_ffff << offset; 101 | pub mod R {} 102 | pub mod W {} 103 | pub mod RW {} 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/blocks/hpm6750/wdg.rs: -------------------------------------------------------------------------------- 1 | #[doc = "WDG0"] 2 | #[repr(C)] 3 | pub struct RegisterBlock { 4 | _reserved0: [u8; 0x10], 5 | #[doc = "Control Register"] 6 | pub CTRL: crate::RWRegister, 7 | #[doc = "Restart Register"] 8 | pub RESTART: crate::RWRegister, 9 | #[doc = "Write Protection Register"] 10 | pub WREN: crate::RWRegister, 11 | #[doc = "Status Register"] 12 | pub ST: crate::RWRegister, 13 | } 14 | #[doc = "Control Register"] 15 | pub mod CTRL { 16 | #[doc = "Enable or disable the watchdog timer 0: Disable 1: Enable"] 17 | pub mod EN { 18 | pub const offset: u32 = 0; 19 | pub const mask: u32 = 0x01 << offset; 20 | pub mod R {} 21 | pub mod W {} 22 | pub mod RW {} 23 | } 24 | #[doc = "Clock source of timer: 0: EXTCLK 1: PCLK"] 25 | pub mod CLKSEL { 26 | pub const offset: u32 = 1; 27 | pub const mask: u32 = 0x01 << offset; 28 | pub mod R {} 29 | pub mod W {} 30 | pub mod RW {} 31 | } 32 | #[doc = "Enable or disable the watchdog interrupt 0: Disable 1: Enable"] 33 | pub mod INTEN { 34 | pub const offset: u32 = 2; 35 | pub const mask: u32 = 0x01 << offset; 36 | pub mod R {} 37 | pub mod W {} 38 | pub mod RW {} 39 | } 40 | #[doc = "Enable or disable the watchdog reset 0: Disable 1: Enable"] 41 | pub mod RSTEN { 42 | pub const offset: u32 = 3; 43 | pub const mask: u32 = 0x01 << offset; 44 | pub mod R {} 45 | pub mod W {} 46 | pub mod RW {} 47 | } 48 | #[doc = "The timer interval of the interrupt stage: 0: Clock period x 2^6 1: Clock period x 2^8 2: Clock period x 2^10 3: Clock period x 2^11 4: Clock period x 2^12 5: Clock period x 2^13 6: Clock period x 2^14 7: Clock period x 2^15 8: Clock period x 2^17 9: Clock period x 2^19 10: Clock period x 2^21 11: Clock period x 2^23 12: Clock period x 2^25 13: Clock period x 2^27 14: Clock period x 2^29 15: Clock period x 2^31"] 49 | pub mod INTTIME { 50 | pub const offset: u32 = 4; 51 | pub const mask: u32 = 0x0f << offset; 52 | pub mod R {} 53 | pub mod W {} 54 | pub mod RW {} 55 | } 56 | #[doc = "The time interval of the reset stage: 0: Clock period x 2^7 1: Clock period x 2^8 2: Clock period x 2^9 3: Clock period x 2^10 4: Clock period x 2^11 5: Clock period x 2^12 6: Clock period x 2^13 7: Clock period x 2^14"] 57 | pub mod RSTTIME { 58 | pub const offset: u32 = 8; 59 | pub const mask: u32 = 0x07 << offset; 60 | pub mod R {} 61 | pub mod W {} 62 | pub mod RW {} 63 | } 64 | } 65 | #[doc = "Restart Register"] 66 | pub mod RESTART { 67 | #[doc = "Write the magic number ATCWDT200_RESTART_NUM to restart the watchdog timer."] 68 | pub mod RESTART { 69 | pub const offset: u32 = 0; 70 | pub const mask: u32 = 0xffff << offset; 71 | pub mod R {} 72 | pub mod W {} 73 | pub mod RW {} 74 | } 75 | } 76 | #[doc = "Write Protection Register"] 77 | pub mod WREN { 78 | #[doc = "Write the magic code to disable the write protection of the Control Register and the Restart Register."] 79 | pub mod WEN { 80 | pub const offset: u32 = 0; 81 | pub const mask: u32 = 0xffff << offset; 82 | pub mod R {} 83 | pub mod W {} 84 | pub mod RW {} 85 | } 86 | } 87 | #[doc = "Status Register"] 88 | pub mod ST { 89 | #[doc = "The status of the watchdog interrupt timer 0: timer is not expired yet 1: timer is expired"] 90 | pub mod INTEXPIRED { 91 | pub const offset: u32 = 0; 92 | pub const mask: u32 = 0x01 << offset; 93 | pub mod R {} 94 | pub mod W {} 95 | pub mod RW {} 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/hpm6750.x: -------------------------------------------------------------------------------- 1 | PROVIDE(Gpio0PortAHandler = DefaultHandler); 2 | PROVIDE(Gpio0PortBHandler = DefaultHandler); 3 | PROVIDE(Gpio0PortCHandler = DefaultHandler); 4 | PROVIDE(Gpio0PortDHandler = DefaultHandler); 5 | PROVIDE(Gpio0PortEHandler = DefaultHandler); 6 | PROVIDE(Gpio0PortFHandler = DefaultHandler); 7 | PROVIDE(Gpio0PortXHandler = DefaultHandler); 8 | PROVIDE(Gpio0PortYHandler = DefaultHandler); 9 | PROVIDE(Gpio0PortZHandler = DefaultHandler); 10 | PROVIDE(Gpio1PortAHandler = DefaultHandler); 11 | PROVIDE(Gpio1PortBHandler = DefaultHandler); 12 | PROVIDE(Gpio1PortCHandler = DefaultHandler); 13 | PROVIDE(Gpio1PortDHandler = DefaultHandler); 14 | PROVIDE(Gpio1PortEHandler = DefaultHandler); 15 | PROVIDE(Gpio1PortFHandler = DefaultHandler); 16 | PROVIDE(Gpio1PortXHandler = DefaultHandler); 17 | PROVIDE(Gpio1PortYHandler = DefaultHandler); 18 | PROVIDE(Gpio1PortZHandler = DefaultHandler); 19 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | # ! [doc = include_str ! ("../doc.md")] 2 | #![no_std] 3 | #![allow( 4 | non_camel_case_types, 5 | non_snake_case, 6 | non_upper_case_globals, 7 | clippy::self_named_constructors, 8 | clippy::module_inception 9 | )] 10 | pub use ral_registers::{modify_reg, read_reg, write_reg, RORegister, RWRegister, WORegister}; 11 | #[doc = r" An owned peripheral of type `T`, instance `N`."] 12 | #[doc = r""] 13 | #[doc = r" Fabricating an `Instance` is always `unsafe`. An owner of an"] 14 | #[doc = r" `Instance` may assume that"] 15 | #[doc = r""] 16 | #[doc = r" - the underlying pointer points to a static register block of type `T`."] 17 | #[doc = r" - the instance number `N` properly describes the peripheral instance."] 18 | #[doc = r" - they own _all_ registers pointed at by `T`."] 19 | #[doc = r""] 20 | #[doc = r" Owners use this guarantee to safely access the peripheral registers."] 21 | #[doc = r" However, nothing guarantees any of these except for your diligence."] 22 | #[doc = r""] 23 | #[doc = r" Constructing an `Instance` is zero cost. Additionally, `Instance` is transparent"] 24 | #[doc = r" and amenable to null-pointer optimizations."] 25 | #[doc = r""] 26 | #[doc = r" See the package-level documentation for more information on fabricating"] 27 | #[doc = r" instances."] 28 | #[doc = r""] 29 | #[doc = r" # Safety of `new()`."] 30 | #[doc = r""] 31 | #[doc = r" By calling `new()`, you claim"] 32 | #[doc = r""] 33 | #[doc = r" 1. `ptr` points to static memory that can be described by a type `T`."] 34 | #[doc = r" 2. The instance number `N` correctly describes `ptr`."] 35 | #[doc = r" 3. You are becoming the sole owner of this instance."] 36 | #[doc = r""] 37 | #[doc = r" # Safety of `instance()`"] 38 | #[doc = r""] 39 | #[doc = r" The various `instance()` methods handle safety concerns 1 and 2 from `new()`."] 40 | #[doc = r" By their construction, each `instance()` implementation provides a pointer to valid"] 41 | #[doc = r" peripheral memory, and associates the correct `N` with that pointer. Therefore,"] 42 | #[doc = r" you're only responsible for ensuring safety concern 3 from `new()`."] 43 | #[repr(transparent)] 44 | pub struct Instance { 45 | ptr: core::ptr::NonNull, 46 | } 47 | impl core::ops::Deref for Instance { 48 | type Target = T; 49 | #[inline] 50 | fn deref(&self) -> &Self::Target { 51 | unsafe { self.ptr.as_ref() } 52 | } 53 | } 54 | impl Instance { 55 | #[doc = r" Create an arbitrary `Instance` from a pointer to `T`."] 56 | #[doc = r""] 57 | #[doc = r" # Safety"] 58 | #[doc = r""] 59 | #[doc = r" See [the struct docs](Instance) for the safety contract."] 60 | #[inline] 61 | pub const unsafe fn new(ptr: *const T) -> Self { 62 | Self { 63 | ptr: core::ptr::NonNull::new_unchecked(ptr as *mut _), 64 | } 65 | } 66 | } 67 | unsafe impl Send for Instance {} 68 | #[doc = r" The instance number for a peripheral singleton."] 69 | #[doc = r""] 70 | #[doc = r" If your peripheral only has one instance, it's given"] 71 | #[doc = r" this number. The CCM peripheral is a good example of"] 72 | #[doc = r" a peripheral that uses this constant."] 73 | #[doc = r""] 74 | #[doc = r" See the package documentation for more information on"] 75 | #[doc = r" this constant."] 76 | pub const SOLE_INSTANCE: u8 = 0u8; 77 | mod private { 78 | pub trait Sealed {} 79 | } 80 | #[doc = r" Vouches for an `Instance`'s validity."] 81 | #[doc = r""] 82 | #[doc = r" This trait is implemented for all `Instance` supported"] 83 | #[doc = r" by your chip. Note that the implementation may change when"] 84 | #[doc = r" selecting new chip features. For instance, i.MX RT 1011 chips"] 85 | #[doc = r" do not have LPUART 4 through 8. So, `Valid` is _not_ implemented"] 86 | #[doc = r" for `lpuart::Instance<4>` through `lpuart::Instance<8>`."] 87 | #[doc = r""] 88 | #[doc = r" See the package documentation for more information on how"] 89 | #[doc = r" to use this trait in your APIs."] 90 | pub trait Valid: private::Sealed {} 91 | #[cfg(feature = "hpm6750")] 92 | #[path = "hpm6750.rs"] 93 | mod hpm6750; 94 | #[cfg(feature = "hpm6750")] 95 | pub use hpm6750::*; 96 | -------------------------------------------------------------------------------- /svd/HPM6360.svd.ignored: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpm-rs/hpm-ral/2c5e5af2b80e59683a146e15f04ce3f3eb97c0e8/svd/HPM6360.svd.ignored --------------------------------------------------------------------------------