static void prvSetupMACBInterrupt(volatile avr32_macb_t *macb) { #ifdef FREERTOS_USED // Create the semaphore used to trigger the MACB task. if (xSemaphore == NULL) { vSemaphoreCreateBinary( xSemaphore ); } #else // Init the variable counting the number of received frames not yet read. DataToRead = 0; #endif #ifdef FREERTOS_USED if( xSemaphore != NULL) { // We start by 'taking' the semaphore so the ISR can 'give' it when the // first interrupt occurs. xSemaphoreTake( xSemaphore, 0 ); #endif // Setup the interrupt for MACB. // Register the interrupt handler to the interrupt controller at interrupt level 2 INTC_register_interrupt((__int_handler)&vMACB_ISR, AVR32_MACB_IRQ, AVR32_INTC_INT2); #if ETHERNET_CONF_USE_PHY_IT == 1 /* GPIO enable interrupt upon rising edge */ gpio_enable_pin_interrupt(EXTPHY_MACB_INTERRUPT_PIN, GPIO_FALLING_EDGE); // Setup the interrupt for PHY. // Register the interrupt handler to the interrupt controller at interrupt level 2 INTC_register_interrupt((__int_handler)&vPHY_ISR, (AVR32_GPIO_IRQ_0 + (EXTPHY_MACB_INTERRUPT_PIN/8)), AVR32_INTC_INT2); /* enable interrupts on INT pin */ vWriteMDIO( macb, PHY_MICR , ( MICR_INTEN | MICR_INTOE )); /* enable "link change" interrupt for Phy */ vWriteMDIO( macb, PHY_MISR , MISR_LINK_INT_EN ); #endif // We want to interrupt on Rx and Tx events macb->ier = AVR32_MACB_IER_RCOMP_MASK | AVR32_MACB_IER_TCOMP_MASK; #ifdef FREERTOS_USED } #endif }
static bool prvProbePHY(volatile avr32_macb_t *macb) { volatile unsigned long mii_status; volatile unsigned long config; unsigned long upper, lower, advertise, lpa; volatile unsigned long physID; // Read Phy Identifier register 1 & 2 lower = ulReadMDIO(macb, PHY_PHYSID2); upper = ulReadMDIO(macb, PHY_PHYSID1); // get Phy ID, ignore Revision physID = ((upper << 16) & 0xFFFF0000) | (lower & 0xFFF0); // check if it match config if (physID == EXTPHY_PHY_ID) { #if ETHERNET_CONF_USE_RMII_INTERFACE // setup rmii mode ethernet_phy_setup_rmii(macb); #endif // set advertise register #if ETHERNET_CONF_AN_ENABLE == 1 advertise = ADVERTISE_CSMA | ADVERTISE_ALL; #else advertise = ADVERTISE_CSMA; #if ETHERNET_CONF_USE_100MB #if ETHERNET_CONF_USE_FULL_DUPLEX advertise |= ADVERTISE_100FULL; #else advertise |= ADVERTISE_100HALF; #endif #else #if ETHERNET_CONF_USE_FULL_DUPLEX advertise |= ADVERTISE_10FULL; #else advertise |= ADVERTISE_10HALF; #endif #endif #endif // write advertise register vWriteMDIO(macb, PHY_ADVERTISE, advertise); // read Control register config = ulReadMDIO(macb, PHY_BMCR); // setup auto negociation ethernet_phy_setup_auto_negociation(macb, &config); // update ctrl register vWriteMDIO(macb, PHY_BMCR, config); // loop while link status isn't OK do { mii_status = ulReadMDIO(macb, PHY_BMSR); } while (!(mii_status & BMSR_LSTATUS)); // read the LPA configuration of the PHY lpa = ulReadMDIO(macb, PHY_LPA); // read the MACB config register config = AVR32_MACB.ncfgr; // if 100MB needed if ((lpa & advertise) & (LPA_100HALF | LPA_100FULL)) { config |= AVR32_MACB_SPD_MASK; } else { config &= ~(AVR32_MACB_SPD_MASK); } // if FULL DUPLEX needed if ((lpa & advertise) & (LPA_10FULL | LPA_100FULL)) { config |= AVR32_MACB_FD_MASK; } else { config &= ~(AVR32_MACB_FD_MASK); } // write the MACB config register macb->ncfgr = config; return true; } return false; }
static void prvSetupMACBInterrupt(volatile avr32_macb_t *macb) { #ifdef FREERTOS_USED // Create the semaphore used to trigger the MACB task. if (xSemaphore == NULL) { vSemaphoreCreateBinary( xSemaphore ); } #else // Init the variable counting the number of received frames not yet read. DataToRead = 0; #endif #ifdef FREERTOS_USED if( xSemaphore != NULL) { // We start by 'taking' the semaphore so the ISR can 'give' it when the // first interrupt occurs. xSemaphoreTake( xSemaphore, 0 ); #endif // Setup the interrupt for MACB. // Register the interrupt handler to the interrupt controller at interrupt level 2 INTC_register_interrupt((__int_handler)&vMACB_ISR, AVR32_MACB_IRQ, AVR32_INTC_INT2); #if ETHERNET_CONF_USE_PHY_IT == 1 #if EXTPHY_MACB_USE_EXTINT static const gpio_map_t EIC_GPIO_MAP = { {EXTPHY_MACB_INTERRUPT_PIN, EXTPHY_MACB_INTERRUPT_FUNCTION}, }; gpio_enable_module(EIC_GPIO_MAP, sizeof(EIC_GPIO_MAP) / sizeof(EIC_GPIO_MAP[0])); // Enable GPIO pull ups for the interrupt pin. gpio_enable_pin_pull_up(EXTPHY_MACB_INTERRUPT_PIN); // Setup the interrupt for PHY. // Register the interrupt handler to the interrupt controller at interrupt level 2 INTC_register_interrupt((__int_handler)&vPHY_ISR, EXTPHY_MACB_INTERRUPT_IRQ, AVR32_INTC_INT2); // Enable edge-triggered interrupt. eic_options.eic_mode = EIC_MODE_EDGE_TRIGGERED; // Interrupt will trigger on falling edge (this is a must-do for the keypad scan // feature if the chosen mode is edge-triggered). eic_options.eic_edge = EIC_EDGE_FALLING_EDGE; // Initialize in synchronous mode : interrupt is synchronized to the clock eic_options.eic_async = EIC_SYNCH_MODE; // Set the interrupt line number. eic_options.eic_line = EXTPHY_MACB_INTERRUPT; // Init the EIC controller with the options eic_init(&AVR32_EIC, &eic_options, 1); // Enable the EIC line. eic_enable_line(&AVR32_EIC, EXTPHY_MACB_INTERRUPT); // Enable the interrupt for the EIC line. eic_enable_interrupt_line(&AVR32_EIC, EXTPHY_MACB_INTERRUPT); #else /* GPIO enable interrupt upon rising edge */ gpio_enable_pin_interrupt(EXTPHY_MACB_INTERRUPT_PIN, GPIO_FALLING_EDGE); // Setup the interrupt for PHY. // Register the interrupt handler to the interrupt controller at interrupt level 2 INTC_register_interrupt((__int_handler)&vPHY_ISR, (AVR32_GPIO_IRQ_0 + (EXTPHY_MACB_INTERRUPT_PIN/8)), AVR32_INTC_INT2); #endif /* enable interrupts on INT pin */ vWriteMDIO( macb, PHY_MICR , ( MICR_INTEN | MICR_INTOE )); /* enable "link change" interrupt for Phy */ vWriteMDIO( macb, PHY_MISR , MISR_LINK_INT_EN ); #endif // We want to interrupt on Rx and Tx events macb->ier = AVR32_MACB_IER_RCOMP_MASK | AVR32_MACB_IER_TCOMP_MASK; #ifdef FREERTOS_USED } #endif }
static bool prvProbePHY(volatile avr32_macb_t *macb) { volatile unsigned long config; unsigned long upper, lower, advertise; volatile unsigned long physID; // Read Phy Identifier register 1 & 2 lower = ulReadMDIO(macb, PHY_PHYSID2); upper = ulReadMDIO(macb, PHY_PHYSID1); // get Phy ID, ignore Revision physID = ((upper << 16) & 0xFFFF0000) | (lower & 0xFFF0); // check if it match config if (physID == EXTPHY_PHY_ID) { #if ETHERNET_CONF_USE_RMII_INTERFACE // setup rmii mode ethernet_phy_setup_rmii(macb); #endif // set advertise register #if ETHERNET_CONF_AN_ENABLE == 1 advertise = ADVERTISE_CSMA | ADVERTISE_ALL; #else advertise = ADVERTISE_CSMA; #if ETHERNET_CONF_USE_100MB #if ETHERNET_CONF_USE_FULL_DUPLEX advertise |= ADVERTISE_100FULL; #else advertise |= ADVERTISE_100HALF; #endif #else #if ETHERNET_CONF_USE_FULL_DUPLEX advertise |= ADVERTISE_10FULL; #else advertise |= ADVERTISE_10HALF; #endif #endif #endif // write advertise register vWriteMDIO(macb, PHY_ADVERTISE, advertise); // read Control register config = ulReadMDIO(macb, PHY_BMCR); // setup auto negotiation ethernet_phy_setup_auto_negotiation(macb, &config); // update ctrl register vWriteMDIO(macb, PHY_BMCR, config); #if (ETHERNET_CONF_USE_PHY_IT == 0) volatile unsigned long mii_status; // loop while link status isn't OK do { mii_status = ulReadMDIO(macb, PHY_BMSR); } while (!(mii_status & BMSR_LSTATUS)); prvSetupMACBConfig(macb); #endif /* ETHERNET_CONF_USE_PHY_IT == 0 */ return true; } return false; }
static Bool prvProbePHY( volatile avr32_macb_t * macb ) { volatile unsigned long mii_status, phy_ctrl; volatile unsigned long config; unsigned long upper, lower, mode, advertise, lpa; volatile unsigned long physID; // Read Phy Identifier register 1 & 2 lower = ulReadMDIO(macb, PHY_PHYSID2); upper = ulReadMDIO(macb, PHY_PHYSID1); // get Phy ID, ignore Revision physID = ((upper << 16) & 0xFFFF0000) | (lower & 0xFFF0); // check if it match config if (physID == ETHERNET_CONF_PHY_ID) { // read RBR mode = ulReadMDIO(macb, PHY_RBR); // set RMII mode if not done if ((mode & RBR_RMII) != RBR_RMII) { // force RMII flag if strap options are wrong mode |= RBR_RMII; vWriteMDIO(macb, PHY_RBR, mode); } // set advertise register #if ETHERNET_CONF_AN_ENABLE == 1 advertise = ADVERTISE_CSMA | ADVERTISE_ALL; #else advertise = ADVERTISE_CSMA; #if ETHERNET_CONF_USE_100MB #if ETHERNET_CONF_USE_FULL_DUPLEX advertise |= ADVERTISE_100FULL; #else advertise |= ADVERTISE_100HALF; #endif #else #if ETHERNET_CONF_USE_FULL_DUPLEX advertise |= ADVERTISE_10FULL; #else advertise |= ADVERTISE_10HALF; #endif #endif #endif // write advertise register vWriteMDIO(macb, PHY_ADVERTISE, advertise); // read Control register config = ulReadMDIO(macb, PHY_BMCR); // read Phy Control register phy_ctrl = ulReadMDIO(macb, PHY_PHYCR); #if ETHERNET_CONF_AN_ENABLE #if ETHERNET_CONF_AUTO_CROSS_ENABLE // enable Auto MDIX phy_ctrl |= PHYCR_MDIX_EN; #else // disable Auto MDIX phy_ctrl &= ~PHYCR_MDIX_EN; #if ETHERNET_CONF_CROSSED_LINK // force direct link = Use crossed RJ45 cable phy_ctrl &= ~PHYCR_MDIX_FORCE; #else // force crossed link = Use direct RJ45 cable phy_ctrl |= PHYCR_MDIX_FORCE; #endif #endif // reset auto-negociation capability config |= (BMCR_ANRESTART | BMCR_ANENABLE); #else // disable Auto MDIX phy_ctrl &= ~PHYCR_MDIX_EN; #if ETHERNET_CONF_CROSSED_LINK // force direct link = Use crossed RJ45 cable phy_ctrl &= ~PHYCR_MDIX_FORCE; #else // force crossed link = Use direct RJ45 cable phy_ctrl |= PHYCR_MDIX_FORCE; #endif // clear AN bit config &= ~BMCR_ANENABLE; #if ETHERNET_CONF_USE_100MB config |= BMCR_SPEED100; #else config &= ~BMCR_SPEED100; #endif #if ETHERNET_CONF_USE_FULL_DUPLEX config |= BMCR_FULLDPLX; #else config &= ~BMCR_FULLDPLX; #endif #endif // update Phy ctrl register vWriteMDIO(macb, PHY_PHYCR, phy_ctrl); // update ctrl register vWriteMDIO(macb, PHY_BMCR, config); // loop while link status isn't OK do { mii_status = ulReadMDIO(macb, PHY_BMSR); } while (!(mii_status & BMSR_LSTATUS)); // read the LPA configuration of the PHY lpa = ulReadMDIO(macb, PHY_LPA); // read the MACB config register config = AVR32_MACB.ncfgr; // if 100MB needed if ((lpa & advertise) & (LPA_100HALF | LPA_100FULL)) { config |= AVR32_MACB_SPD_MASK; } else { config &= ~(AVR32_MACB_SPD_MASK); } // if FULL DUPLEX needed if ((lpa & advertise) & (LPA_10FULL | LPA_100FULL)) { config |= AVR32_MACB_FD_MASK; } else { config &= ~(AVR32_MACB_FD_MASK); } // write the MACB config register macb->ncfgr = config; return TRUE; } return FALSE; }