//WRITE TO MII REGISTERS
void write_mii(unsigned char phyad,unsigned char regad,unsigned int mii_data)
{
unsigned char mask8;
unsigned int i,mask16;
mii_write; //Macro that sends ST and OP for write operation
mask8 = 0x10;
for(i=0;i<5;++i) //Send 5 bits of PHY address
{
switch ((mask8 & phyad))
{
case 0:
clr_mdo; //Macro clears MDO bit
break;
default:
set_mdo; //Macro sets MDO bit
}
mii_clk; //Macro clocks bits out of MDC by setting and clearing MDC bit
mask8 >>= 1;
}
mask8 = 0x10;
for(i=0;i<5;++i) //Send 5 bits of PHY register address
{
switch ((mask8 & regad))
{
case 0:
clr_mdo;
break;
default:
set_mdo;
}
mii_clk;
mask8 >>= 1;
}
mii_w_ta; //Macro that drives two turnaround bits 10
mask16 = 0x8000;
for(i=0;i<16;++i) //Send 16 bits of data to PHY
{
switch (mask16 & mii_data)
{
case 0:
clr_mdo;
break;
default:
set_mdo;
}
mii_clk;
mask16 >>= 1;
}
}
//READ MII REGISTERS
unsigned int read_mii(unsigned char phyad,unsigned char regad)
{
unsigned char mask8,i;
unsigned int mask16,result16;
mii_read; //Macro that sends ST and read OP bits
mask8 = 0x10;
for(i=0;i<5;++i) //Send 5 bits of PHY address
{
switch (mask8 & phyad)
{
case 0:
clr_mdo;
break;
default:
set_mdo;
}
mii_clk;
mask8 >>= 1;
}
mask8 = 0x10;
for(i=0;i<5;++i) //Send 5 bits PHY register address
{
switch (mask8 & regad)
{
case 0:
clr_mdo;
break;
default:
set_mdo;
}
mii_clk; //Sets then clears MDC bit-providing clock
mask8 >>= 1;
}
mii_r_ta; //PHY output buffer turnaround time
mask16 = 0x8000;
result16 = 0x0000;
for(i=0;i<16;++i) //Read 16 bits of data from PHY
{
mii_clk;
read_rtl(MEMR);
switch (byte_read &= 0x04)
{
case 0:
nop;
break;
default:
result16 |= mask16;
}
mask16 >>= 1;
}
return result16;
}
Listing 1—The ability to read and write the MII interface is a plus because you have access to information about the auto-negotiation process and what the PHY is really doing.