USB OHCI
SpinalHDL库中有USB OHCi控制器(主机)。
A few bullet points to summarize support:
它遵循 OpenHCI USB开放式主机控制接口规范 (OHCI)。
它已经与上游的linux/uboot OHCI驱动兼容。(tinyUSB上也有OHCI驱动)
This provides USB host full speed and low speed capabilities (12 Mbps and 1.5 Mbps)
在linux和uboot上测试过
一个可以承载多个端口(多至16个)的控制器
用于DMA访问的Bmb存储器接口
Bmb memory interface for the configuration
内部物理层需要一个时钟,该时钟需要为12 Mhz的倍数,至少48 Mhz
控制器频率不受限制
无需外部物理层
经过测试且功能正常的设备:
大容量存储(ArtyA7 Linux上约为8 Mbps)
键盘/鼠标
音频输出
集线器
限制:
某些USB集线器(目前已有一个)对将低速设备连接至全速主机的模式不友好。
某些现代设备无法在USB全速上运行(例如:Gbps以太网适配器)
需要与CPU保持内存一致性(或者需要CPU能够刷新驱动中的数据缓存)
部署:
https://github.com/SpinalHDL/SaxonSoc/tree/dev-0.3/bsp/digilent/ArtyA7SmpLinux
https://github.com/SpinalHDL/SaxonSoc/tree/dev-0.3/bsp/radiona/ulx3s/smp
用法
import spinal.core._
import spinal.core.sim._
import spinal.lib.bus.bmb._
import spinal.lib.bus.bmb.sim._
import spinal.lib.bus.misc.SizeMapping
import spinal.lib.com.usb.ohci._
import spinal.lib.com.usb.phy.UsbHubLsFs.CtrlCc
import spinal.lib.com.usb.phy._
class UsbOhciTop(val p : UsbOhciParameter) extends Component {
val ohci = UsbOhci(p, BmbParameter(
addressWidth = 12,
dataWidth = 32,
sourceWidth = 0,
contextWidth = 0,
lengthWidth = 2
))
val phyCd = ClockDomain.external("phyCd", frequency = FixedFrequency(48 MHz))
val phy = phyCd(UsbLsFsPhy(p.portCount, sim=true))
val phyCc = CtrlCc(p.portCount, ClockDomain.current, phyCd)
phyCc.input <> ohci.io.phy
phyCc.output <> phy.io.ctrl
// propagate io signals
val irq = ohci.io.interrupt.toIo
val ctrl = ohci.io.ctrl.toIo
val dma = ohci.io.dma.toIo
val usb = phy.io.usb.toIo
val management = phy.io.management.toIo
}
object UsbHostGen extends App {
val p = UsbOhciParameter(
noPowerSwitching = true,
powerSwitchingMode = true,
noOverCurrentProtection = true,
powerOnToPowerGoodTime = 10,
dataWidth = 64, // DMA data width, up to 128
portsConfig = List.fill(4)(OhciPortParameter()) // 4 Ports
)
SpinalVerilog(new UsbOhciTop(p))
}