diff --git a/luna/gateware/platform/cynthion_r0_6.py b/luna/gateware/platform/cynthion_r0_6.py index 369cf67b4..3574fd7d2 100644 --- a/luna/gateware/platform/cynthion_r0_6.py +++ b/luna/gateware/platform/cynthion_r0_6.py @@ -13,8 +13,24 @@ from .core import LUNAApolloPlatform from ..architecture.car import LunaECP5DomainGenerator +from ..architecture.adv import ApolloAdvertiser +from luna.gateware.usb.usb2.control import USBControlEndpoint + __all__ = ["CynthionPlatformRev0D6"] +def control_phy_hook(usb_device, m): + # Add Apollo advertisement submodule and its request handler + m.submodules.apollo_adv = adv = ApolloAdvertiser() + control_ep = None + for endpoint in usb_device._endpoints: + if isinstance(endpoint, USBControlEndpoint): + control_ep = endpoint + break + if control_ep is None: + control_ep = usb_device.add_control_endpoint() + control_ep.add_request_handler(adv.default_request_handler()) + + class CynthionPlatformRev0D6(LUNAApolloPlatform, LatticeECP5Platform): """ Board description for Cynthion r0.6 """ @@ -30,7 +46,7 @@ class CynthionPlatformRev0D6(LUNAApolloPlatform, LatticeECP5Platform): clock_domain_generator = LunaECP5DomainGenerator # By default, assume we'll be connecting via our target PHY. - default_usb_connection = "target_phy" + default_usb_connection = "control_phy" # # Default clock frequencies for each of our clock domains. @@ -196,6 +212,11 @@ class CynthionPlatformRev0D6(LUNAApolloPlatform, LatticeECP5Platform): "- - B9 A9 B10 A10 B11 D14 C14 F14 E14 G13 G12 - - - - C16 C15 B16 B15 A14 B13 A13 D13 A12 B12 A11 - -"), ] + # Provides platform-specific hooks that will be called during USBDevice elaboration + usb_device_hooks = { + "control_phy_0": control_phy_hook + } + def toolchain_prepare(self, fragment, name, **kwargs): overrides = { 'ecppack_opts': '--compress --freq 38.8' diff --git a/luna/gateware/usb/usb2/device.py b/luna/gateware/usb/usb2/device.py index e73b0f522..1dfd0f974 100644 --- a/luna/gateware/usb/usb2/device.py +++ b/luna/gateware/usb/usb2/device.py @@ -150,6 +150,7 @@ def __init__(self, *, bus, handle_clocking=True): # Internals. # self._endpoints = [] + self.bus_name = bus.name def add_endpoint(self, endpoint): @@ -202,6 +203,12 @@ def add_standard_control_endpoint(self, descriptors: DeviceDescriptorCollection, def elaborate(self, platform): m = Module() + # Call any hooks registered for the bus in the platform definition. + if hasattr(platform, "usb_device_hooks"): + hook = platform.usb_device_hooks.get(self.bus_name) + if hook is not None: + hook(self, m) + # If we have a bus translator, include it in our submodules. if self.translator: m.submodules.translator = self.translator