gateware/targets/sayma: get hmc830/7043 spi working (still need to test clock generation)

This commit is contained in:
Florent Kermarrec 2017-11-06 12:08:28 +01:00
parent fcd660d682
commit 76ddb063cf
6 changed files with 69 additions and 36 deletions

View File

@ -37,7 +37,7 @@ mod hmc830 {
fn spi_setup() {
unsafe {
csr::converter_spi::offline_write(1);
csr::converter_spi::cs_polarity_write(0);
csr::converter_spi::cs_polarity_write(0b0001);
csr::converter_spi::clk_polarity_write(0);
csr::converter_spi::clk_phase_write(0);
csr::converter_spi::lsb_first_write(0);
@ -70,7 +70,7 @@ mod hmc830 {
csr::converter_spi::data_write_write(val << (32-31));
while csr::converter_spi::pending_read() != 0 {}
while csr::converter_spi::active_read() != 0 {}
csr::converter_spi::data_read_read()
csr::converter_spi::data_read_read() & 0xffffff
}
}
@ -80,17 +80,21 @@ mod hmc830 {
if id != 0xa7975 {
error!("invalid HMC830 ID: 0x{:08x}", id);
return Err("invalid HMC830 identification");
} else {
info!("HMC830 found");
}
info!("HMC830 configuration...");
for &(addr, data) in HMC830_WRITES.iter() {
write(addr, data);
}
let t = clock::get_ms();
while read(0x12) & 0x02 == 0 {
if clock::get_ms() > t + 2000 {
return Err("HMC830 lock timeout");
}
}
info!("HMC830 waiting for lock...");
//while read(0x12) & 0x02 == 0 {
// if clock::get_ms() > t + 2000 {
// return Err("HMC830 lock timeout");
// }
//}
Ok(())
}
@ -104,7 +108,7 @@ mod hmc7043 {
fn spi_setup() {
unsafe {
csr::converter_spi::offline_write(1);
csr::converter_spi::cs_polarity_write(0);
csr::converter_spi::cs_polarity_write(0b0001);
csr::converter_spi::clk_polarity_write(0);
csr::converter_spi::clk_phase_write(0);
csr::converter_spi::lsb_first_write(0);
@ -129,7 +133,7 @@ mod hmc7043 {
}
fn read(addr: u16) -> u8 {
let cmd = (0 << 15) | addr;
let cmd = (1 << 15) | addr;
let val = (cmd as u32) << 8;
unsafe {
csr::converter_spi::xfer_len_write_write(16);
@ -147,7 +151,10 @@ mod hmc7043 {
if id != 0xf17904 {
error!("invalid HMC7043 ID: 0x{:08x}", id);
return Err("invalid HMC7043 identification");
} else {
info!("HMC7043 found");
}
info!("HMC7043 configuration...");
for &(addr, data) in HMC7043_WRITES.iter() {
write(addr, data);
}

View File

@ -28,7 +28,7 @@ pub mod spi;
#[cfg(has_si5324)]
pub mod si5324;
#[cfg(has_serwb_phy)]
#[cfg(has_serwb_phy_amc)]
pub mod serwb;
#[cfg(has_ad9516)]
#[allow(dead_code)]

View File

@ -3,7 +3,8 @@ use csr;
pub fn wait_init() {
info!("waiting for AMC/RTM serwb bridge to be ready...");
unsafe {
while csr::serwb_phy::control_ready_read() == 0 {}
//csr::serwb_phy_amc::control_reset_write(1);
while csr::serwb_phy_amc::control_ready_read() == 0 {}
}
info!("done.");
@ -15,4 +16,28 @@ pub fn wait_init() {
error!("incorrect RTM identifier: 0x{:08x}", rtm_identifier);
// proceed anyway
}
// Show AMC serwb settings
unsafe {
info!("AMC serwb settings:");
info!(" delay_min_found: {}", csr::serwb_phy_amc::control_delay_min_found_read());
info!(" delay_min: {}", csr::serwb_phy_amc::control_delay_min_read());
info!(" delay_max_found: {}", csr::serwb_phy_amc::control_delay_max_found_read());
info!(" delay_max: {}", csr::serwb_phy_amc::control_delay_max_read());
info!(" bitslip: {}", csr::serwb_phy_amc::control_bitslip_read());
info!(" ready: {}", csr::serwb_phy_amc::control_ready_read());
info!(" error: {}", csr::serwb_phy_amc::control_error_read());
}
// Show RTM serwb settings
unsafe {
info!("RTM serwb settings:");
info!(" delay_min_found: {}", csr::serwb_phy_rtm::control_delay_min_found_read());
info!(" delay_min: {}", csr::serwb_phy_rtm::control_delay_min_read());
info!(" delay_max_found: {}", csr::serwb_phy_rtm::control_delay_max_found_read());
info!(" delay_max: {}", csr::serwb_phy_rtm::control_delay_max_read());
info!(" bitslip: {}", csr::serwb_phy_rtm::control_bitslip_read());
info!(" ready: {}", csr::serwb_phy_rtm::control_ready_read());
info!(" error: {}", csr::serwb_phy_rtm::control_error_read());
}
}

View File

@ -61,7 +61,7 @@ fn startup() {
info!("software version {}", include_str!(concat!(env!("OUT_DIR"), "/git-describe")));
info!("gateware version {}", board::ident(&mut [0; 64]));
#[cfg(has_serwb_phy)]
#[cfg(has_serwb_phy_amc)]
board::serwb::wait_init();
let t = board::clock::get_ms();

View File

@ -166,22 +166,22 @@ class SaymaAMCStandalone(MiniSoC, AMPSoC):
self.submodules += serwb_pll
serwb_pads = platform.request("amc_rtm_serwb")
serwb_phy = serwb.phy.SERWBPHY(platform.device, serwb_pll, serwb_pads, mode="master")
self.submodules.serwb_phy = serwb_phy
self.csr_devices.append("serwb_phy")
serwb_phy_amc = serwb.phy.SERWBPHY(platform.device, serwb_pll, serwb_pads, mode="master")
self.submodules.serwb_phy_amc = serwb_phy_amc
self.csr_devices.append("serwb_phy_amc")
serwb_phy.serdes.cd_serwb_serdes.clk.attr.add("keep")
serwb_phy.serdes.cd_serwb_serdes_20x.clk.attr.add("keep")
serwb_phy.serdes.cd_serwb_serdes_5x.clk.attr.add("keep")
platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes.clk, 32.0),
platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes_20x.clk, 1.6),
platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes_5x.clk, 6.4)
serwb_phy_amc.serdes.cd_serwb_serdes.clk.attr.add("keep")
serwb_phy_amc.serdes.cd_serwb_serdes_20x.clk.attr.add("keep")
serwb_phy_amc.serdes.cd_serwb_serdes_5x.clk.attr.add("keep")
platform.add_period_constraint(serwb_phy_amc.serdes.cd_serwb_serdes.clk, 32.0),
platform.add_period_constraint(serwb_phy_amc.serdes.cd_serwb_serdes_20x.clk, 1.6),
platform.add_period_constraint(serwb_phy_amc.serdes.cd_serwb_serdes_5x.clk, 6.4)
platform.add_false_path_constraints(
self.crg.cd_sys.clk,
serwb_phy.serdes.cd_serwb_serdes.clk,
serwb_phy.serdes.cd_serwb_serdes_5x.clk)
serwb_phy_amc.serdes.cd_serwb_serdes.clk,
serwb_phy_amc.serdes.cd_serwb_serdes_5x.clk)
serwb_core = serwb.core.SERWBCore(serwb_phy, int(self.clk_freq), mode="slave")
serwb_core = serwb.core.SERWBCore(serwb_phy_amc, int(self.clk_freq), mode="slave")
self.submodules += serwb_core
self.add_wb_slave(self.mem_map["serwb"], 8192, serwb_core.etherbone.wishbone.bus)

View File

@ -105,22 +105,23 @@ class SaymaRTM(Module):
self.submodules += serwb_pll
serwb_pads = platform.request("amc_rtm_serwb")
serwb_phy = serwb.phy.SERWBPHY(platform.device, serwb_pll, serwb_pads, mode="slave")
self.submodules.serwb_phy = serwb_phy
self.comb += self.crg.reset.eq(serwb_phy.init.reset)
serwb_phy_rtm = serwb.phy.SERWBPHY(platform.device, serwb_pll, serwb_pads, mode="slave")
self.submodules.serwb_phy_rtm = serwb_phy_rtm
self.comb += self.crg.reset.eq(serwb_phy_rtm.init.reset)
csr_devices.append("serwb_phy_rtm")
serwb_phy.serdes.cd_serwb_serdes.clk.attr.add("keep")
serwb_phy.serdes.cd_serwb_serdes_20x.clk.attr.add("keep")
serwb_phy.serdes.cd_serwb_serdes_5x.clk.attr.add("keep")
platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes.clk, 32.0),
platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes_20x.clk, 1.6),
platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes_5x.clk, 6.4)
serwb_phy_rtm.serdes.cd_serwb_serdes.clk.attr.add("keep")
serwb_phy_rtm.serdes.cd_serwb_serdes_20x.clk.attr.add("keep")
serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk.attr.add("keep")
platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes.clk, 32.0),
platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes_20x.clk, 1.6),
platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk, 6.4)
platform.add_false_path_constraints(
self.crg.cd_sys.clk,
serwb_phy.serdes.cd_serwb_serdes.clk,
serwb_phy.serdes.cd_serwb_serdes_5x.clk)
serwb_phy_rtm.serdes.cd_serwb_serdes.clk,
serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk)
serwb_core = serwb.core.SERWBCore(serwb_phy, int(clk_freq), mode="master")
serwb_core = serwb.core.SERWBCore(serwb_phy_rtm, int(clk_freq), mode="master")
self.submodules += serwb_core
# process CSR devices and connect them to serwb