Flash 57 lines
// GPIO driver for Raspberry Pi 4
const LINEAR_MAP_BASE u64 = 0xFFFF000000000000
const DEVICE_BASE u64 = 0xFE000000
const GPIO_BASE u64 = DEVICE_BASE + 0x00200000 + LINEAR_MAP_BASE
const GpioPinData = extern struct {
reserved u32,
data [2]u32
}
const GpioRegs = extern struct {
func_select [6]u32,
output_set GpioPinData,
output_clear GpioPinData,
level GpioPinData,
ev_detect_status GpioPinData,
re_detect_enable GpioPinData,
fe_detect_enable GpioPinData,
hi_detect_enable GpioPinData,
lo_detect_enable GpioPinData,
async_re_detect GpioPinData,
async_fe_detect GpioPinData,
reserved u32,
pupd_enable u32,
pupd_enable_clocks [2]u32,
reserved2 [18]u32,
pullup_pulldown [4]u32
}
fn getGpioRegs() *mut volatile GpioRegs {
return #as(*mut volatile GpioRegs, #ptrFromInt(GPIO_BASE))
}
/// Set the alternate function for a GPIO pin
export fn gpio_pin_set_func(pin_number u8, func u8) void {
const regs = getGpioRegs()
const bit_start u5 = #intCast((pin_number % 10) * 3)
const reg usize = pin_number / 10
var selector = regs.func_select[reg]
selector &= ~(#as(u32, 7) << bit_start)
selector |= (#as(u32, func) << bit_start)
regs.func_select[reg] = selector
}
/// Disable pull-up/pull-down for a GPIO pin
export fn gpio_pin_enable(pin_number u8) void {
const regs = getGpioRegs()
const idx usize = pin_number / 16
const bit_start u5 = #intCast((pin_number % 16) * 2)
var reg = regs.pullup_pulldown[idx]
reg &= ~(#as(u32, 3) << bit_start)
regs.pullup_pulldown[idx] = reg
}