she blinks
This commit is contained in:
@@ -1,165 +0,0 @@
|
|||||||
/*
|
|
||||||
******************************************************************************
|
|
||||||
**
|
|
||||||
|
|
||||||
** File : LinkerScript.ld
|
|
||||||
**
|
|
||||||
** Author : STM32CubeMX
|
|
||||||
**
|
|
||||||
** Abstract : Linker script for STM32G431CBTx series
|
|
||||||
** 112Kbytes FLASH and 32Kbytes RAM
|
|
||||||
**
|
|
||||||
** Set heap size, stack size and stack location according
|
|
||||||
** to application requirements.
|
|
||||||
**
|
|
||||||
** Set memory bank area and size if external memory is used.
|
|
||||||
**
|
|
||||||
** Target : STMicroelectronics STM32
|
|
||||||
**
|
|
||||||
** Distribution: The file is distributed “as is,” without any warranty
|
|
||||||
** of any kind.
|
|
||||||
**
|
|
||||||
*****************************************************************************
|
|
||||||
** @attention
|
|
||||||
**
|
|
||||||
** <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
|
|
||||||
**
|
|
||||||
** Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
** are permitted provided that the following conditions are met:
|
|
||||||
** 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
** this list of conditions and the following disclaimer.
|
|
||||||
** 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
** this list of conditions and the following disclaimer in the documentation
|
|
||||||
** and/or other materials provided with the distribution.
|
|
||||||
** 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
||||||
** may be used to endorse or promote products derived from this software
|
|
||||||
** without specific prior written permission.
|
|
||||||
**
|
|
||||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
**
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Entry Point */
|
|
||||||
ENTRY(Reset_Handler)
|
|
||||||
|
|
||||||
/* Generate a link error if heap and stack don't fit into RAM */
|
|
||||||
_Min_Heap_Size = 0x200; /* required amount of heap */
|
|
||||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
|
||||||
|
|
||||||
/* Specify the memory areas */
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
|
|
||||||
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 112K
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _estack = ORIGIN(RAM) + LENGTH(RAM); */
|
|
||||||
_estack = 0x20008000;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Highest address of the user mode stack */
|
|
||||||
|
|
||||||
|
|
||||||
/* Define output sections */
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
/* The startup code goes first into FLASH */
|
|
||||||
.isr_vector :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
KEEP(*(.isr_vector)) /* Startup code */
|
|
||||||
. = ALIGN(4);
|
|
||||||
} >FLASH
|
|
||||||
|
|
||||||
/* The program code and other data goes into FLASH */
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
*(.text) /* .text sections (code) */
|
|
||||||
*(.text*) /* .text* sections (code) */
|
|
||||||
*(.glue_7) /* glue arm to thumb code */
|
|
||||||
*(.glue_7t) /* glue thumb to arm code */
|
|
||||||
*(.eh_frame)
|
|
||||||
|
|
||||||
KEEP (*(.init))
|
|
||||||
KEEP (*(.fini))
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
_etext = .; /* define a global symbols at end of code */
|
|
||||||
} >FLASH
|
|
||||||
|
|
||||||
/* Constant data goes into FLASH */
|
|
||||||
.rodata :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
|
||||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
|
||||||
. = ALIGN(4);
|
|
||||||
} >FLASH
|
|
||||||
|
|
||||||
/* used by the startup to initialize data */
|
|
||||||
_sidata = LOADADDR(.data);
|
|
||||||
|
|
||||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
|
||||||
.data :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
_sdata = .; /* create a global symbol at data start */
|
|
||||||
*(.data) /* .data sections */
|
|
||||||
*(.data*) /* .data* sections */
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
_edata = .; /* define a global symbol at data end */
|
|
||||||
} >RAM AT> FLASH
|
|
||||||
|
|
||||||
|
|
||||||
/* Uninitialized data section */
|
|
||||||
. = ALIGN(4);
|
|
||||||
.bss :
|
|
||||||
{
|
|
||||||
/* This is used by the startup in order to initialize the .bss secion */
|
|
||||||
_sbss = .; /* define a global symbol at bss start */
|
|
||||||
__bss_start__ = _sbss;
|
|
||||||
*(.bss)
|
|
||||||
*(.bss*)
|
|
||||||
*(COMMON)
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
_ebss = .; /* define a global symbol at bss end */
|
|
||||||
__bss_end__ = _ebss;
|
|
||||||
} >RAM
|
|
||||||
|
|
||||||
/* User_heap_stack section, used to check that there is enough RAM left */
|
|
||||||
._user_heap_stack :
|
|
||||||
{
|
|
||||||
. = ALIGN(8);
|
|
||||||
PROVIDE ( end = . );
|
|
||||||
PROVIDE ( _end = . );
|
|
||||||
. = . + _Min_Heap_Size;
|
|
||||||
. = . + _Min_Stack_Size;
|
|
||||||
. = ALIGN(8);
|
|
||||||
} >RAM
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Remove information from the standard libraries */
|
|
||||||
/DISCARD/ :
|
|
||||||
{
|
|
||||||
libc.a ( * )
|
|
||||||
libm.a ( * )
|
|
||||||
libgcc.a ( * )
|
|
||||||
}
|
|
||||||
|
|
||||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
|
||||||
}
|
|
||||||
68
build.zig
68
build.zig
@@ -4,6 +4,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
const optimize = b.standardOptimizeOption(.{
|
const optimize = b.standardOptimizeOption(.{
|
||||||
.preferred_optimize_mode = .ReleaseSmall,
|
.preferred_optimize_mode = .ReleaseSmall,
|
||||||
});
|
});
|
||||||
|
|
||||||
const target = b.resolveTargetQuery(.{
|
const target = b.resolveTargetQuery(.{
|
||||||
.cpu_arch = .thumb,
|
.cpu_arch = .thumb,
|
||||||
.cpu_model = .{
|
.cpu_model = .{
|
||||||
@@ -13,26 +14,54 @@ pub fn build(b: *std.Build) void {
|
|||||||
.abi = .eabihf,
|
.abi = .eabihf,
|
||||||
});
|
});
|
||||||
|
|
||||||
// const mod = b.addModule("zig_stm32g4_test", .{
|
const main_mod = b.addModule("Main", .{
|
||||||
// .root_source_file = b.path("src/root.zig"),
|
|
||||||
// .target = target,
|
|
||||||
// });
|
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
|
||||||
.name = "zig_stm32g4_test",
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
}),
|
.link_libc = false,
|
||||||
|
.strip = false,
|
||||||
|
.single_threaded = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const mcu_mod = b.addModule("Mcu", .{
|
||||||
|
.root_source_file = b.path("src/microcontroller/mcu.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = false,
|
||||||
|
.strip = false,
|
||||||
|
.single_threaded = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const stm32G4_mod = b.addModule("main", .{
|
||||||
|
.root_source_file = b.path("src/microcontroller/stm32g4/startup.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = false,
|
||||||
|
.strip = false,
|
||||||
|
.single_threaded = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
stm32G4_mod.addImport("Mcu", mcu_mod);
|
||||||
|
mcu_mod.addImport("Stm32g4", stm32G4_mod);
|
||||||
|
main_mod.addImport("Mcu", mcu_mod);
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "zig_stm32g4_test",
|
||||||
|
.linkage = .static,
|
||||||
|
.use_lld = true,
|
||||||
|
.use_llvm = true,
|
||||||
|
.root_module = stm32G4_mod,
|
||||||
|
});
|
||||||
|
|
||||||
exe.dead_strip_dylibs = true;
|
exe.dead_strip_dylibs = true;
|
||||||
exe.link_gc_sections = true;
|
exe.link_gc_sections = true;
|
||||||
exe.link_function_sections = true;
|
exe.link_function_sections = true;
|
||||||
exe.link_data_sections = true;
|
exe.link_data_sections = true;
|
||||||
exe.lto = .full;
|
exe.lto = .none;
|
||||||
exe.discard_local_symbols = true;
|
exe.discard_local_symbols = true;
|
||||||
|
|
||||||
|
exe.root_module.addImport("Main", main_mod);
|
||||||
|
|
||||||
const bin = exe.addObjCopy(.{ .format = .bin });
|
const bin = exe.addObjCopy(.{ .format = .bin });
|
||||||
const install_exe = b.addInstallArtifact(exe, .{});
|
const install_exe = b.addInstallArtifact(exe, .{});
|
||||||
const install_bin = b.addInstallBinFile(bin.getOutput(), bin.basename);
|
const install_bin = b.addInstallBinFile(bin.getOutput(), bin.basename);
|
||||||
@@ -42,9 +71,24 @@ pub fn build(b: *std.Build) void {
|
|||||||
install_bin.step.dependOn(&install_exe.step);
|
install_bin.step.dependOn(&install_exe.step);
|
||||||
|
|
||||||
b.installArtifact(exe);
|
b.installArtifact(exe);
|
||||||
// const run_step = b.step("run", "Run the app");
|
const flash_run = b.addSystemCommand(&.{
|
||||||
|
"openocd",
|
||||||
|
"-f",
|
||||||
|
"/usr/share/openocd/scripts/board/st_nucleo_g4.cfg",
|
||||||
|
"-c",
|
||||||
|
"init",
|
||||||
|
"-c",
|
||||||
|
"reset halt; flash write_image erase zig-out/bin/zig_stm32g4_test.bin 0x08000000 bin",
|
||||||
|
"-c",
|
||||||
|
"flash verify_image zig-out/bin/zig_stm32g4_test.bin 0x08000000 bin",
|
||||||
|
"-c",
|
||||||
|
"reset run; shutdown",
|
||||||
|
});
|
||||||
|
const flash_step = b.step("flash", "Flash the code to the target");
|
||||||
|
|
||||||
|
flash_run.step.dependOn(&install_bin.step);
|
||||||
|
flash_step.dependOn(&flash_run.step);
|
||||||
|
|
||||||
// const run_cmd = b.addRunArtifact(exe);
|
|
||||||
// run_step.dependOn(&run_cmd.step);
|
// run_step.dependOn(&run_cmd.step);
|
||||||
|
|
||||||
// run_cmd.step.dependOn(b.getInstallStep());
|
// run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|||||||
62
src/main.zig
62
src/main.zig
@@ -1,59 +1,21 @@
|
|||||||
const std = @import("std");
|
const Mcu = @import("Mcu").Mcu;
|
||||||
const Io = std.Io;
|
|
||||||
|
|
||||||
export fn resetHandler() callconv(.c) void {
|
|
||||||
_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn _start() void {
|
|
||||||
|
|
||||||
|
|
||||||
// const io = std.Io{
|
|
||||||
// .vtable
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
try main(undefined);
|
|
||||||
|
|
||||||
|
pub fn main(mcu: Mcu) !void {
|
||||||
|
_ = mcu;
|
||||||
|
|
||||||
|
Mcu.peripherals.RCC.RCC_AHB2ENR.write(.{ .GPIOAEN = .B_0x1 });
|
||||||
|
|
||||||
|
Mcu.peripherals.GPIOA.MODER.write(.{ .MODER5 = 0b01 });
|
||||||
|
|
||||||
|
Mcu.peripherals.GPIOA.ODR.write(.{ .ODR5 = 1 });
|
||||||
|
|
||||||
|
var toggle: u1 = 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
for (0..1000000) |_| {
|
||||||
asm volatile ("nop");
|
asm volatile ("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mcu.peripherals.GPIOA.ODR.write(.{ .ODR5 = toggle });
|
||||||
|
if (toggle == 1) toggle = 0 else toggle = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(init: std.process.Init) !void {
|
|
||||||
_ = init;
|
|
||||||
asm volatile ("nop");
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn nmiHandler() callconv(.c) void {}
|
|
||||||
export fn hardFaultHandler() callconv(.c) void {}
|
|
||||||
export fn memManageHandler() callconv(.c) void {}
|
|
||||||
export fn busFaultHandler() callconv(.c) void {}
|
|
||||||
export fn usageFaultHandler() callconv(.c) void {}
|
|
||||||
export fn svCallHandler() callconv(.c) void {}
|
|
||||||
export fn debugMonitorHandler() callconv(.c) void {}
|
|
||||||
export fn pendSvHandler() callconv(.c) void {}
|
|
||||||
export fn sysTickHandler() callconv(.c) void {}
|
|
||||||
|
|
||||||
export const vectors linksection(".vectors") = [_]?*const fn () callconv(.c) void{
|
|
||||||
resetHandler,
|
|
||||||
nmiHandler,
|
|
||||||
hardFaultHandler,
|
|
||||||
memManageHandler,
|
|
||||||
busFaultHandler,
|
|
||||||
usageFaultHandler,
|
|
||||||
null, // reserved
|
|
||||||
null, // reserved
|
|
||||||
null, // reserved
|
|
||||||
null, // reserved
|
|
||||||
svCallHandler,
|
|
||||||
debugMonitorHandler,
|
|
||||||
null, // reserved
|
|
||||||
pendSvHandler,
|
|
||||||
sysTickHandler,
|
|
||||||
// -- snip: continued for MCU-specific interrupts; consult datasheet
|
|
||||||
};
|
|
||||||
|
|||||||
6
src/microcontroller/mcu.zig
Normal file
6
src/microcontroller/mcu.zig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const stm32g4 = @import("Stm32g4");
|
||||||
|
|
||||||
|
pub const Mcu = struct {
|
||||||
|
pub const peripherals = stm32g4.stm32g4.peripherals;
|
||||||
|
isr_vectors: *stm32g4.VectorTable,
|
||||||
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Description for STM32G431
|
//! Description for STM32G431
|
||||||
const microzig = @import("microzig");
|
const mmio = @import("mmio.zig").mmio;
|
||||||
const mmio = microzig.mmio;
|
const InterruptHandle = @import("interrupt.zig").InterruptHandle;
|
||||||
|
|
||||||
pub const types = @import("types.zig");
|
pub const types = @import("types.zig");
|
||||||
|
|
||||||
@@ -124,10 +124,9 @@ pub const interrupts: []const Interrupt = &.{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const VectorTable = extern struct {
|
pub const VectorTable = extern struct {
|
||||||
const Handler = microzig.interrupt.Handler;
|
const Handler = InterruptHandle;
|
||||||
const unhandled = microzig.interrupt.unhandled;
|
const unhandled = InterruptHandle.unhandled;
|
||||||
|
|
||||||
initial_stack_pointer: *const anyopaque,
|
|
||||||
Reset: Handler,
|
Reset: Handler,
|
||||||
NMI: Handler = unhandled,
|
NMI: Handler = unhandled,
|
||||||
HardFault: Handler = unhandled,
|
HardFault: Handler = unhandled,
|
||||||
9
src/microcontroller/stm32g4/interrupt.zig
Normal file
9
src/microcontroller/stm32g4/interrupt.zig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
fn unhandledInterrupt() callconv(.c) void {}
|
||||||
|
|
||||||
|
pub const InterruptHandle = extern struct {
|
||||||
|
func: *const fn () callconv(.c) void,
|
||||||
|
|
||||||
|
pub const unhandled = InterruptHandle{
|
||||||
|
.func = &unhandledInterrupt,
|
||||||
|
};
|
||||||
|
};
|
||||||
100
src/microcontroller/stm32g4/mmio.zig
Normal file
100
src/microcontroller/stm32g4/mmio.zig
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
//! yoniked https://github.com/ZigEmbeddedGroup/microzig/blob/main/core/src/mmio.zig
|
||||||
|
//!
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
pub fn Mmio(comptime Packed: type) type {
|
||||||
|
@setEvalBranchQuota(2_000);
|
||||||
|
|
||||||
|
const size = @bitSizeOf(Packed);
|
||||||
|
if ((size % 8) != 0)
|
||||||
|
@compileError("size must be divisible by 8!");
|
||||||
|
|
||||||
|
if (!std.math.isPowerOfTwo(size / 8))
|
||||||
|
@compileError("size must encode a power of two number of bytes!");
|
||||||
|
|
||||||
|
const Int = @Int(.unsigned, size);
|
||||||
|
|
||||||
|
if (@sizeOf(Packed) != (size / 8))
|
||||||
|
@compileError(std.fmt.comptimePrint("Int and Packed must have the same size!, they are {} and {} bytes respectively", .{ size / 8, @sizeOf(Packed) }));
|
||||||
|
|
||||||
|
return packed struct(Int) {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
raw: Int,
|
||||||
|
|
||||||
|
pub const underlying_type = Packed;
|
||||||
|
|
||||||
|
pub inline fn read(addr: *volatile Self) Packed {
|
||||||
|
return @bitCast(addr.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn write(addr: *volatile Self, val: Packed) void {
|
||||||
|
comptime {
|
||||||
|
assert(@bitSizeOf(Packed) == @bitSizeOf(Int));
|
||||||
|
}
|
||||||
|
addr.writeRaw(@bitCast(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn writeRaw(addr: *volatile Self, val: Int) void {
|
||||||
|
addr.raw = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set field `field_name` of this register to `value`.
|
||||||
|
/// A one-field version of modify(), more helpful if `field_name` is comptime calculated.
|
||||||
|
pub inline fn modifyOne(addr: *volatile Self, comptime field_name: []const u8, value: @FieldType(underlying_type, field_name)) void {
|
||||||
|
var val = read(addr);
|
||||||
|
@field(val, field_name) = value;
|
||||||
|
write(addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For each `.Field = value` entry of `fields`:
|
||||||
|
/// Set field `Field` of this register to `value`.
|
||||||
|
pub inline fn modify(addr: *volatile Self, fields: anytype) void {
|
||||||
|
var val = read(addr);
|
||||||
|
inline for (@typeInfo(@TypeOf(fields)).@"struct".field_names) |field_name| {
|
||||||
|
@field(val, field_name) = @field(fields, field_name);
|
||||||
|
}
|
||||||
|
write(addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// In field `field_name` of struct `val`, toggle (only) all bits that are set in `value`.
|
||||||
|
inline fn toggleField(val: anytype, comptime field_name: []const u8, value: anytype) void {
|
||||||
|
const FieldType = @TypeOf(@field(val, field_name));
|
||||||
|
switch (@typeInfo(FieldType)) {
|
||||||
|
.int => {
|
||||||
|
@field(val, field_name) = @field(val, field_name) ^ value;
|
||||||
|
},
|
||||||
|
.@"enum" => |enum_info| {
|
||||||
|
// same as for the .Int case, but casting to and from the u... tag type U of the enum FieldType
|
||||||
|
const U = enum_info.tag_type;
|
||||||
|
@field(val, field_name) =
|
||||||
|
@as(FieldType, @enumFromInt(@as(U, @intFromEnum(@field(val, field_name))) ^
|
||||||
|
@as(U, @intFromEnum(@as(FieldType, value)))));
|
||||||
|
},
|
||||||
|
else => |T| {
|
||||||
|
@compileError("unsupported register field type '" ++ @typeName(T) ++ "'");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// In field `field_name` of this register, toggle (only) all bits that are set in `value`.
|
||||||
|
/// A one-field version of toggle(), more helpful if `field_name` is comptime calculated.
|
||||||
|
pub inline fn toggleOne(addr: *volatile Self, comptime field_name: []const u8, value: anytype) void {
|
||||||
|
var val = read(addr);
|
||||||
|
toggleField(&val, field_name, value);
|
||||||
|
write(addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For each `.Field = value` entry of `fields`:
|
||||||
|
/// In field `F` of this register, toggle (only) all bits that are set in `value`.
|
||||||
|
pub inline fn toggle(addr: *volatile Self, fields: anytype) void {
|
||||||
|
var val = read(addr);
|
||||||
|
inline for (@typeInfo(@TypeOf(fields)).@"struct".field_names) |field_name| {
|
||||||
|
toggleField(&val, field_name, @field(fields, field_name));
|
||||||
|
}
|
||||||
|
write(addr, val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
47
src/microcontroller/stm32g4/startup.zig
Normal file
47
src/microcontroller/stm32g4/startup.zig
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
pub const VectorTable = @import("STM32G431.zig").VectorTable;
|
||||||
|
pub const InterruptHandle = @import("interrupt.zig").InterruptHandle;
|
||||||
|
pub const stm32g4 = @import("STM32G431.zig");
|
||||||
|
|
||||||
|
const Mcu = @import("Mcu").Mcu;
|
||||||
|
|
||||||
|
const main = @import("Main").main;
|
||||||
|
|
||||||
|
export fn resetHandler() callconv(.c) void {
|
||||||
|
_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub export var vectors linksection(".vectors") = VectorTable{
|
||||||
|
.Reset = InterruptHandle{ .func = &resetHandler },
|
||||||
|
};
|
||||||
|
|
||||||
|
extern var _szero: u32;
|
||||||
|
extern var _ezero: u32;
|
||||||
|
extern var _sdata: u32;
|
||||||
|
extern var _edata: u32;
|
||||||
|
extern var _ldata: u32;
|
||||||
|
export fn _start() callconv(.c) void {
|
||||||
|
const szero: [*]u8 = @ptrCast(&_szero);
|
||||||
|
const sdata: [*]u8 = @ptrCast(&_sdata);
|
||||||
|
const ldata: [*]u8 = @ptrCast(&_ldata);
|
||||||
|
|
||||||
|
const bss_len = @intFromPtr(&_ezero) - @intFromPtr(&_szero);
|
||||||
|
if (bss_len > 0) {
|
||||||
|
@memset(szero[0..bss_len], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data_len = @intFromPtr(&_edata) - @intFromPtr(&_sdata);
|
||||||
|
if (data_len > 0) {
|
||||||
|
@memcpy(sdata[0..data_len], ldata[0..data_len]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @compileLog(@typeInfo(Mcu));
|
||||||
|
const mcu = Mcu{
|
||||||
|
.isr_vectors = &vectors,
|
||||||
|
};
|
||||||
|
main(mcu) catch {};
|
||||||
|
|
||||||
|
// put error code in here
|
||||||
|
while (true) {
|
||||||
|
asm volatile ("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Comparator control and status register
|
/// Comparator control and status register
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// DMAMUX
|
/// DMAMUX
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Flash
|
/// Flash
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Low power timer
|
/// Low power timer
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Universal synchronous asynchronous receiver transmitter
|
/// Universal synchronous asynchronous receiver transmitter
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Serial audio interface
|
/// Serial audio interface
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Advanced-timers
|
/// Advanced-timers
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// General purpose timers
|
/// General purpose timers
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Advanced-timers
|
/// Advanced-timers
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Universal synchronous asynchronous receiver transmitter
|
/// Universal synchronous asynchronous receiver transmitter
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
/// Voltage reference buffer
|
/// Voltage reference buffer
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const microzig = @import("microzig");
|
const mmio = @import("../../mmio.zig");
|
||||||
const mmio = microzig.mmio;
|
|
||||||
|
|
||||||
const types = @import("../../types.zig");
|
const types = @import("../../types.zig");
|
||||||
|
|
||||||
18
src/root.zig
18
src/root.zig
@@ -1,18 +0,0 @@
|
|||||||
// //! By convention, root.zig is the root source file when making a package.
|
|
||||||
// const std = @import("std");
|
|
||||||
// const Io = std.Io;
|
|
||||||
|
|
||||||
// /// This is a documentation comment to explain the `printAnotherMessage` function below.
|
|
||||||
// ///
|
|
||||||
// /// Accepting an `Io.Writer` instance is a handy way to write reusable code.
|
|
||||||
// pub fn printAnotherMessage(writer: *Io.Writer) Io.Writer.Error!void {
|
|
||||||
// try writer.print("Run `zig build test` to run the tests.\n", .{});
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn add(a: i32, b: i32) i32 {
|
|
||||||
// return a + b;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// test "basic add functionality" {
|
|
||||||
// try std.testing.expect(add(3, 7) == 10);
|
|
||||||
// }
|
|
||||||
@@ -2,7 +2,6 @@ FLASH_SIZE = 0x1b580; /* 112k flash */
|
|||||||
SRAM_SIZE = 0x8000; /* 32k sram */
|
SRAM_SIZE = 0x8000; /* 32k sram */
|
||||||
STACK_SIZE = 0x400; /* 1k stack */
|
STACK_SIZE = 0x400; /* 1k stack */
|
||||||
|
|
||||||
|
|
||||||
ENTRY(resetHandler)
|
ENTRY(resetHandler)
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
@@ -33,7 +32,6 @@ SECTIONS
|
|||||||
__initial_stack_pointer = .;
|
__initial_stack_pointer = .;
|
||||||
} > sram
|
} > sram
|
||||||
|
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
{
|
{
|
||||||
_sdata = .;
|
_sdata = .;
|
||||||
@@ -41,7 +39,7 @@ SECTIONS
|
|||||||
*(.data*)
|
*(.data*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_edata = .;
|
_edata = .;
|
||||||
} > sram AT> flash
|
} > sram
|
||||||
|
|
||||||
_ldata = LOADADDR(.data);
|
_ldata = LOADADDR(.data);
|
||||||
|
|
||||||
|
|||||||
0
using-microzig-regez-for-standalone-projects.md
Normal file
0
using-microzig-regez-for-standalone-projects.md
Normal file
Reference in New Issue
Block a user