diff --git a/Cargo.lock b/Cargo.lock index 005ba98..05c3db1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,6 +154,21 @@ dependencies = [ "cortex-m", ] +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "critical-section" version = "1.1.2" @@ -385,6 +400,7 @@ dependencies = [ "cortex-m-log", "cortex-m-rt", "cortex-m-semihosting 0.5.0", + "crc", "fugit", "ieee802_3_miim", "log", diff --git a/Cargo.toml b/Cargo.toml index 62eac4d..f7cc357 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ miniconf = "0.9.0" serde = { version = "1.0.158", features = ["derive"], default-features = false } sfkv = "0.1" bit_field = "0.10" +crc = "3.0.1" byteorder = { version = "1", default-features = false } [features] semihosting = ["cortex-m-log/semihosting"] diff --git a/src/device/boot.rs b/src/device/boot.rs index 2eb1d29..450184c 100644 --- a/src/device/boot.rs +++ b/src/device/boot.rs @@ -43,7 +43,7 @@ pub fn bootup( sys_timer::setup(core_perif.SYST, clocks); - let (eth_pins, eth_mgmt_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy) = gpio::setup( + let (mut hw_rev, eth_pins, eth_mgmt_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy) = gpio::setup( clocks, perif.TIM4, perif.GPIOA, @@ -84,13 +84,14 @@ pub fn bootup( let flash_store = flash_store::store(perif.FLASH); debug!("Setting up ETH"); + let mac_addr = hw_rev.get_mac_address(); let ethernet_parts_in = stm32_eth::PartsIn { dma: perif.ETHERNET_DMA, mac: perif.ETHERNET_MAC, mmc: perif.ETHERNET_MMC, ptp: perif.ETHERNET_PTP, }; - ServerHandle::new(eth_pins, eth_mgmt_pins, ethernet_parts_in, clocks); + ServerHandle::new(eth_pins, eth_mgmt_pins, ethernet_parts_in, clocks, mac_addr); debug!("Setting Watchdog"); let mut wd = IndependentWatchdog::new(perif.IWDG); diff --git a/src/device/gpio.rs b/src/device/gpio.rs index dcdcc2f..c11b9ab 100644 --- a/src/device/gpio.rs +++ b/src/device/gpio.rs @@ -37,6 +37,7 @@ pub fn setup( otg_fs_device: OTG_FS_DEVICE, otg_fs_pwrclk: OTG_FS_PWRCLK, ) -> ( + HWRev, EthernetPins, EthernetMgmtPins, USB, @@ -158,5 +159,5 @@ pub fn setup( gpioa.pa15.into_push_pull_output(), ).unwrap(); - (eth_pins, eth_mgmt_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy) + (hw_rev, eth_pins, eth_mgmt_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy) } diff --git a/src/device/hw_rev.rs b/src/device/hw_rev.rs index c4e36d1..f5aa2d0 100644 --- a/src/device/hw_rev.rs +++ b/src/device/hw_rev.rs @@ -1,5 +1,8 @@ -use stm32f4xx_hal::gpio::{Input, Output, PushPull, PE10, PE11, PE8, PE9}; +use stm32f4xx_hal::gpio::{Input, PE10, PE11, PE8, PE9}; use crate::device::sys_timer::sleep; +use stm32f4xx_hal::signature; +use crc::{Crc, CRC_24_BLE}; + pub struct HwRevPins{ pub h0: PE8, pub h1: PE9, @@ -32,4 +35,28 @@ impl HWRev { sleep(5000); } } -} \ No newline at end of file + + /// On Rev0_3, it lacks pre-allocated Mac Addresses accessible on PCB. + /// This functions generate a random Mac Address with 96bit unique UUID inside STM32 + /// See Issue #36 on Kirdy Hw Repo + pub fn get_mac_address(&mut self) -> [u8; 6] { + if self.major == 0 && self.minor == 3 { + let uid = signature::Uid::get(); + let mut uid_data: [u8; 12] = [0; 12]; + uid_data[0] = uid.x() as u8; + uid_data[1] = (uid.x() >> 8) as u8; + uid_data[2] = uid.y() as u8; + uid_data[3] = (uid.y() >> 8) as u8; + uid_data[4..11].clone_from_slice(uid.lot_num().as_bytes()); + + let crc: Crc = Crc::::new(&CRC_24_BLE); + let mut digest = crc.digest(); + digest.update(&uid_data); + let crc24 = digest.finalize(); + + [ 0x02, 0xE0, 0xD5, (crc24 >> 16) as u8, (crc24 >> 8) as u8, (crc24 as u8)] + } else { + unimplemented!() + } + } +} diff --git a/src/net/net.rs b/src/net/net.rs index f7d4a9f..ed34cda 100644 --- a/src/net/net.rs +++ b/src/net/net.rs @@ -35,7 +35,6 @@ const ADDRESS: (IpAddress, u16) = ( )), 1337, ); -const MAC: [u8; 6] = [0x02, 0x5f, 0x25, 0x37, 0x93, 0x0e]; /// Interrupt pending flag: set by the `ETH` interrupt handler, should /// be cleared before polling the interface. @@ -88,6 +87,7 @@ impl ServerHandle { eth_mgmt_pins: EthernetMgmtPins, ethernet_parts_in: PartsIn, clocks: Clocks, + mac_addr: [u8; 6] ) { let rx_ring = unsafe { RX_RING.get_or_insert(Default::default()) }; let tx_ring = unsafe { TX_RING.get_or_insert(Default::default()) }; @@ -119,9 +119,10 @@ impl ServerHandle { let tx_buffer = SocketBuffer::new(&mut tcp_socket_storage.tx_storage[..]); let socket = Socket::new(rx_buffer, tx_buffer); - let config = iface::Config::new(EthernetAddress::from_bytes(&MAC).into()); + let config = iface::Config::new(EthernetAddress::from_bytes(&mac_addr).into()); let mut iface = Interface::new(config, &mut &mut dma, smoltcp::time::Instant::ZERO); - iface.set_hardware_addr(EthernetAddress(MAC).into()); + iface.set_hardware_addr(EthernetAddress(mac_addr).into()); + debug!("MAC ADDRESS: {:02X?}", EthernetAddress(mac_addr)); iface.update_ip_addrs(|addr| { addr.push(IP_INIT).unwrap();