Bool xMACBInit( volatile avr32_macb_t * macb ) { volatile unsigned long status; // set up registers macb->ncr = 0; macb->tsr = ~0UL; macb->rsr = ~0UL; macb->idr = ~0UL; status = macb->isr; #if ETHERNET_CONF_USE_RMII_INTERFACE // RMII used, set 0 to the USRIO Register macb->usrio &= ~AVR32_MACB_RMII_MASK; #else // RMII not used, set 1 to the USRIO Register macb->usrio |= AVR32_MACB_RMII_MASK; #endif // Load our MAC address into the MACB. prvSetupMACAddress(macb); // Setup the buffers and descriptors. prvSetupDescriptors(macb); #if ETHERNET_CONF_SYSTEM_CLOCK <= 20000000 macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV8 << AVR32_MACB_NCFGR_CLK_OFFSET); #elif ETHERNET_CONF_SYSTEM_CLOCK <= 40000000 macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV16 << AVR32_MACB_NCFGR_CLK_OFFSET); #elif ETHERNET_CONF_SYSTEM_CLOCK <= 80000000 macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV32 << AVR32_MACB_NCFGR_CLK_OFFSET; #elif ETHERNET_CONF_SYSTEM_CLOCK <= 160000000 macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV64 << AVR32_MACB_NCFGR_CLK_OFFSET; #else # error System clock too fast #endif // Are we connected? if( prvProbePHY(macb) == TRUE ) { // Enable the interrupt! portENTER_CRITICAL(); { prvSetupMACBInterrupt(macb); } portEXIT_CRITICAL(); // Enable Rx and Tx, plus the stats register. macb->ncr = AVR32_MACB_NCR_TE_MASK | AVR32_MACB_NCR_RE_MASK; return (TRUE); } return (FALSE); }
/* See the header file for descriptions of public functions. */ xSemaphoreHandle xEMACInit( void ) { /* Code supplied by Atmel -------------------------------*/ /* Disable pull up on RXDV => PHY normal mode (not in test mode), PHY has internal pull down. */ AT91C_BASE_PIOB->PIO_PPUDR = 1 << 15; #if USE_RMII_INTERFACE != 1 /* PHY has internal pull down : set MII mode. */ AT91C_BASE_PIOB->PIO_PPUDR = 1 << 16; #endif /* Clear PB18 <=> PHY powerdown. */ AT91C_BASE_PIOB->PIO_PER = 1 << 18; AT91C_BASE_PIOB->PIO_OER = 1 << 18; AT91C_BASE_PIOB->PIO_CODR = 1 << 18; /* After PHY power up, hardware reset. */ AT91C_BASE_RSTC->RSTC_RMR = emacRESET_KEY | emacRESET_LENGTH; AT91C_BASE_RSTC->RSTC_RCR = emacRESET_KEY | AT91C_RSTC_EXTRST; /* Wait for hardware reset end. */ while( !( AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL ) ) { __asm volatile ( "NOP" ); } __asm volatile ( "NOP" ); /* Setup the pins. */ AT91C_BASE_PIOB->PIO_ASR = emacPERIPHERAL_A_SETUP; AT91C_BASE_PIOB->PIO_PDR = emacPERIPHERAL_A_SETUP; /* Enable com between EMAC PHY. Enable management port. */ AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; /* MDC = MCK/32. */ AT91C_BASE_EMAC->EMAC_NCFGR |= ( 2 ) << 10; /* Wait for PHY auto init end (rather crude delay!). */ vTaskDelay( emacPHY_INIT_DELAY ); /* PHY configuration. */ #if USE_RMII_INTERFACE != 1 { unsigned long ulControl; /* PHY has internal pull down : disable MII isolate. */ vReadPHY( AT91C_PHY_ADDR, MII_BMCR, &ulControl ); vReadPHY( AT91C_PHY_ADDR, MII_BMCR, &ulControl ); ulControl &= ~BMCR_ISOLATE; vWritePHY( AT91C_PHY_ADDR, MII_BMCR, ulControl ); } #endif /* Disable management port again. */ AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; #if USE_RMII_INTERFACE != 1 /* Enable EMAC in MII mode, enable clock ERXCK and ETXCK. */ AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_CLKEN ; #else /* Enable EMAC in RMII mode, enable RMII clock (50MHz from oscillator on ERFCK). */ AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_RMII | AT91C_EMAC_CLKEN ; #endif /* End of code supplied by Atmel ------------------------*/ /* Setup the buffers and descriptors. */ prvSetupDescriptors(); /* Load our MAC address into the EMAC. */ prvSetupMACAddress(); /* Are we connected? */ if( prvProbePHY() ) { /* Enable the interrupt! */ portENTER_CRITICAL(); { prvSetupEMACInterrupt(); vPassEMACSemaphore( xSemaphore ); } portEXIT_CRITICAL(); } return xSemaphore; }
bool xMACBInit(volatile avr32_macb_t *macb) { bool global_interrupt_enabled = Is_global_interrupt_enabled(); volatile unsigned long status; // generate an hardware reset of the phy ethernet_phy_hw_reset(); // generate a software reset of the phy ethernet_phy_sw_reset(macb); // set up registers macb->ncr = 0; macb->tsr = ~0UL; macb->rsr = ~0UL; if (global_interrupt_enabled) Disable_global_interrupt(); macb->idr = ~0UL; status = macb->isr; if (global_interrupt_enabled) Enable_global_interrupt(); #if ETHERNET_CONF_USE_RMII_INTERFACE // RMII used, set 0 to the USRIO Register macb->usrio &= ~AVR32_MACB_RMII_MASK; #else // RMII not used, set 1 to the USRIO Register macb->usrio |= AVR32_MACB_RMII_MASK; #endif // Load our MAC address into the MACB. prvSetupMACAddress(macb); // Setup the buffers and descriptors. prvSetupDescriptors(macb); #if ETHERNET_CONF_SYSTEM_CLOCK <= 20000000 macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV8 << AVR32_MACB_NCFGR_CLK_OFFSET); #elif ETHERNET_CONF_SYSTEM_CLOCK <= 40000000 macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV16 << AVR32_MACB_NCFGR_CLK_OFFSET); #elif ETHERNET_CONF_SYSTEM_CLOCK <= 80000000 macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV32 << AVR32_MACB_NCFGR_CLK_OFFSET; #elif ETHERNET_CONF_SYSTEM_CLOCK <= 160000000 macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV64 << AVR32_MACB_NCFGR_CLK_OFFSET; #else # error System clock too fast #endif // Are we connected? if( prvProbePHY(macb) == true ) { // Enable the interrupt! portENTER_CRITICAL(); { prvSetupMACBInterrupt(macb); } portEXIT_CRITICAL(); // Enable Rx and Tx, plus the stats register. macb->ncr = AVR32_MACB_NCR_TE_MASK | AVR32_MACB_NCR_RE_MASK; return (true); } return (false); }