use core::sync::atomic::{AtomicUsize, Ordering};
use crate::usb::host::dwc2::regs::{Dwc2HostChannel, Dwc2Regs, DWC2_MAX_HOST_CHANNELS};
#[cfg(feature = "cv182x-host")]
use crate::usb::host::dwc2::regs::Cv182xUsb2Phy;
pub mod error;
pub mod setup;
pub mod host;
pub mod class;
#[cfg(feature = "device-mode")]
pub mod device;
pub use error::{UsbError, UsbResult};
static DWC2_BASE_VIRT: AtomicUsize = AtomicUsize::new(0);
#[cfg(feature = "cv182x-host")]
static CV182X_PHY_BASE_VIRT: AtomicUsize = AtomicUsize::new(0);
#[inline]
pub fn set_dwc2_base_virt(addr: usize) {
DWC2_BASE_VIRT.store(addr, Ordering::SeqCst);
}
#[inline]
pub fn dwc2_base_virt() -> usize {
DWC2_BASE_VIRT.load(Ordering::SeqCst)
}
#[cfg(feature = "cv182x-host")]
#[inline]
pub fn set_cv182x_phy_base_virt(addr: usize) {
CV182X_PHY_BASE_VIRT.store(addr, Ordering::SeqCst);
}
#[cfg(feature = "cv182x-host")]
#[inline]
pub fn cv182x_phy_base_virt() -> usize {
CV182X_PHY_BASE_VIRT.load(Ordering::SeqCst)
}
#[inline]
pub fn dwc2_regs() -> Option<&'static Dwc2Regs> {
let base = dwc2_base_virt();
if base == 0 {
return None;
}
Some(unsafe { &*(base as *const Dwc2Regs) })
}
#[inline]
pub fn dwc2_channel(ch: u32) -> Option<&'static Dwc2HostChannel> {
let regs = dwc2_regs()?;
let idx = ch as usize;
if idx >= DWC2_MAX_HOST_CHANNELS {
return None;
}
Some(®s.hc[idx])
}
#[cfg(feature = "cv182x-host")]
#[inline]
pub fn cv182x_phy_regs() -> Option<&'static Cv182xUsb2Phy> {
let base = cv182x_phy_base_virt();
if base == 0 {
return None;
}
Some(unsafe { &*(base as *const Cv182xUsb2Phy) })
}
pub type UsbDmaToPhysFn = fn(*const u8) -> u32;
static USB_DMA_TO_PHYS: AtomicUsize = AtomicUsize::new(0);
pub fn set_usb_dma_to_phys_fn(f: Option<UsbDmaToPhysFn>) {
let bits = f.map(|p| p as usize).unwrap_or(0);
USB_DMA_TO_PHYS.store(bits, Ordering::SeqCst);
}
#[inline]
pub fn usb_dma_phys_for(ptr: *const u8) -> u32 {
let bits = USB_DMA_TO_PHYS.load(Ordering::SeqCst);
if bits == 0 {
ptr as usize as u32
} else {
let fp: UsbDmaToPhysFn =
unsafe { core::mem::transmute::<usize, UsbDmaToPhysFn>(bits) };
fp(ptr)
}
}