mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-17 04:32:27 +00:00
Enable GPIO Pull Up and Down
This commit is contained in:
BIN
firmware_files/bootcode.bin
Executable file
BIN
firmware_files/bootcode.bin
Executable file
Binary file not shown.
@@ -1,4 +1,3 @@
|
|||||||
kernel=kernel8.img
|
kernel=kernel8.img
|
||||||
arm_64bit=1
|
arm_64bit=1
|
||||||
enable_uart=1
|
enable_uart=1
|
||||||
program_usb_boot_mode=1
|
|
||||||
BIN
firmware_files/start.elf
Executable file
BIN
firmware_files/start.elf
Executable file
Binary file not shown.
48
src/gpio.rs
48
src/gpio.rs
@@ -1,9 +1,16 @@
|
|||||||
use crate::uart::{self};
|
use core::ptr::{read_volatile, write_volatile};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
timer::delay_nops,
|
||||||
|
uart::{self},
|
||||||
|
};
|
||||||
|
|
||||||
const GPFSEL_BASE: u32 = 0x3F20_0000;
|
const GPFSEL_BASE: u32 = 0x3F20_0000;
|
||||||
const GPSET_BASE: u32 = 0x3F20_001C;
|
const GPSET_BASE: u32 = 0x3F20_001C;
|
||||||
const GPCLR_BASE: u32 = 0x3F20_0028;
|
const GPCLR_BASE: u32 = 0x3F20_0028;
|
||||||
const GPLEV_BASE: u32 = 0x3F20_0034;
|
const GPLEV_BASE: u32 = 0x3F20_0034;
|
||||||
|
const GPPUD: u32 = 0x3F20_0094;
|
||||||
|
const GPPUDCLK_BASE: u32 = 0x3F20_0098;
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum GPIOState {
|
pub enum GPIOState {
|
||||||
@@ -39,8 +46,6 @@ pub unsafe fn set_gpio_state(gpio: u8, state: GPIOState) -> Result<(), &'static
|
|||||||
|
|
||||||
pub fn gpio_high(gpio: u8) -> Result<(), &'static str> {
|
pub fn gpio_high(gpio: u8) -> Result<(), &'static str> {
|
||||||
unsafe {
|
unsafe {
|
||||||
uart::print("Pull Up\n");
|
|
||||||
|
|
||||||
let register_index = gpio / 32;
|
let register_index = gpio / 32;
|
||||||
let register_offset = gpio % 32;
|
let register_offset = gpio % 32;
|
||||||
let register_addr = GPSET_BASE + (register_index as u32 * 4);
|
let register_addr = GPSET_BASE + (register_index as u32 * 4);
|
||||||
@@ -52,8 +57,6 @@ pub fn gpio_high(gpio: u8) -> Result<(), &'static str> {
|
|||||||
|
|
||||||
pub fn gpio_low(gpio: u8) -> Result<(), &'static str> {
|
pub fn gpio_low(gpio: u8) -> Result<(), &'static str> {
|
||||||
unsafe {
|
unsafe {
|
||||||
uart::print("Pull Down\n");
|
|
||||||
|
|
||||||
let register_index = gpio / 32;
|
let register_index = gpio / 32;
|
||||||
let register_offset = gpio % 32;
|
let register_offset = gpio % 32;
|
||||||
let register_addr = GPCLR_BASE + (register_index as u32 * 4);
|
let register_addr = GPCLR_BASE + (register_index as u32 * 4);
|
||||||
@@ -73,3 +76,38 @@ pub fn gpio_get_state(gpio: u8) -> u8 {
|
|||||||
return ((state >> register_offset) & 0b1) as u8;
|
return ((state >> register_offset) & 0b1) as u8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gpio_pull_up(gpio: u8) {
|
||||||
|
gpio_pull_up_down(gpio, 0b10);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gpio_pull_down(gpio: u8) {
|
||||||
|
gpio_pull_up_down(gpio, 0b01);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gpio_pull_up_down(gpio: u8, val: u32) {
|
||||||
|
unsafe {
|
||||||
|
// Determine GPPUDCLK Register
|
||||||
|
let register_addr = gpio / 32;
|
||||||
|
let register_offset = gpio % 32;
|
||||||
|
|
||||||
|
// 1. Write Pull up
|
||||||
|
write_volatile(GPPUD as *mut u32, 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);
|
||||||
|
|
||||||
|
// 4. Delay 150 cycles
|
||||||
|
delay_nops(150);
|
||||||
|
|
||||||
|
// 5. reset GPPUD
|
||||||
|
write_volatile(GPPUD as *mut u32, 0);
|
||||||
|
|
||||||
|
// 6. reset clock
|
||||||
|
write_volatile(register_addr as *mut u32, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
13
src/main.rs
13
src/main.rs
@@ -21,6 +21,7 @@ fn panic(_panic: &PanicInfo) -> ! {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[link_section = ".text._start"]
|
#[link_section = ".text._start"]
|
||||||
pub unsafe extern "C" fn _start() {
|
pub unsafe extern "C" fn _start() {
|
||||||
|
// Set the stack pointer
|
||||||
asm!("ldr x0, =0x8004000", "mov sp, x0");
|
asm!("ldr x0, =0x8004000", "mov sp, x0");
|
||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
@@ -29,19 +30,25 @@ pub unsafe extern "C" fn _start() {
|
|||||||
extern "C" fn main() {
|
extern "C" fn main() {
|
||||||
uart::configure_uart();
|
uart::configure_uart();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// Set ACT Led to Outout
|
||||||
let _ = set_gpio_state(29, gpio::GPIOState::Output);
|
let _ = set_gpio_state(29, gpio::GPIOState::Output);
|
||||||
|
|
||||||
|
// Set GPIO Pins to UART
|
||||||
let _ = set_gpio_state(14, gpio::GPIOState::Alternative0);
|
let _ = set_gpio_state(14, gpio::GPIOState::Alternative0);
|
||||||
let _ = set_gpio_state(15, gpio::GPIOState::Alternative0);
|
let _ = set_gpio_state(15, gpio::GPIOState::Alternative0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay so clock speed can stabilize
|
// Delay so clock speed can stabilize
|
||||||
unsafe { delay_nops(50000) }
|
delay_nops(50000);
|
||||||
uart::print("Hello World!\n");
|
uart::print("Hello World!\n");
|
||||||
|
|
||||||
|
sleep(500_000);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let _ = gpio_high(29);
|
let _ = gpio_high(29);
|
||||||
unsafe { sleep(500_000) } // 0.5s
|
|
||||||
|
sleep(500_000); // 0.5s
|
||||||
let _ = gpio_low(29);
|
let _ = gpio_low(29);
|
||||||
unsafe { sleep(500_000) } // 0.5s
|
sleep(500_000) // 0.5s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ fn read_clo() -> u32 {
|
|||||||
unsafe { return core::ptr::read_volatile(TIMER_CLO as *const u32) }
|
unsafe { return core::ptr::read_volatile(TIMER_CLO as *const u32) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn sleep(microseconds: u32) {
|
pub fn sleep(microseconds: u32) {
|
||||||
let start = read_clo();
|
let start = read_clo();
|
||||||
while read_clo() - start < microseconds {
|
while read_clo() - start < microseconds {
|
||||||
core::arch::asm!("nop");
|
unsafe { core::arch::asm!("nop") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn delay_nops(count: u32) {
|
pub fn delay_nops(count: u32) {
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
core::arch::asm!("nop");
|
unsafe { core::arch::asm!("nop") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user