// TODO: upstream these helper functions // TODO: rp2350 support? const std = @import("std"); const microzig = @import("microzig"); const rp2xxx = microzig.hal; const peripherals = microzig.chip.peripherals; const Scenario = packed struct(u4) { low: u1 = 0, high: u1 = 0, fall: u1 = 0, rise: u1 = 0, }; const Destination = packed struct { dormant_wake: u1 = 0, proc0: u1 = 0, proc1: u1 = 0, }; const Bank = packed struct { io_bank0: Destination = @bitCast(@as(u3, 0)), io_qspi: Destination = @bitCast(@as(u3, 0)), }; pub fn enable_interrupt(gpio: rp2xxx.gpio.Pin, bank: Bank, mask: Scenario) void { const shift: u5 = @intCast(@intFromEnum(gpio) % 8 * 4); const shifted_mask: u32 = @as(u32, @intCast(@as(u4, @bitCast(mask)))) << shift; if (@as(u3, @bitCast(bank.io_bank0)) != 0) { const b = peripherals.IO_BANK0; switch (@intFromEnum(gpio)) { 0...7 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE0.raw |= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE0.raw |= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE0.raw |= shifted_mask; }, 8...15 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE1.raw |= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE1.raw |= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE1.raw |= shifted_mask; }, 16...23 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE2.raw |= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE2.raw |= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE2.raw |= shifted_mask; }, 24...29 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE3.raw |= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE3.raw |= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE3.raw |= shifted_mask; }, else => @panic("the RP2040 only has GPIO 0-29"), } // Enable this interrupt type rp2xxx.irq.enable(.IO_IRQ_BANK0); } if (@as(u3, @bitCast(bank.io_qspi)) != 0) { const b = peripherals.IO_QSPI; if (bank.io_qspi.dormant_wake == 1) b.DORMANT_WAKE_INTE.raw |= shifted_mask; if (bank.io_qspi.proc0 == 1) b.PROC0_INTE.raw |= shifted_mask; if (bank.io_qspi.proc1 == 1) b.PROC1_INTE.raw |= shifted_mask; // Enable this interrupt type rp2xxx.irq.enable(.IO_IRQ_QSPI); } // Enable CPU interrupt handling // rp2xxx.irq.globally_enable(); } pub fn disable_interrupt(gpio: rp2xxx.gpio.Pin, bank: Bank, mask: Scenario) void { const shift: u5 = @intCast(@intFromEnum(gpio) % 8 * 4); const shifted_mask: u32 = @as(u32, @intCast(@as(u4, @bitCast(mask)))) << shift; if (@as(u3, @bitCast(bank.io_bank0)) != 0) { const b = peripherals.IO_BANK0; switch (@intFromEnum(gpio)) { 0...7 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE0.raw ^= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE0.raw ^= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE0.raw ^= shifted_mask; }, 8...15 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE1.raw ^= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE1.raw ^= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE1.raw ^= shifted_mask; }, 16...23 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE2.raw ^= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE2.raw ^= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE2.raw ^= shifted_mask; }, 24...29 => { if (bank.io_bank0.dormant_wake == 1) b.DORMANT_WAKE_INTE3.raw ^= shifted_mask; if (bank.io_bank0.proc0 == 1) b.PROC0_INTE3.raw ^= shifted_mask; if (bank.io_bank0.proc1 == 1) b.PROC1_INTE3.raw ^= shifted_mask; }, else => @panic("the RP2040 only has GPIO 0-29"), } } if (@as(u3, @bitCast(bank.io_qspi)) != 0) { const b = peripherals.IO_QSPI; if (bank.io_qspi.dormant_wake == 1) b.DORMANT_WAKE_INTE.raw ^= shifted_mask; if (bank.io_qspi.proc0 == 1) b.PROC0_INTE.raw ^= shifted_mask; if (bank.io_qspi.proc1 == 1) b.PROC1_INTE.raw ^= shifted_mask; } }