forked from M-Labs/artiq
firmware: move i2c to libboard_misoc, enable IPv6 in bootloader, share network settings
This commit is contained in:
parent
1c5e749036
commit
8f76a3218e
|
@ -16,4 +16,4 @@ build_misoc = { path = "../libbuild_misoc" }
|
|||
byteorder = { version = "1.0", default-features = false }
|
||||
crc = { version = "1.7", default-features = false }
|
||||
board_misoc = { path = "../libboard_misoc", features = ["uart_console", "smoltcp"] }
|
||||
smoltcp = { version = "0.5.0", default-features = false, features = ["proto-ipv4", "socket-tcp"] }
|
||||
smoltcp = { version = "0.5.0", default-features = false, features = ["proto-ipv4", "proto-ipv6", "socket-tcp"] }
|
||||
|
|
|
@ -12,7 +12,7 @@ use crc::crc32;
|
|||
use byteorder::{ByteOrder, BigEndian};
|
||||
use board_misoc::{ident, cache, sdram, boot, mem as board_mem};
|
||||
#[cfg(has_ethmac)]
|
||||
use board_misoc::{clock, config, ethmac};
|
||||
use board_misoc::{clock, config, ethmac, net_settings};
|
||||
use board_misoc::uart_console::Console;
|
||||
|
||||
fn check_integrity() -> bool {
|
||||
|
@ -155,18 +155,6 @@ fn network_boot() {
|
|||
|
||||
println!("Initializing network...");
|
||||
|
||||
let eth_addr = match config::read_str("mac", |r| r.map(|s| s.parse())) {
|
||||
Ok(Ok(addr)) => addr,
|
||||
_ => EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01])
|
||||
};
|
||||
|
||||
let ip_addr = match config::read_str("ip", |r| r.map(|s| s.parse())) {
|
||||
Ok(Ok(addr)) => addr,
|
||||
_ => IpAddress::v4(192, 168, 1, 50)
|
||||
};
|
||||
|
||||
println!("Using MAC address {} and IP address {}", eth_addr, ip_addr);
|
||||
|
||||
let mut net_device = unsafe { ethmac::EthernetDevice::new() };
|
||||
net_device.reset_phy_if_any();
|
||||
|
||||
|
@ -174,12 +162,33 @@ fn network_boot() {
|
|||
let neighbor_cache =
|
||||
smoltcp::iface::NeighborCache::new(&mut neighbor_map[..]);
|
||||
let mut ip_addrs = [IpCidr::new(ip_addr, 0)];
|
||||
let mut interface =
|
||||
smoltcp::iface::EthernetInterfaceBuilder::new(net_device)
|
||||
let net_addresses = net_settings::get_adresses();
|
||||
println!("network addresses: {}", net_addresses);
|
||||
let mut interface = 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)
|
||||
];
|
||||
smoltcp::iface::EthernetInterfaceBuilder::new(net_device)
|
||||
.ethernet_addr(net_addresses.hardware_addr)
|
||||
.ip_addrs(ip_addrs)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.ethernet_addr(eth_addr)
|
||||
.ip_addrs(&mut ip_addrs[..])
|
||||
.finalize();
|
||||
.finalize()
|
||||
}
|
||||
None => {
|
||||
let ip_addrs = [
|
||||
IpCidr::new(net_addresses.ipv4_addr, 0),
|
||||
IpCidr::new(net_addresses.ipv6_ll_addr, 0)
|
||||
];
|
||||
smoltcp::iface::EthernetInterfaceBuilder::new(net_device)
|
||||
.ethernet_addr(net_addresses.hardware_addr)
|
||||
.ip_addrs(ip_addrs)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.finalize()
|
||||
}
|
||||
};
|
||||
|
||||
let mut socket_set_storage = [];
|
||||
let mut sockets =
|
||||
|
|
|
@ -17,7 +17,6 @@ extern crate proto_artiq;
|
|||
|
||||
pub mod pcr;
|
||||
|
||||
pub mod i2c;
|
||||
pub mod spi;
|
||||
|
||||
#[cfg(has_kernel_cpu)]
|
||||
|
@ -25,12 +24,8 @@ pub mod mailbox;
|
|||
#[cfg(has_kernel_cpu)]
|
||||
pub mod rpc_queue;
|
||||
|
||||
#[cfg(any(soc_platform = "kasli", has_si5324))]
|
||||
mod pca9548;
|
||||
#[cfg(has_si5324)]
|
||||
pub mod si5324;
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
pub mod i2c_eeprom;
|
||||
|
||||
#[cfg(has_slave_fpga_cfg)]
|
||||
pub mod slave_fpga;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
use i2c;
|
||||
|
||||
pub fn select(busno: u8, address: u8, channels: u8) -> Result<(), &'static str> {
|
||||
i2c::start(busno).unwrap();
|
||||
if !i2c::write(busno, address << 1)? {
|
||||
return Err("PCA9548 failed to ack write address")
|
||||
}
|
||||
if !i2c::write(busno, channels)? {
|
||||
return Err("PCA9548 failed to ack control word")
|
||||
}
|
||||
i2c::stop(busno).unwrap();
|
||||
Ok(())
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
use core::result;
|
||||
use board_misoc::clock;
|
||||
use board_misoc::{clock, i2c};
|
||||
#[cfg(not(si5324_soft_reset))]
|
||||
use board_misoc::csr;
|
||||
use i2c;
|
||||
use pca9548;
|
||||
|
||||
type Result<T> = result::Result<T, &'static str>;
|
||||
|
||||
|
@ -181,15 +179,15 @@ fn init() -> Result<()> {
|
|||
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
{
|
||||
pca9548::select(BUSNO, 0x70, 0)?;
|
||||
pca9548::select(BUSNO, 0x71, 1 << 3)?;
|
||||
i2c::pca9548_select(BUSNO, 0x70, 0)?;
|
||||
i2c::pca9548_select(BUSNO, 0x71, 1 << 3)?;
|
||||
}
|
||||
#[cfg(soc_platform = "sayma_amc")]
|
||||
pca9548::select(BUSNO, 0x70, 1 << 4)?;
|
||||
i2c::pca9548_select(BUSNO, 0x70, 1 << 4)?;
|
||||
#[cfg(soc_platform = "sayma_rtm")]
|
||||
pca9548::select(BUSNO, 0x77, 1 << 5)?;
|
||||
i2c::pca9548_select(BUSNO, 0x77, 1 << 5)?;
|
||||
#[cfg(soc_platform = "kc705")]
|
||||
pca9548::select(BUSNO, 0x74, 1 << 7)?;
|
||||
i2c::pca9548_select(BUSNO, 0x74, 1 << 7)?;
|
||||
|
||||
if ident()? != 0x0182 {
|
||||
return Err("Si5324 does not have expected product number");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[cfg(has_i2c)]
|
||||
mod imp {
|
||||
use board_misoc::{csr, clock};
|
||||
use super::super::{csr, clock};
|
||||
|
||||
const INVALID_BUS: &'static str = "Invalid I2C bus";
|
||||
|
||||
|
@ -46,7 +46,7 @@ mod imp {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
pub fn init() -> Result<(), &'static str> {
|
||||
for busno in 0..csr::CONFIG_I2C_BUS_COUNT {
|
||||
let busno = busno as u8;
|
||||
// Set SCL as output, and high level
|
||||
|
@ -61,8 +61,6 @@ mod imp {
|
|||
half_period();
|
||||
half_period();
|
||||
if !sda_i(busno) {
|
||||
warn!("SDA is stuck low on bus #{}, trying to unstuck", busno);
|
||||
|
||||
// Try toggling SCL a few times
|
||||
for _bit in 0..8 {
|
||||
scl_o(busno, false);
|
||||
|
@ -73,9 +71,10 @@ mod imp {
|
|||
}
|
||||
|
||||
if !sda_i(busno) {
|
||||
error!("SDA is stuck low on bus #{} and doesn't get unstuck", busno);
|
||||
return Err("SDA is stuck low and doesn't get unstuck");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn start(busno: u8) -> Result<(), &'static str> {
|
||||
|
@ -178,17 +177,30 @@ mod imp {
|
|||
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn pca9548_select(busno: u8, address: u8, channels: u8) -> Result<(), &'static str> {
|
||||
start(busno)?;
|
||||
if !write(busno, address << 1)? {
|
||||
return Err("PCA9548 failed to ack write address")
|
||||
}
|
||||
if !write(busno, channels)? {
|
||||
return Err("PCA9548 failed to ack control word")
|
||||
}
|
||||
stop(busno)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(has_i2c))]
|
||||
mod imp {
|
||||
const NO_I2C: &'static str = "No I2C support on this platform";
|
||||
pub fn init() {}
|
||||
pub fn init() { Err(NO_I2C) }
|
||||
pub fn start(_busno: u8) -> Result<(), &'static str> { Err(NO_I2C) }
|
||||
pub fn restart(_busno: u8) -> Result<(), &'static str> { Err(NO_I2C) }
|
||||
pub fn stop(_busno: u8) -> Result<(), &'static str> { Err(NO_I2C) }
|
||||
pub fn write(_busno: u8, _data: u8) -> Result<bool, &'static str> { Err(NO_I2C) }
|
||||
pub fn read(_busno: u8, _ack: bool) -> Result<u8, &'static str> { Err(NO_I2C) }
|
||||
pub fn pca9548_select(busno: u8, address: u8, channels: u8) -> Result<(), &'static str> { Err(NO_I2C) }
|
||||
}
|
||||
|
||||
pub use self::imp::*;
|
|
@ -1,5 +1,4 @@
|
|||
use i2c;
|
||||
use pca9548;
|
||||
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
const I2C_SWITCH0: u8 = 0x70;
|
||||
|
@ -25,8 +24,8 @@ impl EEPROM {
|
|||
|
||||
fn select(&self) -> Result<(), &'static str> {
|
||||
let mask: u16 = 1 << self.port;
|
||||
pca9548::select(self.busno, I2C_SWITCH0, mask as u8)?;
|
||||
pca9548::select(self.busno, I2C_SWITCH1, (mask >> 8) as u8)?;
|
||||
i2c::pca9548_select(self.busno, I2C_SWITCH0, mask as u8)?;
|
||||
i2c::pca9548_select(self.busno, I2C_SWITCH1, (mask >> 8) as u8)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -32,3 +32,8 @@ pub mod uart_console;
|
|||
pub mod uart_logger;
|
||||
#[cfg(all(has_ethmac, feature = "smoltcp"))]
|
||||
pub mod ethmac;
|
||||
pub mod i2c;
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
pub mod i2c_eeprom;
|
||||
#[cfg(all(has_ethmac, feature = "smoltcp"))]
|
||||
pub mod net_settings;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use core::fmt;
|
||||
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress};
|
||||
|
||||
use board_misoc::config;
|
||||
use config;
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
use board_artiq::i2c_eeprom;
|
||||
use i2c_eeprom;
|
||||
|
||||
|
||||
pub struct NetAddresses {
|
||||
|
@ -12,13 +14,22 @@ pub struct NetAddresses {
|
|||
pub ipv6_addr: Option<IpAddress>
|
||||
}
|
||||
|
||||
impl fmt::Display for NetAddresses {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "MAC:{} IPv4:{} IPv6-LL:{} IPv6:",
|
||||
self.hardware_addr, self.ipv4_addr, self.ipv6_ll_addr)?;
|
||||
match self.ipv6_addr {
|
||||
Some(addr) => write!(f, "{}", addr)?,
|
||||
None => write!(f, "no configured address")?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_adresses() -> NetAddresses {
|
||||
let hardware_addr;
|
||||
match config::read_str("mac", |r| r.map(|s| s.parse())) {
|
||||
Ok(Ok(addr)) => {
|
||||
hardware_addr = addr;
|
||||
info!("using MAC address {}", hardware_addr);
|
||||
}
|
||||
Ok(Ok(addr)) => hardware_addr = addr,
|
||||
_ => {
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
{
|
||||
|
@ -27,58 +38,34 @@ pub fn get_adresses() -> NetAddresses {
|
|||
eeprom.read_eui48()
|
||||
.map(|addr_buf| {
|
||||
let hardware_addr = EthernetAddress(addr_buf);
|
||||
info!("using MAC address {} from EEPROM", hardware_addr);
|
||||
hardware_addr
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
error!("failed to read MAC address from EEPROM: {}", e);
|
||||
let hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x21]);
|
||||
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
||||
hardware_addr
|
||||
});
|
||||
}
|
||||
#[cfg(soc_platform = "sayma_amc")]
|
||||
{
|
||||
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x11]);
|
||||
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
||||
}
|
||||
{ hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x11]); }
|
||||
#[cfg(soc_platform = "metlino")]
|
||||
{
|
||||
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x19]);
|
||||
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
||||
}
|
||||
{ hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x19]); }
|
||||
#[cfg(soc_platform = "kc705")]
|
||||
{
|
||||
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
|
||||
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
||||
}
|
||||
{ hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]); }
|
||||
}
|
||||
}
|
||||
|
||||
let ipv4_addr;
|
||||
match config::read_str("ip", |r| r.map(|s| s.parse())) {
|
||||
Ok(Ok(addr)) => {
|
||||
ipv4_addr = addr;
|
||||
info!("using IPv4 address {}", ipv4_addr);
|
||||
}
|
||||
Ok(Ok(addr)) => ipv4_addr = addr,
|
||||
_ => {
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
{
|
||||
ipv4_addr = IpAddress::v4(192, 168, 1, 70);
|
||||
}
|
||||
{ ipv4_addr = IpAddress::v4(192, 168, 1, 70); }
|
||||
#[cfg(soc_platform = "sayma_amc")]
|
||||
{
|
||||
ipv4_addr = IpAddress::v4(192, 168, 1, 60);
|
||||
}
|
||||
{ ipv4_addr = IpAddress::v4(192, 168, 1, 60); }
|
||||
#[cfg(soc_platform = "metlino")]
|
||||
{
|
||||
ipv4_addr = IpAddress::v4(192, 168, 1, 65);
|
||||
}
|
||||
{ ipv4_addr = IpAddress::v4(192, 168, 1, 65); }
|
||||
#[cfg(soc_platform = "kc705")]
|
||||
{
|
||||
ipv4_addr = IpAddress::v4(192, 168, 1, 50);
|
||||
}
|
||||
info!("using default IPv4 address {}", ipv4_addr);
|
||||
{ ipv4_addr = IpAddress::v4(192, 168, 1, 50); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,17 +75,10 @@ pub fn get_adresses() -> NetAddresses {
|
|||
((hardware_addr.0[2] as u16) << 8) | 0x00ff,
|
||||
0xfe00 | (hardware_addr.0[3] as u16),
|
||||
((hardware_addr.0[4] as u16) << 8) | (hardware_addr.0[5] as u16));
|
||||
info!("using IPv6 link-local address {}", ipv6_ll_addr);
|
||||
|
||||
let ipv6_addr = match config::read_str("ip6", |r| r.map(|s| s.parse())) {
|
||||
Ok(Ok(addr)) => {
|
||||
info!("using IPv6 configured address {}", addr);
|
||||
Some(addr)
|
||||
},
|
||||
_ => {
|
||||
info!("no IPv6 configured address");
|
||||
None
|
||||
}
|
||||
Ok(Ok(addr)) => Some(addr),
|
||||
_ => None
|
||||
};
|
||||
|
||||
NetAddresses {
|
|
@ -4,8 +4,8 @@ use sched::{Io, Mutex, Error as SchedError};
|
|||
use session::{kern_acknowledge, kern_send, Error};
|
||||
use rtio_mgt;
|
||||
use urc::Urc;
|
||||
use board_misoc::i2c as local_i2c;
|
||||
use board_artiq::drtio_routing;
|
||||
use board_artiq::i2c as local_i2c;
|
||||
use board_artiq::spi as local_spi;
|
||||
|
||||
#[cfg(has_drtio)]
|
||||
|
|
|
@ -30,7 +30,7 @@ use core::cell::RefCell;
|
|||
use core::convert::TryFrom;
|
||||
use smoltcp::wire::IpCidr;
|
||||
|
||||
use board_misoc::{csr, irq, ident, clock, boot, config};
|
||||
use board_misoc::{csr, irq, ident, clock, boot, config, net_settings};
|
||||
#[cfg(has_ethmac)]
|
||||
use board_misoc::ethmac;
|
||||
#[cfg(has_drtio)]
|
||||
|
@ -41,8 +41,6 @@ use proto_artiq::{mgmt_proto, moninj_proto, rpc_proto, session_proto, kernel_pro
|
|||
#[cfg(has_rtio_analyzer)]
|
||||
use proto_artiq::analyzer_proto;
|
||||
|
||||
mod net_settings;
|
||||
|
||||
mod rtio_clocking;
|
||||
mod rtio_mgt;
|
||||
|
||||
|
@ -122,7 +120,7 @@ fn startup() {
|
|||
|
||||
setup_log_levels();
|
||||
#[cfg(has_i2c)]
|
||||
board_artiq::i2c::init();
|
||||
board_misoc::i2c::init().expect("I2C initialization failed");
|
||||
sayma_hw_init();
|
||||
rtio_clocking::init();
|
||||
|
||||
|
@ -152,6 +150,7 @@ fn startup() {
|
|||
let neighbor_cache =
|
||||
smoltcp::iface::NeighborCache::new(alloc::btree_map::BTreeMap::new());
|
||||
let net_addresses = net_settings::get_adresses();
|
||||
info!("network addresses: {}", net_addresses);
|
||||
let mut interface = match net_addresses.ipv6_addr {
|
||||
Some(addr) => {
|
||||
let ip_addrs = [
|
||||
|
|
|
@ -8,8 +8,8 @@ extern crate board_misoc;
|
|||
extern crate board_artiq;
|
||||
|
||||
use core::convert::TryFrom;
|
||||
use board_misoc::{csr, irq, ident, clock, uart_logger};
|
||||
use board_artiq::{i2c, spi, si5324, drtioaux};
|
||||
use board_misoc::{csr, irq, ident, clock, uart_logger, i2c};
|
||||
use board_artiq::{spi, si5324, drtioaux};
|
||||
use board_artiq::drtio_routing;
|
||||
#[cfg(has_hmc830_7043)]
|
||||
use board_artiq::hmc830_7043;
|
||||
|
@ -451,7 +451,7 @@ pub extern fn main() -> i32 {
|
|||
#[cfg(has_slave_fpga_cfg)]
|
||||
board_artiq::slave_fpga::load().expect("cannot load RTM FPGA gateware");
|
||||
|
||||
i2c::init();
|
||||
i2c::init().expect("I2C initialization failed");
|
||||
si5324::setup(&SI5324_SETTINGS, si5324::Input::Ckin1).expect("cannot initialize Si5324");
|
||||
unsafe {
|
||||
csr::drtio_transceiver::stable_clkin_write(1);
|
||||
|
|
Loading…
Reference in New Issue