Soft panic for RTIO PLL reasons #199
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
});
|
||||
}
|
|
@ -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)}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
Loading…
Reference in New Issue
Why does it disable the LED?
getting eth settings sets up I2C to communicate with the ethernet controller;
I2C setup also resets GPIO:
https://git.m-labs.hk/M-Labs/zynq-rs/src/branch/master/libboard_zynq/src/i2c/mod.rs#L57
and I2C GPIO (MIO 33, 50, 51) is in the same bank as the error led (MIO 37); so resetting the entire port again causes the LED to go off.
Okay I see. Maybe make the comment a bit more clear (e.g. "we reinitialized the GPIO controller, so only now can we turn on the error LED")
Also, the non-mgmt panic handler should also turn on the LED to make sure.