Skip to content
Draft
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
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
workflow_dispatch:

env:
ZIG_VERSION: 0.15.1
ZIG_VERSION: master

jobs:
formatting-check:
Expand Down Expand Up @@ -188,7 +188,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
example_dir: [
example_dir:
[
espressif/esp,
gigadevice/gd32,
microchip/atmega,
Expand Down Expand Up @@ -245,7 +246,7 @@ jobs:
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.15.1
version: master
- name: Build Website
run: zig build
working-directory: website
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.15.1
version: master

- name: Extract version
run: echo "MICROZIG_VERSION=$(zig build package -- get-version)" >> $GITHUB_ENV
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/drivers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.15.1
version: master

- name: Run Test Suite
working-directory: drivers
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.15.1
version: master

# Build linter from trusted base branch code
- name: Build linter
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/publish-github-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.15.1
version: master

- name: Download and install GitHub CLI
run: |
Expand Down Expand Up @@ -65,8 +65,6 @@ jobs:
echo "Generating metadata.json"
echo "{ \"releases\": [$(IFS=,; echo "${releases_with_artifact[*]}")] }" > website/zig-out/downloads/microzig/metadata.json



- name: List Contents
run: tree zig-out
working-directory: website
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sim-aviron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.15.1
version: master

- name: Build
working-directory: sim/aviron
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ __pycache__/
.zig-cache/
boxzer-out
microzig-deploy/
zig-cache/
zig-out/
zig-pkg/

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## What version of Zig to use

Zig 0.15.1
Zig master

## Getting Started With MicroZig

Expand Down
76 changes: 42 additions & 34 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -112,25 +112,27 @@ pub const PortSelect = struct {
// Don't know if this is required but it doesn't hurt either.
// Helps in case there are multiple microzig instances including the same ports (eg: examples).
pub const PortCache = blk: {
var fields: []const std.builtin.Type.StructField = &.{};
for (port_list) |port| {
const typ = ?(custom_lazy_import(port.dep_name) orelse struct {});
fields = fields ++ [_]std.builtin.Type.StructField{.{
.name = port.name,
.type = typ,
.default_value_ptr = @as(*const anyopaque, @ptrCast(&@as(typ, null))),
.is_comptime = false,
.alignment = @alignOf(typ),
}};
var field_names: [port_list.len][]const u8 = undefined;
var field_types: [port_list.len]type = undefined;
var field_attrs: [port_list.len]std.builtin.Type.StructField.Attributes = undefined;

for (port_list, 0..) |port, i| {
const typ = custom_lazy_import(port.dep_name) orelse struct {};
const default: ?typ = null;
field_names[i] = port.name;
field_types[i] = ?typ;
field_attrs[i] = .{
.default_value_ptr = &default,
};
}
break :blk @Type(.{
.@"struct" = .{
.layout = .auto,
.fields = fields,
.decls = &.{},
.is_tuple = false,
},
});

break :blk @Struct(
.auto,
null,
&field_names,
&field_types,
&field_attrs,
);
};

var port_cache: PortCache = .{};
Expand Down Expand Up @@ -174,29 +176,31 @@ pub fn MicroBuild(port_select: PortSelect) type {
const Self = @This();

const SelectedPorts = blk: {
var fields: []const std.builtin.Type.StructField = &.{};
var field_names: [port_list.len][]const u8 = undefined;
var field_types: [port_list.len]type = undefined;
var field_attrs: [port_list.len]std.builtin.Type.StructField.Attributes = undefined;

var count: usize = 0;
for (port_list) |port| {
if (@field(port_select, port.name)) {
const i = count;
const typ = custom_lazy_import(port.dep_name) orelse struct {};
fields = fields ++ [_]std.builtin.Type.StructField{.{
.name = port.name,
.type = typ,
.default_value_ptr = null,
.is_comptime = false,
.alignment = @alignOf(typ),
}};

field_names[i] = port.name;
field_types[i] = typ;
field_attrs[i] = .{};

count += 1;
}
}

break :blk @Type(.{
.@"struct" = .{
.layout = .auto,
.fields = fields,
.decls = &.{},
.is_tuple = false,
},
});
break :blk @Struct(
.auto,
null,
field_names[0..count],
field_types[0..count],
field_attrs[0..count],
);
};

const InitReturnType = blk: {
Expand Down Expand Up @@ -315,6 +319,9 @@ pub fn MicroBuild(port_select: PortSelect) type {

/// Dwarf format option for the firmware executable.
dwarf_format: ?std.dwarf.Format = null,

/// Whether to omit the stack frame pointer.
omit_frame_pointer: ?bool = null,
};

/// Creates a new firmware for a given target.
Expand Down Expand Up @@ -508,6 +515,7 @@ pub fn MicroBuild(port_select: PortSelect) type {
.unwind_tables = options.unwind_tables,
.error_tracing = options.error_tracing,
.dwarf_format = options.dwarf_format,
.omit_frame_pointer = options.omit_frame_pointer,
}),
.linkage = .static,
}),
Expand Down
77 changes: 25 additions & 52 deletions core/src/core/usb.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const assert = std.debug.assert;
const StructFieldAttributes = std.builtin.Type.StructField.Attributes;
const log = std.log.scoped(.usb_ctrl);

pub const descriptor = @import("usb/descriptor.zig");
Expand All @@ -13,41 +14,6 @@ pub const types = @import("usb/types.zig");
pub const ack: []const u8 = "";
pub const nak: ?[]const u8 = null;

/// Meant to make transition to zig 0.16 easier
pub const StructFieldAttributes = struct {
@"comptime": bool = false,
@"align": ?usize = null,
default_value_ptr: ?*const anyopaque = null,
};

/// Helper to create a struct, wrapping around @Type, meant to make transition to zig 0.16 easier
pub fn Struct(
layout: std.builtin.Type.ContainerLayout,
BackingInt: ?type,
field_names: []const [:0]const u8,
field_types: *const [field_names.len]type,
field_attrs: *const [field_names.len]StructFieldAttributes,
) type {
var fields: []const std.builtin.Type.StructField = &.{};
// Iterate over the names, field types, and attributes, creating a new struct field entry
for (field_names, field_types, field_attrs) |n, T, a| {
fields = fields ++ &[1]std.builtin.Type.StructField{.{
.name = n,
.type = T,
.alignment = a.@"align" orelse @alignOf(T),
.default_value_ptr = a.default_value_ptr,
.is_comptime = a.@"comptime",
}};
}
return @Type(.{ .@"struct" = .{
.layout = layout,
.backing_integer = BackingInt,
.decls = &.{},
.fields = fields,
.is_tuple = false,
} });
}

// What does this do? It lets you iterate through interfaces and endpoints?
pub const DescriptorAllocator = struct {
next_ep_num: [2]u8,
Expand Down Expand Up @@ -173,7 +139,7 @@ pub fn DriverHandlers(Driver: type) type {
else => {},
};

return Struct(
return @Struct(
.auto,
null,
field_names,
Expand Down Expand Up @@ -214,7 +180,7 @@ pub const Config = struct {
// And save the type of the third
field_types[i] = params[2].type.?;
}
return Struct(.auto, null, &field_names, &field_types, &@splat(.{}));
return @Struct(.auto, null, &field_names, &field_types, &@splat(.{}));
}
};

Expand Down Expand Up @@ -265,7 +231,7 @@ pub fn validate_controller(T: type) void {
/// Responds to host requests and dispatches to the appropriate drivers.
/// When this type is build (at comptime), it builds descriptor and handler tables based on the
/// provided config.
pub fn DeviceController(config: Config, driver_args: config.DriverArgs()) type {
pub fn DeviceController(comptime config: Config, comptime driver_args: config.DriverArgs()) type {
std.debug.assert(config.configurations.len == 1);

return struct {
Expand Down Expand Up @@ -381,11 +347,9 @@ pub fn DeviceController(config: Config, driver_args: config.DriverArgs()) type {
field_attrs[drv_id] = .{ .default_value_ptr = &descriptors };
}

// Finally, bind the handler functions based on the data collected above.
const Tuple = std.meta.Tuple;
// Create a tuple with the appropriate types
const ep_handlers_types: [2]type = .{ Tuple(&ep_handler_types[0]), Tuple(&ep_handler_types[1]) };
var ep_handlers: Tuple(&ep_handlers_types) = undefined;
const ep_handlers_types: [2]type = .{ @Tuple(&ep_handler_types[0]), @Tuple(&ep_handler_types[1]) };
var ep_handlers: @Tuple(&ep_handlers_types) = undefined;
// Iterate over all IN and OUT endpoints and bind the handler for any that are set.
for (&ep_handler_types, &ep_handler_names, &ep_handler_drivers, 0..) |htypes, hnames, hdrivers, dir| {
for (&htypes, &hnames, &hdrivers, 0..) |T, name, drv_id, ep| {
Expand All @@ -394,30 +358,39 @@ pub fn DeviceController(config: Config, driver_args: config.DriverArgs()) type {
}
}

const DriverConfig = Struct(.@"extern", null, &field_names, &field_types, &field_attrs);
const DriverConfig = @Struct(.@"extern", null, &field_names, &field_types, &field_attrs);
const idx_in = @intFromEnum(types.Dir.In);
const idx_out = @intFromEnum(types.Dir.Out);

const ConfigDescriptor = extern struct {
first: descriptor.Configuration,
drv: DriverConfig,
};
const Handlers_EP = struct {
In: ep_handlers_types[idx_in],
Out: ep_handlers_types[idx_out],
};
break :blk .{
.device_descriptor = desc_device,
.config_descriptor = extern struct {
first: descriptor.Configuration = .{
.config_descriptor = ConfigDescriptor{
.first = .{
.total_length = .from(size),
.num_interfaces = alloc.next_itf_num,
.configuration_value = 1,
.configuration_s = configuration_s,
.attributes = config0.attributes,
.max_current = .from_ma(config0.max_current_ma),
},
drv: DriverConfig = .{},
}{},
.drv = .{},
},
.string_descriptors = alloc.string_descriptors(config.language),
.handlers_itf = itf_handlers,
.handlers_ep = struct {
In: ep_handlers_types[idx_in] = ep_handlers[idx_in],
Out: ep_handlers_types[idx_out] = ep_handlers[idx_out],
}{},
.handlers_ep = Handlers_EP{
.In = ep_handlers[idx_in],
.Out = ep_handlers[idx_out],
},
.drivers_ep = ep_handler_drivers,
.DriverAlloc = Struct(
.DriverAlloc = @Struct(
.auto,
null,
driver_alloc_names,
Expand Down
Loading
Loading