forked from M-Labs/artiq
1
0
Fork 0

firmware: let kasli obtain default hardware_addr from i2c_eeprom

This commit is contained in:
Astro 2019-08-13 02:02:51 +02:00 committed by Sébastien Bourdeauducq
parent d666f3d573
commit 8fc5ce902f
4 changed files with 86 additions and 2 deletions

View File

@ -29,6 +29,8 @@ ARTIQ-5
* ``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
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

View File

@ -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)
}
}

View File

@ -32,6 +32,8 @@ pub mod rpc_queue;
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;

View File

@ -135,23 +135,38 @@ fn startup() {
_ => {
#[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")]
{
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x11]);
warn!("using default MAC address {}; consider changing it", hardware_addr);
}
#[cfg(soc_platform = "metlino")]
{
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x19]);
warn!("using default MAC address {}; consider changing it", hardware_addr);
}
#[cfg(soc_platform = "kc705")]
{
hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
}
warn!("using default MAC address {}; consider changing it", hardware_addr);
}
}
}
let protocol_addr;
match config::read_str("ip", |r| r.map(|s| s.parse())) {