Generate Zig header files from CMSIS-SVD files for accessing MMIO registers.
This is a fork of svd4zig.
Features taken from rbino's svd4zig:
- This was the one used as a starting point
- 100% in Zig
- Naming conventions are taken from the datasheet (i.e. all caps), so it's easy to follow along
- Strong Assumptions™ in the svd are targeted towards STM32 devices (the original used a STM32F767ZG and STM32F407, this fork was developed with an STM32F103)
- The tool doesn't just output registers but also other information about the device (e.g. interrupts)
- Registers are modeled with packed structs (see this post from the original authors)
New features:
zig build -Drelease-safe
./zig-out/bin/svd2zig path/to/svd/file path/to/output.zig
zig fmt path/to/output.zig
https://github.com/posborne/cmsis-svd
Have a look at this blogpost for all the details, a example modified from rbino's STM32F407 blink project to set and read some registers to make led blink on stm32f103c8t6:
// registers.zig is the generated file,
// which is generated from STM32F103xx.svd in "https://github.com/posborne/cmsis-svd/blob/master/data/STMicro/STM32F103xx.svd"
const regs = @import("registers.zig");
pub fn main() void {
systemInit();
// Enable GPIOC port
regs.RCC.APB2ENR.IOPCEN = 1;
// Set pin 13 mode to general purpose output
regs.GPIOC.CRH.MODE13 = 0b01;
// Set pin 13
regs.GPIOC.BSRR.BS13 = 1;
while (true) {
// Set the LED output to the negation of the currrent output
regs.GPIOC.ODR.ODR13 = ~regs.GPIOC.IDR.IDR13;
// Sleep for some time
var i: u32 = 0;
while (i < 6000000) {
i += 1;
}
}
}
fn systemInit() void {
// This init does these things:
// - Enables the FPU coprocessor
// - Sets the external oscillator to achieve a clock frequency of 72MHz
// - Sets the correct PLL prescalers for that clock frequency
// - Enables the flash data and instruction cache and sets the correct latency for 72MHz
// Enable FPU coprocessor
// WARN: currently not supported in qemu, comment if testing it there
// regs.FPU_CPACR.CPACR.modify(.{ .CP = 0b11 });
// Enable HSI
regs.RCC.CR.HSION = 1;
// Wait for HSI ready
while (regs.RCC.CR.HSIRDY != 1) {}
// Select HSI as clock source
regs.RCC.CFGR.SW = 0;
// Enable external high-speed oscillator (HSE)
regs.RCC.CR.HSEON = 1;
// Wait for HSE ready
while (regs.RCC.CR.HSERDY != 1) {}
// Set prescalers for 72 MHz: HPRE = 0, PPRE1 = DIV_2, PPRE2 = 0
regs.RCC.CFGR.PPRE1 = 0b100;
// Disable PLL before changing its configuration
regs.RCC.CR.PLLON = 0;
// Set PLL prescalers and HSE clock source
regs.RCC.CFGR.PLLSRC = 1;
regs.RCC.CFGR.PLLMUL = 9;
// Enable PLL
regs.RCC.CR.PLLON = 1;
// Wait for PLL ready
while (regs.RCC.CR.PLLRDY != 1) {}
// Enable flash data and instruction cache and set flash latency to 2 wait states
regs.FLASH.ACR.LATENCY = 0b10;
// Select PLL as clock source
regs.RCC.CFGR.SW = 0b10;
// // Wait for PLL selected as clock source
var cfgr = regs.RCC.CFGR;
while (cfgr.SWS != 0b10) {}
// Disable HSI
regs.RCC.CR.HSION = 0;
}0.13.0