This commit is contained in:
2025-09-29 14:01:54 +03:00
parent 475bf90eb9
commit aba41cb5b2
+28 -11
View File
@@ -1,6 +1,9 @@
#![no_std]
use core::{sync::atomic::AtomicBool, time::Duration};
use core::{
sync::atomic::{AtomicBool, AtomicU32},
time::Duration,
};
use alloc::sync::Arc;
use device_api::{
@@ -15,6 +18,7 @@ use tock_registers::{
interfaces::{ReadWriteable, Readable, Writeable},
LocalRegisterCopy,
};
use yggdrasil_abi::bitflags;
use crate::{
regs::{PortSpeed, Regs},
@@ -31,6 +35,7 @@ pub struct Dwc2<H: Dwc2Impl> {
regs: IrqSafeSpinlock<DeviceMemoryIo<'static, Regs>>,
name: Arc<str>,
channel_bitmask: AtomicU32,
port_event_mask: BitmapEvent<AtomicWaker>,
}
@@ -46,10 +51,16 @@ impl<H: Dwc2Impl + 'static> Dwc2<H> {
imp,
regs,
name,
channel_bitmask: AtomicU32::new(0),
port_event_mask: BitmapEvent::new(AtomicWaker::new()),
})
}
fn signal_events(&self, channels: u16, ports: u32) {
self.port_event_mask
.signal(((channels as u64) << 32) | (ports as u64));
}
async fn setup_port(self: Arc<Self>, speed: PortSpeed) -> Result<(), Error> {
log::info!("{}: setup port", self.name);
todo!()
@@ -59,6 +70,10 @@ impl<H: Dwc2Impl + 'static> Dwc2<H> {
LocalRegisterCopy::new(self.port_event_mask.wait_mask(0x2A).await as u32)
}
async fn wait_for_channel_events(&self) -> u16 {
(self.port_event_mask.wait_mask(0xFFFF00000000).await >> 32) as u16
}
async fn wait_for_device(&self) -> PortSpeed {
let hprt = self.regs.lock().HPRT.extract();
// If already connected, begin init, if not, wait for connect change
@@ -189,17 +204,19 @@ impl<H: Dwc2Impl + 'static> Device for Dwc2<H> {
impl<H: Dwc2Impl + 'static> InterruptHandler for Dwc2<H> {
fn handle_irq(self: Arc<Self>, vector: IrqVector) -> bool {
let (port_status, interrupt) = {
let regs = self.regs.lock();
(regs.take_port_status(), regs.take_interrupt())
let regs = self.regs.lock();
let gintsts = regs.take_interrupt();
let hprt = if gintsts.matches_all(regs::GINTSTS::HPRTINT::SET) {
regs.take_port_status().get()
} else {
0
};
log::info!(
"USB IRQ: {:#x}, port {:#x} ({})",
interrupt.get(),
port_status.get(),
port_status.get() & 0x2A != 0
);
self.port_event_mask.signal(port_status.get() as u64);
if hprt != 0 {
self.signal_events(0, hprt);
}
true
}
}