#include "FreeRTOS_DNS.h"\r
#include "NetworkBufferManagement.h"\r
#include "NetworkInterface.h"\r
+#include "phyHandling.h"\r
\r
/* ST includes. */\r
-#include "stm32f4xx_hal.h"\r
-\r
-#ifndef BMSR_LINK_STATUS\r
- #define BMSR_LINK_STATUS 0x0004UL\r
-#endif\r
-\r
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS\r
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not\r
- receiving packets. */\r
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000\r
-#endif\r
-\r
-#ifndef PHY_LS_LOW_CHECK_TIME_MS\r
- /* Check if the LinkSStatus in the PHY is still low every second. */\r
- #define PHY_LS_LOW_CHECK_TIME_MS 1000\r
+#ifdef STM32F7xx\r
+ #include "stm32f7xx_hal.h"\r
+#else\r
+ #include "stm32f4xx_hal.h"\r
#endif\r
\r
/* Interrupt events to process. Currently only the Rx event is processed\r
ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \\r
ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )\r
\r
-/* Naming and numbering of PHY registers. */\r
-#define PHY_REG_00_BMCR 0x00 /* Basic Mode Control Register. */\r
-#define PHY_REG_01_BMSR 0x01 /* Basic Mode Status Register. */\r
-#define PHY_REG_02_PHYSID1 0x02 /* PHYS ID 1 */\r
-#define PHY_REG_03_PHYSID2 0x03 /* PHYS ID 2 */\r
-#define PHY_REG_04_ADVERTISE 0x04 /* Advertisement control reg */\r
-\r
-#define PHY_ID_LAN8720 0x0007c0f0\r
-#define PHY_ID_DP83848I 0x20005C90\r
-\r
-#ifndef USE_STM324xG_EVAL\r
- #define USE_STM324xG_EVAL 1\r
-#endif\r
-\r
-#if( USE_STM324xG_EVAL == 0 )\r
- #define EXPECTED_PHY_ID PHY_ID_LAN8720\r
- #define PHY_REG_1F_PHYSPCS 0x1F /* 31 RW PHY Special Control Status */\r
- /* Use 3 bits in register 31 */\r
- #define PHYSPCS_SPEED_MASK 0x0C\r
- #define PHYSPCS_SPEED_10 0x04\r
- #define PHYSPCS_SPEED_100 0x08\r
- #define PHYSPCS_FULL_DUPLEX 0x10\r
-#else\r
- #define EXPECTED_PHY_ID PHY_ID_DP83848I\r
-\r
- #define PHY_REG_10_PHY_SR 0x10 /* PHY status register Offset */\r
- #define PHY_REG_19_PHYCR 0x19 /* 25 RW PHY Control Register */\r
-#endif\r
-\r
-/* Some defines used internally here to indicate preferences about speed, MDIX\r
-(wired direct or crossed), and duplex (half or full). */\r
-#define PHY_SPEED_10 1\r
-#define PHY_SPEED_100 2\r
-#define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)\r
-\r
-#define PHY_MDIX_DIRECT 1\r
-#define PHY_MDIX_CROSSED 2\r
-#define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)\r
-\r
-#define PHY_DUPLEX_HALF 1\r
-#define PHY_DUPLEX_FULL 2\r
-#define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)\r
\r
-#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */\r
-\r
-/*\r
- * Description of all capabilities that can be advertised to\r
- * the peer (usually a switch or router).\r
- */\r
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported. */\r
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex. */\r
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex. */\r
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex. */\r
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex. */\r
-\r
-#define ADVERTISE_ALL ( ADVERTISE_10HALF | ADVERTISE_10FULL | \\r
- ADVERTISE_100HALF | ADVERTISE_100FULL)\r
-\r
-/*\r
- * Value for the 'PHY_REG_00_BMCR', the PHY's Basic Mode Control Register.\r
- */\r
-#define BMCR_FULLDPLX 0x0100 /* Full duplex. */\r
-#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart. */\r
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation. */\r
-#define BMCR_SPEED100 0x2000 /* Select 100Mbps. */\r
-#define BMCR_RESET 0x8000 /* Reset the PHY. */\r
-\r
-#define PHYCR_MDIX_EN 0x8000 /* Enable Auto MDIX. */\r
-#define PHYCR_MDIX_FORCE 0x4000 /* Force MDIX crossed. */\r
\r
#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */\r
\r
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )\r
#endif\r
\r
+/* Two choices must be made: RMII versus MII,\r
+and the index of the PHY in use ( between 0 and 31 ). */\r
+#ifndef ipconfigUSE_RMII\r
+ #ifdef STM32F7xx\r
+ #define ipconfigUSE_RMII 1\r
+ #else\r
+ #define ipconfigUSE_RMII 0\r
+ #endif /* STM32F7xx */\r
+#endif /* ipconfigUSE_RMII */\r
+\r
+\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
*/\r
static void prvDMARxDescListInit( void );\r
\r
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
- /* After packets have been sent, the network\r
- buffers will be released. */\r
- static void vClearTXBuffers( void );\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+/* After packets have been sent, the network\r
+buffers will be released. */\r
+static void vClearTXBuffers( void );\r
\r
/*-----------------------------------------------------------*/\r
\r
-typedef struct _PhyProperties_t\r
-{\r
- uint8_t speed;\r
- uint8_t mdix;\r
- uint8_t duplex;\r
- uint8_t spare;\r
-} PhyProperties_t;\r
-\r
/* Bit map of outstanding ETH interrupt events for processing. Currently only\r
the Rx interrupt is handled, although code is included for other events to\r
enable future expansion. */\r
static volatile uint32_t ulISREvents;\r
\r
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */\r
-static uint32_t ulPHYLinkStatus = 0;\r
-\r
#if( ipconfigUSE_LLMNR == 1 )\r
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };\r
#endif\r
\r
+static EthernetPhy_t xPhyObject;\r
+\r
/* Ethernet handle. */\r
static ETH_HandleTypeDef xETH;\r
\r
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
- /* xTXDescriptorSemaphore is a counting semaphore with\r
- a maximum count of ETH_TXBUFNB, which is the number of\r
- DMA TX descriptors. */\r
- static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+/* xTXDescriptorSemaphore is a counting semaphore with\r
+a maximum count of ETH_TXBUFNB, which is the number of\r
+DMA TX descriptors. */\r
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;\r
\r
/*\r
* Note: it is adviced to define both\r
* TX buffers are allocated in a zero-copy driver.\r
*/\r
/* MAC buffers: ---------------------------------------------------------*/\r
-__ALIGN_BEGIN ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ] __ALIGN_END;/* Ethernet Rx MA Descriptor */\r
+\r
+/* Put the DMA descriptors in '.first_data'.\r
+This is important for STM32F7, which has an L1 data cache.\r
+The first 64KB of the SRAM is not cached. */\r
+\r
+/* Ethernet Rx MA Descriptor */\r
+__attribute__ ((aligned (32)))\r
+__attribute__ ((section(".first_data")))\r
+ ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ];\r
+\r
#if( ipconfigZERO_COPY_RX_DRIVER == 0 )\r
- __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END; /* Ethernet Receive Buffer */\r
+ /* Ethernet Receive Buffer */\r
+ __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END;\r
#endif\r
\r
-__ALIGN_BEGIN ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ] __ALIGN_END;/* Ethernet Tx DMA Descriptor */\r
+/* Ethernet Tx DMA Descriptor */\r
+__attribute__ ((aligned (32)))\r
+__attribute__ ((section(".first_data")))\r
+ ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ];\r
+\r
#if( ipconfigZERO_COPY_TX_DRIVER == 0 )\r
- __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END; /* Ethernet Transmit Buffer */\r
+ /* Ethernet Transmit Buffer */\r
+ __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;\r
#endif\r
\r
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
static __IO ETH_DMADescTypeDef *DMATxDescToClear;\r
#endif\r
\r
-/* Value to be written into the 'Basic mode Control Register'. */\r
-static uint32_t ulBCRvalue;\r
-\r
-/* Value to be written into the 'Advertisement Control Register'. */\r
-static uint32_t ulACRValue;\r
-\r
/* ucMACAddress as it appears in main.c */\r
extern const uint8_t ucMACAddress[ 6 ];\r
\r
const PhyProperties_t xPHYProperties =\r
{\r
#if( ipconfigETHERNET_AN_ENABLE != 0 )\r
- .speed = PHY_SPEED_AUTO,\r
- .duplex = PHY_DUPLEX_AUTO,\r
+ .ucSpeed = PHY_SPEED_AUTO,\r
+ .ucDuplex = PHY_DUPLEX_AUTO,\r
#else\r
#if( ipconfigETHERNET_USE_100MB != 0 )\r
- .speed = PHY_SPEED_100,\r
+ .ucSpeed = PHY_SPEED_100,\r
#else\r
- .speed = PHY_SPEED_10,\r
+ .ucSpeed = PHY_SPEED_10,\r
#endif\r
\r
#if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )\r
#endif\r
\r
#if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )\r
- .mdix = PHY_MDIX_AUTO,\r
+ .ucMDI_X = PHY_MDIX_AUTO,\r
#elif( ipconfigETHERNET_CROSSED_LINK != 0 )\r
- .mdix = PHY_MDIX_CROSSED,\r
+ .ucMDI_X = PHY_MDIX_CROSSED,\r
#else\r
- .mdix = PHY_MDIX_DIRECT,\r
+ .ucMDI_X = PHY_MDIX_DIRECT,\r
#endif\r
};\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
- void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )\r
- {\r
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- /* This call-back is only useful in case packets are being sent\r
- zero-copy. Once they're sent, the buffers will be released\r
- by the function vClearTXBuffers(). */\r
- ulISREvents |= EMAC_IF_TX_EVENT;\r
- /* Wakeup the prvEMACHandlerTask. */\r
- if( xEMACTaskHandle != NULL )\r
- {\r
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );\r
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
- }\r
+void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )\r
+{\r
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
\r
+ /* This call-back is only useful in case packets are being sent\r
+ zero-copy. Once they're sent, the buffers will be released\r
+ by the function vClearTXBuffers(). */\r
+ ulISREvents |= EMAC_IF_TX_EVENT;\r
+ /* Wakeup the prvEMACHandlerTask. */\r
+ if( xEMACTaskHandle != NULL )\r
+ {\r
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );\r
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
}\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
\r
+}\r
/*-----------------------------------------------------------*/\r
\r
+static void vClearTXBuffers()\r
+{\r
+__IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;\r
+size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );\r
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
- static void vClearTXBuffers()\r
- {\r
- __IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;\r
NetworkBufferDescriptor_t *pxNetworkBuffer;\r
uint8_t *ucPayLoad;\r
- size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );\r
+#endif\r
\r
- /* This function is called after a TX-completion interrupt.\r
- It will release each Network Buffer used in xNetworkInterfaceOutput().\r
- 'uxCount' represents the number of descriptors given to DMA for transmission.\r
- After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */\r
- while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )\r
+ /* This function is called after a TX-completion interrupt.\r
+ It will release each Network Buffer used in xNetworkInterfaceOutput().\r
+ 'uxCount' represents the number of descriptors given to DMA for transmission.\r
+ After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */\r
+ while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )\r
+ {\r
+ if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )\r
+ {\r
+ break;\r
+ }\r
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
{\r
- if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )\r
- {\r
- break;\r
- }\r
-\r
ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;\r
\r
if( ucPayLoad != NULL )\r
}\r
DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;\r
}\r
+ }\r
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
\r
- DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );\r
+ DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );\r
\r
- uxCount--;\r
- /* Tell the counting semaphore that one more TX descriptor is available. */\r
- xSemaphoreGive( xTXDescriptorSemaphore );\r
- }\r
+ uxCount--;\r
+ /* Tell the counting semaphore that one more TX descriptor is available. */\r
+ xSemaphoreGive( xTXDescriptorSemaphore );\r
}\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+}\r
/*-----------------------------------------------------------*/\r
\r
BaseType_t xNetworkInterfaceInitialise( void )\r
\r
if( xEMACTaskHandle == NULL )\r
{\r
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
+ if( xTXDescriptorSemaphore == NULL )\r
{\r
- if( xTXDescriptorSemaphore == NULL )\r
- {\r
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );\r
- configASSERT( xTXDescriptorSemaphore );\r
- }\r
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );\r
+ configASSERT( xTXDescriptorSemaphore );\r
}\r
- #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
\r
/* Initialise ETH */\r
\r
xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;\r
xETH.Init.Speed = ETH_SPEED_100M;\r
xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;\r
- xETH.Init.PhyAddress = 1;\r
+ /* Value of PhyAddress doesn't matter, will be probed for. */\r
+ xETH.Init.PhyAddress = 0;\r
\r
xETH.Init.MACAddr = ( uint8_t *) ucMACAddress;\r
xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;\r
by the peripheral. */\r
xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;\r
\r
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;\r
+ #if( ipconfigUSE_RMII != 0 )\r
+ {\r
+ xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;\r
+ }\r
+ #else\r
+ {\r
+ xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;\r
+ }\r
+ #endif /* ipconfigUSE_RMII */\r
+\r
hal_eth_init_status = HAL_ETH_Init( &xETH );\r
\r
/* Only for inspection by debugger. */\r
memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );\r
memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );\r
\r
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
- {\r
- /* Initialize Tx Descriptors list: Chain Mode */\r
- DMATxDescToClear = DMATxDscrTab;\r
- }\r
- #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+ /* Initialize Tx Descriptors list: Chain Mode */\r
+ DMATxDescToClear = DMATxDscrTab;\r
\r
/* Initialise TX-descriptors. */\r
prvDMATxDescListInit();\r
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );\r
} /* if( xEMACTaskHandle == NULL ) */\r
\r
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+ if( xPhyObject.ulLinkStatusMask != 0 )\r
{\r
xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;\r
xResult = pdPASS;\r
else\r
{\r
/* For now pdFAIL will be returned. But prvEMACHandlerTask() is running\r
- and it will keep on checking the PHY and set ulPHYLinkStatus when necessary. */\r
+ and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */\r
xResult = pdFAIL;\r
FreeRTOS_printf( ( "Link Status still low\n" ) ) ;\r
}\r
{\r
ProtocolPacket_t *pxPacket;\r
\r
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )\r
+ {\r
+ configASSERT( bReleaseAfterSend != 0 );\r
+ }\r
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */\r
+\r
/* If the peripheral must calculate the checksum, it wants\r
the protocol checksum to have a value of zero. */\r
pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );\r
/* Open a do {} while ( 0 ) loop to be able to call break. */\r
do\r
{\r
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+ if( xPhyObject.ulLinkStatusMask != 0 )\r
{\r
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )\r
{\r
- if( xTXDescriptorSemaphore == NULL )\r
- {\r
- break;\r
- }\r
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )\r
- {\r
- /* Time-out waiting for a free TX descriptor. */\r
- break;\r
- }\r
+ /* Time-out waiting for a free TX descriptor. */\r
+ break;\r
}\r
- #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
\r
/* This function does the actual transmission of the packet. The packet is\r
contained in 'pxDescriptor' that is passed to the function. */\r
pxDmaTxDesc = xETH.TxDesc;\r
\r
/* Is this buffer available? */\r
- if( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 )\r
+ configASSERT ( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );\r
+\r
{\r
/* Is this buffer available? */\r
/* Get bytes in current buffer. */\r
{\r
/* Copy the bytes. */\r
memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );\r
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL;\r
}\r
#else\r
{\r
/* Move the buffer. */\r
pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;\r
- /* Ask to set the IPv4 checksum.\r
- Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */\r
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;\r
/* The Network Buffer has been passed to DMA, no need to release it. */\r
bReleaseAfterSend = pdFALSE_UNSIGNED;\r
}\r
#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
\r
+ /* Ask to set the IPv4 checksum.\r
+ Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */\r
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;\r
+\r
/* Prepare transmit descriptors to give to DMA. */\r
\r
/* Set LAST and FIRST segment */\r
\r
/* Point to next descriptor */\r
xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );\r
- \r
+ /* Ensure completion of memory access */\r
+ __DSB();\r
/* Resume DMA transmission*/\r
xETH.Instance->DMATPDR = 0;\r
iptraceNETWORK_INTERFACE_TRANSMIT();\r
pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE; \r
pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;\r
\r
+ /* Ensure completion of memory access */\r
+ __DSB();\r
/* When Rx Buffer unavailable flag is set clear it and resume\r
reception. */\r
if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vMACBProbePhy( void )\r
-{\r
-uint32_t ulConfig, ulAdvertise, ulLower, ulUpper, ulMACPhyID, ulValue;\r
-TimeOut_t xPhyTime;\r
-TickType_t xRemTime = 0;\r
-#if( EXPECTED_PHY_ID == PHY_ID_DP83848I )\r
- uint32_t ulPhyControl;\r
-#endif\r
-\r
- HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_03_PHYSID2, &ulLower);\r
- HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_02_PHYSID1, &ulUpper);\r
-\r
- ulMACPhyID = ( ( ulUpper << 16 ) & 0xFFFF0000 ) | ( ulLower & 0xFFF0 );\r
\r
- /* The expected ID for the 'LAN8720' is 0x0007c0f0. */\r
- /* The expected ID for the 'DP83848I' is 0x20005C90. */\r
-\r
- FreeRTOS_printf( ( "PHY ID %lX (%s)\n", ulMACPhyID,\r
- ( ulMACPhyID == EXPECTED_PHY_ID ) ? "OK" : "Unknown" ) );\r
+BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )\r
+{\r
+uint16_t usPrevAddress = xETH.Init.PhyAddress;\r
+BaseType_t xResult;\r
+HAL_StatusTypeDef xHALResult;\r
\r
- /* Remove compiler warning if FreeRTOS_printf() is not defined. */\r
- ( void ) ulMACPhyID;\r
+ xETH.Init.PhyAddress = xAddress;\r
+ xHALResult = HAL_ETH_ReadPHYRegister( &xETH, ( uint16_t )xRegister, pulValue );\r
+ xETH.Init.PhyAddress = usPrevAddress;\r
\r
- /* Set advertise register. */\r
- if( ( xPHYProperties.speed == PHY_SPEED_AUTO ) && ( xPHYProperties.duplex == PHY_DUPLEX_AUTO ) )\r
+ if( xHALResult == HAL_OK )\r
{\r
- ulAdvertise = ADVERTISE_CSMA | ADVERTISE_ALL;\r
- /* Reset auto-negotiation capability. */\r
+ xResult = 0;\r
}\r
else\r
{\r
- ulAdvertise = ADVERTISE_CSMA;\r
-\r
- if( xPHYProperties.speed == PHY_SPEED_AUTO )\r
- {\r
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
- {\r
- ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_100FULL;\r
- }\r
- else\r
- {\r
- ulAdvertise |= ADVERTISE_10HALF | ADVERTISE_100HALF;\r
- }\r
- }\r
- else if( xPHYProperties.duplex == PHY_DUPLEX_AUTO )\r
- {\r
- if( xPHYProperties.speed == PHY_SPEED_10 )\r
- {\r
- ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_10HALF;\r
- }\r
- else\r
- {\r
- ulAdvertise |= ADVERTISE_100FULL | ADVERTISE_100HALF;\r
- }\r
- }\r
- else if( xPHYProperties.speed == PHY_SPEED_100 )\r
- {\r
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
- {\r
- ulAdvertise |= ADVERTISE_100FULL;\r
- }\r
- else\r
- {\r
- ulAdvertise |= ADVERTISE_100HALF;\r
- }\r
- }\r
- else\r
- {\r
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
- {\r
- ulAdvertise |= ADVERTISE_10FULL;\r
- }\r
- else\r
- {\r
- ulAdvertise |= ADVERTISE_10HALF;\r
- }\r
- }\r
- }\r
-\r
- /* Read Control register. */\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );\r
-\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig | BMCR_RESET );\r
- xRemTime = ( TickType_t ) pdMS_TO_TICKS( 1000UL );\r
- vTaskSetTimeOutState( &xPhyTime );\r
-\r
- for( ; ; )\r
- {\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulValue );\r
- if( ( ulValue & BMCR_RESET ) == 0 )\r
- {\r
- FreeRTOS_printf( ( "BMCR_RESET ready\n" ) );\r
- break;\r
- }\r
- if( xTaskCheckForTimeOut( &xPhyTime, &xRemTime ) != pdFALSE )\r
- {\r
- FreeRTOS_printf( ( "BMCR_RESET timed out\n" ) );\r
- break;\r
- }\r
+ xResult = -1;\r
}\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig & ~BMCR_RESET );\r
+ return xResult;\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
- vTaskDelay( pdMS_TO_TICKS( 50ul ) );\r
+BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )\r
+{\r
+uint16_t usPrevAddress = xETH.Init.PhyAddress;\r
+BaseType_t xResult;\r
+HAL_StatusTypeDef xHALResult;\r
\r
- /* Write advertise register. */\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulAdvertise );\r
+ xETH.Init.PhyAddress = xAddress;\r
+ xHALResult = HAL_ETH_WritePHYRegister( &xETH, ( uint16_t )xRegister, ulValue );\r
+ xETH.Init.PhyAddress = usPrevAddress;\r
\r
- /*\r
- AN_EN AN1 AN0 Forced Mode\r
- 0 0 0 10BASE-T, Half-Duplex\r
- 0 0 1 10BASE-T, Full-Duplex\r
- 0 1 0 100BASE-TX, Half-Duplex\r
- 0 1 1 100BASE-TX, Full-Duplex\r
- AN_EN AN1 AN0 Advertised Mode\r
- 1 0 0 10BASE-T, Half/Full-Duplex\r
- 1 0 1 100BASE-TX, Half/Full-Duplex\r
- 1 1 0 10BASE-T Half-Duplex\r
- 100BASE-TX, Half-Duplex\r
- 1 1 1 10BASE-T, Half/Full-Duplex\r
- 100BASE-TX, Half/Full-Duplex\r
- */\r
-\r
- /* Read Control register. */\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );\r
-\r
- ulConfig &= ~( BMCR_ANRESTART | BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX );\r
-\r
- /* HT 12/9/14: always set AN-restart and AN-enable, even though the choices\r
- are limited. */\r
- ulConfig |= (BMCR_ANRESTART | BMCR_ANENABLE);\r
-\r
- if( xPHYProperties.speed == PHY_SPEED_100 )\r
+ if( xHALResult == HAL_OK )\r
{\r
- ulConfig |= BMCR_SPEED100;\r
+ xResult = 0;\r
}\r
- else if( xPHYProperties.speed == PHY_SPEED_10 )\r
+ else\r
{\r
- ulConfig &= ~BMCR_SPEED100;\r
+ xResult = -1;\r
}\r
+ return xResult;\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
- {\r
- ulConfig |= BMCR_FULLDPLX;\r
- }\r
- else if( xPHYProperties.duplex == PHY_DUPLEX_HALF )\r
- {\r
- ulConfig &= ~BMCR_FULLDPLX;\r
- }\r
+void phy_test()\r
+{\r
+BaseType_t xPhyCount;\r
+BaseType_t xPhyIndex;\r
\r
- #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )\r
- {\r
- }\r
- #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )\r
+ vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );\r
+ xPhyCount = xPhyDiscover( &xPhyObject );\r
+ FreeRTOS_printf( ( "PHY count %ld\n", xPhyCount ) );\r
+ for( xPhyIndex = 0; xPhyIndex < xPhyCount; xPhyIndex++ )\r
{\r
- /* Read PHY Control register. */\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_19_PHYCR, &ulPhyControl );\r
+ FreeRTOS_printf( ( "PHY[%d] at address %d ( 0x%08X )\n",\r
+ xPhyIndex,\r
+ xPhyObject.ucPhyIndexes[ xPhyIndex ],\r
+ xPhyObject.ulPhyIDs[ xPhyIndex ] ) );\r
\r
- /* Clear bits which might get set: */\r
- ulPhyControl &= ~( PHYCR_MDIX_EN|PHYCR_MDIX_FORCE );\r
-\r
- if( xPHYProperties.mdix == PHY_MDIX_AUTO )\r
- {\r
- ulPhyControl |= PHYCR_MDIX_EN;\r
- }\r
- else if( xPHYProperties.mdix == PHY_MDIX_CROSSED )\r
- {\r
- /* Force direct link = Use crossed RJ45 cable. */\r
- ulPhyControl &= ~PHYCR_MDIX_FORCE;\r
- }\r
- else\r
- {\r
- /* Force crossed link = Use direct RJ45 cable. */\r
- ulPhyControl |= PHYCR_MDIX_FORCE;\r
- }\r
- /* update PHY Control Register. */\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_19_PHYCR, ulPhyControl );\r
}\r
- #endif\r
- FreeRTOS_printf( ( "+TCP: advertise: %lX config %lX\n", ulAdvertise, ulConfig ) );\r
+ \r
+}\r
\r
- /* Now the two values to global values for later use. */\r
- ulBCRvalue = ulConfig;\r
- ulACRValue = ulAdvertise;\r
+void vMACBProbePhy( void )\r
+{\r
+ vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );\r
+ xPhyDiscover( &xPhyObject );\r
+ xPhyConfigure( &xPhyObject, &xPHYProperties );\r
}\r
/*-----------------------------------------------------------*/\r
\r
static void prvEthernetUpdateConfig( BaseType_t xForce )\r
{\r
-__IO uint32_t ulTimeout = 0;\r
-uint32_t ulRegValue = 0;\r
-\r
- FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS %d Force %d\n",\r
- ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ,\r
- xForce ) );\r
+ FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS mask %02lX Force %d\n",\r
+ xPhyObject.ulLinkStatusMask,\r
+ ( int )xForce ) );\r
\r
- if( ( xForce != pdFALSE ) || ( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) )\r
+ if( ( xForce != pdFALSE ) || ( xPhyObject.ulLinkStatusMask != 0 ) )\r
{\r
/* Restart the auto-negotiation. */\r
if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )\r
{\r
- /* Enable Auto-Negotiation. */\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue | BMCR_ANRESTART );\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulACRValue);\r
+ xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );\r
\r
- /* Wait until the auto-negotiation will be completed */\r
- do\r
+ /* Configure the MAC with the Duplex Mode fixed by the\r
+ auto-negotiation process. */\r
+ if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )\r
{\r
- ulTimeout++;\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue );\r
- } while( ( ( ulRegValue & PHY_AUTONEGO_COMPLETE) == 0 ) && ( ulTimeout < PHY_READ_TO ) );\r
-\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue & ~BMCR_ANRESTART );\r
-\r
- if( ulTimeout < PHY_READ_TO )\r
+ xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;\r
+ }\r
+ else\r
{\r
- /* Reset Timeout counter. */\r
- ulTimeout = 0;\r
-\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue);\r
- if( ( ulRegValue & BMSR_LINK_STATUS ) != 0 )\r
- {\r
- ulPHYLinkStatus |= BMSR_LINK_STATUS;\r
- }\r
- else\r
- {\r
- ulPHYLinkStatus &= ~( BMSR_LINK_STATUS );\r
- }\r
-\r
- #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )\r
- {\r
- /* 31 RW PHY Special Control Status */\r
- uint32_t ulControlStatus;\r
-\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_1F_PHYSPCS, &ulControlStatus);\r
- ulRegValue = 0;\r
- if( ( ulControlStatus & PHYSPCS_FULL_DUPLEX ) != 0 )\r
- {\r
- ulRegValue |= PHY_DUPLEX_STATUS;\r
- }\r
- if( ( ulControlStatus & PHYSPCS_SPEED_MASK ) == PHYSPCS_SPEED_10 )\r
- {\r
- ulRegValue |= PHY_SPEED_STATUS;\r
- }\r
-\r
- }\r
- #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )\r
- {\r
- /* Read the result of the auto-negotiation. */\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_10_PHY_SR, &ulRegValue);\r
- }\r
- #endif\r
- FreeRTOS_printf( ( ">> Autonego ready: %08lx: %s duplex %u mbit %s status\n",\r
- ulRegValue,\r
- (ulRegValue & PHY_DUPLEX_STATUS) ? "full" : "half",\r
- (ulRegValue & PHY_SPEED_STATUS) ? 10 : 100,\r
- ((ulPHYLinkStatus |= BMSR_LINK_STATUS) != 0) ? "high" : "low" ) );\r
-\r
- /* Configure the MAC with the Duplex Mode fixed by the\r
- auto-negotiation process. */\r
- if( ( ulRegValue & PHY_DUPLEX_STATUS ) != ( uint32_t ) RESET )\r
- {\r
- /* Set Ethernet duplex mode to Full-duplex following the\r
- auto-negotiation. */\r
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;\r
- }\r
- else\r
- {\r
- /* Set Ethernet duplex mode to Half-duplex following the\r
- auto-negotiation. */\r
- xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;\r
- }\r
+ xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;\r
+ }\r
\r
- /* Configure the MAC with the speed fixed by the\r
- auto-negotiation process. */\r
- if( ( ulRegValue & PHY_SPEED_STATUS) != 0 )\r
- {\r
- /* Set Ethernet speed to 10M following the\r
- auto-negotiation. */\r
- xETH.Init.Speed = ETH_SPEED_10M;\r
- }\r
- else\r
- {\r
- /* Set Ethernet speed to 100M following the\r
- auto-negotiation. */\r
- xETH.Init.Speed = ETH_SPEED_100M;\r
- }\r
- } /* if( ulTimeout < PHY_READ_TO ) */\r
+ /* Configure the MAC with the speed fixed by the\r
+ auto-negotiation process. */\r
+ if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )\r
+ {\r
+ xETH.Init.Speed = ETH_SPEED_10M;\r
+ }\r
+ else\r
+ {\r
+ xETH.Init.Speed = ETH_SPEED_100M;\r
+ }\r
}\r
else /* AutoNegotiation Disable */\r
{\r
- uint16_t usValue;\r
-\r
/* Check parameters */\r
assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );\r
assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );\r
\r
- /* Set MAC Speed and Duplex Mode to PHY */\r
- usValue = ( uint16_t ) ( xETH.Init.DuplexMode >> 3 ) | ( uint16_t ) ( xETH.Init.Speed >> 1 );\r
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, usValue );\r
+ if( xETH.Init.DuplexMode == ETH_MODE_FULLDUPLEX )\r
+ {\r
+ xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_HALF;\r
+ }\r
+ else\r
+ {\r
+ xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_FULL;\r
+ }\r
+\r
+ if( xETH.Init.Speed == ETH_SPEED_10M )\r
+ {\r
+ xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_10;\r
+ }\r
+ else\r
+ {\r
+ xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_100;\r
+ }\r
+\r
+ xPhyObject.xPhyPreferences.ucMDI_X = PHY_MDIX_AUTO;\r
+\r
+ /* Use predefined (fixed) configuration. */\r
+ xPhyFixedValue( &xPhyObject, xPhyGetMask( &xPhyObject ) );\r
}\r
\r
/* ETHERNET MAC Re-Configuration */\r
{\r
BaseType_t xReturn;\r
\r
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+ if( xPhyObject.ulLinkStatusMask != 0 )\r
{\r
xReturn = pdPASS;\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
+/* Uncomment this in case BufferAllocation_1.c is used. */\r
+\r
+/*\r
+#define niBUFFER_1_PACKET_SIZE 1536\r
+\r
+static __attribute__ ((section(".first_data"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );\r
+\r
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )\r
+{\r
+\r
+uint8_t *ucRAMBuffer = ucNetworkPackets;\r
+uint32_t ul;\r
+\r
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )\r
+ {\r
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;\r
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );\r
+ ucRAMBuffer += niBUFFER_1_PACKET_SIZE;\r
+ }\r
+}\r
+*/\r
+/*-----------------------------------------------------------*/\r
+\r
static void prvEMACHandlerTask( void *pvParameters )\r
{\r
-TimeOut_t xPhyTime;\r
-TickType_t xPhyRemTime;\r
UBaseType_t uxLastMinBufferCount = 0;\r
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )\r
UBaseType_t uxLastMinQueueSpace = 0;\r
#endif\r
UBaseType_t uxCurrentCount;\r
-BaseType_t xResult = 0;\r
-uint32_t xStatus;\r
+BaseType_t xResult;\r
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );\r
\r
/* Remove compiler warnings about unused parameters. */\r
( void ) pvParameters;\r
\r
- vTaskSetTimeOutState( &xPhyTime );\r
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );\r
-\r
for( ;; )\r
{\r
+ xResult = 0;\r
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();\r
if( uxLastMinBufferCount != uxCurrentCount )\r
{\r
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );\r
}\r
\r
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
if( xTXDescriptorSemaphore != NULL )\r
{\r
static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;\r
}\r
\r
}\r
- #endif\r
+\r
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )\r
{\r
uxCurrentCount = uxGetMinimumIPQueueSpace();\r
{\r
/* Code to release TX buffers if zero-copy is used. */\r
ulISREvents &= ~EMAC_IF_TX_EVENT;\r
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
- {\r
- /* Check if DMA packets have been delivered. */\r
- vClearTXBuffers();\r
- }\r
- #endif\r
+ /* Check if DMA packets have been delivered. */\r
+ vClearTXBuffers();\r
}\r
\r
if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )\r
/* Future extension: logging about errors that occurred. */\r
ulISREvents &= ~EMAC_IF_ERR_EVENT;\r
}\r
-\r
- if( xResult > 0 )\r
+ if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )\r
{\r
- /* A packet was received. No need to check for the PHY status now,\r
- but set a timer to check it later on. */\r
- vTaskSetTimeOutState( &xPhyTime );\r
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );\r
- xResult = 0;\r
- }\r
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )\r
- {\r
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &xStatus );\r
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )\r
- {\r
- ulPHYLinkStatus = xStatus;\r
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );\r
- prvEthernetUpdateConfig( pdFALSE );\r
- }\r
-\r
- vTaskSetTimeOutState( &xPhyTime );\r
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
- {\r
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );\r
- }\r
- else\r
- {\r
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );\r
- }\r
+ /* Something has changed to a Link Status, need re-check. */\r
+ prvEthernetUpdateConfig( pdFALSE );\r
}\r
}\r
}\r
{\r
HAL_ETH_IRQHandler( &xETH );\r
}\r
+\r