├── .gitmodules ├── .gitignore ├── .gitattributes ├── docs ├── esp32-c3-32s-pinout.png └── esp32-c3-32s-pinout.xcf ├── README.adoc ├── perform-flash.sh ├── LICENSE └── src ├── hals └── ESP32_C3.zig ├── example └── blinky.zig └── cpus └── espressif-riscv.zig /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | zig-out 2 | zig-cache 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.zig text=auto eol=lf 2 | -------------------------------------------------------------------------------- /docs/esp32-c3-32s-pinout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZigEmbeddedGroup/espressif-esp/HEAD/docs/esp32-c3-32s-pinout.png -------------------------------------------------------------------------------- /docs/esp32-c3-32s-pinout.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZigEmbeddedGroup/espressif-esp/HEAD/docs/esp32-c3-32s-pinout.xcf -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = WE MOVED BACK TO A MONOREPO HERE: https://github.com/ZigEmbeddedGroup/microzig 2 | 3 | == Future contributions go the main repository 4 | -------------------------------------------------------------------------------- /perform-flash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | clear 6 | zig build -Doptimize=ReleaseSmall 7 | llvm-objdump -S ./zig-out/bin/esp-bringup > /tmp/dump.txt 8 | esptool.py \ 9 | --port /dev/ttyUSB0 \ 10 | --baud 115200 \ 11 | write_flash 0x00000000 zig-out/firmware/blinky.bin \ 12 | --verify 13 | picocom --baud 115200 /dev/ttyUSB0 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Zig Embedded Group 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/hals/ESP32_C3.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const microzig = @import("microzig"); 3 | const peripherals = microzig.chip.peripherals; 4 | const GPIO = peripherals.GPIO; 5 | 6 | pub const gpio = struct { 7 | fn assertRange(comptime p: comptime_int) void { 8 | if (p < 0 or p >= 21) 9 | @compileError(std.fmt.comptimePrint("GPIO {} does not exist. GPIO pins can be between 0 and 21", .{p})); 10 | } 11 | 12 | pub const Config = struct { 13 | function: u8 = 0x80, 14 | invert_function: bool = false, 15 | direction: microzig.core.experimental.gpio.Direction, 16 | direct_io: bool = false, 17 | invert_direct_io: bool = false, 18 | }; 19 | 20 | pub fn init(comptime pin: comptime_int, comptime config: Config) void { 21 | assertRange(pin); 22 | GPIO.FUNC_OUT_SEL_CFG[pin].modify(.{ 23 | .OUT_SEL = config.function, 24 | .INV_SEL = @intFromBool(config.invert_function), 25 | .OEN_SEL = @intFromBool(config.direct_io), 26 | .OEN_INV_SEL = @intFromBool(config.invert_direct_io), 27 | }); 28 | switch (config.direction) { 29 | .input => GPIO.ENABLE.raw &= ~(@as(u32, 1) << pin), 30 | .output => GPIO.ENABLE.raw |= (@as(u32, 1) << pin), 31 | } 32 | } 33 | }; 34 | 35 | pub const uart = struct { 36 | fn reg(comptime index: comptime_int) @TypeOf(@field(peripherals, std.fmt.comptimePrint("UART{}", .{index}))) { 37 | return @field(peripherals, std.fmt.comptimePrint("UART{}", .{index})); 38 | } 39 | 40 | pub fn write(comptime index: comptime_int, slice: []const u8) void { 41 | const r = reg(index); 42 | for (slice) |c| { 43 | while (r.STATUS.read().TXFIFO_CNT > 8) {} 44 | r.FIFO.raw = c; 45 | } 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /src/example/blinky.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const microzig = @import("microzig"); 3 | const peripherals = microzig.chip.peripherals; 4 | const TIMG0 = peripherals.TIMG0; 5 | const RTC_CNTL = peripherals.RTC_CNTL; 6 | const INTERRUPT_CORE0 = peripherals.INTERRUPT_CORE0; 7 | const GPIO = peripherals.GPIO; 8 | 9 | const dogfood: u32 = 0x50D83AA1; 10 | const super_dogfood: u32 = 0x8F1D312A; 11 | 12 | pub fn main() !void { 13 | TIMG0.WDTWPROTECT.raw = dogfood; 14 | TIMG0.WDTCONFIG0.raw = 0; 15 | TIMG0.WDTWPROTECT.raw = 0; 16 | 17 | RTC_CNTL.WDTWPROTECT.raw = dogfood; 18 | RTC_CNTL.WDTCONFIG0.raw = 0; 19 | RTC_CNTL.WDTWPROTECT.raw = 0; 20 | 21 | RTC_CNTL.SWD_WPROTECT.raw = super_dogfood; 22 | RTC_CNTL.SWD_CONF.modify(.{ .SWD_DISABLE = 1 }); 23 | RTC_CNTL.SWD_WPROTECT.raw = 0; 24 | 25 | INTERRUPT_CORE0.CPU_INT_ENABLE.raw = 0; 26 | 27 | microzig.hal.gpio.init(LED_R_PIN, .{ 28 | .direction = .output, 29 | .direct_io = true, 30 | }); 31 | microzig.hal.gpio.init(LED_G_PIN, .{ 32 | .direction = .output, 33 | .direct_io = true, 34 | }); 35 | microzig.hal.gpio.init(LED_B_PIN, .{ 36 | .direction = .output, 37 | .direct_io = true, 38 | }); 39 | 40 | microzig.hal.uart.write(0, "Hello from Zig!\r\n"); 41 | 42 | while (true) { 43 | GPIO.OUT.modify(.{ .DATA_ORIG = (1 << LED_R_PIN) }); 44 | microzig.hal.uart.write(0, "R"); 45 | microzig.core.experimental.debug.busy_sleep(100_000); 46 | GPIO.OUT.modify(.{ .DATA_ORIG = (1 << LED_G_PIN) }); 47 | microzig.hal.uart.write(0, "G"); 48 | microzig.core.experimental.debug.busy_sleep(100_000); 49 | GPIO.OUT.modify(.{ .DATA_ORIG = (1 << LED_B_PIN) }); 50 | microzig.hal.uart.write(0, "B"); 51 | microzig.core.experimental.debug.busy_sleep(100_000); 52 | } 53 | } 54 | 55 | const LED_R_PIN = 3; // GPIO 56 | const LED_G_PIN = 16; // GPIO 57 | const LED_B_PIN = 17; // GPIO 58 | -------------------------------------------------------------------------------- /src/cpus/espressif-riscv.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const microzig = @import("microzig"); 3 | const root = @import("root"); 4 | 5 | pub const StatusRegister = enum(u8) { 6 | // machine information 7 | mvendorid, 8 | marchid, 9 | mimpid, 10 | mhartid, 11 | 12 | // machine trap setup 13 | mstatus, 14 | misa, 15 | mtvec, 16 | }; 17 | 18 | pub inline fn setStatusBit(comptime reg: StatusRegister, bits: u32) void { 19 | asm volatile ("csrrs zero, " ++ @tagName(reg) ++ ", %[value]" 20 | : 21 | : [value] "r" (bits), 22 | ); 23 | } 24 | 25 | pub inline fn clearStatusBit(comptime reg: StatusRegister, bits: u32) void { 26 | asm volatile ("csrrc zero, " ++ @tagName(reg) ++ ", %[value]" 27 | : 28 | : [value] "r" (bits), 29 | ); 30 | } 31 | 32 | pub inline fn disable_interrupts() void { 33 | clearStatusBit(.mstatus, 0x08); 34 | } 35 | 36 | pub inline fn enable_interrupts() void { 37 | setStatusBit(.mstatus, 0x08); 38 | } 39 | 40 | pub const startup_logic = struct { 41 | comptime { 42 | // See this: 43 | // https://github.com/espressif/esp32c3-direct-boot-example 44 | 45 | // Direct Boot: does not support Security Boot and programs run directly in flash. To enable this mode, make 46 | // sure that the first two words of the bin file downloading to flash (address: 0x42000000) are 0xaedb041d. 47 | 48 | // In this case, the ROM bootloader sets up Flash MMU to map 4 MB of Flash to 49 | // addresses 0x42000000 (for code execution) and 0x3C000000 (for read-only data 50 | // access). The bootloader then jumps to address 0x42000008, i.e. to the 51 | // instruction at offset 8 in flash, immediately after the magic numbers. 52 | 53 | asm ( 54 | \\.extern _start 55 | \\.section microzig_flash_start 56 | \\.align 4 57 | \\.byte 0x1d, 0x04, 0xdb, 0xae 58 | \\.byte 0x1d, 0x04, 0xdb, 0xae 59 | ); 60 | } 61 | 62 | extern fn microzig_main() noreturn; 63 | 64 | export fn _start() linksection("microzig_flash_start") callconv(.C) noreturn { 65 | microzig.cpu.disable_interrupts(); 66 | asm volatile ("mv sp, %[eos]" 67 | : 68 | : [eos] "r" (@as(u32, microzig.config.end_of_stack)), 69 | ); 70 | asm volatile ("la gp, __global_pointer$"); 71 | microzig.cpu.setStatusBit(.mtvec, microzig.config.end_of_stack); 72 | root.initialize_system_memories(); 73 | microzig_main(); 74 | } 75 | 76 | export fn _rv32_trap() callconv(.C) noreturn { 77 | while (true) {} 78 | } 79 | 80 | const vector_table = [_]fn () callconv(.C) noreturn{ 81 | _rv32_trap, 82 | _rv32_trap, 83 | _rv32_trap, 84 | _rv32_trap, 85 | _rv32_trap, 86 | _rv32_trap, 87 | _rv32_trap, 88 | _rv32_trap, 89 | _rv32_trap, 90 | _rv32_trap, 91 | _rv32_trap, 92 | _rv32_trap, 93 | _rv32_trap, 94 | _rv32_trap, 95 | _rv32_trap, 96 | _rv32_trap, 97 | _rv32_trap, 98 | _rv32_trap, 99 | _rv32_trap, 100 | _rv32_trap, 101 | _rv32_trap, 102 | }; 103 | }; 104 | --------------------------------------------------------------------------------