Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
port_dir: [gigadevice/gd32, raspberrypi/rp2xxx, stmicro/stm32, wch/ch32v]
port_dir: [gigadevice/gd32, espressif/esp, raspberrypi/rp2xxx, stmicro/stm32, wch/ch32v]
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
10 changes: 4 additions & 6 deletions examples/espressif/esp/src/rtos.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ const rtos = esp.rtos;
pub const microzig_options: microzig.Options = .{
.logFn = usb_serial_jtag.logger.log,
.interrupts = .{
.interrupt30 = rtos.general_purpose_interrupt_handler,
.interrupt31 = rtos.yield_interrupt_handler,
.interrupt31 = rtos.tick_interrupt_handler,
},
.log_level = .debug,
.cpu = .{
Expand All @@ -29,8 +28,6 @@ pub const microzig_options: microzig.Options = .{
},
};

var heap_buf: [10 * 1024]u8 = undefined;

fn task1(queue: *rtos.Queue(u32)) void {
for (0..5) |i| {
queue.put_one(i, null) catch unreachable;
Expand All @@ -39,15 +36,16 @@ fn task1(queue: *rtos.Queue(u32)) void {
}

pub fn main() !void {
var heap = try microzig.Allocator.init_with_buffer(&heap_buf);
var heap = try microzig.Allocator.init_with_heap(4096);
const gpa = heap.allocator();

var buffer: [1]u32 = undefined;
var queue: rtos.Queue(u32) = .init(&buffer);

esp.time.sleep_ms(1000);

_ = try rtos.spawn(gpa, task1, .{&queue}, .{});
const task = try rtos.spawn(gpa, task1, .{&queue}, .{});
defer rtos.wait_and_free(gpa, task);

while (true) {
const item = try queue.get_one(.from_ms(1000));
Expand Down
5 changes: 2 additions & 3 deletions examples/espressif/esp/src/tcp_server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ pub const microzig_options: microzig.Options = .{
},
.logFn = usb_serial_jtag.logger.log,
.interrupts = .{
.interrupt29 = radio.interrupt_handler,
.interrupt30 = rtos.general_purpose_interrupt_handler,
.interrupt31 = rtos.yield_interrupt_handler,
.interrupt30 = radio.interrupt_handler,
.interrupt31 = rtos.tick_interrupt_handler,
},
.cpu = .{
.interrupt_stack = .{
Expand Down
40 changes: 20 additions & 20 deletions port/espressif/esp/src/cpus/esp_riscv.zig
Original file line number Diff line number Diff line change
Expand Up @@ -615,11 +615,11 @@ pub const csr = struct {
pub const tdata1 = riscv32_common.csr.tdata1;
pub const tdata2 = riscv32_common.csr.tdata2;
pub const tcontrol = Csr(0x7A5, packed struct {
reserved0: u3,
mte: u1,
reserved1: u3,
mpte: u1,
reserved2: u24,
reserved0: u3 = 0,
mte: u1 = 0,
reserved1: u3 = 0,
mpte: u1 = 0,
reserved2: u24 = 0,
});

pub const dcsr = riscv32_common.csr.dcsr;
Expand All @@ -628,23 +628,23 @@ pub const csr = struct {
pub const dscratch1 = riscv32_common.csr.dscratch1;

pub const mpcer = Csr(0x7E0, packed struct {
cycle: u1,
inst: u1,
ld_hazard: u1,
jmp_hazard: u1,
idle: u1,
load: u1,
store: u1,
jmp_uncond: u1,
branch: u1,
branch_taken: u1,
inst_comp: u1,
reserved0: u21,
cycle: u1 = 0,
inst: u1 = 0,
ld_hazard: u1 = 0,
jmp_hazard: u1 = 0,
idle: u1 = 0,
load: u1 = 0,
store: u1 = 0,
jmp_uncond: u1 = 0,
branch: u1 = 0,
branch_taken: u1 = 0,
inst_comp: u1 = 0,
reserved0: u21 = 0,
});
pub const mpcmr = Csr(0x7E1, packed struct {
count_en: u1,
count_sat: u1,
reserved0: u30,
count_en: u1 = 0,
count_sat: u1 = 0,
reserved0: u30 = 0,
});
pub const mpccr = Csr(0x7E2, u32);

Expand Down
18 changes: 15 additions & 3 deletions port/espressif/esp/src/hal.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const builtin = @import("builtin");
const std = @import("std");

pub const esp_image = @import("esp_image");
Expand All @@ -23,8 +24,15 @@ pub const uart = @import("hal/uart.zig");
pub const usb_serial_jtag = @import("hal/usb_serial_jtag.zig");

comptime {
// export atomic intrinsics
_ = @import("hal/atomic.zig");
if (!builtin.is_test) {
// export atomic intrinsics
_ = @import("hal/atomic.zig");

@export(&app_desc, .{
.name = "esp_app_desc",
.section = ".app_desc",
});
}
}

pub const HAL_Options = struct {
Expand Down Expand Up @@ -89,7 +97,7 @@ fn disable_watchdogs() void {

// Don't change the name of this export, it is checked by espflash tool. Only
// these fields are populated here. The others will be set by elf2image.
export const esp_app_desc: esp_image.AppDesc linksection(".app_desc") = .{
const app_desc: esp_image.AppDesc = .{
.secure_version = microzig.options.hal.info.secure_version,
.version = str(32, microzig.options.hal.info.version),
.project_name = str(32, microzig.options.hal.info.project_name),
Expand All @@ -105,3 +113,7 @@ fn str(comptime l: usize, comptime s: []const u8) [l]u8 {
std.mem.copyForwards(u8, buf[0..s.len], s);
return buf;
}

test {
_ = rtos;
}
4 changes: 2 additions & 2 deletions port/espressif/esp/src/hal/radio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub const wifi = @import("radio/wifi.zig");
const log = std.log.scoped(.esp_radio);

pub const Options = struct {
interrupt: microzig.cpu.Interrupt = .interrupt29,
interrupt: microzig.cpu.Interrupt = .interrupt30,
wifi: wifi.Options = .{},
};

Expand Down Expand Up @@ -81,7 +81,7 @@ pub fn deinit() void {
return;
}

timer.deinit();
timer.deinit(osi.gpa);
}

pub fn read_mac(iface: enum {
Expand Down
20 changes: 10 additions & 10 deletions port/espressif/esp/src/hal/radio/osi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub fn usleep(time_us: u32) callconv(.c) c_int {
}

pub fn vTaskDelay(ticks: u32) callconv(.c) void {
rtos.sleep(.from_us(ticks));
rtos.sleep(.from_ticks(ticks));
}

pub var WIFI_EVENT: c.esp_event_base_t = "WIFI_EVENT";
Expand Down Expand Up @@ -321,8 +321,8 @@ pub fn semphr_take(ptr: ?*anyopaque, tick: u32) callconv(.c) i32 {
log.debug("semphr_take {?} {}", .{ ptr, tick });

const sem: *rtos.Semaphore = @ptrCast(@alignCast(ptr));
const maybe_timeout: ?time.Duration = if (tick == c.OSI_FUNCS_TIME_BLOCKING)
.from_us(tick)
const maybe_timeout: ?rtos.Duration = if (tick == c.OSI_FUNCS_TIME_BLOCKING)
.from_ticks(tick)
else
null;
sem.take_with_timeout(maybe_timeout) catch {
Expand Down Expand Up @@ -512,8 +512,8 @@ pub fn queue_send(ptr: ?*anyopaque, item_ptr: ?*anyopaque, block_time_tick: u32)
else => queue.inner.put(
item[0..queue.item_len],
1,
if (block_time_tick == c.OSI_FUNCS_TIME_BLOCKING)
.from_us(block_time_tick)
if (block_time_tick != c.OSI_FUNCS_TIME_BLOCKING)
.from_ticks(block_time_tick)
else
null,
),
Expand Down Expand Up @@ -553,8 +553,8 @@ pub fn queue_recv(ptr: ?*anyopaque, item_ptr: ?*anyopaque, block_time_tick: u32)
else => queue.inner.get(
item[0..queue.item_len],
queue.item_len,
if (block_time_tick == c.OSI_FUNCS_TIME_BLOCKING)
.from_us(block_time_tick)
if (block_time_tick != c.OSI_FUNCS_TIME_BLOCKING)
.from_ticks(block_time_tick)
else
null,
),
Expand Down Expand Up @@ -673,17 +673,17 @@ pub fn task_delete(handle: ?*anyopaque) callconv(.c) void {
if (handle != null) {
@panic("task_delete(non-null): not implemented");
}
rtos.yield(.delete);
rtos.yield(.exit);
}

pub fn task_delay(tick: u32) callconv(.c) void {
log.debug("task_delay {}", .{tick});

rtos.sleep(.from_us(tick));
rtos.sleep(.from_ticks(tick));
}

pub fn task_ms_to_tick(ms: u32) callconv(.c) i32 {
return @intCast(ms * 1_000);
return @intCast(rtos.Duration.from_ms(ms).to_ticks());
}

pub fn task_get_current_task() callconv(.c) ?*anyopaque {
Expand Down
30 changes: 25 additions & 5 deletions port/espressif/esp/src/hal/radio/timer.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;

const c = @import("esp-wifi-driver");
Expand All @@ -21,20 +22,36 @@ pub const Timer = struct {
node: std.SinglyLinkedList.Node = .{},
};

var timer_task: ?*rtos.Task = null;
var exit_flag: std.atomic.Value(bool) = .init(false);
var reload_semaphore: rtos.Semaphore = .init(0, 1);
var mutex: rtos.Mutex = .{};
var timer_list: std.SinglyLinkedList = .{};

pub fn init(gpa: Allocator) Allocator.Error!void {
_ = try rtos.spawn(gpa, task_fn, .{}, .{
exit_flag.store(false, .monotonic);

assert(timer_task == null);
timer_task = try rtos.spawn(gpa, task_fn, .{}, .{
.name = "radio_timer",
.priority = .lowest, // TODO: what should the priority be?
.stack_size = 4096,
});
}

pub fn deinit() void {
// TODO: exit mechanism
pub fn deinit(gpa: Allocator) void {
exit_flag.store(true, .monotonic);
reload_semaphore.give();

if (timer_task) |task| {
rtos.wait_and_free(gpa, task);
timer_task = null;
}

while (timer_list.popFirst()) |node| {
const timer: *Timer = @alignCast(@fieldParentPtr("node", node));
gpa.destroy(timer);
}
}

pub fn setfn(
Expand Down Expand Up @@ -112,6 +129,9 @@ pub fn done(gpa: std.mem.Allocator, ets_timer: *c.ets_timer) void {

fn task_fn() void {
while (true) {
if (exit_flag.load(.monotonic))
return;

const now = get_time_since_boot();
while (true) {
const callback, const arg = blk: {
Expand All @@ -130,11 +150,11 @@ fn task_fn() void {
callback(arg);
}

const sleep_duration = blk: {
const sleep_duration: ?rtos.Duration = blk: {
mutex.lock();
defer mutex.unlock();
break :blk if (find_next_wake_absolute()) |next_wake_absolute|
next_wake_absolute.diff(now)
.from_us(@truncate(next_wake_absolute.diff(now).to_us()))
else
null;
};
Expand Down
Loading
Loading