Esempio n. 1
0
static long prvPHY_ISR_NonNakedBehaviour(void)
{
	// Variable definitions can be made now.
	volatile unsigned long ulIntStatus, ulEventStatus;
	long xSwitchRequired = false;
	
	// read Phy Interrupt register Status
	ulIntStatus = ulReadMDIO(&AVR32_MACB, PHY_MISR);

	// read Phy status register
	ulEventStatus = ulReadMDIO(&AVR32_MACB, PHY_BMSR);
	// dummy read
	ulEventStatus = ulReadMDIO(&AVR32_MACB, PHY_BMSR);
  
	if(ulEventStatus & BMSR_LSTATUS) 
	{
		prvSetupMACBConfig(&AVR32_MACB);
	}

#if EXTPHY_MACB_USE_EXTINT
	eic_clear_interrupt_line(&AVR32_EIC, EXTPHY_MACB_INTERRUPT);
#else
	volatile avr32_gpio_t *gpio = &AVR32_GPIO;
	volatile avr32_gpio_port_t *gpio_port = &gpio->port[EXTPHY_MACB_INTERRUPT_PIN/32];
	// clear interrupt flag on GPIO
	gpio_port->ifrc =  1 << (EXTPHY_MACB_INTERRUPT_PIN%32);
#endif  

	return ( xSwitchRequired );
}
Esempio n. 2
0
static long prvPHY_ISR_NonNakedBehaviour(void)
{
  // Variable definitions can be made now.
  volatile unsigned long ulIntStatus, ulEventStatus;
  long xSwitchRequired = false;
  volatile avr32_gpio_t *gpio = &AVR32_GPIO;
  volatile avr32_gpio_port_t *gpio_port = &gpio->port[EXTPHY_MACB_INTERRUPT_PIN/32];

  // read Phy Interrupt register Status
  ulIntStatus = ulReadMDIO(&AVR32_MACB, PHY_MISR);

  // read Phy status register
  ulEventStatus = ulReadMDIO(&AVR32_MACB, PHY_BMSR);
  // dummy read
  ulEventStatus = ulReadMDIO(&AVR32_MACB, PHY_BMSR);

   // clear interrupt flag on GPIO
  gpio_port->ifrc =  1 << (EXTPHY_MACB_INTERRUPT_PIN%32);

  return ( xSwitchRequired );
}
Esempio n. 3
0
static void prvSetupMACBConfig(volatile avr32_macb_t *macb)
{
  volatile unsigned long lpa, config, advertise;

  // read the LPA configuration of the PHY
  lpa = ulReadMDIO(macb, PHY_LPA);

  // read the MACB config register
  config = macb->ncfgr;

  // 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

  // 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;
}
Esempio n. 4
0
static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
{
TickType_t xStartTime = xTaskGetTickCount();
TickType_t xEndTime;
BaseType_t xReturn;
const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );

	for( ;; )
	{
		xEndTime = xTaskGetTickCount();

		if( ( xEndTime - xStartTime ) > xMaxTime )
		{
			/* Wated more than xMaxTime, return. */
			xReturn = pdFALSE;
			break;
		}

		/* Check the link status again. */
		ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );

		if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
		{
			/* Link is up - return. */
			xReturn = pdTRUE;
			break;
		}

		/* Link is down - wait in the Blocked state for a short while (to allow
		other tasks to execute) before checking again. */
		vTaskDelay( xShortTime );
	}

	FreeRTOS_printf( ( "xGMACWaitLS: %ld (PHY %d) freq %lu Mz\n",
		xReturn,
		ethernet_phy_addr,
		sysclk_get_cpu_hz() / HZ_PER_MHZ ) );

	return xReturn;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxCount;
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
	NetworkBufferDescriptor_t *pxBuffer;
#endif
uint8_t *pucBuffer;
BaseType_t xResult = 0;
uint32_t xStatus;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );

	/* Remove compiler warnings about unused parameters. */
	( void ) pvParameters;

	configASSERT( xEMACTaskHandle );

	vTaskSetTimeOutState( &xPhyTime );
	xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );

	for( ;; )
	{
		vCheckBuffersAndQueue();

		if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
		{
			/* No events to process now, wait for the next. */
			ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
		}

		if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
		{
			ulISREvents &= ~EMAC_IF_RX_EVENT;

			/* Wait for the EMAC interrupt to indicate that another packet has been
			received. */
			xResult = prvEMACRxPoll();
		}

		if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
		{
			/* Future extension: code to release TX buffers if zero-copy is used. */
			ulISREvents &= ~EMAC_IF_TX_EVENT;
			while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
			{
				#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
				{
					pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
					if( pxBuffer != NULL )
					{
						vReleaseNetworkBufferAndDescriptor( pxBuffer );
						tx_release_count[ 0 ]++;
					}
					else
					{
						tx_release_count[ 1 ]++;
					}
				}
				#else
				{
					tx_release_count[ 0 ]++;
				}
				#endif
				uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
				if( uxCount < GMAC_TX_BUFFERS )
				{
					/* Tell the counting semaphore that one more TX descriptor is available. */
					xSemaphoreGive( xTXDescriptorSemaphore );
				}
			}
		}

		if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
		{
			/* Future extension: logging about errors that occurred. */
			ulISREvents &= ~EMAC_IF_ERR_EVENT;
		}

		if( xResult > 0 )
		{
			/* A packet was received. No need to check for the PHY status now,
			but set a timer to check it later on. */
			vTaskSetTimeOutState( &xPhyTime );
			xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
			xResult = 0;
		}
		else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
		{
			/* Check the link status again. */
			xStatus = ulReadMDIO( PHY_REG_01_BMSR );

			if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
			{
				ulPHYLinkStatus = xStatus;
				FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
			}

			vTaskSetTimeOutState( &xPhyTime );
			if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
			{
				xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
			}
			else
			{
				xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
			}
		}
	}
}