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
8 changes: 8 additions & 0 deletions .github/workflows/ports.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ jobs:
run: zig build test
working-directory: port/texasinstruments/msp430

- name: texasinstruments/mspm0
run: zig build test
working-directory: port/texasinstruments/mspm0

- name: texasinstruments/tm4c
run: zig build test
working-directory: port/texasinstruments/tm4c
Expand Down Expand Up @@ -129,6 +133,10 @@ jobs:
run: zig build -Doptimize=ReleaseSmall
working-directory: examples/texasinstruments/msp430

- name: texasinstruments/mspm0
run: zig build -Doptimize=ReleaseSmall
working-directory: examples/texasinstruments/mspm0

- name: texasinstruments/tm4c
run: zig build -Doptimize=ReleaseSmall
working-directory: examples/texasinstruments/tm4c
Expand Down
2 changes: 2 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const port_list: []const struct {
.{ .name = "stm32", .dep_name = "port/stmicro/stm32" },
.{ .name = "ch32v", .dep_name = "port/wch/ch32v" },
.{ .name = "msp430", .dep_name = "port/texasinstruments/msp430" },
.{ .name = "mspm0", .dep_name = "port/texasinstruments/mspm0" },
.{ .name = "tm4c", .dep_name = "port/texasinstruments/tm4c" },
};

Expand Down Expand Up @@ -70,6 +71,7 @@ pub const PortSelect = struct {
stm32: bool = false,
ch32v: bool = false,
msp430: bool = false,
mspm0: bool = false,
tm4c: bool = false,

pub const all: PortSelect = blk: {
Expand Down
1 change: 1 addition & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
.@"port/raspberrypi/rp2xxx" = .{ .path = "port/raspberrypi/rp2xxx", .lazy = true },
.@"port/stmicro/stm32" = .{ .path = "port/stmicro/stm32", .lazy = true },
.@"port/texasinstruments/msp430" = .{ .path = "port/texasinstruments/msp430", .lazy = true },
.@"port/texasinstruments/mspm0" = .{ .path = "port/texasinstruments/mspm0", .lazy = true },
.@"port/texasinstruments/tm4c" = .{ .path = "port/texasinstruments/tm4c", .lazy = true },
.@"port/wch/ch32v" = .{ .path = "port/wch/ch32v", .lazy = true },
},
Expand Down
53 changes: 53 additions & 0 deletions core/src/utilities.zig
Original file line number Diff line number Diff line change
Expand Up @@ -651,3 +651,56 @@ test "CircularBuffer bounds" {

try std.testing.expectError(error.Full, maybe_err);
}

pub fn IntFracDiv(int_bits: comptime_int, frac_bits: comptime_int) type {
const FixedPoint = @Int(.unsigned, int_bits + frac_bits);
return packed struct(FixedPoint) {
pub const Int = @Int(.unsigned, int_bits);
pub const Frac = @Int(.unsigned, frac_bits);
pub const FixedP = FixedPoint;

frac: Frac,
int: Int,

/// Writes upper bits to int and lower bits to frac
pub fn from_fixedp(fixedp: FixedP) !@This() {
const ret: @This() = @bitCast(fixedp);
return if (ret.int > 0) ret else error.DividerTooSmall;
}

/// Returns clock configuration that most closely matches the given ratio
pub fn from_float(ratio: anytype) @This() {
const info = @typeInfo(@TypeOf(ratio));
if (info != .float and info != .comptime_float)
@compileError("Expected ratio to be a float, got " ++ @typeName(@TypeOf(ratio)));

const fixedp = ratio * (1 << frac_bits);
if (comptime info == .comptime_float and fixedp >= (1 << (int_bits + frac_bits)))
@compileError("Divider too big");

return from_fixedp(@round(fixedp)) catch unreachable;
}

/// Returns clock configuration that most closely matches the ratio of in/out
pub fn from_ratio(in: comptime_int, out: comptime_int) @This() {
// Maybe use rounding instead of truncating division?
return comptime from_fixedp((in << frac_bits) / out) catch unreachable;
}

/// Useful for ratio comparisons
pub fn to_fixedp(self: @This()) FixedP {
return @bitCast(self);
}

/// Returns a ratio that most closely matches this configuration
pub fn to_float(self: @This(), Float: type) Float {
if (@typeInfo(Float) != .float and @typeInfo(Float) != .comptime_float)
@compileError("Expected return type to be a float, got " ++ @typeName(Float));

const int_shifted = @shlExact(@as(FixedP, self.int), frac_bits);
const combined = int_shifted | @as(FixedP, self.frac);

return @as(Float, @floatFromInt(combined)) / (1 << frac_bits);
}
};
}
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/rp2040_only/tiles.zig
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub fn main() !void {
(800_000 * cycles_per_bit);

pio.sm_load_and_start_program(sm, ws2812_program, .{
.clkdiv = rp2xxx.pio.ClkDivOptions.from_float(div),
.clkdiv = .from_float(div),
.pin_mappings = .{
.side_set = .single(led_pin),
},
Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/squarewave.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ comptime {
pub fn main() !void {
pio.gpio_init(pin);
pio.sm_load_and_start_program(sm, squarewave_program, .{
.clkdiv = rp2xxx.pio.ClkDivOptions.from_float(125),
.clkdiv = .from_float(125.0),
.pin_mappings = .{
.set = .single(pin),
},
Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/st7789_lcd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub fn main() !void {
led.set_function(.pwm);
led.set_direction(.out);
led_pwm.slice().set_wrap(100);
led_pwm.slice().set_clk_div(50, 0);
led_pwm.slice().set_clk_div(.from_float(50.0));
led_pwm.set_level(1);
led_pwm.slice().enable();

Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/ws2812.zig
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub fn main() !void {
(800_000 * cycles_per_bit);

pio.sm_load_and_start_program(sm, ws2812_program, .{
.clkdiv = rp2xxx.pio.ClkDivOptions.from_float(div),
.clkdiv = .from_float(div),
.pin_mappings = .{
.side_set = .single(led_pin),
},
Expand Down
1 change: 1 addition & 0 deletions examples/texasinstruments/mspm0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Texas Instructments MSPM0
31 changes: 31 additions & 0 deletions examples/texasinstruments/mspm0/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const std = @import("std");
const microzig = @import("microzig");

const MicroBuild = microzig.MicroBuild(.{ .mspm0 = true });

pub fn build(b: *std.Build) void {
const optimize = b.standardOptimizeOption(.{});

const mz_dep = b.dependency("microzig", .{});
const mb = MicroBuild.init(b, mz_dep) orelse return;

inline for (comptime std.meta.fieldNames(@TypeOf(mb.ports.mspm0.chips))) |field_name| {
const target = @field(mb.ports.mspm0.chips, field_name);

inline for ([_][]const u8{
"blinky",
"raw_blinky",
"uart_echo",
"uart_log",
}) |name| {
const example = mb.add_firmware(.{
.name = name ++ "_" ++ field_name,
.target = target,
.optimize = optimize,
.root_source_file = b.path("src/" ++ name ++ ".zig"),
});

mb.install_firmware(example, .{});
}
}
}
15 changes: 15 additions & 0 deletions examples/texasinstruments/mspm0/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.{
.name = .mz_examples_ti_mspm0,
.fingerprint = 0x6dd3a36fb84aa34a,
.version = "0.0.1",
.minimum_zig_version = "0.17.0",
.dependencies = .{
.microzig = .{ .path = "../../.." },
},
.paths = .{
"src",
"build.zig",
"build.zig.zon",
"README.md",
},
}
25 changes: 25 additions & 0 deletions examples/texasinstruments/mspm0/src/blinky.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// const std = @import("std");
const microzig = @import("microzig");
const mspm0 = microzig.hal;

pub const panic = microzig.panic;
pub const std_options = microzig.std_options(.{});
comptime {
_ = microzig.export_startup();
}

pub fn main() void {
mspm0.gpio.enable(.gpioa);

const led = mspm0.gpio.num(.gpioa, 22);

led.set_function(1);
led.set_direction(.out);

while (true) {
led.toggle();

for (0..2_000_000) |_|
asm volatile ("nop");
}
}
30 changes: 30 additions & 0 deletions examples/texasinstruments/mspm0/src/raw_blinky.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const microzig = @import("microzig");

pub const panic = microzig.panic;
pub const std_options = microzig.std_options(.{});
comptime {
_ = microzig.export_startup();
}

pub fn main() void {
const pin = 22;

const IOMUX_BASE: usize = 0x40428000;
const GPIO0_BASE: usize = 0x400A0000;
const PINCM: *usize = @ptrFromInt(IOMUX_BASE + (pin + 1) * 4);
const GPIO_DOE31_0: *usize = @ptrFromInt(GPIO0_BASE + 0x12c0);
const GPIO_DOUTTGL31_0: *usize = @ptrFromInt(GPIO0_BASE + 0x12b0);
const PIN_MASK: usize = (1 << pin);
const GPIO0_PWREN: *usize = @ptrFromInt(GPIO0_BASE + 0x800);

GPIO0_PWREN.* = 0x26000001;
PINCM.* = (1 << 0) | (1 << 7);
GPIO_DOE31_0.* |= PIN_MASK;

while (true) {
GPIO_DOUTTGL31_0.* = PIN_MASK;

for (0..2_000_000) |_|
asm volatile ("nop");
}
}
40 changes: 40 additions & 0 deletions examples/texasinstruments/mspm0/src/uart_echo.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const std = @import("std");
const microzig = @import("microzig");
const mspm0 = microzig.hal;

pub const panic = microzig.panic;
pub const std_options = microzig.std_options(.{});
comptime {
_ = microzig.export_startup();
}

pub fn main() void {
mspm0.gpio.enable(.gpioa);

const led = mspm0.gpio.num(.gpioa, 22);
const uart_rx = mspm0.gpio.num(.gpioa, 26);
const uart_tx = mspm0.gpio.num(.gpioa, 27);

led.set_function(1);
led.set_direction(.out);

uart_rx.set_function(3);
uart_tx.set_function(5);

const uart = mspm0.Uart.num(0);
uart.configure(.{
.clk = .{ .div = .from_float(3.0) },
});

while (true) {
led.toggle();

if (uart.read()) |c|
_ = uart.write(std.ascii.toUpper(c))
else
_ = uart.write('.');

for (0..1_000_000) |_|
asm volatile ("nop");
}
}
45 changes: 45 additions & 0 deletions examples/texasinstruments/mspm0/src/uart_log.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const std = @import("std");
const microzig = @import("microzig");
const mspm0 = microzig.hal;

pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
std.log.err("panic: {s}", .{message});
while (true) @breakpoint();
}

pub const std_options = microzig.std_options(.{
.log_level = .debug,
.logFn = mspm0.Uart.log,
});

comptime {
_ = microzig.export_startup();
}

pub fn main() void {
mspm0.gpio.enable(.gpioa);

{ // init logger
const uart_tx = mspm0.gpio.num(.gpioa, 27);
uart_tx.set_function(5);
const uart = mspm0.Uart.num(0);
uart.configure(.{
.clk = .{ .div = .from_float(3.0) },
});
mspm0.Uart.init_logger(uart);
}

const led = mspm0.gpio.num(.gpioa, 22);

led.set_function(1);
led.set_direction(.out);

var i: u32 = 0;
while (true) : (i +%= 1) {
std.log.info("Toggling LED {}", .{i});
led.toggle();

for (0..2_000_000) |_|
asm volatile ("nop");
}
}
1 change: 1 addition & 0 deletions port/raspberrypi/rp2xxx/src/hal/adc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub fn apply(config: Config) void {

if (config.sample_frequency) |sample_frequency| {
assert(sample_frequency <= 500_000);
// Shouldn't this be (500_000 << 8) / sample_frequency since a divider of 1 means 500kSa/s?
const cycles = (48_000_000 * 256) / @as(u64, sample_frequency);
ADC.DIV.write(.{
.FRAC = @as(u8, @truncate(cycles)),
Expand Down
8 changes: 4 additions & 4 deletions port/raspberrypi/rp2xxx/src/hal/cyw43439_pio_spi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ pub fn init(config: Config) !Self {
pins.clk.set_slew_rate(.fast);

try pio.sm_load_and_start_program(sm, cyw43spi_program, .{
.clkdiv = .{
// 50MHz is recomended by datasheet
.int = if (hal.compatibility.chip == .RP2040) 2 else 3,
.frac = 0,
// 50MHz is recomended by datasheet
.clkdiv = switch (hal.compatibility.chip) {
.RP2040 => .from_float(2.0),
.RP2350 => .from_float(3.0),
},
.pin_mappings = .{
.out = .single(pins.io),
Expand Down
2 changes: 1 addition & 1 deletion port/raspberrypi/rp2xxx/src/hal/cyw43_pio_spi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn init(config: CYW43_PIO_SPI_Config) !CYW43_PIO_SPI {

try config.pio.sm_load_and_start_program(sm, cyw43spi_program, .{
// Default max value from pico-sdk 62.5Mhz
.clkdiv = .{ .int = 2, .frac = 0 },
.clkdiv = .from_float(2.0),
.pin_mappings = .{
.out = .single(config.io_pin),
.set = .single(config.io_pin),
Expand Down
Loading
Loading