Soft panic for RTIO PLL reasons #199

Merged
sb10q merged 16 commits from mwojcik/artiq-zynq:pll_error into master 2022-10-21 17:56:34 +08:00
4 changed files with 69 additions and 42 deletions
Showing only changes of commit 0e6bf61034 - Show all commits

View File

@ -11,7 +11,6 @@ from migen_axi.integration.soc_core import SoCCore
from migen_axi.platforms import kasli_soc
from misoc.interconnect.csr import *
from misoc.integration import cpu_interface
from misoc.cores import gpio
from artiq.coredevice import jsondesc
from artiq.gateware import rtio, eem_7series

View File

@ -17,6 +17,8 @@ use libboard_zynq::{
},
timer::GlobalTimer,
};
#[cfg(feature = "target_kasli_soc")]
use libboard_zynq::error_led::ErrorLED;
use libcortex_a9::{semaphore::Semaphore, mutex::Mutex, sync_channel::{Sender, Receiver}};
use futures::{select_biased, future::FutureExt};
use libasync::{smoltcp::{Sockets, TcpStream}, task};
@ -490,3 +492,59 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
Instant::from_millis(timer.get_time().0 as i32)
});
}
pub fn soft_panic_setup(timer: GlobalTimer, cfg: Config) {
let net_addresses = net_settings::get_addresses(&cfg);
info!("network addresses: {}", net_addresses);
error!("There has been an error configuring the device. Only mgmt interface will be available.");
#[cfg(feature = "target_kasli_soc")]
{
let mut err_led = ErrorLED::error_led();
err_led.toggle(true);
}
let eth = zynq::eth::Eth::eth0(net_addresses.hardware_addr.0.clone());
const RX_LEN: usize = 64;
// Number of transmission buffers (minimum is two because with
// one, duplicate packet transmission occurs)
const TX_LEN: usize = 64;
let eth = eth.start_rx(RX_LEN);
let mut eth = eth.start_tx(TX_LEN);
let neighbor_cache = NeighborCache::new(alloc::collections::BTreeMap::new());
let mut iface = match net_addresses.ipv6_addr {
Some(addr) => {
let ip_addrs = [
IpCidr::new(net_addresses.ipv4_addr, 0),
IpCidr::new(net_addresses.ipv6_ll_addr, 0),
IpCidr::new(addr, 0)
];
EthernetInterfaceBuilder::new(&mut eth)
.ethernet_addr(net_addresses.hardware_addr)
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.finalize()
}
None => {
let ip_addrs = [
IpCidr::new(net_addresses.ipv4_addr, 0),
IpCidr::new(net_addresses.ipv6_ll_addr, 0)
];
EthernetInterfaceBuilder::new(&mut eth)
.ethernet_addr(net_addresses.hardware_addr)
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.finalize()
}
};
Sockets::init(32);
mgmt::start(cfg);
Sockets::run(&mut iface, || {
Instant::from_millis(timer.get_time().0 as i32)
});
}

View File

@ -120,10 +120,10 @@ pub fn main_core0() {
Config::new_dummy()
}
};
rtio_clocking::init(&mut timer, &cfg);
task::spawn(report_async_rtio_errors());
comms::main(timer, cfg);
match rtio_clocking::init(&mut timer, &cfg) {
Ok(()) => { comms::main(timer, cfg); }
Err(_) => { comms::soft_panic_setup(timer, cfg)}
};
}

View File

@ -1,18 +1,14 @@
use log::{info, warn, error};
use libboard_zynq::timer::GlobalTimer;
use embedded_hal::blocking::delay::DelayMs;
use libasync::task;
use libconfig::Config;
use libboard_artiq::pl;
#[cfg(feature = "target_kasli_soc")]
use libboard_zynq::error_led::ErrorLED;
#[cfg(has_si5324)]
use libboard_zynq::i2c::I2c;
#[cfg(has_si5324)]
use crate::i2c;
#[cfg(has_si5324)]
use libboard_artiq::si5324;
use crate::mgmt;
#[derive(Debug, PartialEq, Copy, Clone)]
#[allow(non_camel_case_types)]
@ -71,7 +67,7 @@ fn get_rtio_clock_cfg(cfg: &Config) -> RtioClock {
}
fn init_rtio(timer: &mut GlobalTimer, _clk: RtioClock) -> Result<()> {
fn init_rtio(timer: &mut GlobalTimer, _clk: RtioClock) -> Result<(), &'static str> {
#[cfg(has_rtio_crg_clock_sel)]
let clock_sel = match _clk {
RtioClock::Ext0_Bypass => {
@ -123,7 +119,7 @@ fn init_drtio(timer: &mut GlobalTimer)
}
#[cfg(has_si5324)]
fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) -> Result<()> {
fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) -> Result<(), &'static str> {
let (si5324_settings, si5324_ref_input) = match clk {
RtioClock::Ext0_Synth0_10to125 => { // 125 MHz output from 10 MHz CLKINx reference, 504 Hz BW
info!("using 10MHz reference to make 125MHz RTIO clock with PLL");
@ -241,47 +237,21 @@ fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) -> Resul
si5324::setup(i2c, &si5324_settings, si5324_ref_input, timer)
}
pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
pub fn init(timer: &mut GlobalTimer, cfg: &Config) -> Result<(), &'static str> {
let clk = get_rtio_clock_cfg(cfg);
#[cfg(has_si5324)]
{
let i2c = unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() };
let si5324_ext_input = si5324::Input::Ckin1;
let res = match clk {
match clk {
RtioClock::Ext0_Bypass => si5324::bypass(i2c, si5324_ext_input, timer),
_ => setup_si5324(i2c, timer, clk),
}
if res.is_err() {
soft_panic();
}
}?;
}
#[cfg(has_drtio)]
init_drtio(timer);
init_rtio(timer, clk)?;
if init_rtio(timer, clk).is_err() {
soft_panic();
}
}
fn soft_panic() {
error!("Error setting up RTIO clocking. Only mgmt interface will be available.");
// start mgmt service but nothing else
let cfg = match Config::new() {
Ok(cfg) => cfg,
Err(_) => Config::new_dummy()
};
mgmt::start(cfg);
#[cfg(feature = "target_kasli_soc")]
{
let mut err_led = ErrorLED::error_led();
err_led.toggle(true);
}
loop {
task::block_on(task::r#yield());
}
Ok(())
}