From 8f76a3218e48ffc70b6da31f73c941076ebe0d6f Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 21 Oct 2019 12:58:52 +0800 Subject: [PATCH] firmware: move i2c to libboard_misoc, enable IPv6 in bootloader, share network settings --- artiq/firmware/bootloader/Cargo.toml | 2 +- artiq/firmware/bootloader/main.rs | 45 ++++++----- artiq/firmware/libboard_artiq/lib.rs | 5 -- artiq/firmware/libboard_artiq/pca9548.rs | 13 ---- artiq/firmware/libboard_artiq/si5324.rs | 14 ++-- .../{libboard_artiq => libboard_misoc}/i2c.rs | 24 ++++-- .../i2c_eeprom.rs | 5 +- artiq/firmware/libboard_misoc/lib.rs | 5 ++ .../net_settings.rs | 74 +++++++------------ artiq/firmware/runtime/kern_hwreq.rs | 2 +- artiq/firmware/runtime/main.rs | 7 +- artiq/firmware/satman/main.rs | 6 +- 12 files changed, 93 insertions(+), 109 deletions(-) delete mode 100644 artiq/firmware/libboard_artiq/pca9548.rs rename artiq/firmware/{libboard_artiq => libboard_misoc}/i2c.rs (89%) rename artiq/firmware/{libboard_artiq => libboard_misoc}/i2c_eeprom.rs (91%) rename artiq/firmware/{runtime => libboard_misoc}/net_settings.rs (51%) diff --git a/artiq/firmware/bootloader/Cargo.toml b/artiq/firmware/bootloader/Cargo.toml index 2a43b72f5..aed6df31b 100644 --- a/artiq/firmware/bootloader/Cargo.toml +++ b/artiq/firmware/bootloader/Cargo.toml @@ -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"] } diff --git a/artiq/firmware/bootloader/main.rs b/artiq/firmware/bootloader/main.rs index fc084d5e4..545e3a73c 100644 --- a/artiq/firmware/bootloader/main.rs +++ b/artiq/firmware/bootloader/main.rs @@ -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 = diff --git a/artiq/firmware/libboard_artiq/lib.rs b/artiq/firmware/libboard_artiq/lib.rs index ce0757427..9a4e727b2 100644 --- a/artiq/firmware/libboard_artiq/lib.rs +++ b/artiq/firmware/libboard_artiq/lib.rs @@ -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; diff --git a/artiq/firmware/libboard_artiq/pca9548.rs b/artiq/firmware/libboard_artiq/pca9548.rs deleted file mode 100644 index a69d72ed7..000000000 --- a/artiq/firmware/libboard_artiq/pca9548.rs +++ /dev/null @@ -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(()) -} diff --git a/artiq/firmware/libboard_artiq/si5324.rs b/artiq/firmware/libboard_artiq/si5324.rs index d02bec693..68005131f 100644 --- a/artiq/firmware/libboard_artiq/si5324.rs +++ b/artiq/firmware/libboard_artiq/si5324.rs @@ -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 = result::Result; @@ -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"); diff --git a/artiq/firmware/libboard_artiq/i2c.rs b/artiq/firmware/libboard_misoc/i2c.rs similarity index 89% rename from artiq/firmware/libboard_artiq/i2c.rs rename to artiq/firmware/libboard_misoc/i2c.rs index d13dc32ce..b816c4921 100644 --- a/artiq/firmware/libboard_artiq/i2c.rs +++ b/artiq/firmware/libboard_misoc/i2c.rs @@ -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 { Err(NO_I2C) } pub fn read(_busno: u8, _ack: bool) -> Result { Err(NO_I2C) } + pub fn pca9548_select(busno: u8, address: u8, channels: u8) -> Result<(), &'static str> { Err(NO_I2C) } } pub use self::imp::*; diff --git a/artiq/firmware/libboard_artiq/i2c_eeprom.rs b/artiq/firmware/libboard_misoc/i2c_eeprom.rs similarity index 91% rename from artiq/firmware/libboard_artiq/i2c_eeprom.rs rename to artiq/firmware/libboard_misoc/i2c_eeprom.rs index e5f6cb9b3..0a15f7535 100644 --- a/artiq/firmware/libboard_artiq/i2c_eeprom.rs +++ b/artiq/firmware/libboard_misoc/i2c_eeprom.rs @@ -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(()) } diff --git a/artiq/firmware/libboard_misoc/lib.rs b/artiq/firmware/libboard_misoc/lib.rs index 1b1b597d9..b49a69446 100644 --- a/artiq/firmware/libboard_misoc/lib.rs +++ b/artiq/firmware/libboard_misoc/lib.rs @@ -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; diff --git a/artiq/firmware/runtime/net_settings.rs b/artiq/firmware/libboard_misoc/net_settings.rs similarity index 51% rename from artiq/firmware/runtime/net_settings.rs rename to artiq/firmware/libboard_misoc/net_settings.rs index d208479d5..3636c6924 100644 --- a/artiq/firmware/runtime/net_settings.rs +++ b/artiq/firmware/libboard_misoc/net_settings.rs @@ -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 } +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 { diff --git a/artiq/firmware/runtime/kern_hwreq.rs b/artiq/firmware/runtime/kern_hwreq.rs index d039d7ce2..53e0daa8a 100644 --- a/artiq/firmware/runtime/kern_hwreq.rs +++ b/artiq/firmware/runtime/kern_hwreq.rs @@ -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)] diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 8d39f4001..0f24877d8 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -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 = [ diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index ce0d92ae4..98cc844c9 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -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);