1313from litex_boards .platforms import digilent_nexys_video
1414
1515from litex .soc .cores .clock import *
16+ from litex .soc .integration .soc import SoCRegion
1617from litex .soc .integration .soc_core import *
1718from litex .soc .integration .builder import *
1819from litex .soc .cores .video import VideoS7HDMIPHY
@@ -73,6 +74,7 @@ def __init__(self, toolchain="vivado", sys_clk_freq=100e6,
7374 with_ethernet = False ,
7475 with_led_chaser = True ,
7576 with_sata = False , sata_gen = "gen2" ,
77+ with_usb = False ,
7678 vadj = "1.2V" ,
7779 with_video_terminal = False ,
7880 with_video_framebuffer = False ,
@@ -151,6 +153,32 @@ def __init__(self, toolchain="vivado", sys_clk_freq=100e6,
151153 if with_video_framebuffer :
152154 self .add_video_framebuffer (phy = self .videophy , timings = "800x600@60Hz" , clock_domain = "hdmi" )
153155
156+ # USB-OHCI ---------------------------------------------------------------------------------
157+ if with_usb :
158+ from litex .build .generic_platform import Subsignal , Pins , IOStandard
159+ from litex .soc .cores .usb_ohci import USBOHCI
160+
161+ # Use the Video PLL if available
162+ self .crg .cd_usb = ClockDomain ()
163+ self .crg .pll .create_clkout (self .crg .cd_usb , 48e6 , margin = 0 )
164+
165+ # Machdyne PMOD (https://github.com/machdyne/usb_host_dual_socket_pmod) on JB
166+ _usb_pmodb_dual_ios = [
167+ ("usb_pmodb_dual" , 0 ,
168+ Subsignal ("dp" , Pins ("pmodb:0 pmodb:2" )),
169+ Subsignal ("dm" , Pins ("pmodb:1 pmodb:3" )),
170+ IOStandard ("LVCMOS33" ),
171+ ),
172+ ]
173+ self .platform .add_extension (_usb_pmodb_dual_ios )
174+
175+ self .submodules .usb_ohci = USBOHCI (self .platform , self .platform .request ("usb_pmodb_dual" ), usb_clk_freq = int (48e6 ))
176+ self .mem_map ["usb_ohci" ] = 0x90000000
177+ self .bus .add_slave ("usb_ohci_ctrl" , self .usb_ohci .wb_ctrl , region = SoCRegion (origin = self .mem_map ["usb_ohci" ], size = 0x1000 , cached = False )) # FIXME: Mapping.
178+ self .dma_bus .add_master ("usb_ohci_dma" , master = self .usb_ohci .wb_dma )
179+
180+ self .comb += self .cpu .interrupt [16 ].eq (self .usb_ohci .interrupt )
181+
154182 # Leds -------------------------------------------------------------------------------------
155183 if with_led_chaser :
156184 self .leds = LedChaser (
@@ -167,6 +195,7 @@ def main():
167195 from litex .build .parser import LiteXArgumentParser
168196 parser = LiteXArgumentParser (platform = digilent_nexys_video .Platform , description = "LiteX SoC on Nexys Video." )
169197 parser .add_target_argument ("--sys-clk-freq" , default = 100e6 , type = float , help = "System clock frequency." )
198+ parser .add_target_argument ("--with-usb" , action = "store_true" , help = "Enable USB Host." )
170199 parser .add_target_argument ("--with-ethernet" , action = "store_true" , help = "Enable Ethernet support." )
171200 sdopts = parser .target_group .add_mutually_exclusive_group ()
172201 sdopts .add_argument ("--with-spi-sdcard" , action = "store_true" , help = "Enable SPI-mode SDCard support." )
@@ -183,6 +212,7 @@ def main():
183212 toolchain = args .toolchain ,
184213 sys_clk_freq = args .sys_clk_freq ,
185214 with_ethernet = args .with_ethernet ,
215+ with_usb = args .with_usb ,
186216 with_sata = args .with_sata ,
187217 sata_gen = "gen" + args .sata_gen ,
188218 vadj = args .vadj ,
0 commit comments