Skip to content

Commit 3e90197

Browse files
authored
Introduce Timeout object for clock device (#862)
1 parent 40897f2 commit 3e90197

3 files changed

Lines changed: 36 additions & 24 deletions

File tree

drivers/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ pub const Clock_Device = struct {
383383
- `sleep_us(time_us)` - Sleep for N microseconds (polls if no custom sleep)
384384
- `sleep_ms(time_ms)` - Sleep for N milliseconds
385385
- `make_timeout(duration)` - Create deadline from current time + duration
386-
- `is_reached(absolute_time)` - Check if time point has passed
386+
- `Timeout.is_reached()` - Check if time point has passed
387387

388388
**Usage Example**:
389389
```zig
@@ -394,7 +394,7 @@ const timeout = clock.make_timeout(mdf.time.Duration.from_ms(100));
394394
395395
// Poll with timeout
396396
while (!is_ready()) {
397-
if (clock.is_reached(timeout)) {
397+
if (timeout.is_reached()) {
398398
return error.Timeout;
399399
}
400400
}

drivers/base/Clock_Device.zig

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,31 @@ ptr: *anyopaque,
1818
/// Virtual table for the digital i/o functions.
1919
vtable: *const VTable,
2020

21-
/// API
21+
/// Object created by make_timeout to perform to hold
22+
/// a duration.
23+
pub const Timeout = struct {
24+
clock: Clock_Device,
25+
time: mdf.time.Absolute,
26+
27+
pub fn is_reached(self: @This()) bool {
28+
return self.clock.is_reached(self.time);
29+
}
30+
31+
pub fn diff(self: @This()) mdf.time.Duration {
32+
return self.time.diff(self.clock.get_time_since_boot());
33+
}
34+
};
35+
2236
pub fn is_reached(td: Clock_Device, time: mdf.time.Absolute) bool {
2337
const now = td.get_time_since_boot();
2438
return time.is_reached_by(now);
2539
}
2640

27-
pub fn make_timeout(td: Clock_Device, timeout: mdf.time.Duration) mdf.time.Absolute {
28-
return @as(mdf.time.Absolute, @enumFromInt(td.get_time_since_boot().to_us() + timeout.to_us()));
29-
}
30-
31-
pub fn make_timeout_us(td: Clock_Device, timeout_us: u64) mdf.time.Absolute {
32-
return @as(mdf.time.Absolute, @enumFromInt(td.get_time_since_boot().to_us() + timeout_us));
41+
pub fn make_timeout(td: Clock_Device, timeout: mdf.time.Duration) Timeout {
42+
return .{
43+
.clock = td,
44+
.time = td.get_time_since_boot().add_duration(timeout),
45+
};
3346
}
3447

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

4659
// Otherwise, fall back to polling
47-
const end_time = td.make_timeout_us(time_us);
48-
while (!td.is_reached(end_time)) {}
60+
const end_time = td.make_timeout(.from_us(time_us));
61+
while (!end_time.is_reached()) {}
4962
}
5063

5164
/// VTable methods
@@ -116,17 +129,17 @@ test Test_Device {
116129
ttd.elapse_time(2);
117130
try std.testing.expectEqual(2, td.get_time_since_boot().to_us());
118131

119-
try std.testing.expect(!td.is_reached(@enumFromInt(4)));
132+
// Time reached
133+
try std.testing.expect(!td.is_reached(.from_us(3)));
120134
ttd.elapse_time(2);
121-
try std.testing.expect(td.is_reached(@enumFromInt(4)));
135+
try std.testing.expect(td.is_reached(.from_us(3)));
122136

123137
// Timeouts
124-
try std.testing.expectEqual(
125-
54,
126-
@intFromEnum(td.make_timeout(mdf.time.Duration.from_us(50))),
127-
);
128-
ttd.elapse_time(50);
129-
try std.testing.expectEqual(104, @intFromEnum(td.make_timeout_us(50)));
138+
const timeout = td.make_timeout(.from_us(50));
139+
ttd.elapse_time(40);
140+
try std.testing.expectEqual(mdf.time.Duration.from_us(10), timeout.diff());
141+
ttd.elapse_time(10);
142+
try std.testing.expect(timeout.is_reached());
130143

131144
try std.testing.expectEqual(0, ttd.get_total_sleep_time());
132145
td.sleep_ms(1000);

drivers/led/ws2812.zig

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub fn WS2812(options: struct {
1818

1919
dev: options.Datagram_Device,
2020
clock_dev: options.Clock_Device,
21-
next_write_time: ?mdf.time.Absolute = null,
21+
next_write_time: ?mdf.base.Clock_Device.Timeout = null,
2222
buffer: [buffer_size]u8 = undefined,
2323

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

3737
// ensures that a reset takes place between writes
3838
if (self.next_write_time) |next_write_time| {
39-
const now = self.clock_dev.get_time_since_boot();
40-
if (!next_write_time.is_reached_by(now)) {
41-
self.clock_dev.sleep_us(next_write_time.diff(now).to_us());
39+
if (!next_write_time.is_reached()) {
40+
self.clock_dev.sleep_us(next_write_time.diff().to_us());
4241
}
4342
}
4443

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

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

66-
self.next_write_time = self.clock_dev.make_timeout_us(300);
65+
self.next_write_time = self.clock_dev.make_timeout(.from_us(300));
6766
}
6867
};
6968
}

0 commit comments

Comments
 (0)