Merge remote-tracking branch 'esp/main' into merge_esp

wch-ch32v003
Felix "xq" Queißner 9 months ago
commit 1c05830e74

1
.gitattributes vendored

@ -0,0 +1 @@
*.zig text=auto eol=lf

2
.gitignore vendored

@ -0,0 +1,2 @@
zig-out
zig-cache

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Zig Embedded Group
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,9 @@
= ESP MicroZig Package
[WIP]
SVD is copied from https://github.com/esp-rs/esp-pacs
== What version of Zig to use
0.11.0

@ -0,0 +1,74 @@
const std = @import("std");
fn path(comptime suffix: []const u8) std.Build.LazyPath {
return .{
.cwd_relative = comptime ((std.fs.path.dirname(@src().file) orelse ".") ++ suffix),
};
}
const esp_riscv = .{
.name = "Espressif RISC-V",
.source_file = path("/src/cpus/espressif-riscv.zig"),
.target = std.zig.CrossTarget{
.cpu_arch = .riscv32,
.cpu_model = .{ .explicit = &std.Target.riscv.cpu.generic_rv32 },
.cpu_features_add = std.Target.riscv.featureSet(&.{
std.Target.riscv.Feature.c,
std.Target.riscv.Feature.m,
}),
.os_tag = .freestanding,
.abi = .eabi,
},
};
const hal = .{
.source_file = path("/src/hals/ESP32_C3.zig"),
};
pub const chips = struct {
pub const esp32_c3 = .{
.preferred_format = .bin, // TODO: Exchange FLAT format with .esp format
.chip = .{
.name = "ESP32-C3",
.url = "https://www.espressif.com/en/products/socs/esp32-c3",
.cpu = .{ .custom = &esp_riscv },
.register_definition = .{
.svd = path("/src/chips/ESP32-C3.svd"),
},
.memory_regions = &.{
.{ .kind = .flash, .offset = 0x4200_0000, .length = 0x0080_0000 }, // external memory, ibus
.{ .kind = .ram, .offset = 0x3FC8_0000, .length = 0x0006_0000 }, // sram 1, data bus
},
},
.hal = hal,
};
};
pub fn build(b: *std.Build) void {
_ = b;
// const optimize = b.standardOptimizeOption(.{});
// var exe = microzig.addEmbeddedExecutable(b, .{
// .name = "esp-bringup",
// .source_file = .{
// .path = "src/example/blinky.zig",
// },
// .backing = .{ .chip = chips.esp32_c3 },
// .optimize = optimize,
// });
// const fw_objcopy = b.addObjCopy(exe.inner.getEmittedBin(), .{
// .format = .bin,
// });
// const fw_bin = fw_objcopy.getOutput();
// const install_fw_bin = b.addInstallFile(fw_bin, "firmware/blinky.bin");
// b.getInstallStep().dependOn(&install_fw_bin.step);
// b.installArtifact(exe.inner);
}

@ -0,0 +1,5 @@
.{
.name = "microzig-espressif-esp",
.version = "0.1.0",
.dependencies = .{},
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

@ -0,0 +1,13 @@
#!/bin/bash
set -e
clear
zig build -Doptimize=ReleaseSmall
llvm-objdump -S ./zig-out/bin/esp-bringup > /tmp/dump.txt
esptool.py \
--port /dev/ttyUSB0 \
--baud 115200 \
write_flash 0x00000000 zig-out/firmware/blinky.bin \
--verify
picocom --baud 115200 /dev/ttyUSB0

File diff suppressed because it is too large Load Diff

@ -0,0 +1,103 @@
const std = @import("std");
const microzig = @import("microzig");
const root = @import("root");
pub const StatusRegister = enum(u8) {
// machine information
mvendorid,
marchid,
mimpid,
mhartid,
// machine trap setup
mstatus,
misa,
mtvec,
};
pub inline fn setStatusBit(comptime reg: StatusRegister, bits: u32) void {
asm volatile ("csrrs zero, " ++ @tagName(reg) ++ ", %[value]"
:
: [value] "r" (bits),
);
}
pub inline fn clearStatusBit(comptime reg: StatusRegister, bits: u32) void {
asm volatile ("csrrc zero, " ++ @tagName(reg) ++ ", %[value]"
:
: [value] "r" (bits),
);
}
pub inline fn disable_interrupts() void {
clearStatusBit(.mstatus, 0x08);
}
pub inline fn enable_interrupts() void {
setStatusBit(.mstatus, 0x08);
}
pub const startup_logic = struct {
comptime {
// See this:
// https://github.com/espressif/esp32c3-direct-boot-example
// Direct Boot: does not support Security Boot and programs run directly in flash. To enable this mode, make
// sure that the first two words of the bin file downloading to flash (address: 0x42000000) are 0xaedb041d.
// In this case, the ROM bootloader sets up Flash MMU to map 4 MB of Flash to
// addresses 0x42000000 (for code execution) and 0x3C000000 (for read-only data
// access). The bootloader then jumps to address 0x42000008, i.e. to the
// instruction at offset 8 in flash, immediately after the magic numbers.
asm (
\\.extern _start
\\.section microzig_flash_start
\\.align 4
\\.byte 0x1d, 0x04, 0xdb, 0xae
\\.byte 0x1d, 0x04, 0xdb, 0xae
);
}
extern fn microzig_main() noreturn;
export fn _start() linksection("microzig_flash_start") callconv(.C) noreturn {
microzig.cpu.disable_interrupts();
asm volatile ("mv sp, %[eos]"
:
: [eos] "r" (@as(u32, microzig.config.end_of_stack)),
);
asm volatile ("la gp, __global_pointer$");
microzig.cpu.setStatusBit(.mtvec, microzig.config.end_of_stack);
root.initialize_system_memories();
microzig_main();
}
export fn _rv32_trap() callconv(.C) noreturn {
while (true) {}
}
const vector_table = [_]fn () callconv(.C) noreturn{
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
_rv32_trap,
};
};

@ -0,0 +1,57 @@
const std = @import("std");
const microzig = @import("microzig");
const peripherals = microzig.chip.peripherals;
const TIMG0 = peripherals.TIMG0;
const RTC_CNTL = peripherals.RTC_CNTL;
const INTERRUPT_CORE0 = peripherals.INTERRUPT_CORE0;
const GPIO = peripherals.GPIO;
const dogfood: u32 = 0x50D83AA1;
const super_dogfood: u32 = 0x8F1D312A;
pub fn main() !void {
TIMG0.WDTWPROTECT.raw = dogfood;
TIMG0.WDTCONFIG0.raw = 0;
TIMG0.WDTWPROTECT.raw = 0;
RTC_CNTL.WDTWPROTECT.raw = dogfood;
RTC_CNTL.WDTCONFIG0.raw = 0;
RTC_CNTL.WDTWPROTECT.raw = 0;
RTC_CNTL.SWD_WPROTECT.raw = super_dogfood;
RTC_CNTL.SWD_CONF.modify(.{ .SWD_DISABLE = 1 });
RTC_CNTL.SWD_WPROTECT.raw = 0;
INTERRUPT_CORE0.CPU_INT_ENABLE.raw = 0;
microzig.hal.gpio.init(LED_R_PIN, .{
.direction = .output,
.direct_io = true,
});
microzig.hal.gpio.init(LED_G_PIN, .{
.direction = .output,
.direct_io = true,
});
microzig.hal.gpio.init(LED_B_PIN, .{
.direction = .output,
.direct_io = true,
});
microzig.hal.uart.write(0, "Hello from Zig!\r\n");
while (true) {
GPIO.OUT.modify(.{ .DATA_ORIG = (1 << LED_R_PIN) });
microzig.hal.uart.write(0, "R");
microzig.core.experimental.debug.busy_sleep(100_000);
GPIO.OUT.modify(.{ .DATA_ORIG = (1 << LED_G_PIN) });
microzig.hal.uart.write(0, "G");
microzig.core.experimental.debug.busy_sleep(100_000);
GPIO.OUT.modify(.{ .DATA_ORIG = (1 << LED_B_PIN) });
microzig.hal.uart.write(0, "B");
microzig.core.experimental.debug.busy_sleep(100_000);
}
}
const LED_R_PIN = 3; // GPIO
const LED_G_PIN = 16; // GPIO
const LED_B_PIN = 17; // GPIO

@ -0,0 +1,47 @@
const std = @import("std");
const microzig = @import("microzig");
const peripherals = microzig.chip.peripherals;
const GPIO = peripherals.GPIO;
pub const gpio = struct {
fn assertRange(comptime p: comptime_int) void {
if (p < 0 or p >= 21)
@compileError(std.fmt.comptimePrint("GPIO {} does not exist. GPIO pins can be between 0 and 21", .{p}));
}
pub const Config = struct {
function: u8 = 0x80,
invert_function: bool = false,
direction: microzig.core.experimental.gpio.Direction,
direct_io: bool = false,
invert_direct_io: bool = false,
};
pub fn init(comptime pin: comptime_int, comptime config: Config) void {
assertRange(pin);
GPIO.FUNC_OUT_SEL_CFG[pin].modify(.{
.OUT_SEL = config.function,
.INV_SEL = @intFromBool(config.invert_function),
.OEN_SEL = @intFromBool(config.direct_io),
.OEN_INV_SEL = @intFromBool(config.invert_direct_io),
});
switch (config.direction) {
.input => GPIO.ENABLE.raw &= ~(@as(u32, 1) << pin),
.output => GPIO.ENABLE.raw |= (@as(u32, 1) << pin),
}
}
};
pub const uart = struct {
fn reg(comptime index: comptime_int) @TypeOf(@field(peripherals, std.fmt.comptimePrint("UART{}", .{index}))) {
return @field(peripherals, std.fmt.comptimePrint("UART{}", .{index}));
}
pub fn write(comptime index: comptime_int, slice: []const u8) void {
const r = reg(index);
for (slice) |c| {
while (r.STATUS.read().TXFIFO_CNT > 8) {}
r.FIFO.raw = c;
}
}
};
Loading…
Cancel
Save