mirror of https://github.com/m-labs/artiq.git
firmware: let kasli obtain default hardware_addr from i2c_eeprom
This commit is contained in:
parent
d666f3d573
commit
8fc5ce902f
|
@ -29,6 +29,8 @@ ARTIQ-5
|
||||||
* ``aqctl_corelog`` now filters log messages below the ``WARNING`` level by default.
|
* ``aqctl_corelog`` now filters log messages below the ``WARNING`` level by default.
|
||||||
This behavior can be changed using the ``-v`` and ``-q`` options like the other
|
This behavior can be changed using the ``-v`` and ``-q`` options like the other
|
||||||
programs.
|
programs.
|
||||||
|
* On Kasli the firmware now starts with a unique default MAC address
|
||||||
|
from EEPROM if `mac` is absent from the flash config.
|
||||||
|
|
||||||
|
|
||||||
ARTIQ-4
|
ARTIQ-4
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
use i2c;
|
||||||
|
use pca9548;
|
||||||
|
|
||||||
|
#[cfg(soc_platform = "kasli")]
|
||||||
|
const I2C_SWITCH0: u8 = 0x70;
|
||||||
|
#[cfg(soc_platform = "kasli")]
|
||||||
|
const I2C_SWITCH1: u8 = 0x71;
|
||||||
|
|
||||||
|
/// [Hardware manual](http://ww1.microchip.com/downloads/en/DeviceDoc/24AA02E48-24AA025E48-24AA02E64-24AA025E64-Data-Sheet-20002124H.pdf)
|
||||||
|
pub struct EEPROM {
|
||||||
|
busno: u8,
|
||||||
|
port: u8,
|
||||||
|
address: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EEPROM {
|
||||||
|
pub fn kasli_eeprom() -> Self {
|
||||||
|
EEPROM {
|
||||||
|
busno: 0,
|
||||||
|
/// Same port as Si5324
|
||||||
|
port: 11,
|
||||||
|
address: 0xa0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read<'a>(&self, addr: u8, buf: &'a mut [u8]) -> Result<(), &'static str> {
|
||||||
|
self.select()?;
|
||||||
|
|
||||||
|
Ok(()).and_then(|()| {
|
||||||
|
i2c::start(self.busno)?;
|
||||||
|
i2c::write(self.busno, self.address)?;
|
||||||
|
i2c::write(self.busno, addr)?;
|
||||||
|
Ok(())
|
||||||
|
}).map_err(|()| "I2C address write error")?;
|
||||||
|
|
||||||
|
Ok(()).and_then(|()| {
|
||||||
|
i2c::restart(self.busno)?;
|
||||||
|
i2c::write(self.busno, self.address | 1)?;
|
||||||
|
let buf_len = buf.len();
|
||||||
|
for (i, byte) in buf.iter_mut().enumerate() {
|
||||||
|
*byte = i2c::read(self.busno, i < buf_len - 1)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c::stop(self.busno)?;
|
||||||
|
Ok(())
|
||||||
|
}).map_err(|()| "I2C read error")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// > The 24AA02XEXX is programmed at the factory with a
|
||||||
|
/// > globally unique node address stored in the upper half
|
||||||
|
/// > of the array and permanently write-protected.
|
||||||
|
pub fn read_eui48<'a>(&self) -> Result<[u8; 6], &'static str> {
|
||||||
|
let mut buffer = [0u8; 6];
|
||||||
|
self.read(0xFA, &mut buffer)?;
|
||||||
|
Ok(buffer)
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,8 @@ pub mod rpc_queue;
|
||||||
mod pca9548;
|
mod pca9548;
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
pub mod si5324;
|
pub mod si5324;
|
||||||
|
#[cfg(soc_platform = "kasli")]
|
||||||
|
pub mod i2c_eeprom;
|
||||||
|
|
||||||
#[cfg(has_slave_fpga_cfg)]
|
#[cfg(has_slave_fpga_cfg)]
|
||||||
pub mod slave_fpga;
|
pub mod slave_fpga;
|
||||||
|
|
|
@ -135,23 +135,38 @@ fn startup() {
|
||||||
_ => {
|
_ => {
|
||||||
#[cfg(soc_platform = "kasli")]
|
#[cfg(soc_platform = "kasli")]
|
||||||
{
|
{
|
||||||
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x21]);
|
let eeprom = board_artiq::i2c_eeprom::EEPROM::kasli_eeprom();
|
||||||
|
hardware_addr =
|
||||||
|
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")]
|
#[cfg(soc_platform = "sayma_amc")]
|
||||||
{
|
{
|
||||||
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x11]);
|
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x11]);
|
||||||
|
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
||||||
}
|
}
|
||||||
#[cfg(soc_platform = "metlino")]
|
#[cfg(soc_platform = "metlino")]
|
||||||
{
|
{
|
||||||
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x19]);
|
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x19]);
|
||||||
|
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
||||||
}
|
}
|
||||||
#[cfg(soc_platform = "kc705")]
|
#[cfg(soc_platform = "kc705")]
|
||||||
{
|
{
|
||||||
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
|
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
|
||||||
}
|
|
||||||
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
warn!("using default MAC address {}; consider changing it", hardware_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let protocol_addr;
|
let protocol_addr;
|
||||||
match config::read_str("ip", |r| r.map(|s| s.parse())) {
|
match config::read_str("ip", |r| r.map(|s| s.parse())) {
|
||||||
|
|
Loading…
Reference in New Issue