summaryrefslogtreecommitdiff
path: root/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx')
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c534
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt40
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c456
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h93
4 files changed, 488 insertions, 635 deletions
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
index 7b98a93ee..6fad9216e 100644
--- a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
@@ -4,28 +4,28 @@
*/
/*
- * FreeRTOS+TCP 191100 experimental
- * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
*/
/* Standard includes. */
@@ -44,12 +44,11 @@
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_DNS.h"
+#include "FreeRTOS_ARP.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
#include "phyHandling.h"
-#define __STM32_HAL_LEGACY 1
-
/* ST includes. */
#if defined( STM32F7xx )
#include "stm32f7xx_hal.h"
@@ -57,7 +56,7 @@
#include "stm32f4xx_hal.h"
#elif defined( STM32F2xx )
#include "stm32f2xx_hal.h"
-#else
+#elif !defined( _lint ) /* Lint does not like an #error */
#error What part?
#endif
@@ -82,6 +81,14 @@ expansion. */
#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
+#if( ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 ) || ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 ) )
+ #warning Consider enabling checksum offloading
+#endif
+
+#ifndef niDESCRIPTOR_WAIT_TIME_MS
+ #define niDESCRIPTOR_WAIT_TIME_MS 250uL
+#endif
+
/*
* Most users will want a PHY that negotiates about
* the connection properties: speed, dmix and duplex.
@@ -139,6 +146,15 @@ and the index of the PHY in use ( between 0 and 31 ). */
#warning Using MII, make sure if this is correct
#endif
+typedef enum
+{
+ eMACInit, /* Must initialise MAC. */
+ eMACPass, /* Initialisation was successful. */
+ eMACFailed, /* Initialisation failed. */
+} eMAC_INIT_STATUS_TYPE;
+
+static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
+
/*-----------------------------------------------------------*/
/*
@@ -179,9 +195,9 @@ static void prvDMATxDescListInit( void );
*/
static void prvDMARxDescListInit( void );
- /* After packets have been sent, the network
- buffers will be released. */
- static void vClearTXBuffers( void );
+/* After packets have been sent, the network
+buffers will be released. */
+static void vClearTXBuffers( void );
/*-----------------------------------------------------------*/
@@ -199,10 +215,10 @@ static EthernetPhy_t xPhyObject;
/* Ethernet handle. */
static ETH_HandleTypeDef xETH;
- /* xTXDescriptorSemaphore is a counting semaphore with
- a maximum count of ETH_TXBUFNB, which is the number of
- DMA TX descriptors. */
- static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+/* xTXDescriptorSemaphore is a counting semaphore with
+a maximum count of ETH_TXBUFNB, which is the number of
+DMA TX descriptors. */
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
/*
* Note: it is adviced to define both
@@ -242,11 +258,9 @@ __attribute__ ((section(".first_data")))
__ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;
#endif
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /* DMATxDescToClear points to the next TX DMA descriptor
- that must be cleared by vClearTXBuffers(). */
- static __IO ETH_DMADescTypeDef *DMATxDescToClear;
-#endif
+/* DMATxDescToClear points to the next TX DMA descriptor
+that must be cleared by vClearTXBuffers(). */
+static __IO ETH_DMADescTypeDef *DMATxDescToClear;
/* Holds the handle of the task used as a deferred interrupt processor. The
handle is used so direct notifications can be sent to the task for all EMAC/DMA
@@ -267,9 +281,9 @@ const PhyProperties_t xPHYProperties =
#endif
#if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )
- .duplex = PHY_DUPLEX_FULL,
+ .ucDuplex = PHY_DUPLEX_FULL,
#else
- .duplex = PHY_DUPLEX_HALF,
+ .ucDuplex = PHY_DUPLEX_HALF,
#endif
#endif
@@ -288,6 +302,8 @@ void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ ( void ) heth;
+
/* Ethernet RX-Complete callback function, elsewhere declared as weak. */
ulISREvents |= EMAC_IF_RX_EVENT;
/* Wakeup the prvEMACHandlerTask. */
@@ -299,43 +315,44 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
}
/*-----------------------------------------------------------*/
- void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
- {
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- /* This call-back is only useful in case packets are being sent
- zero-copy. Once they're sent, the buffers will be released
- by the function vClearTXBuffers(). */
- ulISREvents |= EMAC_IF_TX_EVENT;
- /* Wakeup the prvEMACHandlerTask. */
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
+void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
+{
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ ( void ) heth;
+
+ /* This call-back is only useful in case packets are being sent
+ zero-copy. Once they're sent, the buffers will be released
+ by the function vClearTXBuffers(). */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+ /* Wakeup the prvEMACHandlerTask. */
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
+}
/*-----------------------------------------------------------*/
- static void vClearTXBuffers()
- {
- __IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
+static void vClearTXBuffers()
+{
+__IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
NetworkBufferDescriptor_t *pxNetworkBuffer;
uint8_t *ucPayLoad;
#endif
- /* This function is called after a TX-completion interrupt.
- It will release each Network Buffer used in xNetworkInterfaceOutput().
- 'uxCount' represents the number of descriptors given to DMA for transmission.
- After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
- while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
+ /* This function is called after a TX-completion interrupt.
+ It will release each Network Buffer used in xNetworkInterfaceOutput().
+ 'uxCount' represents the number of descriptors given to DMA for transmission.
+ After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
+ while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
+ {
+ if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
{
- if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
- {
- break;
- }
+ break;
+ }
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;
@@ -352,13 +369,13 @@ size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescr
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
- DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
+ DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
+ uxCount--;
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
}
+}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
@@ -366,91 +383,117 @@ BaseType_t xNetworkInterfaceInitialise( void )
HAL_StatusTypeDef hal_eth_init_status;
BaseType_t xResult;
- if( xEMACTaskHandle == NULL )
+ if( xMacInitStatus == eMACInit )
{
- if( xTXDescriptorSemaphore == NULL )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
- configASSERT( xTXDescriptorSemaphore );
- }
-
- /* Initialise ETH */
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ xMacInitStatus = eMACFailed;
+ }
+ else
+ {
+ /* Initialise ETH */
- xETH.Instance = ETH;
- xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
- xETH.Init.Speed = ETH_SPEED_100M;
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- /* Value of PhyAddress doesn't matter, will be probed for. */
- xETH.Init.PhyAddress = 0;
+ xETH.Instance = ETH;
+ xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
+ xETH.Init.Speed = ETH_SPEED_100M;
+ xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
+ /* Value of PhyAddress doesn't matter, will be probed for. */
+ xETH.Init.PhyAddress = 0;
- xETH.Init.MACAddr = ( uint8_t *)FreeRTOS_GetMACAddress();
- xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
+ xETH.Init.MACAddr = ( uint8_t * ) FreeRTOS_GetMACAddress();
+ xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
- /* using the ETH_CHECKSUM_BY_HARDWARE option:
- both the IP and the protocol checksums will be calculated
- by the peripheral. */
- xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ /* using the ETH_CHECKSUM_BY_HARDWARE option:
+ both the IP and the protocol checksums will be calculated
+ by the peripheral. */
+ xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
+ }
+ #else
+ {
+ xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
+ }
+ #endif
- #if( ipconfigUSE_RMII != 0 )
- {
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
- }
- #else
- {
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
- }
- #endif /* ipconfigUSE_RMII */
+ #if( ipconfigUSE_RMII != 0 )
+ {
+ xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
+ }
+ #else
+ {
+ xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
+ }
+ #endif /* ipconfigUSE_RMII */
- hal_eth_init_status = HAL_ETH_Init( &xETH );
+ hal_eth_init_status = HAL_ETH_Init( &xETH );
- /* Only for inspection by debugger. */
- ( void ) hal_eth_init_status;
+ /* Only for inspection by debugger. */
+ ( void ) hal_eth_init_status;
- /* Set the TxDesc and RxDesc pointers. */
- xETH.TxDesc = DMATxDscrTab;
- xETH.RxDesc = DMARxDscrTab;
+ /* Set the TxDesc and RxDesc pointers. */
+ xETH.TxDesc = DMATxDscrTab;
+ xETH.RxDesc = DMARxDscrTab;
- /* Make sure that all unused fields are cleared. */
- memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
- memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
+ /* Make sure that all unused fields are cleared. */
+ memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
+ memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
/* Initialize Tx Descriptors list: Chain Mode */
DMATxDescToClear = DMATxDscrTab;
- /* Initialise TX-descriptors. */
- prvDMATxDescListInit();
+ /* Initialise TX-descriptors. */
+ prvDMATxDescListInit();
- /* Initialise RX-descriptors. */
- prvDMARxDescListInit();
+ /* Initialise RX-descriptors. */
+ prvDMARxDescListInit();
- #if( ipconfigUSE_LLMNR != 0 )
- {
- /* Program the LLMNR address at index 1. */
- prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
- }
- #endif
+ #if( ipconfigUSE_LLMNR != 0 )
+ {
+ /* Program the LLMNR address at index 1. */
+ prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
+ }
+ #endif
- /* Force a negotiation with the Switch or Router and wait for LS. */
- prvEthernetUpdateConfig( pdTRUE );
+ /* Force a negotiation with the Switch or Router and wait for LS. */
+ prvEthernetUpdateConfig( pdTRUE );
- /* The deferred interrupt handler task is created at the highest
- possible priority to ensure the interrupt handler can return directly
- to it. The task's handle is stored in xEMACTaskHandle so interrupts can
- notify the task when there is something to process. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle );
+ /* The deferred interrupt handler task is created at the highest
+ possible priority to ensure the interrupt handler can return directly
+ to it. The task's handle is stored in xEMACTaskHandle so interrupts can
+ notify the task when there is something to process. */
+ if( xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle ) == pdPASS )
+ {
+ /* The xTXDescriptorSemaphore and the task are created successfully. */
+ xMacInitStatus = eMACPass;
+ }
+ else
+ {
+ xMacInitStatus = eMACFailed;
+ }
+ }
} /* if( xEMACTaskHandle == NULL ) */
- if( xPhyObject.ulLinkStatusMask != 0 )
+ if( xMacInitStatus != eMACPass )
{
- xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
- xResult = pdPASS;
- FreeRTOS_printf( ( "Link Status is high\n" ) ) ;
+ /* EMAC initialisation failed, return pdFAIL. */
+ xResult = pdFAIL;
}
else
{
- /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
- and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
- xResult = pdFAIL;
+ if( xPhyObject.ulLinkStatusMask != 0uL )
+ {
+ xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
+ xResult = pdPASS;
+ FreeRTOS_printf( ( "Link Status is high\n" ) ) ;
+ }
+ else
+ {
+ /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
+ and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
+ xResult = pdFAIL;
+ }
}
/* When returning non-zero, the stack will become active and
start DHCP (in configured) */
@@ -484,6 +527,10 @@ BaseType_t xIndex;
/* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
}
+ else
+ {
+ pxDMADescriptor->Status &= ~( ( uint32_t ) ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL );
+ }
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
if( xIndex < ETH_TXBUFNB - 1 )
@@ -567,6 +614,8 @@ static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8
{
uint32_t ulTempReg;
+ ( void ) heth;
+
/* Calculate the selected MAC address high register. */
ulTempReg = 0x80000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
@@ -592,21 +641,23 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
/* Open a do {} while ( 0 ) loop to be able to call break. */
do
{
+ if( xCheckLoopback( pxDescriptor, bReleaseAfterSend ) != 0 )
+ {
+ /* The packet has been sent back to the IP-task.
+ The IP-task will further handle it.
+ Do not release the descriptor. */
+ bReleaseAfterSend = pdFALSE;
+ break;
+ }
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
{
ProtocolPacket_t *pxPacket;
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- configASSERT( bReleaseAfterSend != 0 );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
/* If the peripheral must calculate the checksum, it wants
the protocol checksum to have a value of zero. */
pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
- if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP )
+ if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
{
pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
}
@@ -644,6 +695,8 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
}
#else
{
+ configASSERT( bReleaseAfterSend != 0 );
+
/* Move the buffer. */
pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;
/* The Network Buffer has been passed to DMA, no need to release it. */
@@ -653,7 +706,17 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
/* Ask to set the IPv4 checksum.
Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
+ }
+ #else
+ {
+ pxDmaTxDesc->Status &= ~( ( uint32_t ) ETH_DMATXDESC_CIC );
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_IC;
+ }
+ #endif
+
/* Prepare transmit descriptors to give to DMA. */
@@ -751,20 +814,24 @@ const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP )
{
- uint16_t port = pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort;
+ uint16_t usSourcePort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort );
+ uint16_t usDestinationPort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort );
- if( ( xPortHasUDPSocket( port ) == pdFALSE )
+ if( ( xPortHasUDPSocket( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort ) == pdFALSE )
#if ipconfigUSE_LLMNR == 1
- && ( port != FreeRTOS_ntohs( ipLLMNR_PORT ) )
+ && ( usDestinationPort != ipLLMNR_PORT )
+ && ( usSourcePort != ipLLMNR_PORT )
#endif
#if ipconfigUSE_NBNS == 1
- && ( port != FreeRTOS_ntohs( ipNBNS_PORT ) )
+ && ( usDestinationPort != ipNBNS_PORT )
+ && ( usSourcePort != ipNBNS_PORT )
#endif
#if ipconfigUSE_DNS == 1
- && ( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort != FreeRTOS_ntohs( ipDNS_PORT ) )
+ && ( usSourcePort != ipDNS_PORT )
#endif
) {
/* Drop this packet, not for this device. */
+ /* FreeRTOS_printf( ( "Drop: UDP port %d -> %d\n", usSourcePort, usDestinationPort ) ); */
return pdFALSE;
}
}
@@ -774,20 +841,59 @@ const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
}
/*-----------------------------------------------------------*/
+static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
+{
+IPStackEvent_t xRxEvent;
+
+ xRxEvent.eEventType = eNetworkRxEvent;
+ xRxEvent.pvData = ( void * ) pxDescriptor;
+
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
+ {
+ /* The buffer could not be sent to the stack so must be released again.
+ This is a deferred handler taskr, not a real interrupt, so it is ok to
+ use the task level function here. */
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ {
+ do
+ {
+ NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ pxDescriptor = pxNext;
+ } while( pxDescriptor != NULL );
+ }
+ #else
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
+ }
+ else
+ {
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+}
+
static BaseType_t prvNetworkInterfaceInput( void )
{
NetworkBufferDescriptor_t *pxCurDescriptor;
NetworkBufferDescriptor_t *pxNewDescriptor = NULL;
-BaseType_t xReceivedLength, xAccepted;
+#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
+ NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
+#endif
+BaseType_t xReceivedLength = 0;
__IO ETH_DMADescTypeDef *pxDMARxDescriptor;
-xIPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( niDESCRIPTOR_WAIT_TIME_MS );
uint8_t *pucBuffer;
pxDMARxDescriptor = xETH.RxDesc;
- if( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN) == 0 )
+ while( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN ) == 0u )
{
+ BaseType_t xAccepted = pdTRUE;
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
@@ -797,19 +903,9 @@ uint8_t *pucBuffer;
/* Chained Mode */
/* Selects the next DMA Rx descriptor list for next buffer to read */
xETH.RxDesc = ( ETH_DMADescTypeDef* )pxDMARxDescriptor->Buffer2NextDescAddr;
- }
- else
- {
- xReceivedLength = 0;
- }
- /* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
-
- /* get received frame */
- if( xReceivedLength > 0ul )
- {
- /* In order to make the code easier and faster, only packets in a single buffer
- will be accepted. This can be done by making the buffers large enough to
+ /* In order to make the code easier and faster, only packets in a single buffer
+ will be accepted. This can be done by making the buffers large enough to
hold a complete Ethernet packet (1536 bytes).
Therefore, two sanity checks: */
configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
@@ -859,20 +955,28 @@ uint8_t *pucBuffer;
if( xAccepted != pdFALSE )
{
pxCurDescriptor->xDataLength = xReceivedLength;
- xRxEvent.pvData = ( void * ) pxCurDescriptor;
-
- /* Pass the data to the TCP/IP task for processing. */
- if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- /* Could not send the descriptor into the TCP/IP stack, it
- must be released. */
- vReleaseNetworkBufferAndDescriptor( pxCurDescriptor );
- iptraceETHERNET_RX_EVENT_LOST();
+ pxCurDescriptor->pxNextBuffer = NULL;
+
+ if( pxFirstDescriptor == NULL )
+ {
+ // Becomes the first message
+ pxFirstDescriptor = pxCurDescriptor;
+ }
+ else if( pxLastDescriptor != NULL )
+ {
+ // Add to the tail
+ pxLastDescriptor->pxNextBuffer = pxCurDescriptor;
+ }
+
+ pxLastDescriptor = pxCurDescriptor;
}
- else
+ #else
{
- iptraceNETWORK_INTERFACE_RECEIVE();
+ prvPassEthMessages( pxCurDescriptor );
}
+ #endif
}
/* Release descriptors to DMA */
@@ -907,15 +1011,25 @@ uint8_t *pucBuffer;
/* Resume DMA reception. */
xETH.Instance->DMARPDR = 0;
}
+ pxDMARxDescriptor = xETH.RxDesc;
}
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ {
+ if( pxFirstDescriptor != NULL )
+ {
+ prvPassEthMessages( pxFirstDescriptor );
+ }
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
+
return ( xReceivedLength > 0 );
}
/*-----------------------------------------------------------*/
BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )
- {
+{
uint16_t usPrevAddress = xETH.Init.PhyAddress;
BaseType_t xResult;
HAL_StatusTypeDef xHALResult;
@@ -933,11 +1047,11 @@ HAL_StatusTypeDef xHALResult;
xResult = -1;
}
return xResult;
- }
+}
/*-----------------------------------------------------------*/
BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )
- {
+{
uint16_t usPrevAddress = xETH.Init.PhyAddress;
BaseType_t xResult;
HAL_StatusTypeDef xHALResult;
@@ -947,15 +1061,15 @@ HAL_StatusTypeDef xHALResult;
xETH.Init.PhyAddress = usPrevAddress;
if( xHALResult == HAL_OK )
- {
+ {
xResult = 0;
- }
- else
- {
+ }
+ else
+ {
xResult = -1;
- }
- return xResult;
}
+ return xResult;
+}
/*-----------------------------------------------------------*/
void vMACBProbePhy( void )
@@ -979,27 +1093,27 @@ static void prvEthernetUpdateConfig( BaseType_t xForce )
{
xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );
- /* Configure the MAC with the Duplex Mode fixed by the
- auto-negotiation process. */
+ /* Configure the MAC with the Duplex Mode fixed by the
+ auto-negotiation process. */
if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )
- {
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- }
- else
- {
- xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
- }
+ {
+ xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
+ }
+ else
+ {
+ xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
+ }
- /* Configure the MAC with the speed fixed by the
- auto-negotiation process. */
+ /* Configure the MAC with the speed fixed by the
+ auto-negotiation process. */
if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )
- {
- xETH.Init.Speed = ETH_SPEED_10M;
- }
- else
- {
- xETH.Init.Speed = ETH_SPEED_100M;
- }
+ {
+ xETH.Init.Speed = ETH_SPEED_10M;
+ }
+ else
+ {
+ xETH.Init.Speed = ETH_SPEED_100M;
+ }
}
else /* AutoNegotiation Disable */
{
@@ -1064,11 +1178,9 @@ BaseType_t xReturn;
/* Uncomment this in case BufferAllocation_1.c is used. */
-#define niBUFFER_1_PACKET_SIZE 1536
-
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
-static __attribute__ ((section(".first_data"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
+static __attribute__ ((section(".first_data"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * ETH_MAX_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
uint8_t *ucRAMBuffer = ucNetworkPackets;
uint32_t ul;
@@ -1076,7 +1188,7 @@ uint32_t ul;
{
pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
*( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
+ ucRAMBuffer += ETH_MAX_PACKET_SIZE;
}
}
/*-----------------------------------------------------------*/
@@ -1144,21 +1256,15 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
ulISREvents &= ~EMAC_IF_RX_EVENT;
xResult = prvNetworkInterfaceInput();
- if( xResult > 0 )
- {
- while( prvNetworkInterfaceInput() > 0 )
- {
- }
- }
}
if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
{
/* Code to release TX buffers if zero-copy is used. */
ulISREvents &= ~EMAC_IF_TX_EVENT;
- /* Check if DMA packets have been delivered. */
- vClearTXBuffers();
- }
+ /* Check if DMA packets have been delivered. */
+ vClearTXBuffers();
+ }
if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
{
@@ -1166,10 +1272,10 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
ulISREvents &= ~EMAC_IF_ERR_EVENT;
}
if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )
- {
+ {
/* Something has changed to a Link Status, need re-check. */
- prvEthernetUpdateConfig( pdFALSE );
- }
+ prvEthernetUpdateConfig( pdFALSE );
+ }
}
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt
index 73fd553a0..51170c041 100644
--- a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt
@@ -18,3 +18,43 @@ It is assumed that one of these words are defined:
STM32F439xx
The driver has been tested on both Eval and Discovery boards with both STM32F4 and STM32F7.
+
+Recommened settings for STM32Fxx Network Interface:
+
+// Defined in FreeRTOSIPConfig.h
+
+#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
+#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
+#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
+#define ipconfigZERO_COPY_RX_DRIVER 1
+#define ipconfigZERO_COPY_TX_DRIVER 1
+#define ipconfigUSE_LINKED_RX_MESSAGES 1
+
+// Defined in stm32f4xx_hal_conf.h
+#define ETH_RXBUFNB 3 or 4
+#define ETH_TXBUFNB 2 or 3
+#define ETH_RX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
+#define ETH_TX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
+
+The best size for 'ETH_RXBUFNB' and 'ETH_TXBUFNB' depends on the speed of the CPU. These macro's define the number of DMA buffers for reception and for transmission.
+In general, if the CPU is very fast, you will need less buffers. You can obtain an estimate empirically.
+
+The optimal value of 'ETH_RX_BUF_SIZE' and 'ETH_TX_BUF_SIZE' depends on the actual value of 'ipconfigNETWORK_MTU'.
+When MTU is 1500, MTU+36 becomes a well-aligned buffer of 1536 bytes ( 0x600 ).
+When MTU is 1200, MTU+48 will make 1248 ( 0x4E0 ), which is also well aligned.
+
+Having well aligned buffers is important for CPU with memory cache. Often the caching system divides memory in blocks of 32 bytes. When two buffers share the same cache buffer, you are bound to see data errors.
+
+Without memory caching, let the size be at least a multiple of 8 ( for DMA ), and make it at least "ipconfigNETWORK_MTU + 14".
+
+The driver contains these files:
+
+ stm32fxx_hal_eth.c
+ stm32f2xx_hal_eth.h
+ stm32f4xx_hal_eth.h
+ stm32f7xx_hal_eth.h
+ stm32fxx_hal_eth.h
+
+These files are copied from ST's HAL library. These work both for STM32F4 and STM32F7.
+Please remove or rename these files from the HAL distribution that you are using.
+
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c
index c67ad1901..dad16aaf8 100644
--- a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c
@@ -99,19 +99,15 @@
*/
/* Includes ------------------------------------------------------------------*/
-#define __STM32_HAL_LEGACY 1
#if defined(STM32F7xx)
#include "stm32f7xx_hal.h"
- #include "stm32f7xx_hal_def.h"
#define stm_is_F7 1
#elif defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
#include "stm32f4xx_hal.h"
- #include "stm32f4xx_hal_def.h"
#define stm_is_F4 1
#elif defined(STM32F2xx)
#include "stm32f2xx_hal.h"
- #include "stm32f2xx_hal_def.h"
#define stm_is_F2 1
#else
#error For what part should this be compiled?
@@ -197,8 +193,8 @@ extern void vMACBProbePhy ( void );
*/
HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
{
- uint32_t tmpreg = 0;
- uint32_t hclk = 60000000;
+ uint32_t tmpreg = 0uL;
+ uint32_t hclk = 60000000uL;
uint32_t err = ETH_SUCCESS;
/* Check the ETH peripheral state */
@@ -244,33 +240,33 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
/* Clear CSR Clock Range CR[2:0] bits */
tmpreg &= ETH_MACMIIAR_CR_MASK;
- /* Get hclk frequency value (168,000,000) */
+ /* Get hclk frequency value (e.g. 168,000,000) */
hclk = HAL_RCC_GetHCLKFreq();
/* Set CR bits depending on hclk value */
- if( ( hclk >= 20000000 ) && ( hclk < 35000000 ) )
+ if(( hclk >= 20000000uL ) && ( hclk < 35000000uL ) )
{
/* CSR Clock Range between 20-35 MHz */
- tmpreg |= (uint32_t) ETH_MACMIIAR_CR_Div16;
+ tmpreg |= ( uint32_t) ETH_MACMIIAR_CR_Div16;
}
- else if( ( hclk >= 35000000 ) && ( hclk < 60000000 ) )
+ else if( ( hclk >= 35000000uL ) && ( hclk < 60000000uL ) )
{
/* CSR Clock Range between 35-60 MHz */
tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26;
}
- else if((hclk >= 60000000 ) && ( hclk < 100000000 ) )
+ else if( ( hclk >= 60000000uL ) && ( hclk < 100000000uL ) )
{
/* CSR Clock Range between 60-100 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
}
- else if((hclk >= 100000000 ) && ( hclk < 150000000))
+ else if( ( hclk >= 100000000uL ) && ( hclk < 150000000uL ) )
{
/* CSR Clock Range between 100-150 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
}
- else /* ((hclk >= 150000000 ) && ( hclk <= 168000000)) */
+ else /* ( ( hclk >= 150000000uL ) && ( hclk <= 183000000uL ) ) */
{
- /* CSR Clock Range between 150-168 MHz */
+ /* CSR Clock Range between 150-183 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
}
@@ -315,161 +311,6 @@ HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
}
/**
- * @brief Initializes the DMA Tx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMATxDescTab: Pointer to the first Tx desc list
- * @param TxBuff: Pointer to the first TxBuffer list
- * @param TxBuffCount: Number of the used Tx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *pxDMATable, uint8_t *ucDataBuffer, uint32_t ulBufferCount)
-{
- uint32_t i = 0;
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the TxDesc pointer with the first one of the pxDMATable list */
- heth->TxDesc = pxDMATable;
-
- /* Fill each DMA descriptor with the right values */
- for( i=0; i < ulBufferCount; i++ )
- {
- /* Get the pointer on the ith member of the descriptor list */
- pxDMADescriptor = pxDMATable + i;
-
- /* Set Second Address Chained bit */
- pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
-
- pxDMADescriptor->ControlBufferSize = 0;
-
- /* Set Buffer1 address pointer */
- if( ucDataBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( &ucDataBuffer[ i * ETH_TX_BUF_SIZE ] );
- }
- else
- {
- /* Buffer space is not provided because it uses zero-copy transmissions. */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )0u;
- }
-
- if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
- pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if(i < ( ulBufferCount - 1 ) )
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMATable + i + 1 );
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) pxDMATable;
- }
- }
-
- /* Set Transmit Descriptor List Address Register */
- heth->Instance->DMATDLAR = ( uint32_t ) pxDMATable;
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DMA Rx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMARxDescTab: Pointer to the first Rx desc list
- * @param RxBuff: Pointer to the first RxBuffer list
- * @param RxBuffCount: Number of the used Rx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *pxDMATable, uint8_t *ucDataBuffer, uint32_t ulBufferCount)
-{
- uint32_t i = 0;
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the RxDesc pointer with the first one of the pxDMATable list */
- heth->RxDesc = pxDMATable;
-
- /* Fill each DMA descriptor with the right values */
- for(i=0; i < ulBufferCount; i++)
- {
- /* Get the pointer on the ith member of the descriptor list */
- pxDMADescriptor = pxDMATable+i;
-
- /* Set Own bit of the Rx descriptor Status */
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
-
- /* Set Buffer1 size and Second Address Chained bit */
- pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
-
- /* Set Buffer1 address pointer */
- if( ucDataBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( &ucDataBuffer[ i * ETH_RX_BUF_SIZE ] );
- }
- else
- {
- /* Buffer space is not provided because it uses zero-copy reception. */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )0u;
- }
-
- if( heth->Init.RxMode == ETH_RXINTERRUPT_MODE )
- {
- /* Enable Ethernet DMA Rx Descriptor interrupt */
- pxDMADescriptor->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if(i < (ulBufferCount-1))
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = (uint32_t)(pxDMATable+i+1);
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) pxDMATable;
- }
- }
-
- /* Set Receive Descriptor List Address Register */
- heth->Instance->DMARDLAR = ( uint32_t ) pxDMATable;
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
* @brief Initializes the ETH MSP.
* @param heth: pointer to a ETH_HandleTypeDef structure that contains
* the configuration information for ETHERNET module
@@ -480,6 +321,7 @@ __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ETH_MspInit could be implemented in the user file
*/
+ ( void ) heth;
}
/**
@@ -493,6 +335,7 @@ __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ETH_MspDeInit could be implemented in the user file
*/
+ ( void ) heth;
}
/**
@@ -522,209 +365,6 @@ __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
* @{
*/
-/**
- * @brief Sends an Ethernet frame.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param FrameLength: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
-{
- uint32_t bufcount = 0, size = 0, i = 0;
- __IO ETH_DMADescTypeDef *pxDmaTxDesc = heth->TxDesc;
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- if( FrameLength == 0 )
- {
- /* Set ETH HAL state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- return HAL_ERROR;
- }
-
- /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
- if( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) != ( uint32_t ) RESET )
- {
- /* OWN bit set */
- heth->State = HAL_ETH_STATE_BUSY_TX;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- return HAL_ERROR;
- }
-
- /* Get the number of needed Tx buffers for the current frame, rounding up. */
- bufcount = ( FrameLength + ETH_TX_BUF_SIZE - 1 ) / ETH_TX_BUF_SIZE;
-
- if (bufcount == 1)
- {
- /* Set LAST and FIRST segment */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
- /* Set frame size */
- pxDmaTxDesc->ControlBufferSize = ( FrameLength & ETH_DMATXDESC_TBS1 );
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
- /* Point to next descriptor */
- heth->TxDesc = ( ETH_DMADescTypeDef * ) ( heth->TxDesc->Buffer2NextDescAddr );
- }
- else
- {
- for( i = 0; i < bufcount; i++ )
- {
- /* Clear FIRST and LAST segment bits */
- uint32_t ulStatus = heth->TxDesc->Status & ~( ETH_DMATXDESC_FS | ETH_DMATXDESC_LS );
-
- if( i == 0 )
- {
- /* Setting the first segment bit */
- heth->TxDesc->Status = ulStatus | ETH_DMATXDESC_FS;
- }
-
- /* Program size */
- if (i < (bufcount-1))
- {
- heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
- }
- else
- {
- /* Setting the last segment bit */
- heth->TxDesc->Status = ulStatus | ETH_DMATXDESC_LS;
- size = FrameLength - (bufcount-1)*ETH_TX_BUF_SIZE;
- heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
- }
-
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
- /* point to next descriptor */
- heth->TxDesc = (ETH_DMADescTypeDef *)( heth->TxDesc->Buffer2NextDescAddr );
- }
- }
-
- __DSB();
-
- /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
- if( ( heth->Instance->DMASR & ETH_DMASR_TBUS ) != ( uint32_t )RESET )
- {
- heth->Instance->DMACHTDR = ( uint32_t )pxDmaTxDesc;
-
- /* Clear TBUS ETHERNET DMA flag */
- heth->Instance->DMASR = ETH_DMASR_TBUS;
- /* Resume DMA transmission*/
- heth->Instance->DMATPDR = 0;
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Checks for received frames.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT( ETH_HandleTypeDef *heth )
-{
- return HAL_ETH_GetReceivedFrame( heth );
-}
-
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame( ETH_HandleTypeDef *heth )
-{
-uint32_t ulCounter = 0;
-ETH_DMADescTypeDef *pxDescriptor = heth->RxDesc;
-HAL_StatusTypeDef xResult = HAL_ERROR;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Check the ETH state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Scan descriptors owned by CPU */
- while( ( ( pxDescriptor->Status & ETH_DMARXDESC_OWN ) == 0ul ) && ( ulCounter < ETH_RXBUFNB ) )
- {
- uint32_t ulStatus = pxDescriptor->Status;
-
- /* Just for security. */
- ulCounter++;
-
- if( ( ulStatus & ( ETH_DMARXDESC_FS | ETH_DMARXDESC_LS ) ) == ( uint32_t )ETH_DMARXDESC_FS )
- {
- /* First segment in frame, but not the last. */
- heth->RxFrameInfos.FSRxDesc = pxDescriptor;
- heth->RxFrameInfos.LSRxDesc = ( ETH_DMADescTypeDef *)NULL;
- heth->RxFrameInfos.SegCount = 1;
- /* Point to next descriptor. */
- pxDescriptor = (ETH_DMADescTypeDef*) (pxDescriptor->Buffer2NextDescAddr);
- heth->RxDesc = pxDescriptor;
- }
- else if( ( ulStatus & ( ETH_DMARXDESC_LS | ETH_DMARXDESC_FS ) ) == 0ul )
- {
- /* This is an intermediate segment, not first, not last. */
- /* Increment segment count. */
- heth->RxFrameInfos.SegCount++;
- /* Move to the next descriptor. */
- pxDescriptor = ( ETH_DMADescTypeDef * ) ( pxDescriptor->Buffer2NextDescAddr );
- heth->RxDesc = pxDescriptor;
- }
- /* Must be a last segment */
- else
- {
- /* This is the last segment. */
- /* Check if last segment is first segment: one segment contains the frame */
- if( heth->RxFrameInfos.SegCount == 0 )
- {
- /* Remember the first segment. */
- heth->RxFrameInfos.FSRxDesc = pxDescriptor;
- }
-
- /* Increment segment count */
- heth->RxFrameInfos.SegCount++;
-
- /* Remember the last segment. */
- heth->RxFrameInfos.LSRxDesc = pxDescriptor;
-
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
- heth->RxFrameInfos.length =
- ( ( ulStatus & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
-
- /* Get the address of the buffer start address */
- heth->RxFrameInfos.buffer = heth->RxFrameInfos.FSRxDesc->Buffer1Addr;
-
- /* Point to next descriptor */
- heth->RxDesc = ( ETH_DMADescTypeDef * ) pxDescriptor->Buffer2NextDescAddr;
-
- /* Return OK status: a packet was received. */
- xResult = HAL_OK;
- break;
- }
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return xResult;
-}
-
#define ETH_DMA_ALL_INTS \
( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_AIS | ETH_DMA_IT_ER | \
ETH_DMA_IT_FBE | ETH_DMA_IT_ET | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
@@ -772,6 +412,7 @@ __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ETH_TxCpltCallback could be implemented in the user file
*/
+ ( void ) heth;
}
/**
@@ -785,6 +426,7 @@ __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ETH_TxCpltCallback could be implemented in the user file
*/
+ ( void ) heth;
}
/**
@@ -798,6 +440,7 @@ __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_ETH_TxCpltCallback could be implemented in the user file
*/
+ ( void ) heth;
}
/**
@@ -814,8 +457,8 @@ __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
*/
HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
{
-uint32_t tmpreg = 0;
-uint32_t tickstart = 0;
+uint32_t tmpreg = 0uL;
+uint32_t tickstart = 0uL;
HAL_StatusTypeDef xResult;
/* Check parameters */
@@ -856,7 +499,7 @@ HAL_StatusTypeDef xResult;
{
tmpreg = heth->Instance->MACMIIAR;
- if( ( tmpreg & ETH_MACMIIAR_MB ) == 0ul )
+ if( ( tmpreg & ETH_MACMIIAR_MB ) == 0uL )
{
/* Get MACMIIDR value */
*RegValue = ( uint32_t ) heth->Instance->MACMIIDR;
@@ -1067,6 +710,28 @@ HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
return HAL_OK;
}
+static void vRegisterDelay()
+{
+uint32_t uxCount;
+ /*
+ * Regarding the HAL delay functions, I noticed that HAL delay is being used to workaround the
+ * "Successive write operations to the same register might not be fully taken into account" errata.
+ * The workaround requires a delay of four TX_CLK/RX_CLK clock cycles. For a 10 Mbit connection,
+ * these clocks are running at 2.5 MHz, so this delay would be at most 1.6 microseconds.
+ * 180 Mhz = 288 loops
+ * 168 Mhz = 269 loops
+ * 100 Mhz = 160 loops
+ * 84 Mhz = 134 loops
+ */
+ #define WAIT_TIME_NS 1600uL /* 1.6 microseconds */
+ #define CPU_MAX_FREQ SystemCoreClock /* 84, 100, 168 or 180 MHz */
+ uint32_t NOP_COUNT = ( WAIT_TIME_NS * ( CPU_MAX_FREQ / 1000uL ) ) / 1000000uL;
+ for( uxCount = NOP_COUNT; uxCount > 0uL; uxCount-- )
+ {
+ __NOP();
+ }
+}
+
static void prvWriteMACFCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
{
/* Enable the MAC transmission */
@@ -1077,7 +742,7 @@ static void prvWriteMACFCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
Read it back, wait a ms and */
( void ) heth->Instance->MACFCR;
- HAL_Delay( ETH_REG_WRITE_DELAY );
+ vRegisterDelay();
heth->Instance->MACFCR = ulValue;
}
@@ -1092,7 +757,7 @@ static void prvWriteDMAOMR( ETH_HandleTypeDef *heth, uint32_t ulValue)
Read it back, wait a ms and */
( void ) heth->Instance->DMAOMR;
- HAL_Delay( ETH_REG_WRITE_DELAY );
+ vRegisterDelay();
heth->Instance->DMAOMR = ulValue;
}
@@ -1107,7 +772,7 @@ static void prvWriteMACCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
Read it back, wait a ms and */
( void ) heth->Instance->MACCR;
- HAL_Delay( ETH_REG_WRITE_DELAY );
+ vRegisterDelay();
heth->Instance->MACCR = ulValue;
}
@@ -1121,7 +786,7 @@ static void prvWriteMACCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
*/
HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
{
- uint32_t tmpreg = 0;
+ uint32_t tmpreg = 0uL;
/* Process Locked */
__HAL_LOCK( heth );
@@ -1202,7 +867,7 @@ HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef
/* Wait until the write operation will be taken into account :
at least four TX_CLK/RX_CLK clock cycles */
tmpreg = heth->Instance->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
+ vRegisterDelay();
heth->Instance->MACFFR = tmpreg;
/*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
@@ -1236,7 +901,7 @@ HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef
/* Wait until the write operation will be taken into account :
at least four TX_CLK/RX_CLK clock cycles */
tmpreg = heth->Instance->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
+ vRegisterDelay();
heth->Instance->MACVLANTR = tmpreg;
}
else /* macconf == NULL : here we just configure Speed and Duplex mode */
@@ -1246,7 +911,7 @@ HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef
tmpreg = heth->Instance->MACCR;
/* Clear FES and DM bits */
- tmpreg &= ~((uint32_t)0x00004800);
+ tmpreg &= ~( ( uint32_t ) 0x00004800uL );
tmpreg |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
@@ -1273,7 +938,7 @@ HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef
*/
HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
{
- uint32_t tmpreg = 0;
+ uint32_t tmpreg = 0uL;
/* Process Locked */
__HAL_LOCK( heth );
@@ -1332,7 +997,7 @@ HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef
/* Wait until the write operation will be taken into account:
at least four TX_CLK/RX_CLK clock cycles */
tmpreg = heth->Instance->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
+ vRegisterDelay();
heth->Instance->DMABMR = tmpreg;
/* Set the ETH state to Ready */
@@ -1402,7 +1067,7 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
{
ETH_MACInitTypeDef macinit;
ETH_DMAInitTypeDef dmainit;
- uint32_t tmpreg = 0;
+ uint32_t tmpreg = 0uL;
if (err != ETH_SUCCESS) /* Auto-negotiation failed */
{
@@ -1440,16 +1105,16 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
- macinit.HashTableHigh = 0x0;
- macinit.HashTableLow = 0x0;
- macinit.PauseTime = 0x0;
+ macinit.HashTableHigh = 0x0uL;
+ macinit.HashTableLow = 0x0uL;
+ macinit.PauseTime = 0x0uL;
macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
- macinit.VLANTagIdentifier = 0x0;
+ macinit.VLANTagIdentifier = 0x0uL;
/*------------------------ ETHERNET MACCR Configuration --------------------*/
/* Get the ETHERNET MACCR value */
@@ -1508,7 +1173,7 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
/* Wait until the write operation will be taken into account:
at least four TX_CLK/RX_CLK clock cycles */
tmpreg = heth->Instance->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
+ vRegisterDelay();
heth->Instance->MACFFR = tmpreg;
/*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
@@ -1549,7 +1214,7 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
/* Wait until the write operation will be taken into account:
at least four TX_CLK/RX_CLK clock cycles */
tmpreg = heth->Instance->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
+ vRegisterDelay();
heth->Instance->MACVLANTR = tmpreg;
/* Ethernet DMA default initialization ************************************/
@@ -1567,7 +1232,7 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
- dmainit.DescriptorSkipLength = 0x0;
+ dmainit.DescriptorSkipLength = 0x0uL;
dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
/* Get the ETHERNET DMAOMR value */
@@ -1617,7 +1282,7 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
/* Wait until the write operation will be taken into account:
at least four TX_CLK/RX_CLK clock cycles */
tmpreg = heth->Instance->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
+ vRegisterDelay();
heth->Instance->DMABMR = tmpreg;
if(heth->Init.RxMode == ETH_RXINTERRUPT_MODE)
@@ -1647,11 +1312,14 @@ static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint
{
uint32_t tmpreg;
+ ( void ) heth;
+
/* Check the parameters */
assert_param( IS_ETH_MAC_ADDRESS0123( MacAddr ) );
/* Calculate the selected MAC address high register */
- tmpreg = 0x80000000ul | ( ( uint32_t )Addr[ 5 ] << 8) | (uint32_t)Addr[ 4 ];
+ /* Register ETH_MACA0HR: Bit 31 MO: Always 1. */
+ tmpreg = 0x80000000uL | ( ( uint32_t )Addr[ 5 ] << 8) | (uint32_t)Addr[ 4 ];
/* Load the selected MAC address high register */
( * ( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + MacAddr ) ) ) = tmpreg;
/* Calculate the selected MAC address low register */
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h
index f4b74d226..f91122594 100644
--- a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h
@@ -44,6 +44,14 @@
#define __STM32F4xx_HAL_ETH_H
#define __STM32F7xx_HAL_ETH_H
+#if defined(STM32F7xx)
+ #include "stm32f7xx_hal_def.h"
+#elif defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+ #include "stm32f4xx_hal_def.h"
+#elif defined(STM32F2xx)
+ #include "stm32f2xx_hal_def.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -367,6 +375,33 @@
* @}
*/
+#ifdef _lint
+ #ifdef __IO
+ #undef __IO
+ #endif
+ #define __IO
+
+ #ifdef ETH_TypeDef
+ #undef ETH_TypeDef
+ #endif
+ #define ETH_TypeDef void
+
+ #ifdef HAL_LockTypeDef
+ #undef HAL_LockTypeDef
+ #endif
+ #define HAL_LockTypeDef unsigned
+
+ #ifdef ETH_RX_BUF_SIZE
+ #undef ETH_RX_BUF_SIZE
+ #endif
+ #define ETH_RX_BUF_SIZE 1536
+
+ #ifdef ETH_TX_BUF_SIZE
+ #undef ETH_TX_BUF_SIZE
+ #endif
+ #define ETH_TX_BUF_SIZE 1536
+#endif
+
/* Exported types ------------------------------------------------------------*/
/** @defgroup ETH_Exported_Types ETH Exported Types
* @{
@@ -1244,33 +1279,37 @@ typedef struct
/** @defgroup ETH_MAC_Debug_flags ETH MAC Debug flags
* @{
*/
-#define ETH_MAC_TXFIFO_FULL ((uint32_t)0x02000000) /* Tx FIFO full */
-#define ETH_MAC_TXFIFONOT_EMPTY ((uint32_t)0x01000000) /* Tx FIFO not empty */
-#define ETH_MAC_TXFIFO_WRITE_ACTIVE ((uint32_t)0x00400000) /* Tx FIFO write active */
-#define ETH_MAC_TXFIFO_IDLE ((uint32_t)0x00000000) /* Tx FIFO read status: Idle */
-#define ETH_MAC_TXFIFO_READ ((uint32_t)0x00100000) /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */
-#define ETH_MAC_TXFIFO_WAITING ((uint32_t)0x00200000) /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */
-#define ETH_MAC_TXFIFO_WRITING ((uint32_t)0x00300000) /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */
-#define ETH_MAC_TRANSMISSION_PAUSE ((uint32_t)0x00080000) /* MAC transmitter in pause */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE ((uint32_t)0x00000000) /* MAC transmit frame controller: Idle */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING ((uint32_t)0x00020000) /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF ((uint32_t)0x00040000) /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING ((uint32_t)0x00060000) /* MAC transmit frame controller: Transferring input frame for transmission */
-#define ETH_MAC_MII_TRANSMIT_ACTIVE ((uint32_t)0x00010000) /* MAC MII transmit engine active */
-#define ETH_MAC_RXFIFO_EMPTY ((uint32_t)0x00000000) /* Rx FIFO fill level: empty */
-#define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */
-#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */
-#define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */
-#define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000060) /* Rx FIFO read controller IDLE state */
-#define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame data */
-#define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame status (or time-stamp) */
-#define ETH_MAC_READCONTROLLER_ FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */
-#define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */
-#define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */
-#define ETH_MAC_SMALL_FIFO_READ_ACTIVE ((uint32_t)0x00000002) /* MAC small FIFO read controller active */
-#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE ((uint32_t)0x00000004) /* MAC small FIFO write controller active */
-#define ETH_MAC_SMALL_FIFO_RW_ACTIVE ((uint32_t)0x00000006) /* MAC small FIFO read / write controllers active */
-#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE ((uint32_t)0x00000001) /* MAC MII receive protocol engine active */
+#ifndef ETH_MAC_TXFIFO_FULL
+ #define ETH_MAC_TXFIFO_FULL ((uint32_t)0x02000000) /* Tx FIFO full */
+ #define ETH_MAC_TXFIFONOT_EMPTY ((uint32_t)0x01000000) /* Tx FIFO not empty */
+ #define ETH_MAC_TXFIFO_WRITE_ACTIVE ((uint32_t)0x00400000) /* Tx FIFO write active */
+ #define ETH_MAC_TXFIFO_IDLE ((uint32_t)0x00000000) /* Tx FIFO read status: Idle */
+ #define ETH_MAC_TXFIFO_READ ((uint32_t)0x00100000) /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */
+ #define ETH_MAC_TXFIFO_WAITING ((uint32_t)0x00200000) /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */
+ #define ETH_MAC_TXFIFO_WRITING ((uint32_t)0x00300000) /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */
+ #define ETH_MAC_TRANSMISSION_PAUSE ((uint32_t)0x00080000) /* MAC transmitter in pause */
+ #define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE ((uint32_t)0x00000000) /* MAC transmit frame controller: Idle */
+ #define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING ((uint32_t)0x00020000) /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */
+ #define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF ((uint32_t)0x00040000) /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */
+ #define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING ((uint32_t)0x00060000) /* MAC transmit frame controller: Transferring input frame for transmission */
+ #define ETH_MAC_MII_TRANSMIT_ACTIVE ((uint32_t)0x00010000) /* MAC MII transmit engine active */
+ #define ETH_MAC_RXFIFO_EMPTY ((uint32_t)0x00000000) /* Rx FIFO fill level: empty */
+ #define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */
+ #define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */
+ #define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */
+ #define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000060) /* Rx FIFO read controller IDLE state */
+ #define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame data */
+ #define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame status (or time-stamp) */
+ #define ETH_MAC_READCONTROLLER_ FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */
+ #define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */
+ #define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */
+ #define ETH_MAC_SMALL_FIFO_READ_ACTIVE ((uint32_t)0x00000002) /* MAC small FIFO read controller active */
+ #define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE ((uint32_t)0x00000004) /* MAC small FIFO write controller active */
+ #define ETH_MAC_SMALL_FIFO_RW_ACTIVE ((uint32_t)0x00000006) /* MAC small FIFO read / write controllers active */
+ #define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE ((uint32_t)0x00000001) /* MAC MII receive protocol engine active */
+#else
+ /* stm32_hal_legacy.h has probably been included. That file defines 'ETH_MAC_TXFIFO_FULL' and all macro's here below. */
+#endif
/**
* @}
*/