Skip to content
Merged
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
7 changes: 5 additions & 2 deletions core/src/cpus/cortex_m.zig
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,9 @@ pub const startup_logic = struct {

@memcpy(ram_vectors[0..vector_count], flash_vector[0..vector_count]);

peripherals.scb.VTOR = @intFromPtr(&ram_vectors);
const vtor_addr: u32 = @intFromPtr(&ram_vectors);
std.debug.assert(std.mem.isAligned(vtor_addr, 256));
peripherals.scb.VTOR = vtor_addr;
}
}

Expand All @@ -662,7 +664,8 @@ pub const startup_logic = struct {
const VectorTable = microzig.chip.VectorTable;

// will be imported by microzig.zig to allow system startup.
pub const _vector_table: VectorTable = blk: {
// must be aligned to 256 as VTOR ignores the lower 8 bits of the address.
pub const _vector_table: VectorTable align(256) = blk: {
var tmp: VectorTable = .{
.initial_stack_pointer = microzig.config.end_of_stack,
.Reset = .{ .c = microzig.cpu.startup_logic._start },
Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/i2c_bus_scan.zig
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn main() !void {
pin.set_function(.i2c);
}

try i2c0.apply(.{
i2c0.apply(.{
.clock_config = rp2xxx.clock_config,
});

Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/mlx90640.zig
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn init() !void {
.clock_config = rpxxxx.clock_config,
});

try i2c0.apply(i2c.Config{ .clock_config = rpxxxx.clock_config });
i2c0.apply(i2c.Config{ .clock_config = rpxxxx.clock_config });

rpxxxx.uart.init_logger(uart);
pin_config.apply();
Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/rp2040_only/hd44780.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn main() !void {
pin.set_function(.i2c);
}

try i2c0.apply(.{
i2c0.apply(.{
.clock_config = rp2040.clock_config,
});
var expander = PCF8574(.{ .Datagram_Device = I2C_Device }).init(i2c_device);
Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/src/rp2040_only/pcf8574.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn main() !void {
pin.set_function(.i2c);
}

try i2c0.apply(.{
i2c0.apply(.{
.clock_config = rp2040.clock_config,
});
var expander = PCF8574(.{ .Datagram_Device = I2C_Device }).init(i2c_device);
Expand Down
2 changes: 1 addition & 1 deletion port/raspberrypi/rp2xxx/src/hal/dma.zig
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub const Channel = enum(u4) {
al3_read_addr_trig: u32,
};

fn get_regs(chan: Channel) *volatile Regs {
pub inline fn get_regs(chan: Channel) *volatile Regs {
const regs = @as(*volatile [num_channels]Regs, @ptrCast(&DMA.CH0_READ_ADDR));
return &regs[@intFromEnum(chan)];
}
Expand Down
8 changes: 4 additions & 4 deletions port/raspberrypi/rp2xxx/src/hal/gpio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -318,22 +318,22 @@ pub const Pin = enum(u6) {
.RP2350 => *volatile [48]PadsReg,
};

fn get_regs(gpio: Pin) *volatile Regs {
pub inline fn get_regs(gpio: Pin) *volatile Regs {
const regs = @as(RegsArray, @ptrCast(&IO_BANK0.GPIO0_STATUS));
return &regs[@intFromEnum(gpio)];
}

fn get_pads_reg(gpio: Pin) *volatile PadsReg {
pub inline fn get_pads_reg(gpio: Pin) *volatile PadsReg {
const regs = @as(PadsRegArray, @ptrCast(&PADS_BANK0.GPIO0));
return &regs[@intFromEnum(gpio)];
}

/// Only relevant for RP2350 which has 48 GPIOs
fn is_upper(gpio: Pin) bool {
pub inline fn is_upper(gpio: Pin) bool {
return @intFromEnum(gpio) > 31;
}

pub fn mask(gpio: Pin) u32 {
pub inline fn mask(gpio: Pin) u32 {
const bitshift_val: u5 = switch (chip) {
.RP2040 => @intCast(@intFromEnum(gpio)),
.RP2350 =>
Expand Down
29 changes: 21 additions & 8 deletions port/raspberrypi/rp2xxx/src/hal/i2c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ pub const instance = struct {
pub const I2C = enum(u1) {
_,

fn get_regs(i2c: I2C) *volatile I2cRegs {
pub inline fn get_regs(i2c: I2C) *volatile I2cRegs {
return switch (@intFromEnum(i2c)) {
0 => I2C0,
1 => I2C1,
Expand Down Expand Up @@ -246,7 +246,7 @@ pub const I2C = enum(u1) {
/// - TX_EMPTY_CTRL is always enabled for easy detection of TX finished
/// - TX and RX FIFO detection thresholds set to 1, this makes polling for TX finished/RX ready much simpler
/// - DREQ signalling is always enabled, harmless if DMA isn't configured to listen for this
pub fn apply(i2c: I2C, comptime config: Config) ConfigError!void {
pub fn apply(i2c: I2C, comptime config: Config) void {
i2c.disable();
const regs = i2c.get_regs();
regs.IC_CON.write(.{
Expand All @@ -273,8 +273,11 @@ pub const I2C = enum(u1) {
});

const peripheral_block_freq = (comptime config.clock_config.get_frequency(.clk_sys)) orelse @compileError("clk_sys must be set for I²C");

const timings = comptime translate_baudrate(config.baud_rate, peripheral_block_freq) catch @compileError("baud_rate is not possible with the provided clock_config");

// set_baudrate() enables I2C block before returning
try i2c.set_baudrate(config.baud_rate, peripheral_block_freq);
i2c.set_computed_baudrate(timings);
}

/// Disables I2C, returns peripheral registers to reset state.
Expand All @@ -289,13 +292,23 @@ pub const I2C = enum(u1) {
/// pin rise/fall time as that is board specific, so actual baud rates may be
/// slightly lower than specified.
pub fn set_baudrate(i2c: I2C, baud_rate: u32, freq_in: u32) ConfigError!void {
const reg_vals = try translate_baudrate(baud_rate, freq_in);
const timings = try translate_baudrate(baud_rate, freq_in);
i2c.set_computed_baudrate(timings);
}

/// Configures I2C to run at a specified baud rate given a peripheral clock frequency.
///
/// Validates configuration to ensure it's both within I2C spec, and the peripheral
/// block's configuration capabilities. Note that this does NOT take into account
/// pin rise/fall time as that is board specific, so actual baud rates may be
/// slightly lower than specified.
pub fn set_computed_baudrate(i2c: I2C, timings: TimingRegisterValues) void {
i2c.disable();
const regs = i2c.get_regs();
regs.IC_FS_SCL_HCNT.write(.{ .IC_FS_SCL_HCNT = reg_vals.scl_hcnt });
regs.IC_FS_SCL_LCNT.write(.{ .IC_FS_SCL_LCNT = reg_vals.scl_lcnt });
regs.IC_FS_SPKLEN.write(.{ .IC_FS_SPKLEN = reg_vals.spklen });
regs.IC_SDA_HOLD.modify(.{ .IC_SDA_TX_HOLD = reg_vals.sda_tx_hold_count });
regs.IC_FS_SCL_HCNT.write(.{ .IC_FS_SCL_HCNT = timings.scl_hcnt });
regs.IC_FS_SCL_LCNT.write(.{ .IC_FS_SCL_LCNT = timings.scl_lcnt });
regs.IC_FS_SPKLEN.write(.{ .IC_FS_SPKLEN = timings.spklen });
regs.IC_SDA_HOLD.modify(.{ .IC_SDA_TX_HOLD = timings.sda_tx_hold_count });
i2c.enable();
}

Expand Down
10 changes: 8 additions & 2 deletions port/raspberrypi/rp2xxx/src/hal/pio/assembler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ pub const Diagnostics = struct {
}
};

/// Creates a copy of a slice at comptime that is guaranteed to be immutable.
fn comptime_copy(comptime T: type, comptime slice: []const T) []const T {
const arr: [slice.len]T = slice[0..slice.len].*;
return &arr;
}

pub fn assemble_impl(comptime chip: Chip, comptime source: []const u8, diags: *?Diagnostics, options: AssembleOptions) !Output {
const tokens = try tokenizer.tokenize(chip, source, diags, options.tokenize);
const encoder_output = try encoder.encode(chip, tokens.slice(), diags, options.encode);
Expand All @@ -87,9 +93,9 @@ pub fn assemble_impl(comptime chip: Chip, comptime source: []const u8, diags: *?
.name = define.name,
.value = define.value,
}) catch unreachable;
break :blk tmp.constSlice();
break :blk comptime_copy(Define, tmp.slice());
},
.programs = programs.constSlice(),
.programs = comptime_copy(Program, programs.slice()),
};
}

Expand Down
7 changes: 6 additions & 1 deletion port/raspberrypi/rp2xxx/src/hal/pio/common.zig
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,12 @@ pub fn PioImpl(EnumType: type, chip: Chip) type {
if (origin != offset)
return false;

// Will never fit in the first place:
if (offset + program.instructions.len > 32)
return false;

const used_mask = UsedInstructionSpace(chip).val[@intFromEnum(self)];
const program_mask = program.get_mask();
const program_mask = (program.get_mask() << offset);

// We can add the program if the masks don't overlap, if there is
// overlap the result of a bitwise AND will have a non-zero result
Expand Down Expand Up @@ -537,6 +541,7 @@ pub fn PioImpl(EnumType: type, chip: Chip) type {

// TODO: check program settings vs pin mapping
const offset = try self.add_program(program);

self.sm_init(sm, offset, .{
.clkdiv = options.clkdiv,
.shift = options.shift,
Expand Down
2 changes: 1 addition & 1 deletion port/raspberrypi/rp2xxx/src/hal/uart.zig
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub const UART = enum(u1) {
return .{ .context = uart };
}

fn get_regs(uart: UART) *volatile UartRegs {
pub inline fn get_regs(uart: UART) *volatile UartRegs {
return switch (@intFromEnum(uart)) {
0 => UART0_reg,
1 => UART1_reg,
Expand Down
Loading