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
4 changes: 2 additions & 2 deletions drivers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ pub const Clock_Device = struct {
- `sleep_us(time_us)` - Sleep for N microseconds (polls if no custom sleep)
- `sleep_ms(time_ms)` - Sleep for N milliseconds
- `make_timeout(duration)` - Create deadline from current time + duration
- `is_reached(absolute_time)` - Check if time point has passed
- `Timeout.is_reached()` - Check if time point has passed

**Usage Example**:
```zig
Expand All @@ -394,7 +394,7 @@ const timeout = clock.make_timeout(mdf.time.Duration.from_ms(100));

// Poll with timeout
while (!is_ready()) {
if (clock.is_reached(timeout)) {
if (timeout.is_reached()) {
return error.Timeout;
}
}
Expand Down
47 changes: 30 additions & 17 deletions drivers/base/Clock_Device.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,31 @@ ptr: *anyopaque,
/// Virtual table for the digital i/o functions.
vtable: *const VTable,

/// API
/// Object created by make_timeout to perform to hold
/// a duration.
pub const Timeout = struct {
clock: Clock_Device,
time: mdf.time.Absolute,

pub fn is_reached(self: @This()) bool {
return self.clock.is_reached(self.time);
}

pub fn diff(self: @This()) mdf.time.Duration {
return self.time.diff(self.clock.get_time_since_boot());
}
};

pub fn is_reached(td: Clock_Device, time: mdf.time.Absolute) bool {
const now = td.get_time_since_boot();
return time.is_reached_by(now);
}

pub fn make_timeout(td: Clock_Device, timeout: mdf.time.Duration) mdf.time.Absolute {
return @as(mdf.time.Absolute, @enumFromInt(td.get_time_since_boot().to_us() + timeout.to_us()));
}

pub fn make_timeout_us(td: Clock_Device, timeout_us: u64) mdf.time.Absolute {
return @as(mdf.time.Absolute, @enumFromInt(td.get_time_since_boot().to_us() + timeout_us));
pub fn make_timeout(td: Clock_Device, timeout: mdf.time.Duration) Timeout {
return .{
.clock = td,
.time = td.get_time_since_boot().add_duration(timeout),
};
}

pub fn sleep_ms(td: Clock_Device, time_ms: u32) void {
Expand All @@ -44,8 +57,8 @@ pub fn sleep_us(td: Clock_Device, time_us: u64) void {
}

// Otherwise, fall back to polling
const end_time = td.make_timeout_us(time_us);
while (!td.is_reached(end_time)) {}
const end_time = td.make_timeout(.from_us(time_us));
while (!end_time.is_reached()) {}
}

/// VTable methods
Expand Down Expand Up @@ -116,17 +129,17 @@ test Test_Device {
ttd.elapse_time(2);
try std.testing.expectEqual(2, td.get_time_since_boot().to_us());

try std.testing.expect(!td.is_reached(@enumFromInt(4)));
// Time reached
try std.testing.expect(!td.is_reached(.from_us(3)));
ttd.elapse_time(2);
try std.testing.expect(td.is_reached(@enumFromInt(4)));
try std.testing.expect(td.is_reached(.from_us(3)));

// Timeouts
try std.testing.expectEqual(
54,
@intFromEnum(td.make_timeout(mdf.time.Duration.from_us(50))),
);
ttd.elapse_time(50);
try std.testing.expectEqual(104, @intFromEnum(td.make_timeout_us(50)));
const timeout = td.make_timeout(.from_us(50));
ttd.elapse_time(40);
try std.testing.expectEqual(mdf.time.Duration.from_us(10), timeout.diff());
ttd.elapse_time(10);
try std.testing.expect(timeout.is_reached());

try std.testing.expectEqual(0, ttd.get_total_sleep_time());
td.sleep_ms(1000);
Expand Down
9 changes: 4 additions & 5 deletions drivers/led/ws2812.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn WS2812(options: struct {

dev: options.Datagram_Device,
clock_dev: options.Clock_Device,
next_write_time: ?mdf.time.Absolute = null,
next_write_time: ?mdf.base.Clock_Device.Timeout = null,
buffer: [buffer_size]u8 = undefined,

/// Initializes the driver.
Expand All @@ -36,9 +36,8 @@ pub fn WS2812(options: struct {

// ensures that a reset takes place between writes
if (self.next_write_time) |next_write_time| {
const now = self.clock_dev.get_time_since_boot();
if (!next_write_time.is_reached_by(now)) {
self.clock_dev.sleep_us(next_write_time.diff(now).to_us());
if (!next_write_time.is_reached()) {
self.clock_dev.sleep_us(next_write_time.diff().to_us());
}
}

Expand All @@ -63,7 +62,7 @@ pub fn WS2812(options: struct {

try self.dev.write(self.buffer[0..i]);

self.next_write_time = self.clock_dev.make_timeout_us(300);
self.next_write_time = self.clock_dev.make_timeout(.from_us(300));
}
};
}
Expand Down
Loading