long lEMACInit( void ) { long lReturn = pdPASS; unsigned long ulID1, ulID2; /* Reset peripherals, configure port pins and registers. */ prvSetupEMACHardware(); /* Check the PHY part number is as expected. */ ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn ); ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn ); if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFFFUL ) ) == KS8721_ID ) { /* Set the Ethernet MAC Address registers */ EMAC->SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1; EMAC->SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3; EMAC->SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5; /* Initialize Tx and Rx DMA Descriptors */ prvInitDescriptors(); /* Receive broadcast and perfect match packets */ EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; /* Setup the PHY. */ prvConfigurePHY(); } else { lReturn = pdFAIL; } /* Check the link status. */ if( lReturn == pdPASS ) { lReturn = prvSetupLinkStatus(); } if( lReturn == pdPASS ) { /* Initialise uip_buf to ensure it points somewhere valid. */ uip_buf = prvGetNextBuffer(); /* Reset all interrupts */ EMAC->IntClear = ( INT_RX_OVERRUN | INT_RX_ERR | INT_RX_FIN | INT_RX_DONE | INT_TX_UNDERRUN | INT_TX_ERR | INT_TX_FIN | INT_TX_DONE | INT_SOFT_INT | INT_WAKEUP ); /* Enable receive and transmit mode of MAC Ethernet core */ EMAC->Command |= ( CR_RX_EN | CR_TX_EN ); EMAC->MAC1 |= MAC1_REC_EN; } return lReturn; }
static void prvSetupEMACHardware( void ) { unsigned short us; long x, lDummy; /* Enable P1 Ethernet Pins. */ PINCON->PINSEL2 = emacPINSEL2_VALUE; PINCON->PINSEL3 = ( PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005; /* Power Up the EMAC controller. */ SC->PCONP |= PCONP_PCENET; vTaskDelay( emacSHORT_DELAY ); /* Reset all EMAC internal modules. */ EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; /* A short delay after reset. */ vTaskDelay( emacSHORT_DELAY ); /* Initialize MAC control registers. */ EMAC->MAC1 = MAC1_PASS_ALL; EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; EMAC->MAXF = ETH_MAX_FLEN; EMAC->CLRT = CLRT_DEF; EMAC->IPGR = IPGR_DEF; EMAC->MCFG = emacDIV_44; /* Enable Reduced MII interface. */ EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; /* Reset Reduced MII Logic. */ EMAC->SUPP = SUPP_RES_RMII; vTaskDelay( emacSHORT_DELAY ); EMAC->SUPP = 0; /* Put the PHY in reset mode */ prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); /* Wait for hardware reset to end. */ for( x = 0; x < 100; x++ ) { vTaskDelay( emacSHORT_DELAY * 5 ); us = prvReadPHY( PHY_REG_BMCR, &lDummy ); if( !( us & MCFG_RES_MII ) ) { /* Reset complete */ break; } } }
static long prvSetupLinkStatus( void ) { long lReturn = pdFAIL, x; unsigned short usLinkStatus; /* Wait with timeout for the link to be established. */ for( x = 0; x < 10; x++ ) { usLinkStatus = prvReadPHY( PHY_CTRLER, &lReturn ); if( usLinkStatus != 0x00 ) { /* Link is established. */ lReturn = pdPASS; break; } vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH ); } if( lReturn == pdPASS ) { /* Configure Full/Half Duplex mode. */ if( usLinkStatus & emacFULL_DUPLEX_ENABLED ) { /* Full duplex is enabled. */ EMAC->MAC2 |= MAC2_FULL_DUP; EMAC->Command |= CR_FULL_DUP; EMAC->IPGT = IPGT_FULL_DUP; } else { /* Half duplex mode. */ EMAC->IPGT = IPGT_HALF_DUP; } /* Configure 100MBit/10MBit mode. */ if( usLinkStatus & emac10BASE_T_MODE ) { /* 10MBit mode. */ EMAC->SUPP = 0; } else { /* 100MBit mode. */ EMAC->SUPP = SUPP_SPEED; } } return lReturn; }
static void prvConfigurePHY( void ) { unsigned short us; long x, lDummy; /* Auto negotiate the configuration. */ if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) { vTaskDelay( emacSHORT_DELAY * 5 ); for( x = 0; x < 10; x++ ) { us = prvReadPHY( PHY_REG_BMSR, &lDummy ); if( us & PHY_AUTO_NEG_COMPLETE ) { break; } vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH ); } } }