mirror of https://github.com/m-labs/artiq.git
firmware: support for multiple JESD DACs
This commit is contained in:
parent
a4144a07c4
commit
0a5904bbaa
|
@ -2,7 +2,7 @@ use csr;
|
||||||
use clock;
|
use clock;
|
||||||
use ad9154_reg;
|
use ad9154_reg;
|
||||||
|
|
||||||
fn spi_setup() {
|
fn spi_setup(dacno: u8) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::converter_spi::offline_write(1);
|
csr::converter_spi::offline_write(1);
|
||||||
csr::converter_spi::cs_polarity_write(0);
|
csr::converter_spi::cs_polarity_write(0);
|
||||||
|
@ -14,7 +14,7 @@ fn spi_setup() {
|
||||||
csr::converter_spi::clk_div_read_write(16);
|
csr::converter_spi::clk_div_read_write(16);
|
||||||
csr::converter_spi::xfer_len_write_write(24);
|
csr::converter_spi::xfer_len_write_write(24);
|
||||||
csr::converter_spi::xfer_len_read_write(0);
|
csr::converter_spi::xfer_len_read_write(0);
|
||||||
csr::converter_spi::cs_write(1 << csr::CONFIG_CONVERTER_SPI_DAC_CS);
|
csr::converter_spi::cs_write(1 << (csr::CONFIG_CONVERTER_SPI_FIRST_AD9154_CS + dacno as u32));
|
||||||
csr::converter_spi::offline_write(0);
|
csr::converter_spi::offline_write(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,39 +35,39 @@ fn read(addr: u16) -> u8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jesd_reset(rst: bool) {
|
fn jesd_reset(dacno: u8, rst: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::ad9154::jesd_jreset_write(if rst {1} else {0})
|
(csr::AD9154[dacno as usize].jesd_jreset_write)(if rst {1} else {0})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jesd_enable(en: bool) {
|
fn jesd_enable(dacno: u8, en: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::ad9154::jesd_control_enable_write(if en {1} else {0})
|
(csr::AD9154[dacno as usize].jesd_control_enable_write)(if en {1} else {0})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jesd_ready() -> bool {
|
fn jesd_ready(dacno: u8) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::ad9154::jesd_control_ready_read() != 0
|
(csr::AD9154[dacno as usize].jesd_control_ready_read)() != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jesd_prbs(en: bool) {
|
fn jesd_prbs(dacno: u8, en: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::ad9154::jesd_control_prbs_config_write(if en {1} else {0})
|
(csr::AD9154[dacno as usize].jesd_control_prbs_config_write)(if en {1} else {0})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jesd_stpl(en: bool) {
|
fn jesd_stpl(dacno: u8, en: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::ad9154::jesd_control_stpl_enable_write(if en {1} else {0})
|
(csr::AD9154[dacno as usize].jesd_control_stpl_enable_write)(if en {1} else {0})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jesd_jsync() -> bool {
|
fn jesd_jsync(dacno: u8) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::ad9154::jesd_control_jsync_read() != 0
|
(csr::AD9154[dacno as usize].jesd_control_jsync_read)() != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,19 +421,24 @@ fn monitor() {
|
||||||
write(ad9154_reg::IRQ_STATUS3, 0x00);
|
write(ad9154_reg::IRQ_STATUS3, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cfg() -> Result<(), &'static str> {
|
fn cfg(dacno: u8) -> Result<(), &'static str> {
|
||||||
jesd_enable(false);
|
spi_setup(dacno);
|
||||||
jesd_prbs(false);
|
// Release the JESD clock domain reset late, as we need to
|
||||||
jesd_stpl(false);
|
// set up clock chips before.
|
||||||
|
jesd_reset(dacno, false);
|
||||||
|
|
||||||
|
jesd_enable(dacno, false);
|
||||||
|
jesd_prbs(dacno, false);
|
||||||
|
jesd_stpl(dacno, false);
|
||||||
clock::spin_us(10000);
|
clock::spin_us(10000);
|
||||||
jesd_enable(true);
|
jesd_enable(dacno, true);
|
||||||
dac_setup()?;
|
dac_setup()?;
|
||||||
jesd_enable(false);
|
jesd_enable(dacno, false);
|
||||||
clock::spin_us(10000);
|
clock::spin_us(10000);
|
||||||
jesd_enable(true);
|
jesd_enable(dacno, true);
|
||||||
monitor();
|
monitor();
|
||||||
let t = clock::get_ms();
|
let t = clock::get_ms();
|
||||||
while !jesd_ready() {
|
while !jesd_ready(dacno) {
|
||||||
if clock::get_ms() > t + 200 {
|
if clock::get_ms() > t + 200 {
|
||||||
return Err("JESD ready timeout");
|
return Err("JESD ready timeout");
|
||||||
}
|
}
|
||||||
|
@ -442,7 +447,7 @@ fn cfg() -> Result<(), &'static str> {
|
||||||
if read(ad9154_reg::CODEGRPSYNCFLG) != 0x0f {
|
if read(ad9154_reg::CODEGRPSYNCFLG) != 0x0f {
|
||||||
return Err("bad CODEGRPSYNCFLG")
|
return Err("bad CODEGRPSYNCFLG")
|
||||||
}
|
}
|
||||||
if !jesd_jsync() {
|
if !jesd_jsync(dacno) {
|
||||||
return Err("bad SYNC")
|
return Err("bad SYNC")
|
||||||
}
|
}
|
||||||
if read(ad9154_reg::FRAMESYNCFLG) != 0x0f {
|
if read(ad9154_reg::FRAMESYNCFLG) != 0x0f {
|
||||||
|
@ -458,18 +463,10 @@ fn cfg() -> Result<(), &'static str> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() -> Result<(), &'static str> {
|
pub fn init() -> Result<(), &'static str> {
|
||||||
spi_setup();
|
for dacno in 0..csr::AD9154.len() {
|
||||||
|
let dacno = dacno as u8;
|
||||||
// Release the JESD clock domain reset late, as we need to
|
debug!("setting up DAC #{}", dacno);
|
||||||
// set up clock chips before.
|
cfg(dacno)?;
|
||||||
jesd_reset(false);
|
|
||||||
|
|
||||||
for i in 0..99 {
|
|
||||||
let outcome = cfg();
|
|
||||||
match outcome {
|
|
||||||
Ok(_) => return outcome,
|
|
||||||
Err(e) => warn!("config attempt #{} failed ({}), retrying", i, e)
|
|
||||||
}
|
}
|
||||||
}
|
Ok(())
|
||||||
cfg()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ fn spi_setup() {
|
||||||
csr::converter_spi::clk_div_read_write(16);
|
csr::converter_spi::clk_div_read_write(16);
|
||||||
csr::converter_spi::xfer_len_write_write(24);
|
csr::converter_spi::xfer_len_write_write(24);
|
||||||
csr::converter_spi::xfer_len_read_write(0);
|
csr::converter_spi::xfer_len_read_write(0);
|
||||||
csr::converter_spi::cs_write(1 << csr::CONFIG_CONVERTER_SPI_CLK_CS);
|
csr::converter_spi::cs_write(1 << csr::CONFIG_CONVERTER_SPI_AD9516_CS);
|
||||||
csr::converter_spi::offline_write(0);
|
csr::converter_spi::offline_write(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,12 +192,14 @@ class Phaser(MiniSoC, AMPSoC):
|
||||||
self.comb += ad9154_spi.en.eq(1)
|
self.comb += ad9154_spi.en.eq(1)
|
||||||
self.submodules.converter_spi = spi_csr.SPIMaster(ad9154_spi)
|
self.submodules.converter_spi = spi_csr.SPIMaster(ad9154_spi)
|
||||||
self.csr_devices.append("converter_spi")
|
self.csr_devices.append("converter_spi")
|
||||||
self.config["CONVERTER_SPI_DAC_CS"] = 0
|
|
||||||
self.config["CONVERTER_SPI_CLK_CS"] = 1
|
|
||||||
self.config["HAS_AD9516"] = None
|
self.config["HAS_AD9516"] = None
|
||||||
|
self.config["CONVERTER_SPI_AD9516_CS"] = 1
|
||||||
|
self.config["CONVERTER_SPI_FIRST_AD9154_CS"] = 0
|
||||||
|
|
||||||
self.submodules.ad9154 = AD9154(platform)
|
self.submodules.ad9154_0 = AD9154(platform)
|
||||||
self.csr_devices.append("ad9154")
|
self.csr_devices.append("ad9154_0")
|
||||||
|
self.config["HAS_AD9154"] = None
|
||||||
|
self.add_csr_group("ad9154", ["ad9154_0"])
|
||||||
|
|
||||||
rtio_channels = []
|
rtio_channels = []
|
||||||
|
|
||||||
|
@ -218,7 +220,7 @@ class Phaser(MiniSoC, AMPSoC):
|
||||||
|
|
||||||
self.config["RTIO_FIRST_SAWG_CHANNEL"] = len(rtio_channels)
|
self.config["RTIO_FIRST_SAWG_CHANNEL"] = len(rtio_channels)
|
||||||
rtio_channels.extend(rtio.Channel.from_phy(phy)
|
rtio_channels.extend(rtio.Channel.from_phy(phy)
|
||||||
for sawg in self.ad9154.sawgs
|
for sawg in self.ad9154_0.sawgs
|
||||||
for phy in sawg.phys)
|
for phy in sawg.phys)
|
||||||
|
|
||||||
self.config["HAS_RTIO_LOG"] = None
|
self.config["HAS_RTIO_LOG"] = None
|
||||||
|
@ -226,7 +228,7 @@ class Phaser(MiniSoC, AMPSoC):
|
||||||
rtio_channels.append(rtio.LogChannel())
|
rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
self.submodules.rtio_crg = _PhaserCRG(
|
self.submodules.rtio_crg = _PhaserCRG(
|
||||||
platform, self.ad9154.jesd.cd_jesd.clk)
|
platform, self.ad9154_0.jesd.cd_jesd.clk)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
||||||
self.csr_devices.append("rtio_core")
|
self.csr_devices.append("rtio_core")
|
||||||
|
@ -248,8 +250,8 @@ class Phaser(MiniSoC, AMPSoC):
|
||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.crg.cd_sys.clk, self.rtio_crg.cd_rtio.clk)
|
self.crg.cd_sys.clk, self.rtio_crg.cd_rtio.clk)
|
||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.crg.cd_sys.clk, self.ad9154.jesd.cd_jesd.clk)
|
self.crg.cd_sys.clk, self.ad9154_0.jesd.cd_jesd.clk)
|
||||||
for phy in self.ad9154.jesd.phys:
|
for phy in self.ad9154_0.jesd.phys:
|
||||||
platform.add_false_path_constraints(
|
platform.add_false_path_constraints(
|
||||||
self.crg.cd_sys.clk, phy.transmitter.cd_tx.clk)
|
self.crg.cd_sys.clk, phy.transmitter.cd_tx.clk)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue