Skip to content

Commit 0d748a4

Browse files
authored
nRF5x: Add basic timer support (#560)
1 parent 0e9376f commit 0d748a4

4 files changed

Lines changed: 59 additions & 17 deletions

File tree

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
const std = @import("std");
22
const microzig = @import("microzig");
33
const board = microzig.board;
4-
5-
fn delay(cycles: u32) void {
6-
var i: u32 = 0;
7-
while (i < cycles) : (i += 1) {
8-
std.mem.doNotOptimizeAway(i);
9-
}
10-
}
4+
const nrf = microzig.hal;
5+
const time = nrf.time;
116

127
pub fn main() !void {
138
board.init();
149

1510
while (true) {
1611
board.led1.toggle();
17-
delay(2000000);
12+
time.sleep_ms(500);
1813

1914
board.led1.toggle();
2015
board.led2.toggle();
21-
delay(2000000);
16+
time.sleep_ms(500);
2217

2318
board.led2.toggle();
2419
board.led3.toggle();
25-
delay(2000000);
20+
time.sleep_ms(500);
2621
}
2722
}

port/nordic/nrf5x/src/hal.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ const microzig = @import("microzig");
22

33
pub const compatibility = @import("hal/compatibility.zig");
44
pub const gpio = @import("hal/gpio.zig");
5+
pub const time = @import("hal/time.zig");
56
pub const uart = @import("hal/uart.zig");
67
// TODO: adc, timers, pwm, rng, rtc, spi, interrupts, i2c, wdt, wifi, nfc, bt, zigbee
78

9+
pub fn init() void {
10+
time.init();
11+
}
12+
813
test "hal tests" {
914
_ = gpio;
15+
_ = time;
16+
_ = uart;
1017
}

port/nordic/nrf5x/src/hal/time.zig

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
///
2+
/// Basic timekeeping for the nRF5x series MCUs.
3+
///
4+
/// This module hogs TIMER0.
5+
/// It uses CC1 as the register to read the current count from.
6+
const std = @import("std");
7+
const microzig = @import("microzig");
8+
const time = microzig.drivers.time;
9+
10+
const timer = microzig.chip.peripherals.TIMER0;
11+
const READ_INDEX = 1;
12+
13+
var overflow_count: u32 = 0;
14+
15+
pub fn init() void {
16+
// Stop timer while we set it up
17+
timer.TASKS_STOP.write(.{ .TASKS_STOP = .Trigger });
18+
defer timer.TASKS_START.write(.{ .TASKS_START = .Trigger });
19+
20+
// Clear the time
21+
timer.TASKS_CLEAR.write(.{ .TASKS_CLEAR = .Trigger });
22+
23+
timer.MODE.write(.{ .MODE = .Timer });
24+
timer.BITMODE.write(.{ .BITMODE = .@"32Bit" });
25+
// 16Mhz / 2^4 = 1MHz: us resolution
26+
timer.PRESCALER.write(.{ .PRESCALER = 4 });
27+
}
28+
29+
pub fn get_time_since_boot() time.Absolute {
30+
timer.TASKS_CAPTURE[READ_INDEX].write(.{ .TASKS_CAPTURE = .Trigger });
31+
return @enumFromInt(@as(u64, overflow_count) << 32 | timer.CC[READ_INDEX].raw);
32+
}
33+
34+
pub fn sleep_ms(time_ms: u32) void {
35+
sleep_us(time_ms * 1000);
36+
}
37+
38+
pub fn sleep_us(time_us: u64) void {
39+
const end_time = time.make_timeout_us(get_time_since_boot(), time_us);
40+
while (!end_time.is_reached_by(get_time_since_boot())) {}
41+
}

port/nordic/nrf5x/src/hal/uart.zig

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const types = microzig.chip.types;
99
const UART_Regs = types.peripherals.UART0;
1010

1111
const gpio = @import("gpio.zig");
12+
const time = @import("time.zig");
1213

1314
var uart_logger: ?UART.Writer = null;
1415

@@ -37,20 +38,18 @@ pub fn logFn(
3738
comptime format: []const u8,
3839
args: anytype,
3940
) void {
40-
const level_prefix = comptime level.asText();
41-
// const level_prefix = comptime "[{}.{:0>6}] " ++ level.asText();
41+
const level_prefix = comptime "[{}.{:0>6}] " ++ level.asText();
4242
const prefix = comptime level_prefix ++ switch (scope) {
4343
.default => ": ",
4444
else => " (" ++ @tagName(scope) ++ "): ",
4545
};
4646

4747
if (uart_logger) |uart| {
48-
// const current_time = time.get_time_since_boot();
49-
// const seconds = current_time.to_us() / std.time.us_per_s;
50-
// const microseconds = current_time.to_us() % std.time.us_per_s;
48+
const current_time = time.get_time_since_boot();
49+
const seconds = current_time.to_us() / std.time.us_per_s;
50+
const microseconds = current_time.to_us() % std.time.us_per_s;
5151

52-
// uart.print(prefix ++ format ++ "\r\n", .{ seconds, microseconds } ++ args) catch {};
53-
uart.print(prefix ++ format ++ "\r\n", args) catch {};
52+
uart.print(prefix ++ format ++ "\r\n", .{ seconds, microseconds } ++ args) catch {};
5453
}
5554
}
5655

0 commit comments

Comments
 (0)