/*
*
*
*
* Description : It can read/write MII Phy Register
*
*
*/
#include "mii-gpio.h"
#include "../driverlib/sysctl.h "
#include "../driverlib/gpio.h "
#include "../driverlib/lm3s9b96.h "
#include "../driverlib/inc/hw_memmap.h "
#define MDC HX_LM3S_PIO_PD6
#define MDIO HX_LM3S_PIO_PD5
#define PHY_RST HX_LM3S_PIO_PD4
#define MDC1 HX_LM3S_PIO_PE5
#define MDIO1 HX_LM3S_PIO_PE4
#define PHY_RST1 HX_LM3S_PIO_PD7
u16 rx_buf,rx_buf1;
static void uudelay(u32 us)
{
while(us--);
}
/*******************************************************/
void Mdc_Pulse(void) /*Clock line */
{
port_write(MDC, 1);
uudelay(1000);
port_write(MDC, 0);
uudelay(1000);
}
void Preamble(void)
{
u8 i;
port_write(MDIO, 1);
/* Transmit Preamble 11....11(32 bits) */
for(i=0 ; i < 32 ; i++)
Mdc_Pulse();
/* Transmit STart of Frame '01' */
port_write(MDIO, 0);
Mdc_Pulse();
port_write(MDIO, 1);
Mdc_Pulse();
}
void Send_Addr(u8 Data)
{
u8 i;
for(i = 0; i < 5; i++)
{
if(Data & 0x10)
port_write(MDIO, 1);
else
port_write(MDIO, 0);
Mdc_Pulse();
Data <<= 1;
}
}
void PHY_Addr(u8 phy_id)
{
/* Transmit Selected Address */
Send_Addr(phy_id);
}
void Reg_Addr(u8 reg_addr)
{
/* Transmit Selected register*/
Send_Addr(reg_addr);
}
void WriteData(u16 value) //MSB
{
u8 i;
u16 bitMask = 0x8000;
for ( i = 0;i < 16; i++)
{
if(value & bitMask)
port_write(MDIO, 1);
else
port_write(MDIO, 0);
Mdc_Pulse();
bitMask >>= 1;
}
}
u16 ReadData(void)
{
u8 i;
for ( i = 0;i < 16; i++)
{
Mdc_Pulse();
if (port_read(MDIO)!= 0)
rx_buf |= 0x0001;
if (i < 15)
rx_buf <<= 1;
//UARTprintf("port_read(MDIO) = %d\n",port_read(MDIO));
}
return rx_buf;
}
void Idle(void)
{
port_write(MDIO, 1);
Mdc_Pulse();
}
u16 Mii_Read(u8 phy_id,u8 reg_addr)
{
rx_buf = 0x0;
Preamble();
/*OP Code 10*/
port_write(MDIO, 1);
Mdc_Pulse();
port_write(MDIO, 0);
Mdc_Pulse();
PHY_Addr(phy_id);
Reg_Addr(reg_addr);
port_write(MDIO, 1);
/*Turnaround Z*/
port_write(MDIO, 1);
Mdc_Pulse();
rx_buf = ReadData();
Idle();
return rx_buf;
}
void Mii_Write(u8 phy_id,u8 reg_addr,u16 value)
{
Preamble();
/*OP Code 01*/
port_write(MDIO, 0);
Mdc_Pulse();
port_write(MDIO, 1);
Mdc_Pulse();
PHY_Addr(phy_id);
Reg_Addr(reg_addr);
/*Turnaround 10*/
port_write(MDIO, 1);
Mdc_Pulse();
port_write(MDIO, 0);
Mdc_Pulse();
WriteData(value);
Idle();
}
void phy_reset(void)
{
port_write(PHY_RST,1);
uudelay(1000);
port_write(PHY_RST,0);
uudelay(1000);
port_write(PHY_RST,1);
uudelay(1000);
}
void Mdc_Pulse1(void) /*Clock line */
{
port_write(MDC1, 1);
uudelay(1000);
port_write(MDC1, 0);
uudelay(1000);
}
void Preamble1(void)
{
u8 i;
port_write(MDIO1, 1);
/* Transmit Preamble 11....11(32 bits) */
for(i=0 ; i < 32 ; i++)
Mdc_Pulse1();
/* Transmit STart of Frame '01' */
port_write(MDIO1, 0);
Mdc_Pulse1();
port_write(MDIO1, 1);
Mdc_Pulse1();
}
void Send_Addr1(u8 Data)
{
u8 i;
for(i = 0; i < 5; i++)
{
if(Data & 0x10)
port_write(MDIO1, 1);
else
port_write(MDIO1, 0);
Mdc_Pulse1();
Data <<= 1;
}
}
void PHY_Addr1(u8 phy_id)
{
/* Transmit Selected Address */
Send_Addr1(phy_id);
}
void Reg_Addr1(u8 reg_addr)
{
/* Transmit Selected register*/
Send_Addr1(reg_addr);
}
void WriteData1(u16 value) //MSB
{
u8 i;
u16 bitMask = 0x8000;
for ( i = 0;i < 16; i++)
{
if(value & bitMask)
port_write(MDIO1, 1);
else
port_write(MDIO1, 0);
Mdc_Pulse1();
bitMask >>= 1;
}
}
u16 ReadData1(void)
{
u8 i;
for ( i = 0;i < 16; i++)
{
Mdc_Pulse1();
if (port_read(MDIO1)!= 0)
rx_buf1 |= 0x0001;
if (i < 15)
rx_buf1 <<= 1;
//UARTprintf("port_read(MDIO) = %d\n",port_read(MDIO));
}
return rx_buf1;
}
void Idle1(void)
{
port_write(MDIO1, 1);
Mdc_Pulse1();
}
u16 Mii_Read1(u8 phy_id,u8 reg_addr)
{
rx_buf1 = 0x0;
Preamble1();
/*OP Code 10*/
port_write(MDIO1, 1);
Mdc_Pulse1();
port_write(MDIO1, 0);
Mdc_Pulse1();
PHY_Addr1(phy_id);
Reg_Addr1(reg_addr);
port_write(MDIO1, 1);
/*Turnaround Z*/
port_write(MDIO1, 1);
Mdc_Pulse1();
rx_buf1 = ReadData1();
Idle1();
return rx_buf1;
}
void Mii_Write1(u8 phy_id,u8 reg_addr,u16 value)
{
Preamble1();
/*OP Code 01*/
port_write(MDIO1, 0);
Mdc_Pulse1();
port_write(MDIO1, 1);
Mdc_Pulse1();
PHY_Addr1(phy_id);
Reg_Addr1(reg_addr);
/*Turnaround 10*/
port_write(MDIO1, 1);
Mdc_Pulse1();
port_write(MDIO1, 0);
Mdc_Pulse1();
WriteData1(value);
Idle1();
}
void phy_reset1(void)
{
port_write(PHY_RST1,1);
uudelay(1000);
port_write(PHY_RST1,0);
uudelay(1000);
port_write(PHY_RST1,1);
uudelay(1000);
}
int phy_find(void)
{
int i,j;
u16 phy_id;
phy_reset();
phy_reset1();
/* Search for PHY... */
for (i = 1; i < 32; i++) {
phy_id = Mii_Read(i,0x02);
if (phy_id != 0xffff) {
UARTprintf("PHY present at %d,ID = 0x%x\n", i,phy_id);
Mii_Write(1,0x9, 0x1200);//0x1200
//Mii_Write(1,0x1c, (0x9 << 10));
//UARTprintf("Mii_Read(1,0x1c) = 0x%x\n",Mii_Read(1,0x1c));
Mii_Write(1,0x1c,0x8000|(0xe << 10)|0x0);//0x1
Mii_Write(1,0x1c,0x8000|(0xd << 10)|0x3e);//0xe3
//Mii_Write1(1,0x9, 0x1200);
Mii_Write1(1,0x1c,0x8000|(0xe << 10)|0x1);
Mii_Write1(1,0x1c,0x8000|(0xd << 10)|0xe3);
Mii_Write1(1,0x1c,0x8000|(0xb << 10)|0x0);
Mii_Write1(1,0x0, 0x3100);//0x2100
Mii_Write1(1,0x4, 0x0101);
Mii_Write1(1,0x9, 0x0);
return 1;
}
}
/* PHY isn't up to snuff */
UARTprintf("PHY not found");
return 0;
}