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))
}