forked from M-Labs/artiq
1
0
Fork 0

kasli: integrate WRPLL

This commit is contained in:
Sebastien Bourdeauducq 2020-05-07 21:34:02 +08:00
parent 60e5f1c18e
commit 4e9a529e5a
4 changed files with 65 additions and 18 deletions

View File

@ -175,7 +175,10 @@ mod si549 {
use board_misoc::clock; use board_misoc::clock;
use super::i2c; use super::i2c;
#[cfg(any(soc_platform = "metlino", soc_platform = "sayma_amc", soc_platform = "sayma_rtm"))]
pub const ADDRESS: u8 = 0x55; pub const ADDRESS: u8 = 0x55;
#[cfg(soc_platform = "kasli")]
pub const ADDRESS: u8 = 0x67;
pub fn write(dcxo: i2c::Dcxo, reg: u8, val: u8) -> Result<(), &'static str> { pub fn write(dcxo: i2c::Dcxo, reg: u8, val: u8) -> Result<(), &'static str> {
i2c::start(dcxo); i2c::start(dcxo);

View File

@ -6,6 +6,7 @@ pub struct IoExpander {
port: u8, port: u8,
address: u8, address: u8,
virtual_led_mapping: &'static [(u8, u8, u8)], virtual_led_mapping: &'static [(u8, u8, u8)],
iodir: [u8; 2],
out_current: [u8; 2], out_current: [u8; 2],
out_target: [u8; 2], out_target: [u8; 2],
} }
@ -22,6 +23,7 @@ impl IoExpander {
port: 11, port: 11,
address: 0x40, address: 0x40,
virtual_led_mapping: &VIRTUAL_LED_MAPPING0, virtual_led_mapping: &VIRTUAL_LED_MAPPING0,
iodir: [0xff; 2],
out_current: [0; 2], out_current: [0; 2],
out_target: [0; 2], out_target: [0; 2],
}, },
@ -30,6 +32,7 @@ impl IoExpander {
port: 11, port: 11,
address: 0x42, address: 0x42,
virtual_led_mapping: &VIRTUAL_LED_MAPPING1, virtual_led_mapping: &VIRTUAL_LED_MAPPING1,
iodir: [0xff; 2],
out_current: [0; 2], out_current: [0; 2],
out_target: [0; 2], out_target: [0; 2],
}, },
@ -54,15 +57,19 @@ impl IoExpander {
Ok(()) Ok(())
} }
fn update_iodir(&self) -> Result<(), &'static str> {
self.write(0x00, self.iodir[0])?;
self.write(0x01, self.iodir[1])?;
Ok(())
}
pub fn init(&mut self) -> Result<(), &'static str> { pub fn init(&mut self) -> Result<(), &'static str> {
self.select()?; self.select()?;
let mut iodir = [0xffu8; 2];
for (_led, port, bit) in self.virtual_led_mapping.iter() { for (_led, port, bit) in self.virtual_led_mapping.iter() {
iodir[*port as usize] &= !(1 << *bit); self.iodir[*port as usize] &= !(1 << *bit);
} }
self.write(0x00, iodir[0])?; self.update_iodir()?;
self.write(0x01, iodir[1])?;
self.out_current[0] = 0x00; self.out_current[0] = 0x00;
self.write(0x12, 0x00)?; self.write(0x12, 0x00)?;
@ -71,6 +78,12 @@ impl IoExpander {
Ok(()) Ok(())
} }
pub fn set_oe(&mut self, port: u8, outputs: u8) -> Result<(), &'static str> {
self.iodir[port as usize] &= !outputs;
self.update_iodir()?;
Ok(())
}
pub fn set(&mut self, port: u8, bit: u8, high: bool) { pub fn set(&mut self, port: u8, bit: u8, high: bool) {
if high { if high {
self.out_target[port as usize] |= 1 << bit; self.out_target[port as usize] |= 1 << bit;

View File

@ -464,6 +464,17 @@ pub extern fn main() -> i32 {
io_expander1 = board_misoc::io_expander::IoExpander::new(1); io_expander1 = board_misoc::io_expander::IoExpander::new(1);
io_expander0.init().expect("I2C I/O expander #0 initialization failed"); io_expander0.init().expect("I2C I/O expander #0 initialization failed");
io_expander1.init().expect("I2C I/O expander #1 initialization failed"); io_expander1.init().expect("I2C I/O expander #1 initialization failed");
#[cfg(has_wrpll)]
{
io_expander0.set_oe(1, 1 << 7).unwrap();
io_expander0.set(1, 7, true);
io_expander0.service().unwrap();
io_expander1.set_oe(0, 1 << 7).unwrap();
io_expander1.set_oe(1, 1 << 7).unwrap();
io_expander1.set(0, 7, true);
io_expander1.set(1, 7, true);
io_expander1.service().unwrap();
}
} }
#[cfg(has_si5324)] #[cfg(has_si5324)]

View File

@ -20,6 +20,7 @@ from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, edge_counter
from artiq.gateware import eem from artiq.gateware import eem
from artiq.gateware.drtio.transceiver import gtp_7series from artiq.gateware.drtio.transceiver import gtp_7series
from artiq.gateware.drtio.siphaser import SiPhaser7Series from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.wrpll import WRPLL, DDMTDSamplerGTP
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import * from artiq.gateware.drtio import *
from artiq.build_soc import * from artiq.build_soc import *
@ -452,7 +453,7 @@ class SatelliteBase(BaseSoC):
} }
mem_map.update(BaseSoC.mem_map) mem_map.update(BaseSoC.mem_map)
def __init__(self, rtio_clk_freq=125e6, enable_sata=False, **kwargs): def __init__(self, rtio_clk_freq=125e6, enable_sata=False, *, with_wrpll=False, **kwargs):
BaseSoC.__init__(self, BaseSoC.__init__(self,
cpu_type="or1k", cpu_type="or1k",
sdram_controller_type="minicon", sdram_controller_type="minicon",
@ -556,24 +557,38 @@ class SatelliteBase(BaseSoC):
self.add_memory_group("drtioaux_mem", drtioaux_memory_group) self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
self.add_csr_group("drtiorep", drtiorep_csr_group) self.add_csr_group("drtiorep", drtiorep_csr_group)
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
self.submodules.siphaser = SiPhaser7Series(
si5324_clkin=platform.request("cdr_clk") if platform.hw_rev == "v2.0"
else platform.request("si5324_clkin"),
rx_synchronizer=self.rx_synchronizer,
ref_clk=self.crg.clk125_div2, ref_div2=True,
rtio_clk_freq=rtio_clk_freq)
platform.add_false_path_constraints(
self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output)
self.csr_devices.append("siphaser")
i2c = self.platform.request("i2c") i2c = self.platform.request("i2c")
self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda])
self.csr_devices.append("i2c") self.csr_devices.append("i2c")
self.config["I2C_BUS_COUNT"] = 1 self.config["I2C_BUS_COUNT"] = 1
self.config["HAS_SI5324"] = None
self.config["SI5324_SOFT_RESET"] = None
rtio_clk_period = 1e9/rtio_clk_freq rtio_clk_period = 1e9/rtio_clk_freq
self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6)
if with_wrpll:
self.submodules.wrpll_sampler = DDMTDSamplerGTP(
self.drtio_transceiver,
platform.request("cdr_clk_clean_fabric"))
self.submodules.wrpll = WRPLL(
helper_clk_pads=platform.request("ddmtd_helper_clk"),
main_dcxo_i2c=platform.request("ddmtd_main_dcxo_i2c"),
helper_dxco_i2c=platform.request("ddmtd_helper_dcxo_i2c"),
ddmtd_inputs=self.wrpll_sampler)
self.csr_devices.append("wrpll")
platform.add_period_constraint(self.wrpll.cd_helper.clk, rtio_clk_period*0.99)
platform.add_false_path_constraints(self.crg.cd_sys.clk, self.wrpll.cd_helper.clk)
else:
self.submodules.siphaser = SiPhaser7Series(
si5324_clkin=platform.request("cdr_clk") if platform.hw_rev == "v2.0"
else platform.request("si5324_clkin"),
rx_synchronizer=self.rx_synchronizer,
ref_clk=self.crg.clk125_div2, ref_div2=True,
rtio_clk_freq=rtio_clk_freq)
platform.add_false_path_constraints(
self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output)
self.csr_devices.append("siphaser")
self.config["HAS_SI5324"] = None
self.config["SI5324_SOFT_RESET"] = None
gtp = self.drtio_transceiver.gtps[0] gtp = self.drtio_transceiver.gtps[0]
platform.add_period_constraint(gtp.txoutclk, rtio_clk_period) platform.add_period_constraint(gtp.txoutclk, rtio_clk_period)
platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period)
@ -658,15 +673,20 @@ def main():
parser.add_argument("-V", "--variant", default="tester", parser.add_argument("-V", "--variant", default="tester",
help="variant: {} (default: %(default)s)".format( help="variant: {} (default: %(default)s)".format(
"/".join(sorted(VARIANTS.keys())))) "/".join(sorted(VARIANTS.keys()))))
parser.add_argument("--with-wrpll", default=False, action="store_true")
args = parser.parse_args() args = parser.parse_args()
argdict = dict()
if args.with_wrpll:
argdict["with_wrpll"] = True
variant = args.variant.lower() variant = args.variant.lower()
try: try:
cls = VARIANTS[variant] cls = VARIANTS[variant]
except KeyError: except KeyError:
raise SystemExit("Invalid variant (-V/--variant)") raise SystemExit("Invalid variant (-V/--variant)")
soc = cls(**soc_kasli_argdict(args)) soc = cls(**soc_kasli_argdict(args), **argdict)
build_artiq_soc(soc, builder_argdict(args)) build_artiq_soc(soc, builder_argdict(args))