7 #include <satcat5/cfgbus_mdio.h>
12 namespace cfg = satcat5::cfg;
13 namespace log = satcat5::log;
14 namespace util = satcat5::util;
17 static const u32 HWREG_OPWR = (1u << 26);
18 static const u32 HWREG_OPRD = (2u << 26);
19 inline u32 HWREG_PADDR(
unsigned x) {
return (x & 0x1F) << 21;}
20 inline u32 HWREG_RADDR(
unsigned x) {
return (x & 0x1F) << 16;}
21 inline u32 HWREG_WDATA(u16 x) {
return x & 0xFFFF;}
24 inline u32 HW_DIR_WRITE(
unsigned p,
unsigned r,
unsigned d)
25 {
return HWREG_OPWR | HWREG_PADDR(p) | HWREG_RADDR(r) | HWREG_WDATA(d);}
26 inline u32 HW_DIR_READ(
unsigned p,
unsigned r)
27 {
return HWREG_OPRD | HWREG_PADDR(p) | HWREG_RADDR(r);}
30 static const u32 HWSTATUS_WRFULL = (1u << 31);
31 static const u32 HWSTATUS_RVALID = (1u << 30);
32 static const u32 HWSTATUS_RDATA = (0xFFFF);
36 : m_ctrl_reg(cfg->get_register(devaddr, regaddr))
46 while (hw_rd_status() & HWSTATUS_RVALID) {}
52 return hw_wr_command(HW_DIR_WRITE(phy, reg, data));
59 if (can_read() && hw_wr_command(HW_DIR_READ(phy, reg))) {
62 unsigned wridx = util::modulo_add_uns(
63 m_addr_rdidx + m_addr_rdcount, SATCAT5_MDIO_BUFFSIZE);
64 m_callback[wridx] = callback;
65 m_addr_buff[wridx] = (u16)ref;
75 u32 cfg::Mdio::hw_rd_status()
78 u32 status = *m_ctrl_reg;
81 u16 regaddr = 0, regval = (u16)(status & HWSTATUS_RDATA);
83 if ((m_addr_rdcount > 0) && (status & HWSTATUS_RVALID)) {
86 regaddr = m_addr_buff[m_addr_rdidx];
87 callback = m_callback[m_addr_rdidx];
88 m_addr_rdidx = util::modulo_add_uns(m_addr_rdidx + 1, SATCAT5_MDIO_BUFFSIZE);
93 if (callback) callback->mdio_done(regaddr, regval);
98 bool cfg::Mdio::hw_wr_command(u32 cmd)
101 u32 status = hw_rd_status();
102 if (status & HWSTATUS_WRFULL) {
110 void cfg::MdioLogger::mdio_done(u16 regaddr, u16 regval)
122 return m_mdio->direct_write(m_phy, reg, data);
124 return m_mdio->direct_write(m_phy, 0x0D, 0x001F)
125 && m_mdio->direct_write(m_phy, 0x0E, reg)
126 && m_mdio->direct_write(m_phy, 0x0D, 0x401F)
127 && m_mdio->direct_write(m_phy, 0x0E, data);
134 return m_mdio->direct_read(m_phy, reg, reg, callback);
136 return m_mdio->can_read()
137 && m_mdio->direct_write(m_phy, 0x0D, 0x001F)
138 && m_mdio->direct_write(m_phy, 0x0E, reg)
139 && m_mdio->direct_write(m_phy, 0x0D, 0x401F)
140 && m_mdio->direct_read (m_phy, 0x0E, reg, callback);
146 unsigned page = (reg >> 8);
147 return m_mdio->direct_write(m_phy, 0x16, page)
148 && m_mdio->direct_write(m_phy, reg, data);
153 unsigned page = (reg >> 8);
154 return m_mdio->can_read()
155 && m_mdio->direct_write(m_phy, 0x16, page)
156 && m_mdio->direct_read (m_phy, reg, reg, callback);
ConfigBus core definitions.
Prototype for the cfg::Mdio callback interface.
bool write(unsigned reg, unsigned data) override
Read and write methods allow indirect access.
bool read(unsigned reg, satcat5::cfg::MdioEventListener *callback) override
Read and write methods allow indirect access.
bool direct_write(unsigned phy, unsigned reg, unsigned data)
Direct write to designated MDIO register.
Mdio(satcat5::cfg::ConfigBus *cfg, unsigned devaddr, unsigned regaddr=satcat5::cfg::REGADDR_ANY)
Constructor ties this driver to a ConfigBus address.
bool direct_read(unsigned phy, unsigned reg, unsigned ref, satcat5::cfg::MdioEventListener *callback)
Direct read from designated MDIO register.
void poll_always()
Child class MUST override this method.
bool write(unsigned reg, unsigned data) override
Read and write methods allow indirect access.
bool read(unsigned reg, satcat5::cfg::MdioEventListener *callback) override
Read and write methods allow indirect access.
The Log class creates and formats one log message.
Log & write(const char *str)
Formatting methods for various data types.
Diagnostic logging to UART and/or Ethernet ports.
Platform-agnostic API for interrupt management.
Miscellaneous mathematical utility functions.