forked from M-Labs/artiq-zynq
Compare commits
10 Commits
5597927df9
...
7d8268adf2
Author | SHA1 | Date |
---|---|---|
mwojcik | 7d8268adf2 | |
mwojcik | 3da71dedd7 | |
Sebastien Bourdeauducq | 4ec1ef125b | |
morgan | 6573ecd487 | |
morgan | b8ff602d93 | |
morgan | 0e75694c6b | |
Sebastien Bourdeauducq | 7cdfb1b830 | |
Egor Savkin | 9b76896edd | |
morgan | 00c5ee01b0 | |
morgan | b47152f2c2 |
28
flake.lock
28
flake.lock
|
@ -11,11 +11,11 @@
|
||||||
"src-pythonparser": "src-pythonparser"
|
"src-pythonparser": "src-pythonparser"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1690427113,
|
"lastModified": 1695781625,
|
||||||
"narHash": "sha256-10XRV7vbdyr/NKDKmBWcVs+9/iYbj6f2bulMRhwy0JY=",
|
"narHash": "sha256-zv8A0Mz2hIYLfD78GxLgXpOkTgnt/kT6rGWzP6NkXkM=",
|
||||||
"ref": "release-7",
|
"ref": "release-7",
|
||||||
"rev": "21c6f57ce18cdd0c41f467434d58c0b9193da374",
|
"rev": "cc81464f53a02cb41d7b4f9efae75f815c63ea4d",
|
||||||
"revCount": 8180,
|
"revCount": 8185,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/m-labs/artiq.git"
|
"url": "https://github.com/m-labs/artiq.git"
|
||||||
},
|
},
|
||||||
|
@ -85,11 +85,11 @@
|
||||||
"mozilla-overlay_2": {
|
"mozilla-overlay_2": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1687771476,
|
"lastModified": 1695805681,
|
||||||
"narHash": "sha256-TSpqz6qYVRoqkEdOCawEQ4/cWt/4pracmvw17HK1tgE=",
|
"narHash": "sha256-1ElPLD8eFfnuIk0G52HGGpRtQZ4QPCjChRlEOfkZ5ro=",
|
||||||
"owner": "mozilla",
|
"owner": "mozilla",
|
||||||
"repo": "nixpkgs-mozilla",
|
"repo": "nixpkgs-mozilla",
|
||||||
"rev": "3a44b8783514e7d6db4b63df96071b6c2b014b07",
|
"rev": "6eabade97bc28d707a8b9d82ad13ef143836736e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -101,11 +101,11 @@
|
||||||
"mozilla-overlay_3": {
|
"mozilla-overlay_3": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1684487559,
|
"lastModified": 1695805681,
|
||||||
"narHash": "sha256-SZcJEM+NnLr8ctzeQf1BGAqBHzJ3jn+tdSeO7lszIJc=",
|
"narHash": "sha256-1ElPLD8eFfnuIk0G52HGGpRtQZ4QPCjChRlEOfkZ5ro=",
|
||||||
"owner": "mozilla",
|
"owner": "mozilla",
|
||||||
"repo": "nixpkgs-mozilla",
|
"repo": "nixpkgs-mozilla",
|
||||||
"rev": "e6ca26fe8b9df914d4567604e426fbc185d9ef3e",
|
"rev": "6eabade97bc28d707a8b9d82ad13ef143836736e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -217,11 +217,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1685182853,
|
"lastModified": 1701572971,
|
||||||
"narHash": "sha256-bEgE8Ph7MEHQr7S+xL33CxLuIm3AqvsaxBwUE1vHTdU=",
|
"narHash": "sha256-f8IPIYenff7B8S3p/pjVxT/0HVZuJXtdg2jtMpaZEbM=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "f20c0082645cfef34575661aeeff8d9c1ed1f127",
|
"rev": "91bae572f913abc2f95acb899ca5afa33eeaa036",
|
||||||
"revCount": 625,
|
"revCount": 634,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.m-labs.hk/m-labs/zynq-rs"
|
"url": "https://git.m-labs.hk/m-labs/zynq-rs"
|
||||||
},
|
},
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
cargoLock = {
|
cargoLock = {
|
||||||
lockFile = src/Cargo.lock;
|
lockFile = src/Cargo.lock;
|
||||||
outputHashes = {
|
outputHashes = {
|
||||||
"libasync-0.0.0" = "sha256-xuwesRrQiccopPTCkwGqQxld74X74q7EVsKIrE0zirc=";
|
"libasync-0.0.0" = "sha256-f8IPIYenff7B8S3p/pjVxT/0HVZuJXtdg2jtMpaZEbM=";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -378,4 +378,4 @@
|
||||||
makeArtiqZynqPackage = build;
|
makeArtiqZynqPackage = build;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libasync"
|
name = "libasync"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#605c8f73a60cf41a6e2d535c5850933d3154e935"
|
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#91bae572f913abc2f95acb899ca5afa33eeaa036"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"libcortex_a9",
|
"libcortex_a9",
|
||||||
|
@ -251,7 +251,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libboard_zynq"
|
name = "libboard_zynq"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#605c8f73a60cf41a6e2d535c5850933d3154e935"
|
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#91bae572f913abc2f95acb899ca5afa33eeaa036"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
|
@ -276,7 +276,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libconfig"
|
name = "libconfig"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#605c8f73a60cf41a6e2d535c5850933d3154e935"
|
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#91bae572f913abc2f95acb899ca5afa33eeaa036"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core_io",
|
"core_io",
|
||||||
"fatfs",
|
"fatfs",
|
||||||
|
@ -287,7 +287,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libcortex_a9"
|
name = "libcortex_a9"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#605c8f73a60cf41a6e2d535c5850933d3154e935"
|
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#91bae572f913abc2f95acb899ca5afa33eeaa036"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"libregister",
|
"libregister",
|
||||||
|
@ -303,7 +303,7 @@ checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libregister"
|
name = "libregister"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#605c8f73a60cf41a6e2d535c5850933d3154e935"
|
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#91bae572f913abc2f95acb899ca5afa33eeaa036"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"vcell",
|
"vcell",
|
||||||
|
@ -313,7 +313,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsupport_zynq"
|
name = "libsupport_zynq"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#605c8f73a60cf41a6e2d535c5850933d3154e935"
|
source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#91bae572f913abc2f95acb899ca5afa33eeaa036"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
|
|
|
@ -10,6 +10,7 @@ from migen.genlib.cdc import MultiReg
|
||||||
from migen_axi.integration.soc_core import SoCCore
|
from migen_axi.integration.soc_core import SoCCore
|
||||||
from migen_axi.platforms import kasli_soc
|
from migen_axi.platforms import kasli_soc
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
|
from misoc.cores import virtual_leds
|
||||||
from misoc.integration import cpu_interface
|
from misoc.integration import cpu_interface
|
||||||
|
|
||||||
from artiq.coredevice import jsondesc
|
from artiq.coredevice import jsondesc
|
||||||
|
@ -76,7 +77,7 @@ class RTIOCRG(Module, AutoCSR):
|
||||||
MultiReg(pll_locked, self.pll_locked.status)
|
MultiReg(pll_locked, self.pll_locked.status)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
eem_iostandard_dict = {
|
eem_iostandard_dict = {
|
||||||
0: "LVDS_25",
|
0: "LVDS_25",
|
||||||
1: "LVDS_25",
|
1: "LVDS_25",
|
||||||
|
@ -113,6 +114,7 @@ class SMAClkinForward(Module):
|
||||||
class GenericStandalone(SoCCore):
|
class GenericStandalone(SoCCore):
|
||||||
def __init__(self, description, acpki=False):
|
def __init__(self, description, acpki=False):
|
||||||
self.acpki = acpki
|
self.acpki = acpki
|
||||||
|
sys_clk_freq = 125e6
|
||||||
|
|
||||||
platform = kasli_soc.Platform()
|
platform = kasli_soc.Platform()
|
||||||
platform.toolchain.bitstream_commands.extend([
|
platform.toolchain.bitstream_commands.extend([
|
||||||
|
@ -123,6 +125,8 @@ class GenericStandalone(SoCCore):
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
|
self.config["hw_rev"] = description["hw_rev"]
|
||||||
|
|
||||||
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
||||||
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
|
@ -139,6 +143,7 @@ class GenericStandalone(SoCCore):
|
||||||
self.ps7.cd_sys.clk,
|
self.ps7.cd_sys.clk,
|
||||||
self.rtio_crg.cd_rtio.clk)
|
self.rtio_crg.cd_rtio.clk)
|
||||||
fix_serdes_timing_path(platform)
|
fix_serdes_timing_path(platform)
|
||||||
|
self.config["CLOCK_FREQUENCY"] = int(sys_clk_freq)
|
||||||
|
|
||||||
self.rtio_channels = []
|
self.rtio_channels = []
|
||||||
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
||||||
|
@ -155,7 +160,9 @@ class GenericStandalone(SoCCore):
|
||||||
self.rtio_channels.append(rtio.LogChannel())
|
self.rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
||||||
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, self.rtio_channels)
|
self.submodules.rtio_core = rtio.Core(
|
||||||
|
self.rtio_tsc, self.rtio_channels, lane_count=description["sed_lanes"]
|
||||||
|
)
|
||||||
self.csr_devices.append("rtio_core")
|
self.csr_devices.append("rtio_core")
|
||||||
|
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
|
@ -209,6 +216,8 @@ class GenericMaster(SoCCore):
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
|
self.config["hw_rev"] = description["hw_rev"]
|
||||||
|
|
||||||
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
||||||
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
|
@ -221,6 +230,7 @@ class GenericMaster(SoCCore):
|
||||||
pads=data_pads,
|
pads=data_pads,
|
||||||
sys_clk_freq=sys_clk_freq)
|
sys_clk_freq=sys_clk_freq)
|
||||||
self.csr_devices.append("drtio_transceiver")
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
self.config["CLOCK_FREQUENCY"] = int(sys_clk_freq)
|
||||||
|
|
||||||
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
||||||
|
@ -279,7 +289,9 @@ class GenericMaster(SoCCore):
|
||||||
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
||||||
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
|
|
||||||
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, self.rtio_channels)
|
self.submodules.rtio_core = rtio.Core(
|
||||||
|
self.rtio_tsc, self.rtio_channels, lane_count=description["sed_lanes"]
|
||||||
|
)
|
||||||
self.csr_devices.append("rtio_core")
|
self.csr_devices.append("rtio_core")
|
||||||
|
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
|
@ -317,10 +329,15 @@ class GenericMaster(SoCCore):
|
||||||
self.config["HAS_GRABBER"] = None
|
self.config["HAS_GRABBER"] = None
|
||||||
self.add_csr_group("grabber", self.grabber_csr_group)
|
self.add_csr_group("grabber", self.grabber_csr_group)
|
||||||
|
|
||||||
|
self.submodules.virtual_leds = virtual_leds.VirtualLeds()
|
||||||
|
self.csr_devices.append("virtual_leds")
|
||||||
|
|
||||||
|
self.comb += [self.virtual_leds.get(i).eq(channel.rx_ready)
|
||||||
|
for i, channel in enumerate(self.drtio_transceiver.channels)]
|
||||||
|
|
||||||
class GenericSatellite(SoCCore):
|
class GenericSatellite(SoCCore):
|
||||||
def __init__(self, description, acpki=False):
|
def __init__(self, description, acpki=False):
|
||||||
sys_clk_freq = 125e6
|
sys_clk_freq = 125e6
|
||||||
rtio_clk_freq = description["rtio_frequency"]
|
rtio_clk_freq = description["rtio_frequency"]
|
||||||
|
|
||||||
self.acpki = acpki
|
self.acpki = acpki
|
||||||
|
@ -334,6 +351,8 @@ class GenericSatellite(SoCCore):
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
|
self.config["hw_rev"] = description["hw_rev"]
|
||||||
|
|
||||||
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
||||||
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
|
@ -341,7 +360,7 @@ class GenericSatellite(SoCCore):
|
||||||
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
fix_serdes_timing_path(platform)
|
fix_serdes_timing_path(platform)
|
||||||
|
|
||||||
data_pads = [platform.request("sfp", i) for i in range(4)]
|
data_pads = [platform.request("sfp", i) for i in range(4)]
|
||||||
|
|
||||||
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
|
@ -429,7 +448,9 @@ class GenericSatellite(SoCCore):
|
||||||
self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0)
|
self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0)
|
||||||
self.csr_devices.append("rtio_dma")
|
self.csr_devices.append("rtio_dma")
|
||||||
|
|
||||||
self.submodules.local_io = SyncRTIO(self.rtio_tsc, self.rtio_channels)
|
self.submodules.local_io = SyncRTIO(
|
||||||
|
self.rtio_tsc, self.rtio_channels, lane_count=description["sed_lanes"]
|
||||||
|
)
|
||||||
self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors)
|
self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors)
|
||||||
|
|
||||||
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
||||||
|
@ -446,6 +467,7 @@ class GenericSatellite(SoCCore):
|
||||||
|
|
||||||
rtio_clk_period = 1e9/rtio_clk_freq
|
rtio_clk_period = 1e9/rtio_clk_freq
|
||||||
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
|
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
|
||||||
|
self.config["CLOCK_FREQUENCY"] = int(sys_clk_freq)
|
||||||
|
|
||||||
self.submodules.siphaser = SiPhaser7Series(
|
self.submodules.siphaser = SiPhaser7Series(
|
||||||
si5324_clkin=platform.request("cdr_clk"),
|
si5324_clkin=platform.request("cdr_clk"),
|
||||||
|
@ -473,7 +495,12 @@ class GenericSatellite(SoCCore):
|
||||||
self.config["HAS_GRABBER"] = None
|
self.config["HAS_GRABBER"] = None
|
||||||
self.add_csr_group("grabber", self.grabber_csr_group)
|
self.add_csr_group("grabber", self.grabber_csr_group)
|
||||||
# no RTIO CRG here
|
# no RTIO CRG here
|
||||||
|
|
||||||
|
self.submodules.virtual_leds = virtual_leds.VirtualLeds()
|
||||||
|
self.csr_devices.append("virtual_leds")
|
||||||
|
|
||||||
|
self.comb += [self.virtual_leds.get(i).eq(channel.rx_ready)
|
||||||
|
for i, channel in enumerate(self.drtio_transceiver.channels)]
|
||||||
|
|
||||||
def write_mem_file(soc, filename):
|
def write_mem_file(soc, filename):
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f:
|
||||||
|
|
|
@ -451,6 +451,7 @@ class _SatelliteBase(SoCCore):
|
||||||
def add_rtio(self, rtio_channels):
|
def add_rtio(self, rtio_channels):
|
||||||
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
|
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
|
||||||
self.csr_devices.append("rtio_moninj")
|
self.csr_devices.append("rtio_moninj")
|
||||||
|
self.rustc_cfg["has_rtio_moninj"] = None
|
||||||
|
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
self.rustc_cfg["ki_impl"] = "acp"
|
self.rustc_cfg["ki_impl"] = "acp"
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
use crate::pl::csr;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
|
enum State {
|
||||||
|
Reset,
|
||||||
|
ExitReset,
|
||||||
|
Lock,
|
||||||
|
Align,
|
||||||
|
Watch,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Info {
|
||||||
|
state: State,
|
||||||
|
frame_size: (u16, u16),
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut INFO: [Info; csr::GRABBER_LEN] = [Info {
|
||||||
|
state: State::Reset,
|
||||||
|
frame_size: (0, 0),
|
||||||
|
}; csr::GRABBER_LEN];
|
||||||
|
|
||||||
|
fn get_pll_reset(g: usize) -> bool {
|
||||||
|
unsafe { (csr::GRABBER[g].pll_reset_read)() != 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_pll_reset(g: usize, reset: bool) {
|
||||||
|
let val = if reset { 1 } else { 0 };
|
||||||
|
unsafe { (csr::GRABBER[g].pll_reset_write)(val) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pll_locked(g: usize) -> bool {
|
||||||
|
unsafe { (csr::GRABBER[g].pll_locked_read)() != 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clock_pattern_ok(g: usize) -> bool {
|
||||||
|
unsafe { (csr::GRABBER[g].clk_sampled_read)() == 0b1100011 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clock_pattern_ok_filter(g: usize) -> bool {
|
||||||
|
for _ in 0..128 {
|
||||||
|
if !clock_pattern_ok(g) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn phase_shift(g: usize, direction: u8) {
|
||||||
|
unsafe {
|
||||||
|
(csr::GRABBER[g].phase_shift_write)(direction);
|
||||||
|
while (csr::GRABBER[g].phase_shift_done_read)() == 0 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clock_align(g: usize) -> bool {
|
||||||
|
while clock_pattern_ok_filter(g) {
|
||||||
|
phase_shift(g, 1);
|
||||||
|
}
|
||||||
|
phase_shift(g, 1);
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
while !clock_pattern_ok_filter(g) {
|
||||||
|
phase_shift(g, 1);
|
||||||
|
count += 1;
|
||||||
|
if count > 1024 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut window = 1;
|
||||||
|
phase_shift(g, 1);
|
||||||
|
while clock_pattern_ok_filter(g) {
|
||||||
|
phase_shift(g, 1);
|
||||||
|
window += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..window / 2 {
|
||||||
|
phase_shift(g, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_last_pixels(g: usize) -> (u16, u16) {
|
||||||
|
unsafe { ((csr::GRABBER[g].last_x_read)(), (csr::GRABBER[g].last_y_read)()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_video_clock(g: usize) -> u32 {
|
||||||
|
let freq_count = unsafe { (csr::GRABBER[g].freq_count_read)() } as u32;
|
||||||
|
2 * freq_count * (csr::CONFIG_CLOCK_FREQUENCY / 1000) / (511 * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick() {
|
||||||
|
for g in 0..csr::GRABBER.len() {
|
||||||
|
let next = match unsafe { INFO[g].state } {
|
||||||
|
State::Reset => {
|
||||||
|
set_pll_reset(g, true);
|
||||||
|
unsafe {
|
||||||
|
INFO[g].frame_size = (0, 0);
|
||||||
|
}
|
||||||
|
State::ExitReset
|
||||||
|
}
|
||||||
|
State::ExitReset => {
|
||||||
|
if get_pll_reset(g) {
|
||||||
|
set_pll_reset(g, false);
|
||||||
|
State::Lock
|
||||||
|
} else {
|
||||||
|
State::ExitReset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::Lock => {
|
||||||
|
if pll_locked(g) {
|
||||||
|
info!("grabber{} locked: {}MHz", g, get_video_clock(g));
|
||||||
|
State::Align
|
||||||
|
} else {
|
||||||
|
State::Lock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::Align => {
|
||||||
|
if pll_locked(g) {
|
||||||
|
if clock_align(g) {
|
||||||
|
info!("grabber{} alignment success", g);
|
||||||
|
State::Watch
|
||||||
|
} else {
|
||||||
|
info!("grabber{} alignment failure", g);
|
||||||
|
State::Reset
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("grabber{} lock lost", g);
|
||||||
|
State::Reset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::Watch => {
|
||||||
|
if pll_locked(g) {
|
||||||
|
if clock_pattern_ok(g) {
|
||||||
|
let last_xy = get_last_pixels(g);
|
||||||
|
if last_xy != unsafe { INFO[g].frame_size } {
|
||||||
|
// x capture is on ~LVAL which is after
|
||||||
|
// the last increment on DVAL
|
||||||
|
// y capture is on ~FVAL which coincides with the
|
||||||
|
// last increment on ~LVAL
|
||||||
|
info!("grabber{} frame size: {}x{}", g, last_xy.0, last_xy.1 + 1);
|
||||||
|
unsafe { INFO[g].frame_size = last_xy }
|
||||||
|
}
|
||||||
|
State::Watch
|
||||||
|
} else {
|
||||||
|
info!("grabber{} alignment lost", g);
|
||||||
|
State::Reset
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("grabber{} lock lost", g);
|
||||||
|
State::Reset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
INFO[g].state = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
use libboard_zynq::i2c;
|
use libboard_zynq::i2c;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
|
use crate::pl::csr;
|
||||||
|
|
||||||
// Only the bare minimum registers. Bits/IO connections equivalent between IC types.
|
// Only the bare minimum registers. Bits/IO connections equivalent between IC types.
|
||||||
struct Registers {
|
struct Registers {
|
||||||
// PCA9539 equivalent register names in comments
|
// PCA9539 equivalent register names in comments
|
||||||
|
@ -10,8 +12,28 @@ struct Registers {
|
||||||
gpiob: u8, // Output Port 1
|
gpiob: u8, // Output Port 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//IO expanders pins
|
||||||
|
const IODIR_OUT_SFP_TX_DISABLE: u8 = 0x02;
|
||||||
|
const IODIR_OUT_SFP_LED: u8 = 0x40;
|
||||||
|
#[cfg(hw_rev = "v1.0")]
|
||||||
|
const IODIR_OUT_SFP0_LED: u8 = 0x40;
|
||||||
|
#[cfg(hw_rev = "v1.1")]
|
||||||
|
const IODIR_OUT_SFP0_LED: u8 = 0x80;
|
||||||
|
|
||||||
|
//IO expander port direction
|
||||||
|
const IODIR0: [u8; 2] = [
|
||||||
|
0xFF & !IODIR_OUT_SFP_TX_DISABLE & !IODIR_OUT_SFP0_LED,
|
||||||
|
0xFF & !IODIR_OUT_SFP_TX_DISABLE & !IODIR_OUT_SFP_LED,
|
||||||
|
];
|
||||||
|
|
||||||
|
const IODIR1: [u8; 2] = [
|
||||||
|
0xFF & !IODIR_OUT_SFP_TX_DISABLE & !IODIR_OUT_SFP_LED,
|
||||||
|
0xFF & !IODIR_OUT_SFP_TX_DISABLE & !IODIR_OUT_SFP_LED,
|
||||||
|
];
|
||||||
|
|
||||||
pub struct IoExpander {
|
pub struct IoExpander {
|
||||||
address: u8,
|
address: u8,
|
||||||
|
virtual_led_mapping: &'static [(u8, u8, u8)],
|
||||||
iodir: [u8; 2],
|
iodir: [u8; 2],
|
||||||
out_current: [u8; 2],
|
out_current: [u8; 2],
|
||||||
out_target: [u8; 2],
|
out_target: [u8; 2],
|
||||||
|
@ -20,12 +42,19 @@ pub struct IoExpander {
|
||||||
|
|
||||||
impl IoExpander {
|
impl IoExpander {
|
||||||
pub fn new(i2c: &mut i2c::I2c, index: u8) -> Result<Self, &'static str> {
|
pub fn new(i2c: &mut i2c::I2c, index: u8) -> Result<Self, &'static str> {
|
||||||
|
#[cfg(hw_rev = "v1.0")]
|
||||||
|
const VIRTUAL_LED_MAPPING0: [(u8, u8, u8); 2] = [(0, 0, 6), (1, 1, 6)];
|
||||||
|
#[cfg(hw_rev = "v1.1")]
|
||||||
|
const VIRTUAL_LED_MAPPING0: [(u8, u8, u8); 2] = [(0, 0, 7), (1, 1, 6)];
|
||||||
|
|
||||||
|
const VIRTUAL_LED_MAPPING1: [(u8, u8, u8); 2] = [(2, 0, 6), (3, 1, 6)];
|
||||||
|
|
||||||
// Both expanders on SHARED I2C bus
|
// Both expanders on SHARED I2C bus
|
||||||
let mut io_expander = match index {
|
let mut io_expander = match index {
|
||||||
0 => IoExpander {
|
0 => IoExpander {
|
||||||
address: 0x40,
|
address: 0x40,
|
||||||
iodir: [0xff; 2],
|
virtual_led_mapping: &VIRTUAL_LED_MAPPING0,
|
||||||
|
iodir: IODIR0,
|
||||||
out_current: [0; 2],
|
out_current: [0; 2],
|
||||||
out_target: [0; 2],
|
out_target: [0; 2],
|
||||||
registers: Registers {
|
registers: Registers {
|
||||||
|
@ -37,7 +66,8 @@ impl IoExpander {
|
||||||
},
|
},
|
||||||
1 => IoExpander {
|
1 => IoExpander {
|
||||||
address: 0x42,
|
address: 0x42,
|
||||||
iodir: [0xff; 2],
|
virtual_led_mapping: &VIRTUAL_LED_MAPPING1,
|
||||||
|
iodir: IODIR1,
|
||||||
out_current: [0; 2],
|
out_current: [0; 2],
|
||||||
out_target: [0; 2],
|
out_target: [0; 2],
|
||||||
registers: Registers {
|
registers: Registers {
|
||||||
|
@ -124,6 +154,12 @@ impl IoExpander {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn service(&mut self, i2c: &mut i2c::I2c) -> Result<(), &'static str> {
|
pub fn service(&mut self, i2c: &mut i2c::I2c) -> Result<(), &'static str> {
|
||||||
|
#[cfg(has_virtual_leds)]
|
||||||
|
for (led, port, bit) in self.virtual_led_mapping.iter() {
|
||||||
|
let level = unsafe { csr::virtual_leds::status_read() >> led & 1 };
|
||||||
|
self.set(*port, *bit, level != 0);
|
||||||
|
}
|
||||||
|
|
||||||
if self.out_target != self.out_current {
|
if self.out_target != self.out_current {
|
||||||
self.select(i2c)?;
|
self.select(i2c)?;
|
||||||
if self.out_target[0] != self.out_current[0] {
|
if self.out_target[0] != self.out_current[0] {
|
||||||
|
|
|
@ -27,8 +27,10 @@ pub mod drtioaux_async;
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
#[path = "../../../build/mem.rs"]
|
#[path = "../../../build/mem.rs"]
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(all(feature = "target_kasli_soc", has_drtio))]
|
||||||
pub mod io_expander;
|
pub mod io_expander;
|
||||||
|
#[cfg(has_grabber)]
|
||||||
|
pub mod grabber;
|
||||||
|
|
||||||
use core::{cmp, str};
|
use core::{cmp, str};
|
||||||
use libboard_zynq::slcr;
|
use libboard_zynq::slcr;
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[cfg(all(feature = "target_kasli_soc", has_drtio))]
|
||||||
|
use core::cell::RefCell;
|
||||||
use log::{info, warn, error};
|
use log::{info, warn, error};
|
||||||
|
|
||||||
use libboard_zynq::{timer::GlobalTimer, mpcore, gic};
|
use libboard_zynq::{timer::GlobalTimer, mpcore, gic};
|
||||||
|
@ -21,7 +23,7 @@ use void::Void;
|
||||||
use libconfig::Config;
|
use libconfig::Config;
|
||||||
use libcortex_a9::l2c::enable_l2_cache;
|
use libcortex_a9::l2c::enable_l2_cache;
|
||||||
use libboard_artiq::{logger, identifier_read, init_gateware, pl};
|
use libboard_artiq::{logger, identifier_read, init_gateware, pl};
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(all(feature = "target_kasli_soc", has_drtio))]
|
||||||
use libboard_artiq::io_expander;
|
use libboard_artiq::io_expander;
|
||||||
|
|
||||||
const ASYNC_ERROR_COLLISION: u8 = 1 << 0;
|
const ASYNC_ERROR_COLLISION: u8 = 1 << 0;
|
||||||
|
@ -91,6 +93,39 @@ async fn report_async_rtio_errors() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(all(feature = "target_kasli_soc", has_drtio))]
|
||||||
|
async fn io_expanders_service(
|
||||||
|
i2c_bus: RefCell<&mut libboard_zynq::i2c::I2c>,
|
||||||
|
io_expander0: RefCell<io_expander::IoExpander>,
|
||||||
|
io_expander1: RefCell<io_expander::IoExpander>,
|
||||||
|
) {
|
||||||
|
loop {
|
||||||
|
task::r#yield().await;
|
||||||
|
io_expander0
|
||||||
|
.borrow_mut()
|
||||||
|
.service(&mut i2c_bus.borrow_mut())
|
||||||
|
.expect("I2C I/O expander #0 service failed");
|
||||||
|
io_expander1
|
||||||
|
.borrow_mut()
|
||||||
|
.service(&mut i2c_bus.borrow_mut())
|
||||||
|
.expect("I2C I/O expander #1 service failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(has_grabber)]
|
||||||
|
mod grabber {
|
||||||
|
use libasync::delay;
|
||||||
|
use libboard_artiq::grabber;
|
||||||
|
use libboard_zynq::time::Milliseconds;
|
||||||
|
use crate::GlobalTimer;
|
||||||
|
pub async fn grabber_thread(timer: GlobalTimer) {
|
||||||
|
let mut countdown = timer.countdown();
|
||||||
|
loop {
|
||||||
|
grabber::tick();
|
||||||
|
delay(&mut countdown, Milliseconds(200)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -114,31 +149,29 @@ pub fn main_core0() {
|
||||||
info!("gateware ident: {}", identifier_read(&mut [0; 64]));
|
info!("gateware ident: {}", identifier_read(&mut [0; 64]));
|
||||||
|
|
||||||
i2c::init();
|
i2c::init();
|
||||||
let i2c_bus = unsafe { (i2c::I2C_BUS).as_mut().unwrap() };
|
#[cfg(all(feature = "target_kasli_soc", has_drtio))]
|
||||||
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
|
||||||
let (mut io_expander0, mut io_expander1);
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
|
||||||
{
|
{
|
||||||
io_expander0 = io_expander::IoExpander::new(i2c_bus, 0).unwrap();
|
let i2c_bus = unsafe { (i2c::I2C_BUS).as_mut().unwrap() };
|
||||||
io_expander1 = io_expander::IoExpander::new(i2c_bus, 1).unwrap();
|
let mut io_expander0 = io_expander::IoExpander::new(i2c_bus, 0).unwrap();
|
||||||
|
let mut io_expander1 = io_expander::IoExpander::new(i2c_bus, 1).unwrap();
|
||||||
io_expander0
|
io_expander0
|
||||||
.init(i2c_bus)
|
.init(i2c_bus)
|
||||||
.expect("I2C I/O expander #0 initialization failed");
|
.expect("I2C I/O expander #0 initialization failed");
|
||||||
io_expander1
|
io_expander1
|
||||||
.init(i2c_bus)
|
.init(i2c_bus)
|
||||||
.expect("I2C I/O expander #1 initialization failed");
|
.expect("I2C I/O expander #1 initialization failed");
|
||||||
// Actively drive TX_DISABLE to false on SFP0..3
|
// Drive TX_DISABLE to false on SFP0..3
|
||||||
io_expander0.set_oe(i2c_bus, 0, 1 << 1).unwrap();
|
|
||||||
io_expander1.set_oe(i2c_bus, 0, 1 << 1).unwrap();
|
|
||||||
io_expander0.set_oe(i2c_bus, 1, 1 << 1).unwrap();
|
|
||||||
io_expander1.set_oe(i2c_bus, 1, 1 << 1).unwrap();
|
|
||||||
io_expander0.set(0, 1, false);
|
io_expander0.set(0, 1, false);
|
||||||
io_expander1.set(0, 1, false);
|
io_expander1.set(0, 1, false);
|
||||||
io_expander0.set(1, 1, false);
|
io_expander0.set(1, 1, false);
|
||||||
io_expander1.set(1, 1, false);
|
io_expander1.set(1, 1, false);
|
||||||
io_expander0.service(i2c_bus).unwrap();
|
io_expander0.service(i2c_bus).unwrap();
|
||||||
io_expander1.service(i2c_bus).unwrap();
|
io_expander1.service(i2c_bus).unwrap();
|
||||||
|
task::spawn(io_expanders_service(
|
||||||
|
RefCell::new(i2c_bus),
|
||||||
|
RefCell::new(io_expander0),
|
||||||
|
RefCell::new(io_expander1),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg = match Config::new() {
|
let cfg = match Config::new() {
|
||||||
|
@ -153,5 +186,8 @@ pub fn main_core0() {
|
||||||
|
|
||||||
task::spawn(report_async_rtio_errors());
|
task::spawn(report_async_rtio_errors());
|
||||||
|
|
||||||
|
#[cfg(has_grabber)]
|
||||||
|
task::spawn(grabber::grabber_thread(timer));
|
||||||
|
|
||||||
comms::main(timer, cfg);
|
comms::main(timer, cfg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ mod remote_moninj {
|
||||||
use libboard_artiq::drtioaux_async;
|
use libboard_artiq::drtioaux_async;
|
||||||
use crate::rtio_mgt::drtio;
|
use crate::rtio_mgt::drtio;
|
||||||
use log::error;
|
use log::error;
|
||||||
|
use libasync::delay;
|
||||||
|
|
||||||
pub async fn read_probe(aux_mutex: &Rc<Mutex<bool>>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, probe: i8) -> i64 {
|
pub async fn read_probe(aux_mutex: &Rc<Mutex<bool>>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, probe: i8) -> i64 {
|
||||||
let reply = drtio::aux_transact(aux_mutex, linkno, &drtioaux_async::Packet::MonitorRequest {
|
let reply = drtio::aux_transact(aux_mutex, linkno, &drtioaux_async::Packet::MonitorRequest {
|
||||||
|
@ -77,7 +78,7 @@ mod remote_moninj {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn inject(aux_mutex: &Rc<Mutex<bool>>, _timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8, value: i8) {
|
pub async fn inject(aux_mutex: &Rc<Mutex<bool>>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8, value: i8) {
|
||||||
let _lock = aux_mutex.lock();
|
let _lock = aux_mutex.lock();
|
||||||
drtioaux_async::send(linkno, &drtioaux_async::Packet::InjectionRequest {
|
drtioaux_async::send(linkno, &drtioaux_async::Packet::InjectionRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
|
@ -85,6 +86,9 @@ mod remote_moninj {
|
||||||
overrd: overrd as _,
|
overrd: overrd as _,
|
||||||
value: value as _
|
value: value as _
|
||||||
}).await.unwrap();
|
}).await.unwrap();
|
||||||
|
// give time for the satellite to process the request before releasing mutex
|
||||||
|
let mut countdown = timer.countdown();
|
||||||
|
delay(&mut countdown, Milliseconds(10)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_injection_status(aux_mutex: &Rc<Mutex<bool>>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8) -> i8 {
|
pub async fn read_injection_status(aux_mutex: &Rc<Mutex<bool>>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8) -> i8 {
|
||||||
|
|
|
@ -11,6 +11,7 @@ pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2;
|
||||||
pub const RTIO_O_STATUS_DESTINATION_UNREACHABLE: i32 = 4;
|
pub const RTIO_O_STATUS_DESTINATION_UNREACHABLE: i32 = 4;
|
||||||
pub const RTIO_I_STATUS_WAIT_EVENT: i32 = 1;
|
pub const RTIO_I_STATUS_WAIT_EVENT: i32 = 1;
|
||||||
pub const RTIO_I_STATUS_OVERFLOW: i32 = 2;
|
pub const RTIO_I_STATUS_OVERFLOW: i32 = 2;
|
||||||
|
#[allow(unused)]
|
||||||
pub const RTIO_I_STATUS_WAIT_STATUS: i32 = 4; // TODO
|
pub const RTIO_I_STATUS_WAIT_STATUS: i32 = 4; // TODO
|
||||||
pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: i32 = 8;
|
pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: i32 = 8;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ extern crate alloc;
|
||||||
|
|
||||||
use libboard_zynq::{i2c::I2c, timer::GlobalTimer, time::Milliseconds, print, println, mpcore, gic, stdio};
|
use libboard_zynq::{i2c::I2c, timer::GlobalTimer, time::Milliseconds, print, println, mpcore, gic, stdio};
|
||||||
use libsupport_zynq::ram;
|
use libsupport_zynq::ram;
|
||||||
|
#[cfg(has_grabber)]
|
||||||
|
use libboard_artiq::grabber;
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
use libboard_artiq::si5324;
|
use libboard_artiq::si5324;
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
@ -417,6 +419,8 @@ fn hardware_tick(ts: &mut u64, timer: &mut GlobalTimer) {
|
||||||
if now > ts_ms {
|
if now > ts_ms {
|
||||||
ts_ms = now + Milliseconds(200);
|
ts_ms = now + Milliseconds(200);
|
||||||
*ts = ts_ms.0;
|
*ts = ts_ms.0;
|
||||||
|
#[cfg(has_grabber)]
|
||||||
|
grabber::tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,11 +487,7 @@ pub extern fn main_core0() -> i32 {
|
||||||
io_expander1
|
io_expander1
|
||||||
.init(&mut i2c)
|
.init(&mut i2c)
|
||||||
.expect("I2C I/O expander #1 initialization failed");
|
.expect("I2C I/O expander #1 initialization failed");
|
||||||
// Actively drive TX_DISABLE to false on SFP0..3
|
// Drive TX_DISABLE to false on SFP0..3
|
||||||
io_expander0.set_oe(&mut i2c, 0, 1 << 1).unwrap();
|
|
||||||
io_expander1.set_oe(&mut i2c, 0, 1 << 1).unwrap();
|
|
||||||
io_expander0.set_oe(&mut i2c, 1, 1 << 1).unwrap();
|
|
||||||
io_expander1.set_oe(&mut i2c, 1, 1 << 1).unwrap();
|
|
||||||
io_expander0.set(0, 1, false);
|
io_expander0.set(0, 1, false);
|
||||||
io_expander1.set(0, 1, false);
|
io_expander1.set(0, 1, false);
|
||||||
io_expander0.set(1, 1, false);
|
io_expander0.set(1, 1, false);
|
||||||
|
@ -528,6 +528,16 @@ pub extern fn main_core0() -> i32 {
|
||||||
for mut rep in repeaters.iter_mut() {
|
for mut rep in repeaters.iter_mut() {
|
||||||
rep.service(&routing_table, rank, &mut timer);
|
rep.service(&routing_table, rank, &mut timer);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
{
|
||||||
|
io_expander0
|
||||||
|
.service(&mut i2c)
|
||||||
|
.expect("I2C I/O expander #0 service failed");
|
||||||
|
io_expander1
|
||||||
|
.service(&mut i2c)
|
||||||
|
.expect("I2C I/O expander #1 service failed");
|
||||||
|
}
|
||||||
|
|
||||||
hardware_tick(&mut hardware_tick_ts, &mut timer);
|
hardware_tick(&mut hardware_tick_ts, &mut timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,6 +559,15 @@ pub extern fn main_core0() -> i32 {
|
||||||
for mut rep in repeaters.iter_mut() {
|
for mut rep in repeaters.iter_mut() {
|
||||||
rep.service(&routing_table, rank, &mut timer);
|
rep.service(&routing_table, rank, &mut timer);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
{
|
||||||
|
io_expander0
|
||||||
|
.service(&mut i2c)
|
||||||
|
.expect("I2C I/O expander #0 service failed");
|
||||||
|
io_expander1
|
||||||
|
.service(&mut i2c)
|
||||||
|
.expect("I2C I/O expander #1 service failed");
|
||||||
|
}
|
||||||
hardware_tick(&mut hardware_tick_ts, &mut timer);
|
hardware_tick(&mut hardware_tick_ts, &mut timer);
|
||||||
if drtiosat_tsc_loaded() {
|
if drtiosat_tsc_loaded() {
|
||||||
info!("TSC loaded from uplink");
|
info!("TSC loaded from uplink");
|
||||||
|
|
Loading…
Reference in New Issue