Source code for jitxexamples.jumpstart_kits.js2_circuits.straps

"""Strap-in configuration of the KSZ9031RNX.

Transcribed from Table 2-2 ("Strap-In Options - KSZ9031RNX") of data sheet
DS00002117K. Each strap-in function is latched from the level on its pin at
power-up or reset: a pull-up latches 1, a pull-down latches 0. The strap pins
have no internal pull (Table 2-1 types them I/O, and Table 6-6 lists internal
pull-ups only on MDC, MDIO and RESET_N), so every strap pin takes an external
resistor for every configuration.

======  ==========  ==================  =======================================
Pin     Pin name    Strap function      Value
======  ==========  ==================  =======================================
35      RX_CLK      PHYAD2              PHY address bit 2
15      LED2        PHYAD1              PHY address bit 1
17      LED1        PHYAD0              PHY address bit 0
27      RXD3        MODE3               ``Mode`` code bit 3
28      RXD2        MODE2               ``Mode`` code bit 2
31      RXD1        MODE1               ``Mode`` code bit 1
32      RXD0        MODE0               ``Mode`` code bit 0
33      RX_DV       CLK125_EN           1 enables the 125 MHz CLK125_NDO output
41      CLK125_NDO  LED_MODE            1 is single-LED, 0 tri-color dual-LED
======  ==========  ==================  =======================================
"""

from dataclasses import dataclass
from enum import Enum


[docs] class Strap(Enum): """A strap-in function of Table 2-2, valued by the pin number carrying it.""" PHYAD2 = 35 PHYAD1 = 15 PHYAD0 = 17 MODE3 = 27 MODE2 = 28 MODE1 = 31 MODE0 = 32 CLK125_EN = 33 LED_MODE = 41
[docs] class Mode(Enum): """The MODE[3:0] codes Table 2-2 defines, valued by the 4-bit code. The codes it marks "Reserved - not used" (0000 to 0011, 0101, 0110, 1000 to 1011) have no member, so ``Mode(0b0101)`` raises ``ValueError``. """ NAND_TREE = 0b0100 CHIP_POWER_DOWN = 0b0111 RGMII_1000_FULL = 0b1100 """RGMII, advertise 1000BASE-T full-duplex only.""" RGMII_1000_FULL_HALF = 0b1101 """RGMII, advertise 1000BASE-T full- and half-duplex only.""" RGMII_ALL_EXCEPT_1000_HALF = 0b1110 """RGMII, advertise 10/100/1000 half- and full-duplex except 1000BASE-T half-duplex.""" RGMII_ALL = 0b1111 """RGMII, advertise 10/100/1000 half- and full-duplex."""
[docs] class LedMode(Enum): """LED_MODE, valued by the latched bit.""" TRI_COLOR_DUAL = 0 SINGLE = 1
[docs] @dataclass(frozen=True) class StrapConfig: """The configuration the strap resistors latch. Args: phy_address: PHYAD[2:0], 0 to 7. Address bits [4:3] are always 00. mode: MODE[3:0]. clk125_output: CLK125_EN, whether CLK125_NDO drives a 125 MHz clock. led_mode: LED_MODE. Raises: ValueError: ``phy_address`` is outside 0 to 7. """ phy_address: int = 0 mode: Mode = Mode.RGMII_ALL clk125_output: bool = False led_mode: LedMode = LedMode.SINGLE def __post_init__(self) -> None: if not 0 <= self.phy_address <= 7: raise ValueError( f"KSZ9031RNX PHY address {self.phy_address} is outside 0 to 7: " "PHYAD[2:0] sets three bits" ) if not isinstance(self.mode, Mode): raise TypeError(f"mode must be a Mode, not {self.mode!r}") if not isinstance(self.led_mode, LedMode): raise TypeError(f"led_mode must be a LedMode, not {self.led_mode!r}")
[docs] def level(self, strap: Strap) -> bool: """The level ``strap`` latches: True for a pull-up, False for a pull-down.""" match strap: case Strap.PHYAD2: return bool(self.phy_address & 0b100) case Strap.PHYAD1: return bool(self.phy_address & 0b010) case Strap.PHYAD0: return bool(self.phy_address & 0b001) case Strap.MODE3: return bool(self.mode.value & 0b1000) case Strap.MODE2: return bool(self.mode.value & 0b0100) case Strap.MODE1: return bool(self.mode.value & 0b0010) case Strap.MODE0: return bool(self.mode.value & 0b0001) case Strap.CLK125_EN: return self.clk125_output case Strap.LED_MODE: return self.led_mode is LedMode.SINGLE
DEFAULT_STRAPS = StrapConfig() """PHY address 0, every RGMII mode advertised, CLK125_NDO off, single-LED mode."""