fix: orangepi3 gpio ctrl
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
//! Allwinner H6 GPIO port controller driver.
|
||||
//!
|
||||
//! GPIO ports are split into two register groups:
|
||||
//!
|
||||
//! 1. CPUS-PORT (TODO PL, PM)
|
||||
//! 2. CPUX-PORT (PC, PD, PF, PG, PH)
|
||||
//!
|
||||
use crate::arch::MemoryIo;
|
||||
use crate::dev::{
|
||||
gpio::{GpioDevice, PinConfig, PinMode, PullMode},
|
||||
@@ -21,29 +28,33 @@ register_structs! {
|
||||
}
|
||||
|
||||
struct CpuxGpio {
|
||||
regs: MemoryIo<[CpuxPortRegs; 5]>,
|
||||
regs: MemoryIo<[CpuxPortRegs; 8]>,
|
||||
}
|
||||
|
||||
pub(super) struct Gpio {
|
||||
pub struct Gpio {
|
||||
cpux: IrqSafeNullLock<CpuxGpio>,
|
||||
}
|
||||
|
||||
/// Structure combining bank and pin numbers
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PinAddress(u32);
|
||||
|
||||
impl PinAddress {
|
||||
/// Constructs a new pin address from `bank` and `pin` numbers
|
||||
#[inline(always)]
|
||||
pub const fn new(bank: u32, pin: u32) -> Self {
|
||||
// TODO sanity checks
|
||||
Self((bank << 16) | pin)
|
||||
}
|
||||
|
||||
/// Returns bank number of this pin
|
||||
#[inline(always)]
|
||||
pub const fn bank(self) -> usize {
|
||||
(self.0 >> 16) as usize
|
||||
}
|
||||
|
||||
/// Returns pin number of this pin
|
||||
#[inline(always)]
|
||||
pub const fn pin(self) -> u32 {
|
||||
self.0 & 0xFFFF
|
||||
@@ -70,7 +81,6 @@ impl CpuxPortRegs {
|
||||
|
||||
impl CpuxGpio {
|
||||
unsafe fn set_pin_config(&self, bank: usize, pin: u32, cfg: &PinConfig) -> Result<(), Errno> {
|
||||
assert!((0..=7).contains(&bank));
|
||||
let regs = &self.regs[bank];
|
||||
|
||||
let pull = match cfg.pull {
|
||||
@@ -144,8 +154,8 @@ impl GpioDevice for Gpio {
|
||||
let pin = pin.pin();
|
||||
|
||||
match bank {
|
||||
2..=7 => self.cpux.lock().set_pin_config(bank - 2, pin, cfg),
|
||||
_ => unimplemented!(),
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => self.cpux.lock().set_pin_config(bank, pin, cfg),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,8 +168,8 @@ impl GpioDevice for Gpio {
|
||||
let pin = pin.pin();
|
||||
|
||||
match bank {
|
||||
2..=7 => self.cpux.lock().write_pin(bank - 2, pin, state),
|
||||
_ => unimplemented!(),
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => self.cpux.lock().write_pin(bank, pin, state),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,8 +178,8 @@ impl GpioDevice for Gpio {
|
||||
let pin = pin.pin();
|
||||
|
||||
match bank {
|
||||
2..=7 => self.cpux.lock().toggle_pin(bank - 2, pin),
|
||||
_ => unimplemented!(),
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => self.cpux.lock().toggle_pin(bank, pin),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,8 +188,8 @@ impl GpioDevice for Gpio {
|
||||
let pin = pin.pin();
|
||||
|
||||
match bank {
|
||||
2..=7 => Ok(self.cpux.lock().read_pin(bank - 2, pin)),
|
||||
_ => unimplemented!(),
|
||||
0 | 1 | 4 => unimplemented!(),
|
||||
_ => Ok(self.cpux.lock().read_pin(bank, pin)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::arch::aarch64::{
|
||||
timer::GenericTimer,
|
||||
};
|
||||
use crate::dev::{
|
||||
gpio::{GpioDevice, PinConfig},
|
||||
irq::{IntController, IntSource},
|
||||
serial::SerialDevice,
|
||||
timer::TimestampSource,
|
||||
@@ -16,6 +17,7 @@ mod gpio;
|
||||
mod uart;
|
||||
|
||||
pub use gic::IrqNumber;
|
||||
pub use gpio::PinAddress;
|
||||
use gpio::Gpio;
|
||||
use uart::Uart;
|
||||
|
||||
@@ -25,6 +27,7 @@ pub fn init_board() -> Result<(), Errno> {
|
||||
GIC.enable()?;
|
||||
|
||||
GPIO.cfg_uart0_ph0_ph1()?;
|
||||
GPIO.set_pin_config(PinAddress::new(3, 26), &PinConfig::out_pull_down())?;
|
||||
|
||||
UART0.enable()?;
|
||||
UART0.init_irqs()?;
|
||||
@@ -57,5 +60,5 @@ pub fn intc() -> &'static impl IntController<IrqNumber = IrqNumber> {
|
||||
|
||||
static UART0: Uart = unsafe { Uart::new(UART0_BASE, IrqNumber::new(32)) };
|
||||
static LOCAL_TIMER: GenericTimer = GenericTimer {};
|
||||
static GPIO: Gpio = unsafe { Gpio::new(PIO_BASE) };
|
||||
pub(super) static GPIO: Gpio = unsafe { Gpio::new(PIO_BASE) };
|
||||
static GIC: Gic = unsafe { Gic::new(GICD_BASE, GICC_BASE) };
|
||||
|
||||
@@ -113,6 +113,8 @@ impl IntSource for Uart {
|
||||
let regs = self.regs.lock();
|
||||
let byte = regs.DR_DLL.get();
|
||||
debugln!("irq byte = {:#04x}!", byte);
|
||||
use crate::dev::gpio::{GpioDevice};
|
||||
machine::GPIO.toggle_pin(machine::PinAddress::new(3, 26));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user