use crate::clock::RefClockPin;
use crate::pins::{MdioPinConfig, PhyResetPinConfig, RmiiPinConfig};
#[derive(Clone, Copy, Debug)]
pub struct BoardConfig {
pub rmii_pins: RmiiPinConfig,
pub mdio_pins: MdioPinConfig,
pub phy_reset: PhyResetPinConfig,
pub ref_clock: RefClockPin,
pub phy_addr: u8,
}
impl BoardConfig {
pub const WAVESHARE_P4_ETH: Self = Self {
rmii_pins: RmiiPinConfig::WAVESHARE_P4_ETH,
mdio_pins: MdioPinConfig::WAVESHARE_P4_ETH,
phy_reset: PhyResetPinConfig::WAVESHARE_P4_ETH,
ref_clock: RefClockPin::Gpio50,
phy_addr: 1,
};
}
#[cfg(test)]
mod tests {
use super::*;
use crate::clock::RefClockPin;
#[test]
fn waveshare_phy_addr_is_one_and_in_legal_range() {
let cfg = BoardConfig::WAVESHARE_P4_ETH;
assert_eq!(cfg.phy_addr, 1, "Waveshare straps the IP101 to MDIO addr 1");
assert!(cfg.phy_addr < 32, "MDIO addr must fit in 5 bits");
}
#[test]
fn waveshare_rmii_pin_map_matches_dev_board_silkscreen() {
let pins = BoardConfig::WAVESHARE_P4_ETH.rmii_pins;
assert_eq!(pins.txd0, 34);
assert_eq!(pins.txd1, 35);
assert_eq!(pins.tx_en, 49);
assert_eq!(pins.rxd0, 30);
assert_eq!(pins.rxd1, 29);
assert_eq!(pins.crs_dv, 28);
}
#[test]
fn waveshare_mdio_pins_match_dev_board_silkscreen() {
let pins = BoardConfig::WAVESHARE_P4_ETH.mdio_pins;
assert_eq!(pins.mdc, 31);
assert_eq!(pins.mdio, 52);
}
#[test]
fn waveshare_phy_reset_is_gpio51_active_low() {
let reset = BoardConfig::WAVESHARE_P4_ETH.phy_reset;
assert_eq!(reset.pin, 51);
assert!(
reset.active_low,
"IP101GRI RST_N is active low — flipping this strands the PHY in reset"
);
}
#[test]
fn waveshare_ref_clock_pad_is_gpio50() {
assert!(matches!(
BoardConfig::WAVESHARE_P4_ETH.ref_clock,
RefClockPin::Gpio50
));
}
#[test]
fn board_config_is_copy_clone() {
fn assert_copy<T: Copy>() {}
fn assert_clone<T: Clone>() {}
assert_copy::<BoardConfig>();
assert_clone::<BoardConfig>();
let a = BoardConfig::WAVESHARE_P4_ETH;
let b = a; let _c = a.clone();
assert_eq!(a.phy_addr, b.phy_addr);
}
#[test]
fn all_waveshare_gpio_numbers_fit_p4_pinout() {
let cfg = BoardConfig::WAVESHARE_P4_ETH;
let pins = [
cfg.rmii_pins.txd0,
cfg.rmii_pins.txd1,
cfg.rmii_pins.tx_en,
cfg.rmii_pins.rxd0,
cfg.rmii_pins.rxd1,
cfg.rmii_pins.crs_dv,
cfg.mdio_pins.mdc,
cfg.mdio_pins.mdio,
cfg.phy_reset.pin,
];
for p in pins {
assert!(p < 56, "P4 has GPIO 0..55; got {}", p);
}
}
#[test]
fn waveshare_pin_assignments_are_unique() {
let cfg = BoardConfig::WAVESHARE_P4_ETH;
let pins = [
cfg.rmii_pins.txd0,
cfg.rmii_pins.txd1,
cfg.rmii_pins.tx_en,
cfg.rmii_pins.rxd0,
cfg.rmii_pins.rxd1,
cfg.rmii_pins.crs_dv,
cfg.mdio_pins.mdc,
cfg.mdio_pins.mdio,
cfg.phy_reset.pin,
];
let mut sorted = pins;
sorted.sort();
for w in sorted.windows(2) {
assert_ne!(w[0], w[1], "duplicate GPIO assignment in BoardConfig: {}", w[0]);
}
}
}