migrate read and write volatile to a function

This commit is contained in:
2025-06-08 20:10:55 +02:00
parent 5f85a40f13
commit 8c193f5c15
5 changed files with 110 additions and 126 deletions

View File

@@ -1,8 +1,8 @@
use core::ptr::{read_volatile, write_volatile};
use core::result::Result;
use core::result::Result::Ok;
use crate::timer::delay_nops;
use crate::{mmio_read, mmio_write};
const GPFSEL_BASE: u32 = 0x3F20_0000;
const GPSET_BASE: u32 = 0x3F20_001C;
@@ -30,16 +30,14 @@ pub fn set_gpio_function(gpio: u8, state: GPIOFunction) -> Result<(), &'static s
let register_index = gpio / 10;
let register_offset = (gpio % 10) * 3;
let register_addr = GPFSEL_BASE + (register_index as u32 * 4);
unsafe {
let current = core::ptr::read_volatile(register_addr as *const u32);
let current = mmio_read(register_addr);
let mask = !(0b111 << register_offset);
let cleared = current & mask;
let mask = !(0b111 << register_offset);
let cleared = current & mask;
let new_val = cleared | ((state as u32) << register_offset);
let new_val = cleared | ((state as u32) << register_offset);
core::ptr::write_volatile(register_addr as *mut u32, new_val);
}
mmio_write(register_addr, new_val);
Ok(())
}
@@ -47,13 +45,11 @@ pub fn set_gpio_function(gpio: u8, state: GPIOFunction) -> Result<(), &'static s
///
/// Should be used when GPIO function is set to `OUTPUT` via `set_gpio_function`
pub fn gpio_high(gpio: u8) -> Result<(), &'static str> {
unsafe {
let register_index = gpio / 32;
let register_offset = gpio % 32;
let register_addr = GPSET_BASE + (register_index as u32 * 4);
let register_index = gpio / 32;
let register_offset = gpio % 32;
let register_addr = GPSET_BASE + (register_index as u32 * 4);
core::ptr::write_volatile(register_addr as *mut u32, 1 << register_offset);
}
mmio_write(register_addr, 1 << register_offset);
Ok(())
}
@@ -61,26 +57,22 @@ pub fn gpio_high(gpio: u8) -> Result<(), &'static str> {
///
/// Should be used when GPIO function is set to `OUTPUT` via `set_gpio_function`
pub fn gpio_low(gpio: u8) -> Result<(), &'static str> {
unsafe {
let register_index = gpio / 32;
let register_offset = gpio % 32;
let register_addr = GPCLR_BASE + (register_index as u32 * 4);
let register_index = gpio / 32;
let register_offset = gpio % 32;
let register_addr = GPCLR_BASE + (register_index as u32 * 4);
core::ptr::write_volatile(register_addr as *mut u32, 1 << register_offset);
}
mmio_write(register_addr, 1 << register_offset);
Ok(())
}
/// Read the current GPIO power state
pub fn gpio_get_state(gpio: u8) -> u8 {
unsafe {
let register_index = gpio / 32;
let register_offset = gpio % 32;
let register_addr = GPLEV_BASE + (register_index as u32 * 4);
let register_index = gpio / 32;
let register_offset = gpio % 32;
let register_addr = GPLEV_BASE + (register_index as u32 * 4);
let state = core::ptr::read_volatile(register_addr as *mut u32);
return ((state >> register_offset) & 0b1) as u8;
}
let state = mmio_read(register_addr);
return ((state >> register_offset) & 0b1) as u8;
}
/// Pull GPIO up
@@ -104,81 +96,73 @@ fn gpio_pull_up_down(gpio: u8, val: u32) {
let register_offset = gpio % 32;
// 1. Write Pull up
write_volatile(GPPUD as *mut u32, val);
mmio_write(GPPUD, val);
// 2. Delay 150 cycles
delay_nops(150);
// 3. Write to clock
let new_val = 0b1 << register_offset;
write_volatile(register_addr as *mut u32, new_val);
mmio_write(register_addr, new_val);
// 4. Delay 150 cycles
delay_nops(150);
// 5. reset GPPUD
write_volatile(GPPUD as *mut u32, 0);
mmio_write(GPPUD, 0);
// 6. reset clock
write_volatile(register_addr as *mut u32, 0);
mmio_write(register_addr, 0);
}
}
/// Get the current status if falling edge detection is set
pub fn read_falling_edge_detect(gpio: u8) -> bool {
unsafe {
let register_addr = GPFEN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let register_addr = GPFEN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let current = read_volatile(register_addr as *const u32);
((current >> register_offset) & 0b1) != 0
}
let current = mmio_read(register_addr);
((current >> register_offset) & 0b1) != 0
}
/// Get the current status if falling edge detection is set
pub fn read_rising_edge_detect(gpio: u8) -> bool {
unsafe {
let register_addr = GPREN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let register_addr = GPREN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let current = read_volatile(register_addr as *const u32);
((current >> register_offset) & 0b1) != 0
}
let current = mmio_read(register_addr);
((current >> register_offset) & 0b1) != 0
}
/// Enables falling edge detection
pub fn set_falling_edge_detect(gpio: u8, enable: bool) {
unsafe {
let register_addr = GPFEN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let register_addr = GPFEN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let current = read_volatile(register_addr as *const u32);
let mask = 0b1 << register_offset;
let new_val = if enable {
current | mask
} else {
current & !mask
};
let current = mmio_read(register_addr);
let mask = 0b1 << register_offset;
let new_val = if enable {
current | mask
} else {
current & !mask
};
write_volatile(register_addr as *mut u32, new_val);
}
mmio_write(register_addr, new_val);
}
/// Enables rising edge detection
pub fn set_rising_edge_detect(gpio: u8, enable: bool) {
unsafe {
let register_addr = GPREN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let register_addr = GPREN_BASE + 4 * (gpio as u32 / 32);
let register_offset = gpio % 32;
let current = read_volatile(register_addr as *const u32);
let current = mmio_read(register_addr);
let mask = 0b1 << register_offset;
let new_val = if enable {
current | mask
} else {
current & !mask
};
let mask = 0b1 << register_offset;
let new_val = if enable {
current | mask
} else {
current & !mask
};
write_volatile(register_addr as *mut u32, new_val);
}
mmio_write(register_addr, new_val);
}