LinkedIn YouTube Facebook
Szukaj

Wstecz
IoT

Komunikacja sieciowa z wykorzystaniem mikrokontrolerów Freescale Kinetis

Zarządzanie interfejsem PHY

Moduł MAC-NET wykorzystuje interfejs PHY do komunikacji z układem PHY. Dzięki temu interfejsowi istnieje dostęp do rejestrów kontrolnych i statusowych układu PHY. Komunikacja przebiega z wykorzystaniem dwóch linii:

  • Linii zegarowej, na której sygnał zegarowy generowany jest przez moduł MAC-NET. Częstotliwość sygnału zegarowego nie może być większa niż 2.5 MHz,
  • Dwukierunkowej linii danych, która służy do przesyłania informacji między modułem ENET i układem PHY.

Przykładowy kod źródłowy do zarządzania PHY i rozpoczęcia auto-negocjacji z siecią przedstawiono w listingu:

void
enet_start_mii(void)
{
PORTB_PCR0 = PORT_PCR_MUX(4);//GPIO;//RMII0_MDIO/MII0_MDIO
PORTB_PCR1 = PORT_PCR_MUX(4);//GPIO;//RMII0_MDC/MII0_MDC
/*FSL: start MII interface*/
mii_init(0, periph_clk_khz/1000/*MHz*/);
/* Can we talk to the PHY? */
do
{
vTaskDelay( netifLINK_DELAY );
usData = 0xffff;
mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &usData );
} while( usData == 0xffff );
/* Start auto negotiate. */
mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
}
void
mii_init(int ch, int sys_clk_mhz)
{
ENET_MSCR/*(ch)*/ = 0
#ifdef TSIEVB/*TSI EVB requires a longer hold time than default 10 ns*/
| ENET_MSCR_HOLDTIME(2)
#endif
| ENET_MSCR_MII_SPEED((2*sys_clk_mhz/5)+1)
;
}
int
mii_write(int ch, int phy_addr, int reg_addr, int data)
{
int timeout;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
/* Initiatate the MII Management write */
ENET_MMFR/*(ch)*/ = 0
| ENET_MMFR_ST(0x01)
| ENET_MMFR_OP(0x01)
| ENET_MMFR_PA(phy_addr)
| ENET_MMFR_RA(reg_addr)
| ENET_MMFR_TA(0x02)
| ENET_MMFR_DATA(data);
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
{
if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)
break;
}
if(timeout == MII_TIMEOUT)
return 1;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
return 0;
}
/********************************************************************/
int
mii_read(int ch, int phy_addr, int reg_addr, int *data)
{
int timeout;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
/* Initiatate the MII Management read */
ENET_MMFR/*(ch)*/ = 0
| ENET_MMFR_ST(0x01)
| ENET_MMFR_OP(0x2)
| ENET_MMFR_PA(phy_addr)
| ENET_MMFR_RA(reg_addr)
| ENET_MMFR_TA(0x02);
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
{
if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)
break;
}
if(timeout == MII_TIMEOUT)
return 1;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
*data = ENET_MMFR/*(ch)*/ & 0x0000FFFF;
return 0;
}