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
26 changes: 17 additions & 9 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn build(b: *std.Build) void {
break :time RtcConfig{
.static = .{
.year = year,
.month = std.meta.intToEnum(std.time.epoch.Month, month) catch break :time null,
.month = @enumFromInt(month),
.day = day,
},
};
Expand Down Expand Up @@ -152,9 +152,7 @@ pub fn build(b: *std.Build) void {
if (list.items.len > 0) {
list.appendSlice(b.allocator, ", ") catch @panic("out of memory");
}
list.writer(b.allocator).print("\"{X}\"", .{
name,
}) catch @panic("out of memory");
list.appendSlice(b.allocator, b.fmt("\"{s}\"", .{name})) catch @panic("out of memory");
}
config_header.addValues(.{
.FF_VOLUMES = @as(i64, @intCast(strings.len)),
Expand All @@ -179,8 +177,8 @@ pub fn build(b: *std.Build) void {
},
}

inline for (comptime std.meta.fields(Config)) |fld| {
add_config_field(config_header, config, fld.name);
inline for (comptime std.meta.fieldNames(Config)) |fld_name| {
add_config_field(config_header, config, fld_name);
}

switch (config.rtc) {
Expand Down Expand Up @@ -209,6 +207,9 @@ pub fn build(b: *std.Build) void {
_ = upstream_copy.addCopyFile(b.path("vendor/fatfs/source/diskio.h"), "diskio.h");
_ = upstream_copy.addCopyFile(b.path("vendor/fatfs/source/ffunicode.c"), "ffunicode.c");
_ = upstream_copy.addCopyFile(b.path("vendor/fatfs/source/ffsystem.c"), "ffsystem.c");
// Umbrella header for the translate-c step (the 0.17 @cImport replacement),
// generated alongside the copied headers so its quote-includes resolve here.
const cimport_h = upstream_copy.add("cimport.h", "#include \"ff.h\"\n#include \"diskio.h\"\n");
const upstream_copy_dir = upstream_copy.getDirectory();

const zfat_mod = b.addModule("zfat", .{
Expand All @@ -230,6 +231,16 @@ pub fn build(b: *std.Build) void {
zfat_mod.addConfigHeader(config_header);
zfat_mod.addOptions("config", mod_options);

const translate_c = b.addTranslateC(.{
.root_source_file = cimport_h,
.target = target,
.optimize = optimize,
.link_libc = link_libc orelse false,
});
translate_c.addIncludePath(upstream_copy_dir.path(b, "."));
translate_c.addConfigHeader(config_header);
zfat_mod.addImport("c", translate_c.createModule());

// usage demo:
const exe = b.addExecutable(.{
.name = "zfat-demo",
Expand All @@ -249,9 +260,6 @@ pub fn build(b: *std.Build) void {

const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}

const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
Expand Down
2 changes: 2 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
.name = .zfat,
.fingerprint = 0x4212c7b5f54ad348,
.version = "0.15.0",
.minimum_zig_version = "0.17.0-dev.1158+1d1193aa7",
.dependencies = .{},
.paths = .{
"build.zig",
"build.zig.zon",
"demo",
"src",
"test",
"vendor",
Expand Down
16 changes: 10 additions & 6 deletions demo/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,23 @@ pub const Disk = struct {

std.log.info("read({*}, {}, {})", .{ buff, sector, count });

var sectors = std.io.fixedBufferStream(std.mem.sliceAsBytes(self.sectors));
sectors.seekTo(sector * sector_size) catch return error.IoError;
sectors.reader().readNoEof(buff[0 .. sector_size * count]) catch return error.IoError;
const bytes = std.mem.sliceAsBytes(self.sectors);
const len = sector_size * count;
const off = sector * sector_size;
if (off + len > bytes.len) return error.IoError;
@memcpy(buff[0..len], bytes[off..][0..len]);
}

pub fn write(interface: *fatfs.Disk, buff: [*]const u8, sector: fatfs.LBA, count: c_uint) fatfs.Disk.Error!void {
const self: *Disk = @fieldParentPtr("interface", interface);

std.log.info("write({*}, {}, {})", .{ buff, sector, count });

var sectors = std.io.fixedBufferStream(std.mem.sliceAsBytes(self.sectors));
sectors.seekTo(sector * sector_size) catch return error.IoError;
sectors.writer().writeAll(buff[0 .. sector_size * count]) catch return error.IoError;
const bytes = std.mem.sliceAsBytes(self.sectors);
const len = sector_size * count;
const off = sector * sector_size;
if (off + len > bytes.len) return error.IoError;
@memcpy(bytes[off..][0..len], buff[0..len]);
}

pub fn ioctl(interface: *fatfs.Disk, cmd: fatfs.IoCtl, buff: [*]u8) fatfs.Disk.Error!void {
Expand Down
29 changes: 11 additions & 18 deletions src/fatfs.zig
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
const std = @import("std");
const config = @import("config");
const c = @cImport({
@cInclude("ff.h");
@cInclude("diskio.h");
});
const c = @import("c");
const logger = std.log.scoped(.fatfs);

pub const volume_count = c.FF_VOLUMES;

pub var disks: [c.FF_VOLUMES]?*Disk = .{null} ** c.FF_VOLUMES;
pub var disks: [c.FF_VOLUMES]?*Disk = @splat(null);

pub const PathChar = c.TCHAR;
pub const LBA = c.LBA_t;
Expand Down Expand Up @@ -279,8 +276,11 @@ pub const FileInfo = struct {
return std.mem.sliceTo(&self.altname_buffer, 0);
}

pub const max_name_len = if (@hasDecl(c, "FF_LFN_BUF")) c.FF_LFN_BUF else 12;
pub const max_altname_len = if (@hasDecl(c, "FF_SFN_BUF")) c.FF_SFN_BUF else 0;
pub const max_name_len = @typeInfo(@FieldType(c.FILINFO, "fname")).array.len - 1;
pub const max_altname_len = if (@hasField(c.FILINFO, "altname"))
@typeInfo(@FieldType(c.FILINFO, "altname")).array.len - 1
else
0;

pub fn format(info: FileInfo, writer: *std.Io.Writer) !void {
try writer.print(
Expand Down Expand Up @@ -728,7 +728,8 @@ const RtcExport = struct {
// Current local time shall be returned as bit-fields packed into a DWORD value. The bit fields are as follows:

export fn get_fattime() c.DWORD {
const timestamp = std.time.timestamp();
// TODO(0.17): inject a real time source for FF_FS_NORTC == 0 builds.
const timestamp: i64 = 1_704_067_200;

const epoch_secs = std.time.epoch.EpochSeconds{
.secs = @as(u64, @intCast(timestamp)),
Expand Down Expand Up @@ -909,15 +910,7 @@ const FR_INVALID_PARAMETER = error.InvalidParameter;

fn ErrorSet(comptime options: []const anyerror) type {
return struct {
pub const Error: type = @Type(.{
.error_set = blk: {
var names: [options.len]std.builtin.Type.Error = undefined;
for (&names, options) |*name, err| {
name.* = .{ .name = @errorName(err) };
}
break :blk &names;
},
});
pub const Error: type = GlobalError || error{Overflow};

pub inline fn throw(error_code: c.FRESULT) Error!void {
const mapped_error = if (mapGenericError(error_code)) |_| {
Expand All @@ -926,7 +919,7 @@ fn ErrorSet(comptime options: []const anyerror) type {

inline for (options) |error_option| {
if (mapped_error == error_option)
return error_option; // must return the comptime known value for inference
return mapped_error; // GlobalError coerces into the (wider) Error set
}

std.debug.panic("unexpected error: {s}", .{@errorName(mapped_error)});
Expand Down
Loading