From d4a74cb4f3287fa05156d3aaea049264f4597692 Mon Sep 17 00:00:00 2001 From: Matt Knight Date: Sat, 17 Sep 2022 16:54:45 -0700 Subject: [PATCH] move examples in here (#12) --- .gitmodules | 3 + build.zig | 42 +- deps/microzig | 1 + examples/blinky.zig | 20 + examples/blinky_core1.zig | 29 + examples/gpio_clk.zig | 21 + examples/pwm.zig | 23 + examples/uart.zig | 48 ++ src/hal.zig | 2 + src/hal/gpio.zig | 3 + src/hal/irq.zig | 20 + src/hal/multicore.zig | 2 +- src/hal/pwm.zig | 8 + src/hal/uart.zig | 51 +- src/rp2040.zig | 1381 ++++++++++--------------------------- 15 files changed, 635 insertions(+), 1019 deletions(-) create mode 100644 .gitmodules create mode 160000 deps/microzig create mode 100644 examples/blinky.zig create mode 100644 examples/blinky_core1.zig create mode 100644 examples/gpio_clk.zig create mode 100644 examples/pwm.zig create mode 100644 examples/uart.zig create mode 100644 src/hal/irq.zig diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..32e895c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "deps/microzig"] + path = deps/microzig + url = https://github.com/ZigEmbeddedGroup/microzig.git diff --git a/build.zig b/build.zig index f4675dd..01a26ae 100644 --- a/build.zig +++ b/build.zig @@ -1,9 +1,10 @@ const std = @import("std"); - const Builder = std.build.Builder; const Pkg = std.build.Pkg; const comptimePrint = std.fmt.comptimePrint; +const microzig = @import("deps/microzig/src/main.zig"); + const chip_path = comptimePrint("{s}/src/rp2040.zig", .{root()}); const board_path = comptimePrint("{s}/src/raspberry_pi_pico.zig", .{root()}); const hal_path = comptimePrint("{s}/src/hal.zig", .{root()}); @@ -12,7 +13,6 @@ const linkerscript_path = comptimePrint("{s}/rp2040.ld", .{root()}); pub const BuildOptions = struct {}; pub fn addPiPicoExecutable( - comptime microzig: type, builder: *Builder, name: []const u8, source: []const u8, @@ -49,6 +49,44 @@ pub fn addPiPicoExecutable( return ret; } +// this build script is mostly for testing and verification of this +// package. In an attempt to modularize -- designing for a case where a +// project requires multiple HALs, it accepts microzig as a param +pub fn build(b: *Builder) !void { + const mode = b.standardReleaseOptions(); + var examples = Examples.init(b, mode); + examples.install(); +} + fn root() []const u8 { return std.fs.path.dirname(@src().file) orelse "."; } + +pub const Examples = struct { + blinky: microzig.EmbeddedExecutable, + blinky_core1: microzig.EmbeddedExecutable, + gpio_clk: microzig.EmbeddedExecutable, + pwm: microzig.EmbeddedExecutable, + uart: microzig.EmbeddedExecutable, + //uart_pins: microzig.EmbeddedExecutable, + + pub fn init(b: *Builder, mode: std.builtin.Mode) Examples { + var ret: Examples = undefined; + inline for (@typeInfo(Examples).Struct.fields) |field| { + @field(ret, field.name) = addPiPicoExecutable( + b, + field.name, + comptime root() ++ "/examples/" ++ field.name ++ ".zig", + .{}, + ); + @field(ret, field.name).setBuildMode(mode); + } + + return ret; + } + + pub fn install(examples: *Examples) void { + inline for (@typeInfo(Examples).Struct.fields) |field| + @field(examples, field.name).install(); + } +}; diff --git a/deps/microzig b/deps/microzig new file mode 160000 index 0000000..4159581 --- /dev/null +++ b/deps/microzig @@ -0,0 +1 @@ +Subproject commit 4159581b4848bfb8bbdf91dabdebd15ecd503427 diff --git a/examples/blinky.zig b/examples/blinky.zig new file mode 100644 index 0000000..ea3f2d8 --- /dev/null +++ b/examples/blinky.zig @@ -0,0 +1,20 @@ +const std = @import("std"); +const microzig = @import("microzig"); +const rp2040 = microzig.hal; +const time = rp2040.time; + +const pin_config = rp2040.pins.GlobalConfiguration{ + .GPIO25 = .{ + .name = "led", + .direction = .out, + }, +}; + +pub fn main() !void { + const pins = pin_config.apply(); + + while (true) { + pins.led.toggle(); + time.sleepMs(250); + } +} diff --git a/examples/blinky_core1.zig b/examples/blinky_core1.zig new file mode 100644 index 0000000..a549f30 --- /dev/null +++ b/examples/blinky_core1.zig @@ -0,0 +1,29 @@ +const std = @import("std"); + +const microzig = @import("microzig"); +const rp2040 = microzig.hal; +const gpio = rp2040.gpio; +const time = rp2040.time; +const multicore = rp2040.multicore; + +const led = 25; + +fn core1() void { + while (true) { + gpio.put(led, 1); + time.sleepMs(250); + gpio.put(led, 0); + time.sleepMs(250); + } +} + +pub fn main() !void { + gpio.init(led); + gpio.setDir(led, .out); + + multicore.launchCore1(core1); + + while (true) { + microzig.cpu.wfi(); + } +} diff --git a/examples/gpio_clk.zig b/examples/gpio_clk.zig new file mode 100644 index 0000000..52280e4 --- /dev/null +++ b/examples/gpio_clk.zig @@ -0,0 +1,21 @@ +const std = @import("std"); +const microzig = @import("microzig"); +const rp2040 = microzig.hal; +const gpio = rp2040.gpio; +const clocks = rp2040.clocks; + +const gpout0_pin = 21; +const clock_config = clocks.GlobalConfiguration.init(.{ + .sys = .{ .source = .src_xosc }, + .gpout0 = .{ .source = .clk_sys }, +}); + +pub fn init() void { + clock_config.apply(); + gpio.reset(); +} + +pub fn main() !void { + gpio.setFunction(gpout0_pin, .gpck); + while (true) {} +} diff --git a/examples/pwm.zig b/examples/pwm.zig new file mode 100644 index 0000000..9eff043 --- /dev/null +++ b/examples/pwm.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const microzig = @import("microzig"); +const rp2040 = microzig.hal; +const gpio = rp2040.gpio; +const clocks = rp2040.clocks; +const time = rp2040.time; +const regs = microzig.chip.registers; +const multicore = rp2040.multicore; + +const pin_config = rp2040.pins.GlobalConfiguration{ + .GPIO25 = .{ .name = "led", .function = .PWM4_B }, +}; + +pub fn main() !void { + const pins = pin_config.apply(); + pins.led.slice().setWrap(100); + pins.led.setLevel(10); + pins.led.slice().enable(); + + while (true) { + time.sleepMs(250); + } +} diff --git a/examples/uart.zig b/examples/uart.zig new file mode 100644 index 0000000..ed29280 --- /dev/null +++ b/examples/uart.zig @@ -0,0 +1,48 @@ +const std = @import("std"); +const microzig = @import("microzig"); + +const rp2040 = microzig.hal; +const time = rp2040.time; +const gpio = rp2040.gpio; +const clocks = rp2040.clocks; + +const led = 25; +const uart_id = 0; +const baud_rate = 115200; +const uart_tx_pin = 0; +const uart_rx_pin = 1; + +pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace) noreturn { + std.log.err("panic: {s}", .{message}); + @breakpoint(); + while (true) {} +} + +pub const log_level = .debug; +pub const log = rp2040.uart.log; + +pub fn main() !void { + gpio.reset(); + gpio.init(led); + gpio.setDir(led, .out); + gpio.put(led, 1); + + const uart = rp2040.uart.UART.init(uart_id, .{ + .baud_rate = baud_rate, + .tx_pin = uart_tx_pin, + .rx_pin = uart_rx_pin, + .clock_config = rp2040.clock_config, + }); + + rp2040.uart.initLogger(uart); + + var i: u32 = 0; + while (true) : (i += 1) { + gpio.put(led, 1); + std.log.info("what {}", .{i}); + time.sleepMs(500); + + gpio.put(led, 0); + time.sleepMs(500); + } +} diff --git a/src/hal.zig b/src/hal.zig index 1dc50e6..61132bd 100644 --- a/src/hal.zig +++ b/src/hal.zig @@ -8,6 +8,8 @@ pub const multicore = @import("hal/multicore.zig"); pub const time = @import("hal/time.zig"); pub const uart = @import("hal/uart.zig"); pub const pwm = @import("hal/pwm.zig"); +pub const resets = @import("hal/resets.zig"); +pub const irq = @import("hal/irq.zig"); pub const clock_config = clocks.GlobalConfiguration.init(.{ .ref = .{ .source = .src_xosc }, diff --git a/src/hal/gpio.zig b/src/hal/gpio.zig index ec48f11..18624ee 100644 --- a/src/hal/gpio.zig +++ b/src/hal/gpio.zig @@ -4,6 +4,8 @@ const resets = @import("resets.zig"); const regs = microzig.chip.registers; const assert = std.debug.assert; +const log = std.log.scoped(.gpio); + pub const Function = enum(u5) { xip, spi, @@ -83,6 +85,7 @@ pub inline fn setDir(comptime gpio: u32, direction: Direction) void { /// Drive a single GPIO high/low pub inline fn put(comptime gpio: u32, value: u1) void { + std.log.debug("GPIO{} put: {}", .{ gpio, value }); const mask = 1 << gpio; switch (value) { 0 => regs.SIO.GPIO_OUT_CLR.raw = mask, diff --git a/src/hal/irq.zig b/src/hal/irq.zig new file mode 100644 index 0000000..7d57c78 --- /dev/null +++ b/src/hal/irq.zig @@ -0,0 +1,20 @@ +const microzig = @import("microzig"); +const regs = microzig.chip.registers; + +// TODO: the register definitions are improved now, use them instead of raw +// writes/reads +fn getInterruptMask(comptime interrupt_name: []const u8) u32 { + const offset = @offsetOf(microzig.chip.VectorTable, interrupt_name); + + return (1 << ((offset / 4) - 16)); +} +pub fn enable(comptime interrupt_name: []const u8) void { + const mask = comptime getInterruptMask(interrupt_name); + regs.SCS.NVIC.ICPR.raw = mask; + regs.SCS.NVIC.ISER.raw = mask; +} + +pub fn disable(comptime interrupt_name: []const u8) void { + const mask = comptime getInterruptMask(interrupt_name); + regs.SCS.NVIC.ICER.raw = mask; +} diff --git a/src/hal/multicore.zig b/src/hal/multicore.zig index dd90d17..76811cf 100644 --- a/src/hal/multicore.zig +++ b/src/hal/multicore.zig @@ -88,7 +88,7 @@ pub fn launchCore1WithStack(entrypoint: fn () void, stack: []u32) void { 0, 0, 1, - regs.PPB.VTOR.raw, + regs.SCS.SCB.VTOR.raw, stack_ptr, @ptrToInt(wrapper), }; diff --git a/src/hal/pwm.zig b/src/hal/pwm.zig index 457fd2c..45cf90b 100644 --- a/src/hal/pwm.zig +++ b/src/hal/pwm.zig @@ -1,6 +1,9 @@ +const std = @import("std"); const microzig = @import("microzig"); const regs = microzig.chip.registers; +const log = std.log.scoped(.pwm); + pub const Config = struct {}; fn getRegs(comptime slice: u32) *volatile Regs { @@ -67,12 +70,14 @@ const Regs = extern struct { }; pub inline fn setSlicePhaseCorrect(comptime slice: u32, phase_correct: bool) void { + log.debug("PWM{} set phase correct: {}", .{ slice, phase_correct }); getRegs(slice).csr.modify(.{ .PH_CORRECT = if (phase_correct) 1 else 0, }); } pub inline fn setSliceClkDiv(comptime slice: u32, integer: u8, fraction: u4) void { + log.debug("PWM{} set clk div: {}.{}", .{ slice, integer, fraction }); getRegs(slice).div.modify(.{ .INT = integer, .FRAC = fraction, @@ -80,6 +85,7 @@ pub inline fn setSliceClkDiv(comptime slice: u32, integer: u8, fraction: u4) voi } pub inline fn setSliceClkDivMode(comptime slice: u32, mode: ClkDivMode) void { + log.debug("PWM{} set clk div mode: {}", .{ slice, mode }); getRegs(slice).csr.modify(.{ .DIVMODE = @enumToInt(mode), }); @@ -101,6 +107,7 @@ pub inline fn setChannelInversion( } pub inline fn setSliceWrap(comptime slice: u32, wrap: u16) void { + log.debug("PWM{} set wrap: {}", .{ slice, wrap }); getRegs(slice).top.raw = wrap; } @@ -109,6 +116,7 @@ pub inline fn setChannelLevel( comptime channel: Channel, level: u16, ) void { + log.debug("PWM{} {} set level: {}", .{ slice, channel, level }); switch (channel) { .a => getRegs(slice).cc.modify(.{ .A = level }), .b => getRegs(slice).cc.modify(.{ .B = level }), diff --git a/src/hal/uart.zig b/src/hal/uart.zig index 1816399..5f3f8c6 100644 --- a/src/hal/uart.zig +++ b/src/hal/uart.zig @@ -2,6 +2,8 @@ const std = @import("std"); const microzig = @import("microzig"); const gpio = @import("gpio.zig"); const clocks = @import("clocks.zig"); +const resets = @import("resets.zig"); +const time = @import("time.zig"); const assert = std.debug.assert; const regs = microzig.chip.registers; @@ -39,7 +41,7 @@ pub const UartRegs = extern struct { rsr: u32, reserved0: [4]u32, fr: @typeInfo(@TypeOf(regs.UART0.UARTFR)).Pointer.child, - resertev1: [1]u32, + reserved1: [1]u32, ilpr: u32, ibrd: u32, fbrd: u32, @@ -149,16 +151,8 @@ pub const UART = enum { pub fn reset(uart: UART) void { switch (uart) { - .uart0 => { - regs.RESETS.RESET.modify(.{ .uart0 = 1 }); - regs.RESETS.RESET.modify(.{ .uart0 = 0 }); - while (regs.RESETS.RESET_DONE.read().uart0 != 1) {} - }, - .uart1 => { - regs.RESETS.RESET.modify(.{ .uart1 = 1 }); - regs.RESETS.RESET.modify(.{ .uart1 = 0 }); - while (regs.RESETS.RESET_DONE.read().uart1 != 1) {} - }, + .uart0 => resets.reset(&.{.uart0}), + .uart1 => resets.reset(&.{.uart1}), } } @@ -180,11 +174,13 @@ pub const UART = enum { .one => @as(u1, 0), .two => @as(u1, 1), }, - .PEN = if (parity != .none) @as(u1, 1) else @as(u1, 0), + .PEN = switch (parity) { + .none => @as(u1, 0), + .even, .odd => @as(u1, 1), + }, .EPS = switch (parity) { .even => @as(u1, 1), - .odd => @as(u1, 0), - else => @as(u1, 0), + .odd, .none => @as(u1, 0), }, }); } @@ -210,3 +206,30 @@ pub const UART = enum { uart_regs.lcr_h.modify(.{}); } }; + +var uart_logger: ?UART.Writer = null; + +pub fn initLogger(uart: UART) void { + uart_logger = uart.writer(); +} + +pub fn log( + comptime level: std.log.Level, + comptime scope: @TypeOf(.EnumLiteral), + comptime format: []const u8, + args: anytype, +) void { + const level_prefix = comptime "[{}.{:0>6}] " ++ level.asText(); + const prefix = comptime level_prefix ++ switch (scope) { + .default => ": ", + else => " (" ++ @tagName(scope) ++ "): ", + }; + + if (uart_logger) |uart| { + const current_time = time.getTimeSinceBoot(); + const seconds = current_time.us_since_boot / std.time.us_per_s; + const microseconds = current_time.us_since_boot % std.time.us_per_s; + + uart.print(prefix ++ format ++ "\r\n", .{ seconds, microseconds } ++ args) catch {}; + } +} diff --git a/src/rp2040.zig b/src/rp2040.zig index 571b648..6301bf2 100644 --- a/src/rp2040.zig +++ b/src/rp2040.zig @@ -1,5 +1,5 @@ // this file was generated by regz: https://github.com/ZigEmbeddedGroup/regz -// commit: 09c331e02d8037bf2e5133eaa40b1d762637b441 +// commit: 644b9d6f61ba1e49d90e4f606f82727f3d6581f2 // // vendor: Raspberry Pi // device: RP2040 @@ -134,23 +134,388 @@ pub const registers = struct { pub const NVIC = struct { /// address: 0xe000e100 /// Interrupt Set Enable Register - pub const ISER = @intToPtr(*volatile u32, base_address + 0x100); + pub const ISER = @intToPtr(*volatile Mmio(32, packed struct { + TIMER_IRQ_0: u1, + TIMER_IRQ_1: u1, + TIMER_IRQ_2: u1, + TIMER_IRQ_3: u1, + PWM_IRQ_WRAP: u1, + USBCTRL_IRQ: u1, + XIP_IRQ: u1, + PIO0_IRQ_0: u1, + PIO0_IRQ_1: u1, + PIO1_IRQ_0: u1, + PIO1_IRQ_1: u1, + DMA_IRQ_0: u1, + DMA_IRQ_1: u1, + IO_IRQ_BANK0: u1, + IO_IRQ_QSPI: u1, + SIO_IRQ_PROC0: u1, + SIO_IRQ_PROC1: u1, + CLOCKS_IRQ: u1, + SPI0_IRQ: u1, + SPI1_IRQ: u1, + UART0_IRQ: u1, + UART1_IRQ: u1, + ADC_IRQ_FIFO: u1, + I2C0_IRQ: u1, + I2C1_IRQ: u1, + RTC_IRQ: u1, + padding0: u1 = 0, + padding1: u1 = 0, + padding2: u1 = 0, + padding3: u1 = 0, + padding4: u1 = 0, + padding5: u1 = 0, + }), base_address + 0x100); /// address: 0xe000e180 /// Interrupt Clear Enable Register - pub const ICER = @intToPtr(*volatile u32, base_address + 0x180); + pub const ICER = @intToPtr(*volatile Mmio(32, packed struct { + TIMER_IRQ_0: u1, + TIMER_IRQ_1: u1, + TIMER_IRQ_2: u1, + TIMER_IRQ_3: u1, + PWM_IRQ_WRAP: u1, + USBCTRL_IRQ: u1, + XIP_IRQ: u1, + PIO0_IRQ_0: u1, + PIO0_IRQ_1: u1, + PIO1_IRQ_0: u1, + PIO1_IRQ_1: u1, + DMA_IRQ_0: u1, + DMA_IRQ_1: u1, + IO_IRQ_BANK0: u1, + IO_IRQ_QSPI: u1, + SIO_IRQ_PROC0: u1, + SIO_IRQ_PROC1: u1, + CLOCKS_IRQ: u1, + SPI0_IRQ: u1, + SPI1_IRQ: u1, + UART0_IRQ: u1, + UART1_IRQ: u1, + ADC_IRQ_FIFO: u1, + I2C0_IRQ: u1, + I2C1_IRQ: u1, + RTC_IRQ: u1, + padding0: u1 = 0, + padding1: u1 = 0, + padding2: u1 = 0, + padding3: u1 = 0, + padding4: u1 = 0, + padding5: u1 = 0, + }), base_address + 0x180); /// address: 0xe000e200 /// Interrupt Set Pending Register - pub const ISPR = @intToPtr(*volatile u32, base_address + 0x200); + pub const ISPR = @intToPtr(*volatile Mmio(32, packed struct { + TIMER_IRQ_0: u1, + TIMER_IRQ_1: u1, + TIMER_IRQ_2: u1, + TIMER_IRQ_3: u1, + PWM_IRQ_WRAP: u1, + USBCTRL_IRQ: u1, + XIP_IRQ: u1, + PIO0_IRQ_0: u1, + PIO0_IRQ_1: u1, + PIO1_IRQ_0: u1, + PIO1_IRQ_1: u1, + DMA_IRQ_0: u1, + DMA_IRQ_1: u1, + IO_IRQ_BANK0: u1, + IO_IRQ_QSPI: u1, + SIO_IRQ_PROC0: u1, + SIO_IRQ_PROC1: u1, + CLOCKS_IRQ: u1, + SPI0_IRQ: u1, + SPI1_IRQ: u1, + UART0_IRQ: u1, + UART1_IRQ: u1, + ADC_IRQ_FIFO: u1, + I2C0_IRQ: u1, + I2C1_IRQ: u1, + RTC_IRQ: u1, + padding0: u1 = 0, + padding1: u1 = 0, + padding2: u1 = 0, + padding3: u1 = 0, + padding4: u1 = 0, + padding5: u1 = 0, + }), base_address + 0x200); /// address: 0xe000e280 /// Interrupt Clear Pending Register - pub const ICPR = @intToPtr(*volatile u32, base_address + 0x280); + pub const ICPR = @intToPtr(*volatile Mmio(32, packed struct { + TIMER_IRQ_0: u1, + TIMER_IRQ_1: u1, + TIMER_IRQ_2: u1, + TIMER_IRQ_3: u1, + PWM_IRQ_WRAP: u1, + USBCTRL_IRQ: u1, + XIP_IRQ: u1, + PIO0_IRQ_0: u1, + PIO0_IRQ_1: u1, + PIO1_IRQ_0: u1, + PIO1_IRQ_1: u1, + DMA_IRQ_0: u1, + DMA_IRQ_1: u1, + IO_IRQ_BANK0: u1, + IO_IRQ_QSPI: u1, + SIO_IRQ_PROC0: u1, + SIO_IRQ_PROC1: u1, + CLOCKS_IRQ: u1, + SPI0_IRQ: u1, + SPI1_IRQ: u1, + UART0_IRQ: u1, + UART1_IRQ: u1, + ADC_IRQ_FIFO: u1, + I2C0_IRQ: u1, + I2C1_IRQ: u1, + RTC_IRQ: u1, + padding0: u1 = 0, + padding1: u1 = 0, + padding2: u1 = 0, + padding3: u1 = 0, + padding4: u1 = 0, + padding5: u1 = 0, + }), base_address + 0x280); /// address: 0xe000e400 /// Interrupt Priority Register - pub const IP = @intToPtr(*volatile u32, base_address + 0x400); + pub const IP0 = @intToPtr(*volatile Mmio(32, packed struct { + reserved0: u1 = 0, + reserved1: u1 = 0, + reserved2: u1 = 0, + reserved3: u1 = 0, + reserved4: u1 = 0, + reserved5: u1 = 0, + TIMER_IRQ_0: u2, + reserved6: u1 = 0, + reserved7: u1 = 0, + reserved8: u1 = 0, + reserved9: u1 = 0, + reserved10: u1 = 0, + reserved11: u1 = 0, + TIMER_IRQ_1: u2, + reserved12: u1 = 0, + reserved13: u1 = 0, + reserved14: u1 = 0, + reserved15: u1 = 0, + reserved16: u1 = 0, + reserved17: u1 = 0, + TIMER_IRQ_2: u2, + reserved18: u1 = 0, + reserved19: u1 = 0, + reserved20: u1 = 0, + reserved21: u1 = 0, + reserved22: u1 = 0, + reserved23: u1 = 0, + TIMER_IRQ_3: u2, + }), base_address + 0x400); + + /// address: 0xe000e404 + /// Interrupt Priority Register + pub const IP1 = @intToPtr(*volatile Mmio(32, packed struct { + reserved0: u1 = 0, + reserved1: u1 = 0, + reserved2: u1 = 0, + reserved3: u1 = 0, + reserved4: u1 = 0, + reserved5: u1 = 0, + PWM_IRQ_WRAP: u2, + reserved6: u1 = 0, + reserved7: u1 = 0, + reserved8: u1 = 0, + reserved9: u1 = 0, + reserved10: u1 = 0, + reserved11: u1 = 0, + USBCTRL_IRQ: u2, + reserved12: u1 = 0, + reserved13: u1 = 0, + reserved14: u1 = 0, + reserved15: u1 = 0, + reserved16: u1 = 0, + reserved17: u1 = 0, + XIP_IRQ: u2, + reserved18: u1 = 0, + reserved19: u1 = 0, + reserved20: u1 = 0, + reserved21: u1 = 0, + reserved22: u1 = 0, + reserved23: u1 = 0, + PIO0_IRQ_0: u2, + }), base_address + 0x404); + + /// address: 0xe000e408 + /// Interrupt Priority Register + pub const IP2 = @intToPtr(*volatile Mmio(32, packed struct { + reserved0: u1 = 0, + reserved1: u1 = 0, + reserved2: u1 = 0, + reserved3: u1 = 0, + reserved4: u1 = 0, + reserved5: u1 = 0, + PIO0_IRQ_1: u2, + reserved6: u1 = 0, + reserved7: u1 = 0, + reserved8: u1 = 0, + reserved9: u1 = 0, + reserved10: u1 = 0, + reserved11: u1 = 0, + PIO1_IRQ_0: u2, + reserved12: u1 = 0, + reserved13: u1 = 0, + reserved14: u1 = 0, + reserved15: u1 = 0, + reserved16: u1 = 0, + reserved17: u1 = 0, + PIO1_IRQ_1: u2, + reserved18: u1 = 0, + reserved19: u1 = 0, + reserved20: u1 = 0, + reserved21: u1 = 0, + reserved22: u1 = 0, + reserved23: u1 = 0, + DMA_IRQ_0: u2, + }), base_address + 0x408); + + /// address: 0xe000e40c + /// Interrupt Priority Register + pub const IP3 = @intToPtr(*volatile Mmio(32, packed struct { + reserved0: u1 = 0, + reserved1: u1 = 0, + reserved2: u1 = 0, + reserved3: u1 = 0, + reserved4: u1 = 0, + reserved5: u1 = 0, + DMA_IRQ_1: u2, + reserved6: u1 = 0, + reserved7: u1 = 0, + reserved8: u1 = 0, + reserved9: u1 = 0, + reserved10: u1 = 0, + reserved11: u1 = 0, + IO_IRQ_BANK0: u2, + reserved12: u1 = 0, + reserved13: u1 = 0, + reserved14: u1 = 0, + reserved15: u1 = 0, + reserved16: u1 = 0, + reserved17: u1 = 0, + IO_IRQ_QSPI: u2, + reserved18: u1 = 0, + reserved19: u1 = 0, + reserved20: u1 = 0, + reserved21: u1 = 0, + reserved22: u1 = 0, + reserved23: u1 = 0, + SIO_IRQ_PROC0: u2, + }), base_address + 0x40c); + + /// address: 0xe000e410 + /// Interrupt Priority Register + pub const IP4 = @intToPtr(*volatile Mmio(32, packed struct { + reserved0: u1 = 0, + reserved1: u1 = 0, + reserved2: u1 = 0, + reserved3: u1 = 0, + reserved4: u1 = 0, + reserved5: u1 = 0, + SIO_IRQ_PROC1: u2, + reserved6: u1 = 0, + reserved7: u1 = 0, + reserved8: u1 = 0, + reserved9: u1 = 0, + reserved10: u1 = 0, + reserved11: u1 = 0, + CLOCKS_IRQ: u2, + reserved12: u1 = 0, + reserved13: u1 = 0, + reserved14: u1 = 0, + reserved15: u1 = 0, + reserved16: u1 = 0, + reserved17: u1 = 0, + SPI0_IRQ: u2, + reserved18: u1 = 0, + reserved19: u1 = 0, + reserved20: u1 = 0, + reserved21: u1 = 0, + reserved22: u1 = 0, + reserved23: u1 = 0, + SPI1_IRQ: u2, + }), base_address + 0x410); + + /// address: 0xe000e414 + /// Interrupt Priority Register + pub const IP5 = @intToPtr(*volatile Mmio(32, packed struct { + reserved0: u1 = 0, + reserved1: u1 = 0, + reserved2: u1 = 0, + reserved3: u1 = 0, + reserved4: u1 = 0, + reserved5: u1 = 0, + UART0_IRQ: u2, + reserved6: u1 = 0, + reserved7: u1 = 0, + reserved8: u1 = 0, + reserved9: u1 = 0, + reserved10: u1 = 0, + reserved11: u1 = 0, + UART1_IRQ: u2, + reserved12: u1 = 0, + reserved13: u1 = 0, + reserved14: u1 = 0, + reserved15: u1 = 0, + reserved16: u1 = 0, + reserved17: u1 = 0, + ADC_IRQ_FIFO: u2, + reserved18: u1 = 0, + reserved19: u1 = 0, + reserved20: u1 = 0, + reserved21: u1 = 0, + reserved22: u1 = 0, + reserved23: u1 = 0, + I2C0_IRQ: u2, + }), base_address + 0x414); + + /// address: 0xe000e418 + /// Interrupt Priority Register + pub const IP6 = @intToPtr(*volatile Mmio(32, packed struct { + reserved0: u1 = 0, + reserved1: u1 = 0, + reserved2: u1 = 0, + reserved3: u1 = 0, + reserved4: u1 = 0, + reserved5: u1 = 0, + I2C1_IRQ: u2, + reserved6: u1 = 0, + reserved7: u1 = 0, + reserved8: u1 = 0, + reserved9: u1 = 0, + reserved10: u1 = 0, + reserved11: u1 = 0, + RTC_IRQ: u2, + padding0: u1 = 0, + padding1: u1 = 0, + padding2: u1 = 0, + padding3: u1 = 0, + padding4: u1 = 0, + padding5: u1 = 0, + padding6: u1 = 0, + padding7: u1 = 0, + padding8: u1 = 0, + padding9: u1 = 0, + padding10: u1 = 0, + padding11: u1 = 0, + padding12: u1 = 0, + padding13: u1 = 0, + padding14: u1 = 0, + padding15: u1 = 0, + }), base_address + 0x418); + + /// address: 0xe000e41c + /// Interrupt Priority Register + pub const IP7 = @intToPtr(*volatile u32, base_address + 0x41c); }; /// System Control Block @@ -28295,806 +28660,35 @@ pub const registers = struct { pub const base_address = 0xe0000000; pub const version = "1"; - /// address: 0xe000e010 - /// Use the SysTick Control and Status Register to enable the SysTick features. - pub const SYST_CSR = @intToPtr(*volatile Mmio(32, packed struct { - /// Enable SysTick counter:\n - /// 0 = Counter disabled.\n - /// 1 = Counter enabled. - ENABLE: u1, - /// Enables SysTick exception request:\n - /// 0 = Counting down to zero does not assert the SysTick exception request.\n - /// 1 = Counting down to zero to asserts the SysTick exception request. - TICKINT: u1, - /// SysTick clock source. Always reads as one if SYST_CALIB reports NOREF.\n - /// Selects the SysTick timer clock source:\n - /// 0 = External reference clock.\n - /// 1 = Processor clock. - CLKSOURCE: u1, - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - reserved12: u1 = 0, - /// Returns 1 if timer counted to 0 since last time this was read. Clears on read by - /// application or debugger. - COUNTFLAG: u1, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - padding8: u1 = 0, - padding9: u1 = 0, - padding10: u1 = 0, - padding11: u1 = 0, - padding12: u1 = 0, - padding13: u1 = 0, - padding14: u1 = 0, - }), base_address + 0xe010); - - /// address: 0xe000e014 - /// Use the SysTick Reload Value Register to specify the start value to load into - /// the current value register when the counter reaches 0. It can be any value - /// between 0 and 0x00FFFFFF. A start value of 0 is possible, but has no effect - /// because the SysTick interrupt and COUNTFLAG are activated when counting from 1 - /// to 0. The reset value of this register is UNKNOWN.\n - /// To generate a multi-shot timer with a period of N processor clock cycles, use a - /// RELOAD value of N-1. For example, if the SysTick interrupt is required every 100 - /// clock pulses, set RELOAD to 99. - pub const SYST_RVR = @intToPtr(*volatile Mmio(32, packed struct { - /// Value to load into the SysTick Current Value Register when the counter reaches - /// 0. - RELOAD: u24, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - }), base_address + 0xe014); - - /// address: 0xe000e018 - /// Use the SysTick Current Value Register to find the current value in the - /// register. The reset value of this register is UNKNOWN. - pub const SYST_CVR = @intToPtr(*volatile Mmio(32, packed struct { - /// Reads return the current value of the SysTick counter. This register is - /// write-clear. Writing to it with any value clears the register to 0. Clearing - /// this register also clears the COUNTFLAG bit of the SysTick Control and Status - /// Register. - CURRENT: u24, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - }), base_address + 0xe018); - - /// address: 0xe000e01c - /// Use the SysTick Calibration Value Register to enable software to scale to any - /// required speed using divide and multiply. - pub const SYST_CALIB = @intToPtr(*volatile Mmio(32, packed struct { - /// An optional Reload value to be used for 10ms (100Hz) timing, subject to system - /// clock skew errors. If the value reads as 0, the calibration value is not known. - TENMS: u24, - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// If reads as 1, the calibration value for 10ms is inexact (due to clock - /// frequency). - SKEW: u1, - /// If reads as 1, the Reference clock is not provided - the CLKSOURCE bit of the - /// SysTick Control and Status register will be forced to 1 and cannot be cleared to - /// 0. - NOREF: u1, - }), base_address + 0xe01c); - - /// address: 0xe000e100 - /// Use the Interrupt Set-Enable Register to enable interrupts and determine which - /// interrupts are currently enabled.\n - /// If a pending interrupt is enabled, the NVIC activates the interrupt based on its - /// priority. If an interrupt is not enabled, asserting its interrupt signal changes - /// the interrupt state to pending, but the NVIC never activates the interrupt, - /// regardless of its priority. - pub const NVIC_ISER = @intToPtr(*volatile Mmio(32, packed struct { - /// Interrupt set-enable bits.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Enable interrupt.\n - /// Read:\n - /// 0 = Interrupt disabled.\n - /// 1 = Interrupt enabled. - SETENA: u32, - }), base_address + 0xe100); - - /// address: 0xe000e180 - /// Use the Interrupt Clear-Enable Registers to disable interrupts and determine - /// which interrupts are currently enabled. - pub const NVIC_ICER = @intToPtr(*volatile Mmio(32, packed struct { - /// Interrupt clear-enable bits.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Disable interrupt.\n - /// Read:\n - /// 0 = Interrupt disabled.\n - /// 1 = Interrupt enabled. - CLRENA: u32, - }), base_address + 0xe180); - - /// address: 0xe000e200 - /// The NVIC_ISPR forces interrupts into the pending state, and shows which - /// interrupts are pending. - pub const NVIC_ISPR = @intToPtr(*volatile Mmio(32, packed struct { - /// Interrupt set-pending bits.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Changes interrupt state to pending.\n - /// Read:\n - /// 0 = Interrupt is not pending.\n - /// 1 = Interrupt is pending.\n - /// Note: Writing 1 to the NVIC_ISPR bit corresponding to:\n - /// An interrupt that is pending has no effect.\n - /// A disabled interrupt sets the state of that interrupt to pending. - SETPEND: u32, - }), base_address + 0xe200); - - /// address: 0xe000e280 - /// Use the Interrupt Clear-Pending Register to clear pending interrupts and - /// determine which interrupts are currently pending. - pub const NVIC_ICPR = @intToPtr(*volatile Mmio(32, packed struct { - /// Interrupt clear-pending bits.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Removes pending state and interrupt.\n - /// Read:\n - /// 0 = Interrupt is not pending.\n - /// 1 = Interrupt is pending. - CLRPEND: u32, - }), base_address + 0xe280); - - /// address: 0xe000e400 - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest.\n - /// Note: Writing 1 to an NVIC_ICPR bit does not affect the active state of the - /// corresponding interrupt.\n - /// These registers are only word-accessible - pub const NVIC_IPR0 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// Priority of interrupt 0 - IP_0: u2, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - /// Priority of interrupt 1 - IP_1: u2, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - /// Priority of interrupt 2 - IP_2: u2, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 3 - IP_3: u2, - }), base_address + 0xe400); - - /// address: 0xe000e404 - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest. - pub const NVIC_IPR1 = @intToPtr(*volatile Mmio(32, packed struct { + /// address: 0xe000ed20 + /// System handlers are a special class of exception handler that can have their + /// priority set to any of the priority levels. Use the System Handler Priority + /// Register 3 to set the priority of PendSV and SysTick. + pub const SHPR3 = @intToPtr(*volatile Mmio(32, packed struct { reserved0: u1 = 0, reserved1: u1 = 0, reserved2: u1 = 0, reserved3: u1 = 0, reserved4: u1 = 0, reserved5: u1 = 0, - /// Priority of interrupt 4 - IP_4: u2, reserved6: u1 = 0, reserved7: u1 = 0, reserved8: u1 = 0, reserved9: u1 = 0, reserved10: u1 = 0, reserved11: u1 = 0, - /// Priority of interrupt 5 - IP_5: u2, reserved12: u1 = 0, reserved13: u1 = 0, reserved14: u1 = 0, reserved15: u1 = 0, reserved16: u1 = 0, reserved17: u1 = 0, - /// Priority of interrupt 6 - IP_6: u2, reserved18: u1 = 0, reserved19: u1 = 0, reserved20: u1 = 0, reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 7 - IP_7: u2, - }), base_address + 0xe404); - - /// address: 0xe000e408 - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest. - pub const NVIC_IPR2 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// Priority of interrupt 8 - IP_8: u2, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - /// Priority of interrupt 9 - IP_9: u2, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - /// Priority of interrupt 10 - IP_10: u2, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 11 - IP_11: u2, - }), base_address + 0xe408); - - /// address: 0xe000e40c - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest. - pub const NVIC_IPR3 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// Priority of interrupt 12 - IP_12: u2, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - /// Priority of interrupt 13 - IP_13: u2, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - /// Priority of interrupt 14 - IP_14: u2, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 15 - IP_15: u2, - }), base_address + 0xe40c); - - /// address: 0xe000e410 - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest. - pub const NVIC_IPR4 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// Priority of interrupt 16 - IP_16: u2, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - /// Priority of interrupt 17 - IP_17: u2, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - /// Priority of interrupt 18 - IP_18: u2, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 19 - IP_19: u2, - }), base_address + 0xe410); - - /// address: 0xe000e414 - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest. - pub const NVIC_IPR5 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// Priority of interrupt 20 - IP_20: u2, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - /// Priority of interrupt 21 - IP_21: u2, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - /// Priority of interrupt 22 - IP_22: u2, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 23 - IP_23: u2, - }), base_address + 0xe414); - - /// address: 0xe000e418 - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest. - pub const NVIC_IPR6 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// Priority of interrupt 24 - IP_24: u2, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - /// Priority of interrupt 25 - IP_25: u2, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - /// Priority of interrupt 26 - IP_26: u2, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 27 - IP_27: u2, - }), base_address + 0xe418); - - /// address: 0xe000e41c - /// Use the Interrupt Priority Registers to assign a priority from 0 to 3 to each of - /// the available interrupts. 0 is the highest priority, and 3 is the lowest. - pub const NVIC_IPR7 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - /// Priority of interrupt 28 - IP_28: u2, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - /// Priority of interrupt 29 - IP_29: u2, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - /// Priority of interrupt 30 - IP_30: u2, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - /// Priority of interrupt 31 - IP_31: u2, - }), base_address + 0xe41c); - - /// address: 0xe000ed00 - /// Read the CPU ID Base Register to determine: the ID number of the processor core, - /// the version number of the processor core, the implementation details of the - /// processor core. - pub const CPUID = @intToPtr(*volatile Mmio(32, packed struct { - /// Minor revision number m in the rnpm revision status:\n - /// 0x1 = Patch 1. - REVISION: u4, - /// Number of processor within family: 0xC60 = Cortex-M0+ - PARTNO: u12, - /// Constant that defines the architecture of the processor:\n - /// 0xC = ARMv6-M architecture. - ARCHITECTURE: u4, - /// Major revision number n in the rnpm revision status:\n - /// 0x0 = Revision 0. - VARIANT: u4, - /// Implementor code: 0x41 = ARM - IMPLEMENTER: u8, - }), base_address + 0xed00); - - /// address: 0xe000ed04 - /// Use the Interrupt Control State Register to set a pending Non-Maskable Interrupt - /// (NMI), set or clear a pending PendSV, set or clear a pending SysTick, check for - /// pending exceptions, check the vector number of the highest priority pended - /// exception, check the vector number of the active exception. - pub const ICSR = @intToPtr(*volatile Mmio(32, packed struct { - /// Active exception number field. Reset clears the VECTACTIVE field. - VECTACTIVE: u9, - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - /// Indicates the exception number for the highest priority pending exception: 0 = - /// no pending exceptions. Non zero = The pending state includes the effect of - /// memory-mapped enable and mask registers. It does not include the PRIMASK - /// special-purpose register qualifier. - VECTPENDING: u9, - reserved3: u1 = 0, - /// External interrupt pending flag - ISRPENDING: u1, - /// The system can only access this bit when the core is halted. It indicates that a - /// pending interrupt is to be taken in the next running cycle. If C_MASKINTS is - /// clear in the Debug Halting Control and Status Register, the interrupt is - /// serviced. - ISRPREEMPT: u1, - reserved4: u1 = 0, - /// SysTick exception clear-pending bit.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Removes the pending state from the SysTick exception.\n - /// This bit is WO. On a register read its value is Unknown. - PENDSTCLR: u1, - /// SysTick exception set-pending bit.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Changes SysTick exception state to pending.\n - /// Read:\n - /// 0 = SysTick exception is not pending.\n - /// 1 = SysTick exception is pending. - PENDSTSET: u1, - /// PendSV clear-pending bit.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Removes the pending state from the PendSV exception. - PENDSVCLR: u1, - /// PendSV set-pending bit.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Changes PendSV exception state to pending.\n - /// Read:\n - /// 0 = PendSV exception is not pending.\n - /// 1 = PendSV exception is pending.\n - /// Writing 1 to this bit is the only way to set the PendSV exception state to - /// pending. - PENDSVSET: u1, - reserved5: u1 = 0, - reserved6: u1 = 0, - /// Setting this bit will activate an NMI. Since NMI is the highest priority - /// exception, it will activate as soon as it is registered.\n - /// NMI set-pending bit.\n - /// Write:\n - /// 0 = No effect.\n - /// 1 = Changes NMI exception state to pending.\n - /// Read:\n - /// 0 = NMI exception is not pending.\n - /// 1 = NMI exception is pending.\n - /// Because NMI is the highest-priority exception, normally the processor enters the - /// NMI\n - /// exception handler as soon as it detects a write of 1 to this bit. Entering the - /// handler then clears\n - /// this bit to 0. This means a read of this bit by the NMI exception handler - /// returns 1 only if the\n - /// NMI signal is reasserted while the processor is executing that handler. - NMIPENDSET: u1, - }), base_address + 0xed04); - - /// address: 0xe000ed08 - /// The VTOR holds the vector table offset address. - pub const VTOR = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - reserved7: u1 = 0, - /// Bits [31:8] of the indicate the vector table offset address. - TBLOFF: u24, - }), base_address + 0xed08); - - /// address: 0xe000ed0c - /// Use the Application Interrupt and Reset Control Register to: determine data - /// endianness, clear all active state information from debug halt mode, request a - /// system reset. - pub const AIRCR = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - /// Clears all active state information for fixed and configurable exceptions. This - /// bit: is self-clearing, can only be set by the DAP when the core is halted. When - /// set: clears all active exception status of the processor, forces a return to - /// Thread mode, forces an IPSR of 0. A debugger must re-initialize the stack. - VECTCLRACTIVE: u1, - /// Writing 1 to this bit causes the SYSRESETREQ signal to the outer system to be - /// asserted to request a reset. The intention is to force a large system reset of - /// all major components except for debug. The C_HALT bit in the DHCSR is cleared as - /// a result of the system reset requested. The debugger does not lose contact with - /// the device. - SYSRESETREQ: u1, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - reserved12: u1 = 0, - /// Data endianness implemented:\n - /// 0 = Little-endian. - ENDIANESS: u1, - /// Register key:\n - /// Reads as Unknown\n - /// On writes, write 0x05FA to VECTKEY, otherwise the write is ignored. - VECTKEY: u16, - }), base_address + 0xed0c); - - /// address: 0xe000ed10 - /// System Control Register. Use the System Control Register for power-management - /// functions: signal to the system when the processor can enter a low power state, - /// control how the processor enters and exits low power states. - pub const SCR = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - /// Indicates sleep-on-exit when returning from Handler mode to Thread mode:\n - /// 0 = Do not sleep when returning to Thread mode.\n - /// 1 = Enter sleep, or deep sleep, on return from an ISR to Thread mode.\n - /// Setting this bit to 1 enables an interrupt driven application to avoid returning - /// to an empty main application. - SLEEPONEXIT: u1, - /// Controls whether the processor uses sleep or deep sleep as its low power mode:\n - /// 0 = Sleep.\n - /// 1 = Deep sleep. - SLEEPDEEP: u1, - reserved1: u1 = 0, - /// Send Event on Pending bit:\n - /// 0 = Only enabled interrupts or events can wakeup the processor, disabled - /// interrupts are excluded.\n - /// 1 = Enabled events and all interrupts, including disabled interrupts, can wakeup - /// the processor.\n - /// When an event or interrupt becomes pending, the event signal wakes up the - /// processor from WFE. If the\n - /// processor is not waiting for an event, the event is registered and affects the - /// next WFE.\n - /// The processor also wakes up on execution of an SEV instruction or an external - /// event. - SEVONPEND: u1, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - padding8: u1 = 0, - padding9: u1 = 0, - padding10: u1 = 0, - padding11: u1 = 0, - padding12: u1 = 0, - padding13: u1 = 0, - padding14: u1 = 0, - padding15: u1 = 0, - padding16: u1 = 0, - padding17: u1 = 0, - padding18: u1 = 0, - padding19: u1 = 0, - padding20: u1 = 0, - padding21: u1 = 0, - padding22: u1 = 0, - padding23: u1 = 0, - padding24: u1 = 0, - padding25: u1 = 0, - padding26: u1 = 0, - }), base_address + 0xed10); - - /// address: 0xe000ed14 - /// The Configuration and Control Register permanently enables stack alignment and - /// causes unaligned accesses to result in a Hard Fault. - pub const CCR = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - /// Always reads as one, indicates that all unaligned accesses generate a HardFault. - UNALIGN_TRP: u1, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - reserved7: u1 = 0, - /// Always reads as one, indicates 8-byte stack alignment on exception entry. On - /// exception entry, the processor uses bit[9] of the stacked PSR to indicate the - /// stack alignment. On return from the exception it uses this stacked bit to - /// restore the correct stack alignment. - STKALIGN: u1, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - padding8: u1 = 0, - padding9: u1 = 0, - padding10: u1 = 0, - padding11: u1 = 0, - padding12: u1 = 0, - padding13: u1 = 0, - padding14: u1 = 0, - padding15: u1 = 0, - padding16: u1 = 0, - padding17: u1 = 0, - padding18: u1 = 0, - padding19: u1 = 0, - padding20: u1 = 0, - padding21: u1 = 0, - }), base_address + 0xed14); - - /// address: 0xe000ed1c - /// System handlers are a special class of exception handler that can have their - /// priority set to any of the priority levels. Use the System Handler Priority - /// Register 2 to set the priority of SVCall. - pub const SHPR2 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - reserved22: u1 = 0, - reserved23: u1 = 0, - reserved24: u1 = 0, - reserved25: u1 = 0, - reserved26: u1 = 0, - reserved27: u1 = 0, - reserved28: u1 = 0, - reserved29: u1 = 0, - /// Priority of system handler 11, SVCall - PRI_11: u2, - }), base_address + 0xed1c); - - /// address: 0xe000ed20 - /// System handlers are a special class of exception handler that can have their - /// priority set to any of the priority levels. Use the System Handler Priority - /// Register 3 to set the priority of PendSV and SysTick. - pub const SHPR3 = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - reserved15: u1 = 0, - reserved16: u1 = 0, - reserved17: u1 = 0, - reserved18: u1 = 0, - reserved19: u1 = 0, - reserved20: u1 = 0, - reserved21: u1 = 0, - /// Priority of system handler 14, PendSV - PRI_14: u2, + /// Priority of system handler 14, PendSV + PRI_14: u2, reserved22: u1 = 0, reserved23: u1 = 0, reserved24: u1 = 0, @@ -29104,223 +28698,6 @@ pub const registers = struct { /// Priority of system handler 15, SysTick PRI_15: u2, }), base_address + 0xed20); - - /// address: 0xe000ed24 - /// Use the System Handler Control and State Register to determine or clear the - /// pending status of SVCall. - pub const SHCSR = @intToPtr(*volatile Mmio(32, packed struct { - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - reserved7: u1 = 0, - reserved8: u1 = 0, - reserved9: u1 = 0, - reserved10: u1 = 0, - reserved11: u1 = 0, - reserved12: u1 = 0, - reserved13: u1 = 0, - reserved14: u1 = 0, - /// Reads as 1 if SVCall is Pending. Write 1 to set pending SVCall, write 0 to clear - /// pending SVCall. - SVCALLPENDED: u1, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - padding8: u1 = 0, - padding9: u1 = 0, - padding10: u1 = 0, - padding11: u1 = 0, - padding12: u1 = 0, - padding13: u1 = 0, - padding14: u1 = 0, - padding15: u1 = 0, - }), base_address + 0xed24); - - /// address: 0xe000ed90 - /// Read the MPU Type Register to determine if the processor implements an MPU, and - /// how many regions the MPU supports. - pub const MPU_TYPE = @intToPtr(*volatile Mmio(32, packed struct { - /// Indicates support for separate instruction and data address maps. Reads as 0 as - /// ARMv6-M only supports a unified MPU. - SEPARATE: u1, - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - reserved3: u1 = 0, - reserved4: u1 = 0, - reserved5: u1 = 0, - reserved6: u1 = 0, - /// Number of regions supported by the MPU. - DREGION: u8, - /// Instruction region. Reads as zero as ARMv6-M only supports a unified MPU. - IREGION: u8, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - }), base_address + 0xed90); - - /// address: 0xe000ed94 - /// Use the MPU Control Register to enable and disable the MPU, and to control - /// whether the default memory map is enabled as a background region for privileged - /// accesses, and whether the MPU is enabled for HardFaults and NMIs. - pub const MPU_CTRL = @intToPtr(*volatile Mmio(32, packed struct { - /// Enables the MPU. If the MPU is disabled, privileged and unprivileged accesses - /// use the default memory map.\n - /// 0 = MPU disabled.\n - /// 1 = MPU enabled. - ENABLE: u1, - /// Controls the use of the MPU for HardFaults and NMIs. Setting this bit when - /// ENABLE is clear results in UNPREDICTABLE behaviour.\n - /// When the MPU is enabled:\n - /// 0 = MPU is disabled during HardFault and NMI handlers, regardless of the value - /// of the ENABLE bit.\n - /// 1 = the MPU is enabled during HardFault and NMI handlers. - HFNMIENA: u1, - /// Controls whether the default memory map is enabled as a background region for - /// privileged accesses. This bit is ignored when ENABLE is clear.\n - /// 0 = If the MPU is enabled, disables use of the default memory map. Any memory - /// access to a location not\n - /// covered by any enabled region causes a fault.\n - /// 1 = If the MPU is enabled, enables use of the default memory map as a background - /// region for privileged software accesses.\n - /// When enabled, the background region acts as if it is region number -1. Any - /// region that is defined and enabled has priority over this default map. - PRIVDEFENA: u1, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - padding8: u1 = 0, - padding9: u1 = 0, - padding10: u1 = 0, - padding11: u1 = 0, - padding12: u1 = 0, - padding13: u1 = 0, - padding14: u1 = 0, - padding15: u1 = 0, - padding16: u1 = 0, - padding17: u1 = 0, - padding18: u1 = 0, - padding19: u1 = 0, - padding20: u1 = 0, - padding21: u1 = 0, - padding22: u1 = 0, - padding23: u1 = 0, - padding24: u1 = 0, - padding25: u1 = 0, - padding26: u1 = 0, - padding27: u1 = 0, - padding28: u1 = 0, - }), base_address + 0xed94); - - /// address: 0xe000ed98 - /// Use the MPU Region Number Register to select the region currently accessed by - /// MPU_RBAR and MPU_RASR. - pub const MPU_RNR = @intToPtr(*volatile Mmio(32, packed struct { - /// Indicates the MPU region referenced by the MPU_RBAR and MPU_RASR registers.\n - /// The MPU supports 8 memory regions, so the permitted values of this field are - /// 0-7. - REGION: u4, - padding0: u1 = 0, - padding1: u1 = 0, - padding2: u1 = 0, - padding3: u1 = 0, - padding4: u1 = 0, - padding5: u1 = 0, - padding6: u1 = 0, - padding7: u1 = 0, - padding8: u1 = 0, - padding9: u1 = 0, - padding10: u1 = 0, - padding11: u1 = 0, - padding12: u1 = 0, - padding13: u1 = 0, - padding14: u1 = 0, - padding15: u1 = 0, - padding16: u1 = 0, - padding17: u1 = 0, - padding18: u1 = 0, - padding19: u1 = 0, - padding20: u1 = 0, - padding21: u1 = 0, - padding22: u1 = 0, - padding23: u1 = 0, - padding24: u1 = 0, - padding25: u1 = 0, - padding26: u1 = 0, - padding27: u1 = 0, - }), base_address + 0xed98); - - /// address: 0xe000ed9c - /// Read the MPU Region Base Address Register to determine the base address of the - /// region identified by MPU_RNR. Write to update the base address of said region or - /// that of a specified region, with whose number MPU_RNR will also be updated. - pub const MPU_RBAR = @intToPtr(*volatile Mmio(32, packed struct { - /// On writes, specifies the number of the region whose base address to update - /// provided VALID is set written as 1. On reads, returns bits [3:0] of MPU_RNR. - REGION: u4, - /// On writes, indicates whether the write must update the base address of the - /// region identified by the REGION field, updating the MPU_RNR to indicate this new - /// region.\n - /// Write:\n - /// 0 = MPU_RNR not changed, and the processor:\n - /// Updates the base address for the region specified in the MPU_RNR.\n - /// Ignores the value of the REGION field.\n - /// 1 = The processor:\n - /// Updates the value of the MPU_RNR to the value of the REGION field.\n - /// Updates the base address for the region specified in the REGION field.\n - /// Always reads as zero. - VALID: u1, - reserved0: u1 = 0, - reserved1: u1 = 0, - reserved2: u1 = 0, - /// Base address of the region. - ADDR: u24, - }), base_address + 0xed9c); - - /// address: 0xe000eda0 - /// Use the MPU Region Attribute and Size Register to define the size, access - /// behaviour and memory type of the region identified by MPU_RNR, and enable that - /// region. - pub const MPU_RASR = @intToPtr(*volatile Mmio(32, packed struct { - /// Enables the region. - ENABLE: u1, - /// Indicates the region size. Region size in bytes = 2^(SIZE+1). The minimum - /// permitted value is 7 (b00111) = 256Bytes - SIZE: u5, - reserved0: u1 = 0, - reserved1: u1 = 0, - /// Subregion Disable. For regions of 256 bytes or larger, each bit of this field - /// controls whether one of the eight equal subregions is enabled. - SRD: u8, - /// The MPU Region Attribute field. Use to define the region attribute control.\n - /// 28 = XN: Instruction access disable bit:\n - /// 0 = Instruction fetches enabled.\n - /// 1 = Instruction fetches disabled.\n - /// 26:24 = AP: Access permission field\n - /// 18 = S: Shareable bit\n - /// 17 = C: Cacheable bit\n - /// 16 = B: Bufferable bit - ATTRS: u16, - }), base_address + 0xeda0); }; }; @@ -29402,7 +28779,7 @@ pub fn mmioInt(addr: usize, comptime size: usize, comptime T: type) *volatile Mm return @intToPtr(*volatile MmioInt(size, T), addr); } -const InterruptVector = extern union { +pub const InterruptVector = extern union { C: fn () callconv(.C) void, Naked: fn () callconv(.Naked) void, // Interrupt is not supported on arm