use core::fmt::{Debug, Display}; use bitfield::{bitfield, bitfield_bitrange, bitfield_fields}; #[allow(non_camel_case_types)] #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u16)] /// SPI REGISTER DETAILS /// Table 38. pub enum SpiRegisters { IDVER = 0x00, PHYID = 0x01, CAPABILITY = 0x02, RESET = 0x03, CONFIG0 = 0x04, CONFIG2 = 0x06, STATUS0 = 0x08, STATUS1 = 0x09, IMASK0 = 0x0C, IMASK1 = 0x0D, MDIO_ACC = 0x20, TX_FSIZE = 0x30, TX = 0x31, TX_SPACE = 0x32, FIFO_CLR = 0x36, ADDR_FILT_UPR0 = 0x50, ADDR_FILT_LWR0 = 0x51, ADDR_FILT_UPR1 = 0x52, ADDR_FILT_LWR1 = 0x53, ADDR_MSK_LWR0 = 0x70, ADDR_MSK_UPR0 = 0x71, ADDR_MSK_LWR1 = 0x72, ADDR_MSK_UPR1 = 0x73, RX_FSIZE = 0x90, RX = 0x91, } impl Display for SpiRegisters { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{self:?}") } } impl From for u16 { fn from(val: SpiRegisters) -> Self { val as u16 } } impl From for SpiRegisters { fn from(value: u16) -> Self { match value { 0x00 => Self::IDVER, 0x01 => Self::PHYID, 0x02 => Self::CAPABILITY, 0x03 => Self::RESET, 0x04 => Self::CONFIG0, 0x06 => Self::CONFIG2, 0x08 => Self::STATUS0, 0x09 => Self::STATUS1, 0x0C => Self::IMASK0, 0x0D => Self::IMASK1, 0x20 => Self::MDIO_ACC, 0x30 => Self::TX_FSIZE, 0x31 => Self::TX, 0x32 => Self::TX_SPACE, 0x36 => Self::FIFO_CLR, 0x50 => Self::ADDR_FILT_UPR0, 0x51 => Self::ADDR_FILT_LWR0, 0x52 => Self::ADDR_FILT_UPR1, 0x53 => Self::ADDR_FILT_LWR1, 0x70 => Self::ADDR_MSK_LWR0, 0x71 => Self::ADDR_MSK_UPR0, 0x72 => Self::ADDR_MSK_LWR1, 0x73 => Self::ADDR_MSK_UPR1, 0x90 => Self::RX_FSIZE, 0x91 => Self::RX, e => panic!("Unknown value {}", e), } } } // Register definitions bitfield! { /// Status0 Register bits pub struct Status0(u32); impl Debug; u32; /// Control Data Protection Error pub cdpe, _ : 12; /// Transmit Frame Check Squence Error pub txfcse, _: 11; /// Transmit Time Stamp Capture Available C pub ttscac, _ : 10; /// Transmit Time Stamp Capture Available B pub ttscab, _ : 9; /// Transmit Time Stamp Capture Available A pub ttscaa, _ : 8; /// PHY Interrupt for Port 1 pub phyint, _ : 7; /// Reset Complete pub resetc, _ : 6; /// Header error pub hdre, _ : 5; /// Loss of Frame Error pub lofe, _ : 4; /// Receiver Buffer Overflow Error pub rxboe, _ : 3; /// Host Tx FIFO Under Run Error pub txbue, _ : 2; /// Host Tx FIFO Overflow pub txboe, _ : 1; /// Transmit Protocol Error pub txpe, _ : 0; } bitfield! { /// Status1 Register bits pub struct Status1(u32); impl Debug; u32; /// ECC Error on Reading the Frame Size from a Tx FIFO pub tx_ecc_err, set_tx_ecc_err: 12; /// ECC Error on Reading the Frame Size from an Rx FIFO pub rx_ecc_err, set_rx_ecc_err : 11; /// Detected an Error on an SPI Transaction pub spi_err, set_spi_err: 10; /// Rx MAC Interframe Gap Error pub p1_rx_ifg_err, set_p1_rx_ifg_err : 8; /// Port1 Rx Ready High Priority pub p1_rx_rdy_hi, set_p1_rx_rdy_hi : 5; /// Port 1 Rx FIFO Contains Data pub p1_rx_rdy, set_p1_rx_rdy : 4; /// Tx Ready pub tx_rdy, set_tx_rdy : 3; /// Link Status Changed pub link_change, set_link_change : 1; /// Port 1 Link Status pub p1_link_status, _ : 0; } bitfield! { /// Config0 Register bits pub struct Config0(u32); impl Debug; u32; /// Configuration Synchronization pub sync, set_sync : 15; /// Transmit Frame Check Sequence Validation Enable pub txfcsve, set_txfcsve : 14; /// !CS Align Receive Frame Enable pub csarfe, set_csarfe : 13; /// Zero Align Receive Frame Enable pub zarfe, set_zarfe : 12; /// Transmit Credit Threshold pub tcxthresh, set_tcxthresh : 11, 10; /// Transmit Cut Through Enable pub txcte, set_txcte : 9; /// Receive Cut Through Enable pub rxcte, set_rxcte : 8; /// Frame Time Stamp Enable pub ftse, set_ftse : 7; /// Receive Frame Time Stamp Select pub ftss, set_ftss : 6; /// Enable Control Data Read Write Protection pub prote, set_prote : 5; /// Enable TX Data Chunk Sequence and Retry pub seqe, set_seqe : 4; /// Chunk Payload Selector (N). pub cps, set_cps : 2, 0; } bitfield! { /// Config2 Register bits pub struct Config2(u32); impl Debug; u32; /// Assert TX_RDY When the Tx FIFO is Empty pub tx_rdy_on_empty, set_tx_rdy_on_empty : 8; /// Determines If the SFD is Detected in the PHY or MAC pub sdf_detect_src, set_sdf_detect_src : 7; /// Statistics Clear on Reading pub stats_clr_on_rd, set_stats_clr_on_rd : 6; /// Enable SPI CRC pub crc_append, set_crc_append : 5; /// Admit Frames with IFG Errors on Port 1 (P1) pub p1_rcv_ifg_err_frm, set_p1_rcv_ifg_err_frm : 4; /// Forward Frames Not Matching Any MAC Address to the Host pub p1_fwd_unk2host, set_p1_fwd_unk2host : 2; /// SPI to MDIO Bridge MDC Clock Speed pub mspeed, set_mspeed : 0; } bitfield! { /// IMASK0 Register bits pub struct IMask0(u32); impl Debug; u32; /// Control Data Protection Error Mask pub cppem, set_cppem : 12; /// Transmit Frame Check Sequence Error Mask pub txfcsem, set_txfcsem : 11; /// Transmit Time Stamp Capture Available C Mask pub ttscacm, set_ttscacm : 10; /// Transmit Time Stamp Capture Available B Mask pub ttscabm, set_ttscabm : 9; /// Transmit Time Stamp Capture Available A Mask pub ttscaam, set_ttscaam : 8; /// Physical Layer Interrupt Mask pub phyintm, set_phyintm : 7; /// RESET Complete Mask pub resetcm, set_resetcm : 6; /// Header Error Mask pub hdrem, set_hdrem : 5; /// Loss of Frame Error Mask pub lofem, set_lofem : 4; /// Receive Buffer Overflow Error Mask pub rxboem, set_rxboem : 3; /// Transmit Buffer Underflow Error Mask pub txbuem, set_txbuem : 2; /// Transmit Buffer Overflow Error Mask pub txboem, set_txboem : 1; /// Transmit Protocol Error Mask pub txpem, set_txpem : 0; } bitfield! { /// IMASK1 Register bits pub struct IMask1(u32); impl Debug; u32; /// Mask Bit for TXF_ECC_ERR pub tx_ecc_err_mask, set_tx_ecc_err_mask : 12; /// Mask Bit for RXF_ECC_ERR pub rx_ecc_err_mask, set_rx_ecc_err_mask : 11; /// Mask Bit for SPI_ERR /// This field is only used with the generic SPI protocol pub spi_err_mask, set_spi_err_mask : 10; /// Mask Bit for RX_IFG_ERR pub p1_rx_ifg_err_mask, set_p1_rx_ifg_err_mask : 8; /// Mask Bit for P1_RX_RDY /// This field is only used with the generic SPI protocol pub p1_rx_rdy_mask, set_p1_rx_rdy_mask : 4; /// Mask Bit for TX_FRM_DONE /// This field is only used with the generic SPI protocol pub tx_rdy_mask, set_tx_rdy_mask : 3; /// Mask Bit for LINK_CHANGE pub link_change_mask, set_link_change_mask : 1; } /// LED Functions #[repr(u8)] pub enum LedFunc { LinkupTxRxActicity = 0, LinkupTxActicity, LinkupRxActicity, LinkupOnly, TxRxActivity, TxActivity, RxActivity, LinkupRxEr, LinkupRxTxEr, RxEr, RxTxEr, TxSop, RxSop, On, Off, Blink, TxLevel2P4, TxLevel1P0, Master, Slave, IncompatiableLinkCfg, AnLinkGood, AnComplete, TsTimer, LocRcvrStatus, RemRcvrStatus, Clk25Ref, TxTCLK, Clk120MHz, } impl From for u8 { fn from(val: LedFunc) -> Self { val as u8 } } impl From for LedFunc { fn from(value: u8) -> Self { match value { 0 => LedFunc::LinkupTxRxActicity, 1 => LedFunc::LinkupTxActicity, 2 => LedFunc::LinkupRxActicity, 3 => LedFunc::LinkupOnly, 4 => LedFunc::TxRxActivity, 5 => LedFunc::TxActivity, 6 => LedFunc::RxActivity, 7 => LedFunc::LinkupRxEr, 8 => LedFunc::LinkupRxTxEr, 9 => LedFunc::RxEr, 10 => LedFunc::RxTxEr, 11 => LedFunc::TxSop, 12 => LedFunc::RxSop, 13 => LedFunc::On, 14 => LedFunc::Off, 15 => LedFunc::Blink, 16 => LedFunc::TxLevel2P4, 17 => LedFunc::TxLevel1P0, 18 => LedFunc::Master, 19 => LedFunc::Slave, 20 => LedFunc::IncompatiableLinkCfg, 21 => LedFunc::AnLinkGood, 22 => LedFunc::AnComplete, 23 => LedFunc::TsTimer, 24 => LedFunc::LocRcvrStatus, 25 => LedFunc::RemRcvrStatus, 26 => LedFunc::Clk25Ref, 27 => LedFunc::TxTCLK, 28 => LedFunc::Clk120MHz, e => panic!("Invalid value {}", e), } } } /// LED Control Register #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct LedCntrl(pub u16); bitfield_bitrange! {struct LedCntrl(u16)} impl LedCntrl { bitfield_fields! { u8; /// LED 0 Pin Function pub from into LedFunc, led0_function, set_led0_function: 4, 0; /// LED 0 Mode Selection pub led0_mode, set_led0_mode: 5; /// Qualify Certain LED 0 Options with Link Status. pub led0_link_st_qualify, set_led0_link_st_qualify: 6; /// LED 0 Enable pub led0_en, set_led0_en: 7; /// LED 1 Pin Function pub from into LedFunc, led1_function, set_led1_function: 12, 8; /// /// LED 1 Mode Selection pub led1_mode, set_led1_mode: 13; /// Qualify Certain LED 1 Options with Link Status. pub led1_link_st_qualify, set_led1_link_st_qualify: 14; /// LED 1 Enable pub led1_en, set_led1_en: 15; } pub fn new() -> Self { LedCntrl(0) } } // LED Polarity #[repr(u8)] pub enum LedPol { AutoSense = 0, ActiveHigh, ActiveLow, } impl From for u8 { fn from(val: LedPol) -> Self { val as u8 } } impl From for LedPol { fn from(value: u8) -> Self { match value { 0 => LedPol::AutoSense, 1 => LedPol::ActiveHigh, 2 => LedPol::ActiveLow, e => panic!("Invalid value {}", e), } } } /// LED Control Register #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct LedPolarity(pub u16); bitfield_bitrange! {struct LedPolarity(u16)} impl LedPolarity { bitfield_fields! { u8; /// LED 1 Polarity pub from into LedPol, led1_polarity, set_led1_polarity: 3, 2; /// LED 0 Polarity pub from into LedPol, led0_polarity, set_led0_polarity: 1, 0; } } /// SPI Header #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct SpiHeader(pub u16); bitfield_bitrange! {struct SpiHeader(u16)} impl SpiHeader { bitfield_fields! { u16; /// Mask Bit for TXF_ECC_ERR pub control, set_control : 15; pub full_duplex, set_full_duplex : 14; /// Read or Write to register pub write, set_write : 13; /// Registers ID/addr pub from into SpiRegisters, addr, set_addr: 11, 0; } }