Add SFP fibers support for satman #217
|
@ -0,0 +1,83 @@
|
||||||
|
use libboard_zynq;
|
||||||
|
|
||||||
|
pub static mut I2C_BUS: Option<libboard_zynq::i2c::I2c> = None;
|
||||||
|
|
||||||
|
pub fn start() -> Result<(), &'static str> {
|
||||||
|
unsafe {
|
||||||
|
if (&mut I2C_BUS).as_mut().unwrap().start().is_err() {
|
||||||
|
Err("I2C start failed")
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn restart() -> Result<(), &'static str> {
|
||||||
|
unsafe {
|
||||||
|
if (&mut I2C_BUS).as_mut().unwrap().restart().is_err() {
|
||||||
|
Err("I2C restart failed")
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop() -> Result<(), &'static str> {
|
||||||
|
unsafe {
|
||||||
|
if (&mut I2C_BUS).as_mut().unwrap().stop().is_err() {
|
||||||
|
Err("I2C stop failed")
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(data: i32) -> Result<bool, &'static str> {
|
||||||
|
unsafe {
|
||||||
|
match (&mut I2C_BUS).as_mut().unwrap().write(data as u8) {
|
||||||
|
Ok(r) =>Ok(r),
|
||||||
|
Err(_) => Err("I2C write failed"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(ack: bool) -> Result<i32, &'static str> {
|
||||||
|
unsafe {
|
||||||
|
match (&mut I2C_BUS).as_mut().unwrap().read(ack) {
|
||||||
|
Ok(r) => Ok(r as i32),
|
||||||
|
Err(_) => Err("I2C read failed"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pca954x_select(address: i32, channel: Option<u8>) -> Result<(), &'static str> {
|
||||||
|
unsafe {
|
||||||
|
if (&mut I2C_BUS).as_mut().unwrap().pca954x_select(address as u8, channel).is_err() {
|
||||||
|
Err("switch select failed")
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn switch_select(address: i32, mask: i32) -> Result<(), &'static str> {
|
||||||
|
let ch = match mask { //decode from mainline, PCA9548-centric API
|
||||||
|
0x00 => None,
|
||||||
|
0x01 => Some(0),
|
||||||
|
0x02 => Some(1),
|
||||||
|
0x04 => Some(2),
|
||||||
|
0x08 => Some(3),
|
||||||
|
0x10 => Some(4),
|
||||||
|
0x20 => Some(5),
|
||||||
|
0x40 => Some(6),
|
||||||
|
0x80 => Some(7),
|
||||||
|
_ => return Err("switch select supports only one channel")
|
||||||
|
};
|
||||||
|
pca954x_select(address, ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
let mut i2c = libboard_zynq::i2c::I2c::i2c0();
|
||||||
|
i2c.init().expect("I2C bus initialization failed");
|
||||||
|
unsafe { I2C_BUS = Some(i2c) };
|
||||||
|
}
|
|
@ -11,7 +11,6 @@ struct Registers {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IoExpander {
|
pub struct IoExpander {
|
||||||
busno: i32,
|
|
||||||
port: u8,
|
port: u8,
|
||||||
address: i32,
|
address: i32,
|
||||||
iodir: [u8; 2],
|
iodir: [u8; 2],
|
||||||
|
@ -27,7 +26,6 @@ impl IoExpander {
|
||||||
// Both expanders on SHARED I2C bus
|
// Both expanders on SHARED I2C bus
|
||||||
let mut io_expander = match index {
|
let mut io_expander = match index {
|
||||||
0 => IoExpander {
|
0 => IoExpander {
|
||||||
busno: 0,
|
|
||||||
port: 11,
|
port: 11,
|
||||||
address: 0x40,
|
address: 0x40,
|
||||||
iodir: [0xff; 2],
|
iodir: [0xff; 2],
|
||||||
|
@ -41,7 +39,6 @@ impl IoExpander {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
1 => IoExpander {
|
1 => IoExpander {
|
||||||
busno: 0,
|
|
||||||
port: 11,
|
port: 11,
|
||||||
address: 0x42,
|
address: 0x42,
|
||||||
iodir: [0xff; 2],
|
iodir: [0xff; 2],
|
||||||
|
@ -77,26 +74,26 @@ impl IoExpander {
|
||||||
|
|
||||||
fn select(&self) -> Result<(), &'static str> {
|
fn select(&self) -> Result<(), &'static str> {
|
||||||
let mask: u16 = 1 << self.port;
|
let mask: u16 = 1 << self.port;
|
||||||
i2c::switch_select(self.busno, 0x70, mask as u8 as i32);
|
i2c::switch_select(0x70, mask as u8 as i32)?;
|
||||||
i2c::switch_select(self.busno, 0x71, (mask >> 8) as u8 as i32);
|
i2c::switch_select(0x71, (mask >> 8) as u8 as i32)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, addr: u8, value: u8) -> Result<(), &'static str> {
|
fn write(&self, addr: u8, value: u8) -> Result<(), &'static str> {
|
||||||
i2c::start(self.busno);
|
i2c::start()?;
|
||||||
i2c::write(self.busno, self.address as i32);
|
i2c::write(self.address as i32)?;
|
||||||
i2c::write(self.busno, addr as i32);
|
i2c::write(addr as i32)?;
|
||||||
i2c::write(self.busno, value as i32);
|
i2c::write(value as i32)?;
|
||||||
i2c::stop(self.busno);
|
i2c::stop()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_ack(&self) -> Result<bool, &'static str> {
|
fn check_ack(&self) -> Result<bool, &'static str> {
|
||||||
// Check for ack from io expander
|
// Check for ack from io expander
|
||||||
self.select()?;
|
self.select()?;
|
||||||
i2c::start(self.busno);
|
i2c::start()?;
|
||||||
let ack = i2c::write(self.busno, self.address);
|
let ack = i2c::write(self.address)?;
|
||||||
i2c::stop(self.busno);
|
i2c::stop()?;
|
||||||
Ok(ack)
|
Ok(ack)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ pub mod drtioaux_async;
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
#[path = "../../../build/mem.rs"]
|
#[path = "../../../build/mem.rs"]
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
|
pub mod i2c;
|
||||||
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
pub mod io_expander;
|
||||||
|
|
||||||
use core::{cmp, str};
|
use core::{cmp, str};
|
||||||
|
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
use libboard_zynq;
|
|
||||||
use crate::artiq_raise;
|
|
||||||
|
|
||||||
pub static mut I2C_BUS: Option<libboard_zynq::i2c::I2c> = None;
|
|
||||||
|
|
||||||
pub extern fn start(busno: i32) {
|
|
||||||
if busno > 0 {
|
|
||||||
artiq_raise!("I2CError", "I2C bus could not be accessed");
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
if (&mut I2C_BUS).as_mut().unwrap().start().is_err() {
|
|
||||||
artiq_raise!("I2CError", "I2C start failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern fn restart(busno: i32) {
|
|
||||||
if busno > 0 {
|
|
||||||
artiq_raise!("I2CError", "I2C bus could not be accessed");
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
if (&mut I2C_BUS).as_mut().unwrap().restart().is_err() {
|
|
||||||
artiq_raise!("I2CError", "I2C restart failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern fn stop(busno: i32) {
|
|
||||||
if busno > 0 {
|
|
||||||
artiq_raise!("I2CError", "I2C bus could not be accessed");
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
if (&mut I2C_BUS).as_mut().unwrap().stop().is_err() {
|
|
||||||
artiq_raise!("I2CError", "I2C stop failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern fn write(busno: i32, data: i32) -> bool {
|
|
||||||
if busno > 0 {
|
|
||||||
artiq_raise!("I2CError", "I2C bus could not be accessed");
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
match (&mut I2C_BUS).as_mut().unwrap().write(data as u8) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(_) => artiq_raise!("I2CError", "I2C write failed"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern fn read(busno: i32, ack: bool) -> i32 {
|
|
||||||
if busno > 0 {
|
|
||||||
artiq_raise!("I2CError", "I2C bus could not be accessed");
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
match (&mut I2C_BUS).as_mut().unwrap().read(ack) {
|
|
||||||
Ok(r) => r as i32,
|
|
||||||
Err(_) => artiq_raise!("I2CError", "I2C read failed"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub extern fn switch_select(busno: i32, address: i32, mask: i32) {
|
|
||||||
if busno > 0 {
|
|
||||||
artiq_raise!("I2CError", "I2C bus could not be accessed");
|
|
||||||
}
|
|
||||||
let ch = match mask { //decode from mainline, PCA9548-centric API
|
|
||||||
0x00 => None,
|
|
||||||
0x01 => Some(0),
|
|
||||||
0x02 => Some(1),
|
|
||||||
0x04 => Some(2),
|
|
||||||
0x08 => Some(3),
|
|
||||||
0x10 => Some(4),
|
|
||||||
0x20 => Some(5),
|
|
||||||
0x40 => Some(6),
|
|
||||||
0x80 => Some(7),
|
|
||||||
_ => artiq_raise!("I2CError", "switch select supports only one channel")
|
|
||||||
};
|
|
||||||
unsafe {
|
|
||||||
if (&mut I2C_BUS).as_mut().unwrap().pca954x_select(address as u8, ch).is_err() {
|
|
||||||
artiq_raise!("I2CError", "switch select failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
let mut i2c = libboard_zynq::i2c::I2c::i2c0();
|
|
||||||
i2c.init().expect("I2C bus initialization failed");
|
|
||||||
unsafe { I2C_BUS = Some(i2c) };
|
|
||||||
}
|
|
|
@ -21,7 +21,7 @@ use nb;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
use libconfig::Config;
|
use libconfig::Config;
|
||||||
use libcortex_a9::l2c::enable_l2_cache;
|
use libcortex_a9::l2c::enable_l2_cache;
|
||||||
use libboard_artiq::{logger, identifier_read, pl};
|
use libboard_artiq::{logger, identifier_read, pl, i2c, io_expander};
|
||||||
|
|
||||||
const ASYNC_ERROR_COLLISION: u8 = 1 << 0;
|
const ASYNC_ERROR_COLLISION: u8 = 1 << 0;
|
||||||
const ASYNC_ERROR_BUSY: u8 = 1 << 1;
|
const ASYNC_ERROR_BUSY: u8 = 1 << 1;
|
||||||
|
@ -45,9 +45,6 @@ mod panic;
|
||||||
mod mgmt;
|
mod mgmt;
|
||||||
mod analyzer;
|
mod analyzer;
|
||||||
mod irq;
|
mod irq;
|
||||||
mod i2c;
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
|
||||||
mod io_expander;
|
|
||||||
|
|
||||||
static mut SEEN_ASYNC_ERRORS: u8 = 0;
|
static mut SEEN_ASYNC_ERRORS: u8 = 0;
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,12 @@ extern crate unwind;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use libboard_zynq::{i2c::I2c, timer::GlobalTimer, time::Milliseconds, print, println, mpcore, gic, stdio};
|
use libboard_zynq::{timer::GlobalTimer, time::Milliseconds, print, println, mpcore, gic, stdio};
|
||||||
use libsupport_zynq::ram;
|
use libsupport_zynq::ram;
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
use libboard_artiq::si5324;
|
use libboard_artiq::si5324;
|
||||||
use libboard_artiq::{pl::csr, drtio_routing, drtioaux, logger, identifier_read};
|
use libboard_artiq::{pl::csr, drtio_routing, drtioaux, logger,
|
||||||
|
identifier_read, i2c, io_expander};
|
||||||
use libcortex_a9::{spin_lock_yield, interrupt_handler, regs::{MPIDR, SP}, notify_spin_lock, asm, l2c::enable_l2_cache};
|
use libcortex_a9::{spin_lock_yield, interrupt_handler, regs::{MPIDR, SP}, notify_spin_lock, asm, l2c::enable_l2_cache};
|
||||||
use libregister::{RegisterW, RegisterR};
|
use libregister::{RegisterW, RegisterR};
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
@ -84,7 +85,7 @@ macro_rules! forward {
|
||||||
|
|
||||||
fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
_routing_table: &mut drtio_routing::RoutingTable, _rank: &mut u8,
|
_routing_table: &mut drtio_routing::RoutingTable, _rank: &mut u8,
|
||||||
packet: drtioaux::Packet, timer: &mut GlobalTimer, i2c: &mut I2c) -> Result<(), drtioaux::Error> {
|
packet: drtioaux::Packet, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
||||||
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
||||||
// and u16 otherwise; hence the `as _` conversion.
|
// and u16 otherwise; hence the `as _` conversion.
|
||||||
match packet {
|
match packet {
|
||||||
|
@ -253,22 +254,22 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
|
|
||||||
drtioaux::Packet::I2cStartRequest { destination: _destination, busno: _busno } => {
|
drtioaux::Packet::I2cStartRequest { destination: _destination, busno: _busno } => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
||||||
let succeeded = i2c.start().is_ok();
|
let succeeded = i2c::start().is_ok();
|
||||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cRestartRequest { destination: _destination, busno: _busno } => {
|
drtioaux::Packet::I2cRestartRequest { destination: _destination, busno: _busno } => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
||||||
let succeeded = i2c.restart().is_ok();
|
let succeeded = i2c::restart().is_ok();
|
||||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cStopRequest { destination: _destination, busno: _busno } => {
|
drtioaux::Packet::I2cStopRequest { destination: _destination, busno: _busno } => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
||||||
let succeeded = i2c.stop().is_ok();
|
let succeeded = i2c::stop().is_ok();
|
||||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cWriteRequest { destination: _destination, busno: _busno, data } => {
|
drtioaux::Packet::I2cWriteRequest { destination: _destination, busno: _busno, data } => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
||||||
match i2c.write(data) {
|
match i2c::write(data as i32) {
|
||||||
Ok(ack) => drtioaux::send(0,
|
Ok(ack) => drtioaux::send(0,
|
||||||
&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }),
|
&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }),
|
||||||
Err(_) => drtioaux::send(0,
|
Err(_) => drtioaux::send(0,
|
||||||
|
@ -277,9 +278,9 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cReadRequest { destination: _destination, busno: _busno, ack } => {
|
drtioaux::Packet::I2cReadRequest { destination: _destination, busno: _busno, ack } => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
||||||
match i2c.read(ack) {
|
match i2c::read(ack) {
|
||||||
Ok(data) => drtioaux::send(0,
|
Ok(data) => drtioaux::send(0,
|
||||||
&drtioaux::Packet::I2cReadReply { succeeded: true, data: data }),
|
&drtioaux::Packet::I2cReadReply { succeeded: true, data: data as u8 }),
|
||||||
Err(_) => drtioaux::send(0,
|
Err(_) => drtioaux::send(0,
|
||||||
&drtioaux::Packet::I2cReadReply { succeeded: false, data: 0xff })
|
&drtioaux::Packet::I2cReadReply { succeeded: false, data: 0xff })
|
||||||
}
|
}
|
||||||
|
@ -298,7 +299,7 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
0x80 => Some(7),
|
0x80 => Some(7),
|
||||||
_ => { return drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: false }); }
|
_ => { return drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: false }); }
|
||||||
};
|
};
|
||||||
let succeeded = i2c.pca954x_select(address, ch).is_ok();
|
let succeeded = i2c::pca954x_select(address as i32, ch).is_ok();
|
||||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,11 +340,11 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
|
|
||||||
fn process_aux_packets(repeaters: &mut [repeater::Repeater],
|
fn process_aux_packets(repeaters: &mut [repeater::Repeater],
|
||||||
routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8,
|
routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8,
|
||||||
timer: &mut GlobalTimer, i2c: &mut I2c) {
|
timer: &mut GlobalTimer) {
|
||||||
let result =
|
let result =
|
||||||
drtioaux::recv(0).and_then(|packet| {
|
drtioaux::recv(0).and_then(|packet| {
|
||||||
if let Some(packet) = packet {
|
if let Some(packet) = packet {
|
||||||
process_aux_packet(repeaters, routing_table, rank, packet, timer, i2c)
|
process_aux_packet(repeaters, routing_table, rank, packet, timer)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -447,11 +448,32 @@ pub extern fn main_core0() -> i32 {
|
||||||
|
|
||||||
ram::init_alloc_core0();
|
ram::init_alloc_core0();
|
||||||
|
|
||||||
let mut i2c = I2c::i2c0();
|
i2c::init();
|
||||||
i2c.init().expect("I2C initialization failed");
|
|
||||||
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
{
|
||||||
|
let (mut io_expander0, mut io_expander1) = (io_expander::IoExpander::new(0).unwrap(), io_expander::IoExpander::new(1).unwrap());
|
||||||
|
|||||||
|
io_expander0.init().expect("I2C I/O expander #0 initialization failed");
|
||||||
|
io_expander1.init().expect("I2C I/O expander #1 initialization failed");
|
||||||
|
|
||||||
|
// Actively drive TX_DISABLE to false on SFP0..3
|
||||||
|
io_expander0.set_oe(0, 1 << 1).unwrap();
|
||||||
|
io_expander0.set_oe(1, 1 << 1).unwrap();
|
||||||
|
io_expander1.set_oe(0, 1 << 1).unwrap();
|
||||||
|
io_expander1.set_oe(1, 1 << 1).unwrap();
|
||||||
|
io_expander0.set(0, 1, false);
|
||||||
|
io_expander0.set(1, 1, false);
|
||||||
|
io_expander1.set(0, 1, false);
|
||||||
|
io_expander1.set(1, 1, false);
|
||||||
|
io_expander0.service().unwrap();
|
||||||
|
io_expander1.service().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
|
{
|
||||||
|
let mut i2c = unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() };
|
||||||
si5324::setup(&mut i2c, &SI5324_SETTINGS, si5324::Input::Ckin1, &mut timer).expect("cannot initialize Si5324");
|
si5324::setup(&mut i2c, &SI5324_SETTINGS, si5324::Input::Ckin1, &mut timer).expect("cannot initialize Si5324");
|
||||||
|
}
|
||||||
|
|
||||||
timer.delay_us(100_000);
|
timer.delay_us(100_000);
|
||||||
info!("Switching SYS clocks...");
|
info!("Switching SYS clocks...");
|
||||||
|
@ -495,6 +517,7 @@ pub extern fn main_core0() -> i32 {
|
||||||
info!("uplink is up, switching to recovered clock");
|
info!("uplink is up, switching to recovered clock");
|
||||||
#[cfg(has_siphaser)]
|
#[cfg(has_siphaser)]
|
||||||
{
|
{
|
||||||
|
let mut i2c = unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() };
|
||||||
si5324::siphaser::select_recovered_clock(&mut i2c, true, &mut timer).expect("failed to switch clocks");
|
si5324::siphaser::select_recovered_clock(&mut i2c, true, &mut timer).expect("failed to switch clocks");
|
||||||
si5324::siphaser::calibrate_skew(&mut timer).expect("failed to calibrate skew");
|
si5324::siphaser::calibrate_skew(&mut timer).expect("failed to calibrate skew");
|
||||||
}
|
}
|
||||||
|
@ -505,7 +528,7 @@ pub extern fn main_core0() -> i32 {
|
||||||
|
|
||||||
while drtiosat_link_rx_up() {
|
while drtiosat_link_rx_up() {
|
||||||
drtiosat_process_errors();
|
drtiosat_process_errors();
|
||||||
process_aux_packets(&mut repeaters, &mut routing_table, &mut rank, &mut timer, &mut i2c);
|
process_aux_packets(&mut repeaters, &mut routing_table, &mut rank, &mut timer);
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
for mut rep in repeaters.iter_mut() {
|
for mut rep in repeaters.iter_mut() {
|
||||||
rep.service(&routing_table, rank, &mut timer);
|
rep.service(&routing_table, rank, &mut timer);
|
||||||
|
@ -529,8 +552,11 @@ pub extern fn main_core0() -> i32 {
|
||||||
drtiosat_tsc_loaded();
|
drtiosat_tsc_loaded();
|
||||||
info!("uplink is down, switching to local oscillator clock");
|
info!("uplink is down, switching to local oscillator clock");
|
||||||
#[cfg(has_siphaser)]
|
#[cfg(has_siphaser)]
|
||||||
|
{
|
||||||
|
let mut i2c = unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() };
|
||||||
si5324::siphaser::select_recovered_clock(&mut i2c, false, &mut timer).expect("failed to switch clocks");
|
si5324::siphaser::select_recovered_clock(&mut i2c, false, &mut timer).expect("failed to switch clocks");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
Loading…
Reference in New Issue
I doubt the & and * are necessary here.
& makes a slice from array (to make it iterable)
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6f1f8688caff98619cc0d08dd6d99a27
https://github.com/rust-lang/rust/issues/84837
Doesn't seem relevant to this case?
Maybe the link is not really relevant, but the compiler output is
Seems to be a peculiar issue with the particular compiler version we use here. What was the problem with 0..2 that you had written earlier?
0..2 may seem be confusing, because only 0 and 1 are used, from my point of view
You can expect developers to know range boundaries.
There's also the
0..=1
syntax...