diff --git a/source/FreeRTOS_ARP.c b/source/FreeRTOS_ARP.c index a9a3edfec9..afa9866fac 100644 --- a/source/FreeRTOS_ARP.c +++ b/source/FreeRTOS_ARP.c @@ -893,10 +893,11 @@ *( ppxEndPoint ) = NULL; ulAddressToLookup = *pulIPAddress; - pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulAddressToLookup ); if( xIsIPv4Loopback( ulAddressToLookup ) != 0 ) { + pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulAddressToLookup ); + if( pxEndPoint != NULL ) { /* For multi-cast, use the first IPv4 end-point. */ @@ -925,16 +926,15 @@ } } } - else if( ( FreeRTOS_htonl( ulAddressToLookup ) & 0xffU ) == 0xffU ) /* Is this a broadcast address like x.x.x.255 ? */ + else if( xIsIPv4Broadcast( ulAddressToLookup, ppxEndPoint ) ) { /* This is a broadcast so it uses the broadcast MAC address. */ ( void ) memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); - pxEndPoint = FreeRTOS_FindEndPointOnNetMask( ulAddressToLookup ); - if( pxEndPoint != NULL ) - { - *( ppxEndPoint ) = pxEndPoint; - } + /* Note that xIsIPv4Broadcast() already filled in ppxEndPoint with the corresponding endpoint + * or the first IPv4 endpoint in case ulAddressToLookup was FREERTOS_INADDR_BROADCAST. + * It is also safe to call xIsIPv4Broadcast() with a null pointer so no need to use + * the intermediary pxEndPoint */ eReturn = eResolutionCacheHit; } diff --git a/source/FreeRTOS_DHCP.c b/source/FreeRTOS_DHCP.c index 09d8d7f5cc..6bca3e1708 100644 --- a/source/FreeRTOS_DHCP.c +++ b/source/FreeRTOS_DHCP.c @@ -1047,7 +1047,7 @@ const void * pvCopySource = &( pxSet->pucByte[ uxByteIndex ] ); ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxSet->ulParameter ) ); - if( ( pxSet->ulParameter != FREERTOS_INADDR_ANY ) && ( pxSet->ulParameter != ipBROADCAST_IP_ADDRESS ) ) + if( ( pxSet->ulParameter != FREERTOS_INADDR_ANY ) && ( pxSet->ulParameter != FREERTOS_INADDR_BROADCAST ) ) { EP_IPv4_SETTINGS.ulDNSServerAddresses[ uxTargetIndex ] = pxSet->ulParameter; uxTargetIndex++; @@ -1470,7 +1470,7 @@ pxEndPoint->xMACAddress.ucBytes, sizeof( MACAddress_t ) ); /* Set the addressing. */ - pxAddress->sin_address.ulIP_IPv4 = ipBROADCAST_IP_ADDRESS; + pxAddress->sin_address.ulIP_IPv4 = FREERTOS_INADDR_BROADCAST; pxAddress->sin_port = ( uint16_t ) dhcpSERVER_PORT_IPv4; pxAddress->sin_family = FREERTOS_AF_INET4; } @@ -1676,7 +1676,7 @@ EP_IPv4_SETTINGS.ulIPAddress = EP_DHCPData.ulOfferedIPAddress; /* Setting the 'local' broadcast address, something like 192.168.1.255' */ - EP_IPv4_SETTINGS.ulBroadcastAddress = ( EP_DHCPData.ulOfferedIPAddress & EP_IPv4_SETTINGS.ulNetMask ) | ~EP_IPv4_SETTINGS.ulNetMask; + EP_IPv4_SETTINGS.ulBroadcastAddress = ( EP_DHCPData.ulOfferedIPAddress | ( ~EP_IPv4_SETTINGS.ulNetMask ) ); /* Close socket to ensure packets don't queue on it. not needed anymore as DHCP failed. but still need timer for ARP testing. */ prvCloseDHCPSocket( pxEndPoint ); diff --git a/source/FreeRTOS_DNS.c b/source/FreeRTOS_DNS.c index 81d66facc5..020e9b5149 100644 --- a/source/FreeRTOS_DNS.c +++ b/source/FreeRTOS_DNS.c @@ -1006,7 +1006,7 @@ const MACAddress_t xMDNS_MacAddressIPv6 = { { 0x33, 0x33, 0x00, 0x00, 0x00, 0xFB configASSERT( ucIndex < ipconfigENDPOINT_DNS_ADDRESS_COUNT ); ulIPAddress = pxEndPoint->ipv4_settings.ulDNSServerAddresses[ ucIndex ]; - if( ( ulIPAddress != 0U ) && ( ulIPAddress != ipBROADCAST_IP_ADDRESS ) ) + if( ( ulIPAddress != 0U ) && ( ulIPAddress != FREERTOS_INADDR_BROADCAST ) ) { pxAddress->sin_family = FREERTOS_AF_INET; pxAddress->sin_len = ( uint8_t ) sizeof( struct freertos_sockaddr ); diff --git a/source/FreeRTOS_IPv4.c b/source/FreeRTOS_IPv4.c index 726a5d3fd6..027a54e2ac 100644 --- a/source/FreeRTOS_IPv4.c +++ b/source/FreeRTOS_IPv4.c @@ -210,6 +210,65 @@ BaseType_t xIsIPv4Multicast( uint32_t ulIPAddress ) } /*-----------------------------------------------------------*/ +/** + * @brief Checks if the IP address matches the global 255.255.255.255 broadcast address or + * the broadcast address for any of our IPv4 endpoints. + * + * @param[in] ulIPAddress The IP address being checked. + * + * @param[out] ppxEndPoint Pointer to an end-point where we store the endpoint whose broadcast address we matched. Or NULL if no IPv4 endpoints were found. + * + * @return pdTRUE if the IP address is a broadcast address or else, pdFALSE. + */ +BaseType_t xIsIPv4Broadcast( uint32_t ulIPAddress, + struct xNetworkEndPoint ** ppxEndPoint ) +{ + BaseType_t xIsBroadcast; + NetworkEndPoint_t * pxEndPoint; + + /* Assign a default answer based on the "global" broadcast. This way + * we can still return the correct result even if there are no endpoints. */ + xIsBroadcast = ( ulIPAddress == FREERTOS_INADDR_BROADCAST ) ? pdTRUE : pdFALSE; + + for( pxEndPoint = FreeRTOS_FirstEndPoint( NULL ); + pxEndPoint != NULL; + pxEndPoint = FreeRTOS_NextEndPoint( NULL, pxEndPoint ) ) + { + #if ( ipconfigUSE_IPv6 == ipconfigENABLE ) + /* Skip over any IPv6 endpoints. */ + if( pxEndPoint->bits.bIPv6 == pdTRUE ) + { + continue; + } + #endif /* ( ipconfigUSE_IPv6 == ipconfigENABLE ) */ + + /* If we already know if ulIPAddress is a broadcast, + * simply return this first matching IPv4 endpoint. */ + if( xIsBroadcast == pdTRUE ) + { + break; + } + else if( ulIPAddress == pxEndPoint->ipv4_settings.ulBroadcastAddress ) + { + xIsBroadcast = pdTRUE; + break; + } + } + + /* If the caller wants to know the corresponding endpoint, copy the result. + * Note that this may be null if ulIPAddress is 255.255.255.255 AND there are + * no IPv4 endpoints. + * Also, when ulIPAddress is 255.255.255.255, we will + * return the first IPv4 endpoint that we run across. */ + if( xIsBroadcast && ( ppxEndPoint != NULL ) ) + { + *ppxEndPoint = pxEndPoint; + } + + return xIsBroadcast; +} +/*-----------------------------------------------------------*/ + /** * @brief Check if the packet is an illegal loopback packet. * @@ -284,9 +343,11 @@ enum eFrameProcessingResult prvAllowIPPacketIPv4( const struct xIP_PACKET * cons { /* In systems with a very small amount of RAM, it might be advantageous * to have incoming messages checked earlier, by the network card driver. - * This method may decrease the usage of sparse network buffers. */ + * This method may decrease the usage of scarce network buffers. */ uint32_t ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress; uint32_t ulSourceIPAddress = pxIPHeader->ulSourceIPAddress; + /* Get a reference to the endpoint that the packet was assigned to during pxEasyFit() */ + NetworkEndPoint_t * pxEndPoint = pxNetworkBuffer->pxEndPoint; /* Ensure that the incoming packet is not fragmented because the stack * doesn't not support IP fragmentation. All but the last fragment coming in will have their @@ -318,16 +379,20 @@ enum eFrameProcessingResult prvAllowIPPacketIPv4( const struct xIP_PACKET * cons } } else if( - ( FreeRTOS_FindEndPointOnIP_IPv4( ulDestinationIPAddress ) == NULL ) && - /* Is it an IPv4 broadcast address x.x.x.255 ? */ - ( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xffU ) != 0xffU ) && + /* Not destined for the assigned endpoint IPv4 address? */ + ( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulIPAddress ) && + /* Also not an IPv4 broadcast address ? */ + ( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulBroadcastAddress ) && + ( ulDestinationIPAddress != FREERTOS_INADDR_BROADCAST ) && + /* And not an IPv4 multicast address ? */ ( xIsIPv4Multicast( ulDestinationIPAddress ) == pdFALSE ) ) { /* Packet is not for this node, release it */ eReturn = eReleaseBuffer; } /* Is the source address correct? */ - else if( ( FreeRTOS_ntohl( ulSourceIPAddress ) & 0xffU ) == 0xffU ) + else if( ( ulSourceIPAddress == pxEndPoint->ipv4_settings.ulBroadcastAddress ) || + ( ulSourceIPAddress == FREERTOS_INADDR_BROADCAST ) ) { /* The source address cannot be broadcast address. Replying to this * packet may cause network storms. Drop the packet. */ @@ -336,7 +401,7 @@ enum eFrameProcessingResult prvAllowIPPacketIPv4( const struct xIP_PACKET * cons else if( ( memcmp( xBroadcastMACAddress.ucBytes, pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) && - ( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xffU ) != 0xffU ) ) + ( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulBroadcastAddress ) && ( ulDestinationIPAddress != FREERTOS_INADDR_BROADCAST ) ) { /* Ethernet address is a broadcast address, but the IP address is not a * broadcast address. */ diff --git a/source/include/FreeRTOS_IP_Private.h b/source/include/FreeRTOS_IP_Private.h index cd5afb8c01..14cb7e9249 100644 --- a/source/include/FreeRTOS_IP_Private.h +++ b/source/include/FreeRTOS_IP_Private.h @@ -258,8 +258,6 @@ struct xPacketSummary uint16_t usProtocolBytes; /**< The total length of the protocol data. */ }; -#define ipBROADCAST_IP_ADDRESS 0xffffffffU - /* Offset into the Ethernet frame that is used to temporarily store information * on the fragmentation status of the packet being sent. The value is important, * as it is past the location into which the destination address will get placed. */ diff --git a/source/include/FreeRTOS_IPv4.h b/source/include/FreeRTOS_IPv4.h index 7197ab9f00..99ad9a2b73 100644 --- a/source/include/FreeRTOS_IPv4.h +++ b/source/include/FreeRTOS_IPv4.h @@ -84,6 +84,10 @@ uint32_t FreeRTOS_GetIPAddress( void ); /* Return pdTRUE if the IPv4 address is a multicast address. */ BaseType_t xIsIPv4Multicast( uint32_t ulIPAddress ); +/* Return pdTRUE if the IPv4 address is a broadcast address. */ +BaseType_t xIsIPv4Broadcast( uint32_t ulIPAddress, + struct xNetworkEndPoint ** ppxEndPoint ); + /* Return pdTRUE if the IPv4 address is a loopback address. */ BaseType_t xIsIPv4Loopback( uint32_t ulAddress ); diff --git a/source/include/FreeRTOS_Sockets.h b/source/include/FreeRTOS_Sockets.h index 4045e51bcf..39ffce31c9 100644 --- a/source/include/FreeRTOS_Sockets.h +++ b/source/include/FreeRTOS_Sockets.h @@ -150,9 +150,10 @@ #if ( ipconfigUSE_TCP == 1 ) #define FREERTOS_SO_SET_LOW_HIGH_WATER ( 18 ) #endif - #define FREERTOS_INADDR_ANY ( 0U ) /* The 0.0.0.0 IPv4 address. */ + #define FREERTOS_INADDR_ANY ( 0U ) /* The 0.0.0.0 IPv4 address. */ + #define FREERTOS_INADDR_BROADCAST ( 0xffffffffUL ) /* 255.255.255.255 is a special broadcast address that represents all host attached to the physical network. */ - #if ( 0 ) /* Not Used */ + #if ( 0 ) /* Not Used */ #define FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET ( 0x80 ) #define FREERTOS_FRAGMENTED_PACKET ( 0x40 ) #endif diff --git a/source/portable/NetworkInterface/STM32/CMakeLists.txt b/source/portable/NetworkInterface/STM32/CMakeLists.txt index 0b30b2821c..6c81c7cec2 100644 --- a/source/portable/NetworkInterface/STM32/CMakeLists.txt +++ b/source/portable/NetworkInterface/STM32/CMakeLists.txt @@ -24,7 +24,7 @@ target_sources( freertos_plus_tcp_network_if Drivers/H7/stm32h7xx_hal_eth.c> ) -target_include_directories( freertos_plus_tcp_network_if +target_include_directories( freertos_plus_tcp_network_if PUBLIC $<$: Drivers/F4> diff --git a/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.c b/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.c index df3ccc65c8..3896a9040e 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.c +++ b/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.c @@ -1,3221 +1,3304 @@ /** - ****************************************************************************** - * @file stm32f4xx_hal_eth.c - * @author MCD Application Team - * @brief ETH HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Ethernet (ETH) peripheral: - * + Initialization and deinitialization functions - * + IO operation functions - * + Peripheral Control functions - * + Peripheral State and Errors functions - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2016 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - The ETH HAL driver can be used as follows: - - (#)Declare a ETH_HandleTypeDef handle structure, for example: - ETH_HandleTypeDef heth; - - (#)Fill parameters of Init structure in heth handle - - (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) - - (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: - (##) Enable the Ethernet interface clock using - (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() - (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() - (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() - - (##) Initialize the related GPIO clocks - (##) Configure Ethernet pinout - (##) Configure Ethernet NVIC interrupt (in Interrupt mode) - - (#) Ethernet data reception is asynchronous, so call the following API - to start the listening mode: - (##) HAL_ETH_Start(): - This API starts the MAC and DMA transmission and reception process, - without enabling end of transfer interrupts, in this mode user - has to poll for data reception by calling HAL_ETH_ReadData() - (##) HAL_ETH_Start_IT(): - This API starts the MAC and DMA transmission and reception process, - end of transfer interrupts are enabled in this mode, - HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received - - (#) When data is received user can call the following API to get received data: - (##) HAL_ETH_ReadData(): Read a received packet - - (#) For transmission path, two APIs are available: - (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode - (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, - HAL_ETH_TxCpltCallback() will be executed when end of transfer occur - - (#) Communication with an external PHY device: - (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY - (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register - - (#) Configure the Ethernet MAC after ETH peripheral initialization - (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef - (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef - - (#) Configure the Ethernet DMA after ETH peripheral initialization - (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef - (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef - - (#) Configure the Ethernet PTP after ETH peripheral initialization - (##) Define HAL_ETH_USE_PTP to use PTP APIs. - (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers - (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission - (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp - (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp - - -@- The ARP offload feature is not supported in this driver. - - -@- The PTP offload feature is not supported in this driver. - - *** Callback registration *** - ============================================= - - The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 - allows the user to configure dynamically the driver callbacks. - Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. - - Function HAL_ETH_RegisterCallback() allows to register following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - This function takes as parameters the HAL peripheral handle, the Callback ID - and a pointer to the user callback function. - - For specific callbacks RxAllocateCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxPtpCallback(). - - Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default - weak function. - HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, - and the Callback ID. - This function allows to reset following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - For specific callbacks RxAllocateCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxPtpCallback(). - - By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET - all callbacks are set to the corresponding weak functions: - examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). - Exception done for MspInit and MspDeInit functions that are - reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when - these callbacks are null (not registered beforehand). - if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit - keep and use the user MspInit/MspDeInit callbacks (registered beforehand) - - Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. - Exception done MspInit/MspDeInit that can be registered/unregistered - in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, - thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. - In that case first register the MspInit/MspDeInit user callbacks - using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit - or HAL_ETH_Init function. - - When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or - not defined, the callback registration feature is not available and all callbacks - are set to the corresponding weak functions. - - @endverbatim - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32f4xx_hal_eth.c + * @author MCD Application Team + * @brief ETH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Ethernet (ETH) peripheral: + * + Initialization and deinitialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @verbatim + * ============================================================================== + ##### How to use this driver ##### + #####============================================================================== + #####[..] + #####The ETH HAL driver can be used as follows: + ##### + #####(#)Declare a ETH_HandleTypeDef handle structure, for example: + ##### ETH_HandleTypeDef heth; + ##### + #####(#)Fill parameters of Init structure in heth handle + ##### + #####(#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) + ##### + #####(#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: + ##### (##) Enable the Ethernet interface clock using + ##### (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() + ##### + ##### (##) Initialize the related GPIO clocks + ##### (##) Configure Ethernet pinout + ##### (##) Configure Ethernet NVIC interrupt (in Interrupt mode) + ##### + #####(#) Ethernet data reception is asynchronous, so call the following API + ##### to start the listening mode: + ##### (##) HAL_ETH_Start(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### without enabling end of transfer interrupts, in this mode user + ##### has to poll for data reception by calling HAL_ETH_ReadData() + ##### (##) HAL_ETH_Start_IT(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### end of transfer interrupts are enabled in this mode, + ##### HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received + ##### + #####(#) When data is received user can call the following API to get received data: + ##### (##) HAL_ETH_ReadData(): Read a received packet + ##### + #####(#) For transmission path, two APIs are available: + ##### (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode + ##### (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, + ##### HAL_ETH_TxCpltCallback() will be executed when end of transfer occur + ##### + #####(#) Communication with an external PHY device: + ##### (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY + ##### (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register + ##### + #####(#) Configure the Ethernet MAC after ETH peripheral initialization + ##### (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef + ##### (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef + ##### + #####(#) Configure the Ethernet DMA after ETH peripheral initialization + ##### (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef + ##### (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef + ##### + #####(#) Configure the Ethernet PTP after ETH peripheral initialization + ##### (##) Define HAL_ETH_USE_PTP to use PTP APIs. + ##### (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission + ##### (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp + ##### (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp + ##### + #####-@- The ARP offload feature is not supported in this driver. + ##### + #####-@- The PTP offload feature is not supported in this driver. + ##### + *** Callback registration *** + ***============================================= + *** + ***The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 + ***allows the user to configure dynamically the driver callbacks. + ***Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. + *** + ***Function HAL_ETH_RegisterCallback() allows to register following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***This function takes as parameters the HAL peripheral handle, the Callback ID + ***and a pointer to the user callback function. + *** + ***For specific callbacks RxAllocateCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxPtpCallback(). + *** + ***Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default + ***weak function. + ***HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, + ***and the Callback ID. + ***This function allows to reset following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***For specific callbacks RxAllocateCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxPtpCallback(). + *** + ***By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET + ***all callbacks are set to the corresponding weak functions: + ***examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). + ***Exception done for MspInit and MspDeInit functions that are + ***reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when + ***these callbacks are null (not registered beforehand). + ***if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit + ***keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + *** + ***Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. + ***Exception done MspInit/MspDeInit that can be registered/unregistered + ***in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, + ***thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + ***In that case first register the MspInit/MspDeInit user callbacks + ***using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit + ***or HAL_ETH_Init function. + *** + ***When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or + ***not defined, the callback registration feature is not available and all callbacks + ***are set to the corresponding weak functions. + *** + ***@endverbatim + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" /** @addtogroup STM32F4xx_HAL_Driver - * @{ - */ + * @{ + */ #ifdef HAL_ETH_MODULE_ENABLED -#if defined(ETH) + #if defined( ETH ) /** @defgroup ETH ETH - * @brief ETH HAL module driver - * @{ - */ + * @brief ETH HAL module driver + * @{ + */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ + /** @addtogroup ETH_Private_Constants ETH Private Constants - * @{ - */ -#define ETH_MACCR_MASK 0xFFFB7F7CU -#define ETH_MACECR_MASK 0x3F077FFFU -#define ETH_MACFFR_MASK 0x800007FFU -#define ETH_MACWTR_MASK 0x0000010FU -#define ETH_MACTFCR_MASK 0xFFFF00F2U -#define ETH_MACRFCR_MASK 0x00000003U -#define ETH_MTLTQOMR_MASK 0x00000072U -#define ETH_MTLRQOMR_MASK 0x0000007BU - -#define ETH_DMAMR_MASK 0x00007802U -#define ETH_DMASBMR_MASK 0x0000D001U -#define ETH_DMACCR_MASK 0x00013FFFU -#define ETH_DMACTCR_MASK 0x003F1010U -#define ETH_DMACRCR_MASK 0x803F0000U -#define ETH_MACPMTCSR_MASK (ETH_MACPMTCSR_PD | ETH_MACPMTCSR_WFE | \ - ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU) + * @{ + */ + #define ETH_MACCR_MASK 0xFFFB7F7CU + #define ETH_MACECR_MASK 0x3F077FFFU + #define ETH_MACFFR_MASK 0x800007FFU + #define ETH_MACWTR_MASK 0x0000010FU + #define ETH_MACTFCR_MASK 0xFFFF00F2U + #define ETH_MACRFCR_MASK 0x00000003U + #define ETH_MTLTQOMR_MASK 0x00000072U + #define ETH_MTLRQOMR_MASK 0x0000007BU + + #define ETH_DMAMR_MASK 0x00007802U + #define ETH_DMASBMR_MASK 0x0000D001U + #define ETH_DMACCR_MASK 0x00013FFFU + #define ETH_DMACTCR_MASK 0x003F1010U + #define ETH_DMACRCR_MASK 0x803F0000U + #define ETH_MACPMTCSR_MASK \ + ( ETH_MACPMTCSR_PD | ETH_MACPMTCSR_WFE | \ + ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU ) /* Timeout values */ -#define ETH_SWRESET_TIMEOUT 500U -#define ETH_MDIO_BUS_TIMEOUT 1000U + #define ETH_SWRESET_TIMEOUT 500U + #define ETH_MDIO_BUS_TIMEOUT 1000U -#define ETH_DMARXDESC_ERRORS_MASK ((uint32_t)(ETH_DMARXDESC_DBE | ETH_DMARXDESC_RE | \ - ETH_DMARXDESC_OE | ETH_DMARXDESC_RWT |\ - ETH_DMARXDESC_LC | ETH_DMARXDESC_CE |\ - ETH_DMARXDESC_DE | ETH_DMARXDESC_IPV4HCE)) + #define ETH_DMARXDESC_ERRORS_MASK \ + ( ( uint32_t ) ( ETH_DMARXDESC_DBE | ETH_DMARXDESC_RE | \ + ETH_DMARXDESC_OE | ETH_DMARXDESC_RWT | \ + ETH_DMARXDESC_LC | ETH_DMARXDESC_CE | \ + ETH_DMARXDESC_DE | ETH_DMARXDESC_IPV4HCE ) ) -#define ETH_MAC_US_TICK 1000000U + #define ETH_MAC_US_TICK 1000000U -#define ETH_MACTSCR_MASK 0x0087FF2FU + #define ETH_MACTSCR_MASK 0x0087FF2FU -#define ETH_PTPTSHR_VALUE 0xFFFFFFFFU -#define ETH_PTPTSLR_VALUE 0xBB9ACA00U + #define ETH_PTPTSHR_VALUE 0xFFFFFFFFU + #define ETH_PTPTSLR_VALUE 0xBB9ACA00U /* Ethernet MACMIIAR register Mask */ -#define ETH_MACMIIAR_CR_MASK 0xFFFFFFE3U + #define ETH_MACMIIAR_CR_MASK 0xFFFFFFE3U /* Delay to wait when writing to some Ethernet registers */ -#define ETH_REG_WRITE_DELAY 0x00000001U + #define ETH_REG_WRITE_DELAY 0x00000001U /* ETHERNET MACCR register Mask */ -#define ETH_MACCR_CLEAR_MASK 0xFF20810FU + #define ETH_MACCR_CLEAR_MASK 0xFF20810FU /* ETHERNET MACFCR register Mask */ -#define ETH_MACFCR_CLEAR_MASK 0x0000FF41U + #define ETH_MACFCR_CLEAR_MASK 0x0000FF41U /* ETHERNET DMAOMR register Mask */ -#define ETH_DMAOMR_CLEAR_MASK 0xF8DE3F23U + #define ETH_DMAOMR_CLEAR_MASK 0xF8DE3F23U /* ETHERNET MAC address offsets */ -#define ETH_MAC_ADDR_HBASE (uint32_t)(ETH_MAC_BASE + 0x40U) /* ETHERNET MAC address high offset */ -#define ETH_MAC_ADDR_LBASE (uint32_t)(ETH_MAC_BASE + 0x44U) /* ETHERNET MAC address low offset */ + #define ETH_MAC_ADDR_HBASE ( uint32_t ) ( ETH_MAC_BASE + 0x40U ) /* ETHERNET MAC address high offset */ + #define ETH_MAC_ADDR_LBASE ( uint32_t ) ( ETH_MAC_BASE + 0x44U ) /* ETHERNET MAC address low offset */ /* ETHERNET DMA Rx descriptors Frame length Shift */ -#define ETH_DMARXDESC_FRAMELENGTHSHIFT 16U + #define ETH_DMARXDESC_FRAMELENGTHSHIFT 16U + /** - * @} - */ + * @} + */ /* Private macros ------------------------------------------------------------*/ + /** @defgroup ETH_Private_Macros ETH Private Macros - * @{ - */ + * @{ + */ /* Helper macros for TX descriptor handling */ -#define INCR_TX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\ - } while (0) + #define INCR_TX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_TX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_TX_DESC_CNT ); } \ + } while( 0 ) /* Helper macros for RX descriptor handling */ -#define INCR_RX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\ - } while (0) -/** - * @} - */ + #define INCR_RX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_RX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_RX_DESC_CNT ); } \ + } while( 0 ) + +/** + * @} + */ /* Private function prototypes -----------------------------------------------*/ + /** @defgroup ETH_Private_Functions ETH Private Functions - * @{ - */ -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth); -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth); -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth); -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode); -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth); -static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth); -static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ -/** - * @} - */ + * @{ + */ + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ); + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ); + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ); + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + ETH_TxPacketConfig * pTxConfig, + uint32_t ItMode ); + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ); + static void ETH_FlushTransmitFIFO( ETH_HandleTypeDef * heth ); + static void ETH_MACAddressConfig( ETH_HandleTypeDef * heth, + uint32_t MacAddr, + uint8_t * Addr ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /* Exported functions ---------------------------------------------------------*/ + /** @defgroup ETH_Exported_Functions ETH Exported Functions - * @{ - */ + * @{ + */ /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions - * @brief Initialization and Configuration functions - * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] This subsection provides a set of functions allowing to initialize and - deinitialize the ETH peripheral: - - (+) User must Implement HAL_ETH_MspInit() function in which he configures - all related peripherals resources (CLOCK, GPIO and NVIC ). - - (+) Call the function HAL_ETH_Init() to configure the selected device with - the selected configuration: - (++) MAC address - (++) Media interface (MII or RMII) - (++) Rx DMA Descriptors Tab - (++) Tx DMA Descriptors Tab - (++) Length of Rx Buffers - - (+) Call the function HAL_ETH_DeInit() to restore the default configuration - of the selected ETH peripheral. - -@endverbatim - * @{ - */ - -/** - * @brief Initialize the Ethernet peripheral registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) -{ - uint32_t tickstart; - - if (heth == NULL) - { - return HAL_ERROR; - } - if (heth->gState == HAL_ETH_STATE_RESET) - { - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - ETH_InitCallbacksToDefault(heth); - - if (heth->MspInitCallback == NULL) - { - heth->MspInitCallback = HAL_ETH_MspInit; - } - - /* Init the low level hardware */ - heth->MspInitCallback(heth); -#else - /* Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - } - - __HAL_RCC_SYSCFG_CLK_ENABLE(); - - /* Select MII or RMII Mode*/ - SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL); - SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface; - /* Dummy read to sync SYSCFG with ETH */ - (void)SYSCFG->PMC; - - /* Ethernet Software reset */ - /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ - /* After reset all the registers holds their respective reset values */ - SET_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Wait for software reset */ - while (READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)) - { - /* Set Error Code */ - heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; - /* Set State as Error */ - heth->gState = HAL_ETH_STATE_ERROR; - /* Return Error */ - return HAL_ERROR; - } - } - - - /*------------------ MAC, MTL and DMA default Configuration ----------------*/ - ETH_MACDMAConfig(heth); - - - /*------------------ DMA Tx Descriptors Configuration ----------------------*/ - ETH_DMATxDescListInit(heth); - - /*------------------ DMA Rx Descriptors Configuration ----------------------*/ - ETH_DMARxDescListInit(heth); - - /*--------------------- ETHERNET MAC Address Configuration ------------------*/ - ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr); - - /* Disable MMC Interrupts */ - SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM); - - /* Disable Rx MMC Interrupts */ - SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | \ - ETH_MMCRIMR_RFCEM); - - /* Disable Tx MMC Interrupts */ - SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | \ - ETH_MMCTIMR_TGFSCM); - - heth->ErrorCode = HAL_ETH_ERROR_NONE; - heth->gState = HAL_ETH_STATE_READY; - - return HAL_OK; -} - -/** - * @brief DeInitializes the ETH peripheral. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) -{ - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - if (heth->MspDeInitCallback == NULL) - { - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - } - /* DeInit the low level hardware */ - heth->MspDeInitCallback(heth); -#else - - /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspDeInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - - /* Set ETH HAL state to Disabled */ - heth->gState = HAL_ETH_STATE_RESET; - - /* 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 - * @retval None - */ -__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspInit could be implemented in the user file - */ -} - -/** - * @brief DeInitializes ETH MSP. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspDeInit could be implemented in the user file - */ -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -/** - * @brief Register a User ETH Callback - * To be used instead of the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be registered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @param pCallback pointer to the Callback function - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = pCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = pCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = pCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = pCallback; - break; - - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = pCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} - -/** - * @brief Unregister an ETH Callback - * ETH callback is redirected to the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be unregistered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = HAL_ETH_ErrorCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = HAL_ETH_PMTCallback; - break; - - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ + * @brief Initialization and Configuration functions + * + * @verbatim + * =============================================================================== + ##### Initialization and Configuration functions ##### + #####=============================================================================== + #####[..] This subsection provides a set of functions allowing to initialize and + ##### deinitialize the ETH peripheral: + ##### + #####(+) User must Implement HAL_ETH_MspInit() function in which he configures + ##### all related peripherals resources (CLOCK, GPIO and NVIC ). + ##### + #####(+) Call the function HAL_ETH_Init() to configure the selected device with + ##### the selected configuration: + ##### (++) MAC address + ##### (++) Media interface (MII or RMII) + ##### (++) Rx DMA Descriptors Tab + ##### (++) Tx DMA Descriptors Tab + ##### (++) Length of Rx Buffers + ##### + #####(+) Call the function HAL_ETH_DeInit() to restore the default configuration + ##### of the selected ETH peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Initialize the Ethernet peripheral registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ) + { + uint32_t tickstart; + + if( heth == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_RESET ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + ETH_InitCallbacksToDefault( heth ); + + if( heth->MspInitCallback == NULL ) + { + heth->MspInitCallback = HAL_ETH_MspInit; + } + + /* Init the low level hardware */ + heth->MspInitCallback( heth ); + #else + /* Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + } + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + /* Select MII or RMII Mode*/ + SYSCFG->PMC &= ~( SYSCFG_PMC_MII_RMII_SEL ); + SYSCFG->PMC |= ( uint32_t ) heth->Init.MediaInterface; + /* Dummy read to sync SYSCFG with ETH */ + ( void ) SYSCFG->PMC; + + /* Ethernet Software reset */ + /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ + /* After reset all the registers holds their respective reset values */ + SET_BIT( heth->Instance->DMABMR, ETH_DMABMR_SR ); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for software reset */ + while( READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_SR ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_SWRESET_TIMEOUT ) ) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + } + + /*------------------ MAC, MTL and DMA default Configuration ----------------*/ + ETH_MACDMAConfig( heth ); + + + /*------------------ DMA Tx Descriptors Configuration ----------------------*/ + ETH_DMATxDescListInit( heth ); + + /*------------------ DMA Rx Descriptors Configuration ----------------------*/ + ETH_DMARxDescListInit( heth ); + + /*--------------------- ETHERNET MAC Address Configuration ------------------*/ + ETH_MACAddressConfig( heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr ); + + /* Disable MMC Interrupts */ + SET_BIT( heth->Instance->MACIMR, ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM ); + + /* Disable Rx MMC Interrupts */ + SET_BIT( heth->Instance->MMCRIMR, ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | \ + ETH_MMCRIMR_RFCEM ); + + /* Disable Tx MMC Interrupts */ + SET_BIT( heth->Instance->MMCTIMR, ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | \ + ETH_MMCTIMR_TGFSCM ); + + heth->ErrorCode = HAL_ETH_ERROR_NONE; + heth->gState = HAL_ETH_STATE_READY; + + return HAL_OK; + } + +/** + * @brief DeInitializes the ETH peripheral. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + if( heth->MspDeInitCallback == NULL ) + { + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + } + + /* DeInit the low level hardware */ + heth->MspDeInitCallback( heth ); + #else + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspDeInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + + /* Set ETH HAL state to Disabled */ + heth->gState = HAL_ETH_STATE_RESET; + + /* 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 + * @retval None + */ + __weak void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspInit could be implemented in the user file + */ + } + +/** + * @brief DeInitializes ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspDeInit could be implemented in the user file + */ + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + +/** + * @brief Register a User ETH Callback + * To be used instead of the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( pCallback == NULL ) + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = pCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = pCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = pCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = pCallback; + break; + + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = pCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + +/** + * @brief Unregister an ETH Callback + * ETH callback is redirected to the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = HAL_ETH_ErrorCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = HAL_ETH_PMTCallback; + break; + + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group2 IO operation functions - * @brief ETH Transmit and Receive functions - * -@verbatim - ============================================================================== - ##### IO operation functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to manage the ETH - data transfer. - -@endverbatim - * @{ - */ - -/** - * @brief Enables Ethernet MAC and DMA reception and transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - heth->gState = HAL_ETH_STATE_STARTED; - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* save IT mode to ETH Handle */ - heth->RxDescList.ItMode = 1U; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - /* Enable ETH DMA interrupts: - - Tx complete interrupt - - Rx complete interrupt - - Fatal bus interrupt - */ - __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | - ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE)); - - heth->gState = HAL_ETH_STATE_STARTED; - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t descindex; - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | - ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE)); - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Clear IOC bit to all Rx descriptors */ - for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++) - { - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; - SET_BIT(dmarxdesc->DESC1, ETH_DMARXDESC_DIC); - } - - heth->RxDescList.ItMode = 0U; - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in polling mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @param Timeout: timeout value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout) -{ - uint32_t tickstart; - ETH_DMADescTypeDef *dmatxdesc; - - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE) - { - /* Set the ETH error code */ - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc]; - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - WRITE_REG(heth->Instance->DMATPDR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); - - tickstart = HAL_GetTick(); - - /* Wait for data to be transmitted or timeout occurred */ - while ((dmatxdesc->DESC0 & ETH_DMATXDESC_OWN) != (uint32_t)RESET) - { - if ((heth->Instance->DMASR & ETH_DMASR_FBES) != (uint32_t)RESET) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - heth->DMAErrorCode = heth->Instance->DMASR; - /* Return function status */ - return HAL_ERROR; - } - - /* Check for the Timeout */ - if (Timeout != HAL_MAX_DELAY) - { - if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + * @brief ETH Transmit and Receive functions + * + * @verbatim + * ============================================================================== + ##### IO operation functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to manage the ETH + #####data transfer. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Enables Ethernet MAC and DMA reception and transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ) + { + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + heth->gState = HAL_ETH_STATE_STARTED; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ) + { + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* save IT mode to ETH Handle */ + heth->RxDescList.ItMode = 1U; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + /* Enable ETH DMA interrupts: + * - Tx complete interrupt + * - Rx complete interrupt + * - Fatal bus interrupt + */ + __HAL_ETH_DMA_ENABLE_IT( heth, ( ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | + ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE ) ); + + heth->gState = HAL_ETH_STATE_STARTED; + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ) + { + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmarxdesc; + uint32_t descindex; + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + __HAL_ETH_DMA_DISABLE_IT( heth, ( ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | + ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE ) ); + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Clear IOC bit to all Rx descriptors */ + for( descindex = 0; descindex < ( uint32_t ) ETH_RX_DESC_CNT; descindex++ ) + { + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descindex ]; + SET_BIT( dmarxdesc->DESC1, ETH_DMARXDESC_DIC ); + } + + heth->RxDescList.ItMode = 0U; + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Sends an Ethernet Packet in polling mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @param Timeout: timeout value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfig * pTxConfig, + uint32_t Timeout ) + { + uint32_t tickstart; + ETH_DMADescTypeDef * dmatxdesc; + + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 0 ) != HAL_ETH_ERROR_NONE ) + { + /* Set the ETH error code */ + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + dmatxdesc = ( ETH_DMADescTypeDef * ) ( &heth->TxDescList )->TxDesc[ heth->TxDescList.CurTxDesc ]; + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG( heth->Instance->DMATPDR, ( uint32_t ) ( heth->TxDescList.TxDesc[ heth->TxDescList.CurTxDesc ] ) ); + + tickstart = HAL_GetTick(); + + /* Wait for data to be transmitted or timeout occurred */ + while( ( dmatxdesc->DESC0 & ETH_DMATXDESC_OWN ) != ( uint32_t ) RESET ) + { + if( ( heth->Instance->DMASR & ETH_DMASR_FBES ) != ( uint32_t ) RESET ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + heth->DMAErrorCode = heth->Instance->DMASR; + /* Return function status */ + return HAL_ERROR; + } + + /* Check for the Timeout */ + if( Timeout != HAL_MAX_DELAY ) + { + if( ( ( HAL_GetTick() - tickstart ) > Timeout ) || ( Timeout == 0U ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; + /* Clear TX descriptor so that we can proceed */ + dmatxdesc->DESC0 = ( ETH_DMATXDESC_FS | ETH_DMATXDESC_LS ); + return HAL_ERROR; + } + } + } + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Sends an Ethernet Packet in interrupt mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfig * pTxConfig ) + { + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Save the packet pointer to release. */ + heth->TxDescList.CurrentPacketAddress = ( uint32_t * ) pTxConfig->pData; + + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 1 ) != HAL_ETH_ERROR_NONE ) + { + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + if( ( ( heth->Instance )->DMASR & ETH_DMASR_TBUS ) != ( uint32_t ) RESET ) + { + /* Clear TBUS ETHERNET DMA flag */ + ( heth->Instance )->DMASR = ETH_DMASR_TBUS; + /* Resume DMA transmission*/ + ( heth->Instance )->DMATPDR = 0U; + } + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Read a received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pAppBuff: Pointer to an application buffer to receive the packet. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ) + { + uint32_t descidx; + ETH_DMADescTypeDef * dmarxdesc; + uint32_t desccnt = 0U; + uint32_t desccntmax; + uint32_t bufflength; + uint8_t rxdataready = 0U; + + if( pAppBuff == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState != HAL_ETH_STATE_STARTED ) + { + return HAL_ERROR; + } + + descidx = heth->RxDescList.RxDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; + + /* Check if descriptor is not owned by DMA */ + while( ( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_OWN ) == ( uint32_t ) RESET ) && ( desccnt < desccntmax ) && + ( rxdataready == 0U ) ) + { + if( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_LS ) != ( uint32_t ) RESET ) + { + /* Get timestamp high */ + heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC7; + /* Get timestamp low */ + heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC6; + } + + if( ( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_FS ) != ( uint32_t ) RESET ) || ( heth->RxDescList.pRxStart != NULL ) ) + { + /* Check first descriptor */ + if( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_FS ) != ( uint32_t ) RESET ) + { + heth->RxDescList.RxDescCnt = 0; + heth->RxDescList.RxDataLength = 0; + } + + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + bufflength = ( ( dmarxdesc->DESC0 & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4U; + + /* Check if last descriptor */ + if( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_LS ) != ( uint32_t ) RESET ) + { + /* Save Last descriptor index */ + heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC0; + + /* Packet ready */ + rxdataready = 1; + } + + /* Link data */ + WRITE_REG( dmarxdesc->BackupAddr0, dmarxdesc->DESC2 ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Link callback*/ + heth->rxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, bufflength ); + #else + /* Link callback */ + HAL_ETH_RxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, ( uint16_t ) bufflength ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->RxDescList.RxDescCnt++; + heth->RxDescList.RxDataLength += bufflength; + + /* Clear buffer pointer */ + dmarxdesc->BackupAddr0 = 0; + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccnt++; + } + + heth->RxDescList.RxBuildDescCnt += desccnt; + + if( ( heth->RxDescList.RxBuildDescCnt ) != 0U ) + { + /* Update Descriptors */ + ETH_UpdateDescriptor( heth ); + } + + heth->RxDescList.RxDescIdx = descidx; + + if( rxdataready == 1U ) + { + /* Return received packet */ + *pAppBuff = heth->RxDescList.pRxStart; + /* Reset first element */ + heth->RxDescList.pRxStart = NULL; + + return HAL_OK; + } + + /* Packet not ready */ + return HAL_ERROR; + } + +/** + * @brief This function gives back Rx Desc of the last received Packet + * to the DMA, so ETH DMA will be able to use these descriptors + * to receive next Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ) + { + uint32_t tailidx; + uint32_t descidx; + uint32_t desccount; + ETH_DMADescTypeDef * dmarxdesc; + uint8_t * buff = NULL; + uint8_t allocStatus = 1U; + + descidx = heth->RxDescList.RxBuildDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount = heth->RxDescList.RxBuildDescCnt; + + while( ( desccount > 0U ) && ( allocStatus != 0U ) ) + { + /* Check if a buffer's attached the descriptor */ + if( READ_REG( dmarxdesc->BackupAddr0 ) == 0U ) + { + /* Get a new buffer. */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Allocate callback*/ + heth->rxAllocateCallback( &buff ); + #else + /* Allocate callback */ + HAL_ETH_RxAllocateCallback( &buff ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + if( buff == NULL ) + { + allocStatus = 0U; + } + else + { + WRITE_REG( dmarxdesc->BackupAddr0, ( uint32_t ) buff ); + WRITE_REG( dmarxdesc->DESC2, ( uint32_t ) buff ); + } + } + + if( allocStatus != 0U ) + { + if( heth->RxDescList.ItMode == 0U ) + { + WRITE_REG( dmarxdesc->DESC1, ETH_DMARXDESC_DIC | ETH_RX_BUF_SIZE | ETH_DMARXDESC_RCH ); + } + else + { + WRITE_REG( dmarxdesc->DESC1, ETH_RX_BUF_SIZE | ETH_DMARXDESC_RCH ); + } + + SET_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_OWN ); + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount--; + } + } + + if( heth->RxDescList.RxBuildDescCnt != desccount ) + { + /* Set the tail pointer index */ + tailidx = ( descidx + 1U ) % ETH_RX_DESC_CNT; + + /* DMB instruction to avoid race condition */ + __DMB(); + + /* Set the Tail pointer address */ + WRITE_REG( heth->Instance->DMARPDR, ( ( uint32_t ) ( heth->Init.RxDesc + ( tailidx ) ) ) ); + + heth->RxDescList.RxBuildDescIdx = descidx; + heth->RxDescList.RxBuildDescCnt = desccount; + } + } + +/** + * @brief Register the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxAllocateCallback: pointer to function to alloc buffer + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ) + { + if( rxAllocateCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to allocate buffer */ + heth->rxAllocateCallback = rxAllocateCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; + + return HAL_OK; + } + +/** + * @brief Rx Allocate callback. + * @param buff: pointer to allocated buffer + * @retval None + */ + __weak void HAL_ETH_RxAllocateCallback( uint8_t ** buff ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxAllocateCallback could be implemented in the user file + */ + } + +/** + * @brief Rx Link callback. + * @param pStart: pointer to packet start + * @param pEnd: pointer to packet end + * @param buff: pointer to received data + * @param Length: received data length + * @retval None + */ + __weak void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( pStart ); + UNUSED( pEnd ); + UNUSED( buff ); + UNUSED( Length ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxLinkCallback could be implemented in the user file + */ + } + +/** + * @brief Set the Rx link data function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxLinkCallback: pointer to function to link data + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ) + { + if( rxLinkCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to link data */ + heth->rxLinkCallback = rxLinkCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Rx link callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; + + return HAL_OK; + } + +/** + * @brief Get the error state of the last received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pErrorCode: pointer to uint32_t to hold the error code + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ) + { + /* Get error bits. */ + *pErrorCode = READ_BIT( heth->RxDescList.pRxLastRxDesc, ETH_DMARXDESC_ERRORS_MASK ); + + return HAL_OK; + } + +/** + * @brief Set the Tx free function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txFreeCallback: pointer to function to release the packet + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ) + { + if( txFreeCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to free transmmitted packet */ + heth->txFreeCallback = txFreeCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx free callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; + + return HAL_OK; + } + +/** + * @brief Tx Free callback. + * @param buff: pointer to buffer to free + * @retval None + */ + __weak void HAL_ETH_TxFreeCallback( uint32_t * buff ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxFreeCallback could be implemented in the user file + */ + } + +/** + * @brief Release transmitted Tx packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t numOfBuf = dmatxdesclist->BuffersInUse; + uint32_t idx = dmatxdesclist->releaseIndex; + uint8_t pktTxStatus = 1U; + uint8_t pktInUse; + + #ifdef HAL_ETH_USE_PTP + ETH_TimeStampTypeDef * timestamp = &heth->TxTimestamp; + #endif /* HAL_ETH_USE_PTP */ + + /* Loop through buffers in use. */ + while( ( numOfBuf != 0U ) && ( pktTxStatus != 0U ) ) + { + pktInUse = 1U; + numOfBuf--; + + /* If no packet, just examine the next packet. */ + if( dmatxdesclist->PacketAddress[ idx ] == NULL ) + { + /* No packet in use, skip to next. */ + idx = ( idx + 1U ) & ( ETH_TX_DESC_CNT - 1U ); + pktInUse = 0U; + } + + if( pktInUse != 0U ) + { + /* Determine if the packet has been transmitted. */ + if( ( heth->Init.TxDesc[ idx ].DESC0 & ETH_DMATXDESC_OWN ) == 0U ) + { + #ifdef HAL_ETH_USE_PTP + /* Get timestamp low */ + timestamp->TimeStampLow = heth->Init.TxDesc[ idx ].DESC6; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->Init.TxDesc[ idx ].DESC7; + #endif /* HAL_ETH_USE_PTP */ + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered callbacks*/ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + heth->txPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + heth->txFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #else + /* Call callbacks */ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + HAL_ETH_TxPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + HAL_ETH_TxFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + /* Clear the entry in the in-use array. */ + dmatxdesclist->PacketAddress[ idx ] = NULL; + + /* Update the transmit relesae index and number of buffers in use. */ + idx = ( idx + 1U ) & ( ETH_TX_DESC_CNT - 1U ); + dmatxdesclist->BuffersInUse = numOfBuf; + dmatxdesclist->releaseIndex = idx; + } + else + { + /* Get out of the loop! */ + pktTxStatus = 0U; + } + } + } + + return HAL_OK; + } + + #ifdef HAL_ETH_USE_PTP + +/** + * @brief Set the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + uint32_t tmpTSCR; + ETH_TimeTypeDef time; + + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + tmpTSCR = ptpconfig->Timestamp | + ( ( uint32_t ) ptpconfig->TimestampUpdate << ETH_PTPTSCR_TSFCU_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampAll << ETH_PTPTSCR_TSSARFE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampRolloverMode << ETH_PTPTSCR_TSSSR_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampV2 << ETH_PTPTSCR_TSPTPPSV2E_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEthernet << ETH_PTPTSCR_TSSPTPOEFE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv6 << ETH_PTPTSCR_TSSIPV6FE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv4 << ETH_PTPTSCR_TSSIPV4FE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEvent << ETH_PTPTSCR_TSSEME_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampMaster << ETH_PTPTSCR_TSSMRME_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampFilter << ETH_PTPTSCR_TSPFFMAE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampClockType << ETH_PTPTSCR_TSCNT_Pos ); + + /* Write to MACTSCR */ + MODIFY_REG( heth->Instance->PTPTSCR, ETH_MACTSCR_MASK, tmpTSCR ); + + /* Enable Timestamp */ + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE ); + WRITE_REG( heth->Instance->PTPSSIR, ptpconfig->TimestampSubsecondInc ); + WRITE_REG( heth->Instance->PTPTSAR, ptpconfig->TimestampAddend ); + + /* Enable Timestamp */ + if( ptpconfig->TimestampAddendUpdate == ENABLE ) + { + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU ); + + while( ( heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU ) != 0 ) + { + } + } + + /* Enable Update mode */ + if( ptpconfig->TimestampUpdateMode == ENABLE ) + { + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSFCU ); + } + + /* Initialize Time */ + time.Seconds = 0; + time.NanoSeconds = 0; + HAL_ETH_PTP_SetTime( heth, &time ); + + /* Ptp Init */ + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTI ); + + /* Set PTP Configuration done */ + heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED; + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Get the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + ptpconfig->Timestamp = READ_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE ); + ptpconfig->TimestampUpdate = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSFCU ) >> ETH_PTPTSCR_TSFCU_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampAll = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSARFE ) >> ETH_PTPTSCR_TSSARFE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampRolloverMode = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSSR ) >> ETH_PTPTSCR_TSSSR_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampV2 = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSPTPPSV2E ) >> ETH_PTPTSCR_TSPTPPSV2E_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEthernet = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSPTPOEFE ) >> ETH_PTPTSCR_TSSPTPOEFE_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampIPv6 = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSIPV6FE ) >> ETH_PTPTSCR_TSSIPV6FE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv4 = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSIPV4FE ) >> ETH_PTPTSCR_TSSIPV4FE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEvent = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSEME ) >> ETH_PTPTSCR_TSSEME_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampMaster = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSMRME ) >> ETH_PTPTSCR_TSSMRME_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampFilter = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSPFFMAE ) >> ETH_PTPTSCR_TSPFFMAE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampClockType = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSCNT ) >> ETH_PTPTSCR_TSCNT_Pos ) > 0U ) ? ENABLE : DISABLE; + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param heth: pointer to a ETH_TimeTypeDef structure that contains + * time to set + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED ) + { + /* Set Seconds */ + heth->Instance->PTPTSHUR = time->Seconds; + + /* Set NanoSeconds */ + heth->Instance->PTPTSLUR = time->NanoSeconds; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param heth: pointer to a ETH_TimeTypeDef structure that contains + * time to get + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED ) + { + /* Get Seconds */ + time->Seconds = heth->Instance->PTPTSHR; + + /* Get NanoSeconds */ + time->NanoSeconds = heth->Instance->PTPTSLR; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Update time for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timeupdate: pointer to a ETH_TIMEUPDATETypeDef structure that contains + * the time update information + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED ) + { + if( ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE ) + { + /* Set Seconds update */ + heth->Instance->PTPTSHUR = ETH_PTPTSHR_VALUE - timeoffset->Seconds + 1U; + + if( READ_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSSR ) == ETH_PTPTSCR_TSSSR ) + { + /* Set nanoSeconds update */ + heth->Instance->PTPTSLUR = ETH_PTPTSLR_VALUE - timeoffset->NanoSeconds; + } + else + { + heth->Instance->PTPTSLUR = ETH_PTPTSHR_VALUE - timeoffset->NanoSeconds + 1U; + } + } + else + { + /* Set Seconds update */ + heth->Instance->PTPTSHUR = timeoffset->Seconds; + /* Set nanoSeconds update */ + heth->Instance->PTPTSLUR = timeoffset->NanoSeconds; + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Insert Timestamp in transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txtimestampconf: Enable or Disable timestamp in transmission + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED ) + { + /* Enable Time Stamp transmission */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_TTSE ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get transmission timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * transmission timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t idx = dmatxdesclist->releaseIndex; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ idx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = dmatxdesc->DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = dmatxdesc->DESC1; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get receive timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * receive timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Register the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txPtpCallback: Function to handle Ptp transmission + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ) + { + if( txPtpCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set Function to handle Tx Ptp */ + heth->txPtpCallback = txPtpCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txPtpCallback = HAL_ETH_TxPtpCallback; + + return HAL_OK; + } + +/** + * @brief Tx Ptp callback. + * @param buff: pointer to application buffer + * @retval None + */ + __weak void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxPtpCallback could be implemented in the user file + */ + } + #endif /* HAL_ETH_USE_PTP */ + +/** + * @brief This function handles ETH interrupt request. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ) + { + /* Packet received */ + if( __HAL_ETH_DMA_GET_IT( heth, ETH_DMASR_RS ) ) + { + if( __HAL_ETH_DMA_GET_IT_SOURCE( heth, ETH_DMAIER_RIE ) ) + { + /* Clear the Eth DMA Rx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMASR_RS | ETH_DMASR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Receive complete callback*/ + heth->RxCpltCallback( heth ); + #else + /* Receive complete callback */ + HAL_ETH_RxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + + /* Packet transmitted */ + if( __HAL_ETH_DMA_GET_IT( heth, ETH_DMASR_TS ) ) + { + if( __HAL_ETH_DMA_GET_IT_SOURCE( heth, ETH_DMAIER_TIE ) ) + { + /* Clear the Eth DMA Tx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMASR_TS | ETH_DMASR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Transmit complete callback*/ + heth->TxCpltCallback( heth ); + #else + /* Transfer complete callback */ + HAL_ETH_TxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + + /* ETH DMA Error */ + if( __HAL_ETH_DMA_GET_IT( heth, ETH_DMASR_AIS ) ) + { + if( __HAL_ETH_DMA_GET_IT_SOURCE( heth, ETH_DMAIER_AISE ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + + /* if fatal bus error occurred */ + if( __HAL_ETH_DMA_GET_IT( heth, ETH_DMASR_FBES ) ) + { + /* Get DMA error code */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMASR, ( ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS ) ); + + /* Disable all interrupts */ + __HAL_ETH_DMA_DISABLE_IT( heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE ); + + /* Set HAL state to ERROR */ + heth->gState = HAL_ETH_STATE_ERROR; + } + else + { + /* Get DMA error status */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMASR, ( ETH_DMASR_ETS | ETH_DMASR_RWTS | + ETH_DMASR_RBUS | ETH_DMASR_AIS ) ); + + /* Clear the interrupt summary flag */ + __HAL_ETH_DMA_CLEAR_IT( heth, ( ETH_DMASR_ETS | ETH_DMASR_RWTS | + ETH_DMASR_RBUS | ETH_DMASR_AIS ) ); + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered Error callback*/ + heth->ErrorCallback( heth ); + #else + /* Ethernet DMA Error callback */ + HAL_ETH_ErrorCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + + /* ETH PMT IT */ + if( __HAL_ETH_MAC_GET_IT( heth, ETH_MAC_PMT_IT ) ) + { + /* Get MAC Wake-up source and clear the status register pending bit */ + heth->MACWakeUpEvent = READ_BIT( heth->Instance->MACPMTCSR, ( ETH_MACPMTCSR_WFR | ETH_MACPMTCSR_MPR ) ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered PMT callback*/ + heth->PMTCallback( heth ); + #else + /* Ethernet PMT callback */ + HAL_ETH_PMTCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACWakeUpEvent = ( uint32_t ) ( 0x0U ); + } + + /* check ETH WAKEUP exti flag */ + if( __HAL_ETH_WAKEUP_EXTI_GET_FLAG( ETH_WAKEUP_EXTI_LINE ) != ( uint32_t ) RESET ) + { + /* Clear ETH WAKEUP Exti pending bit */ + __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( ETH_WAKEUP_EXTI_LINE ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered WakeUp callback*/ + heth->WakeUpCallback( heth ); + #else + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + +/** + * @brief Tx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Rx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet transfer error callbacks + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_ErrorCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet Power Management module IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_PMTCallback could be implemented in the user file + */ + } + + +/** + * @brief ETH WAKEUP interrupt callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ) { - heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; - /* Clear TX descriptor so that we can proceed */ - dmatxdesc->DESC0 = (ETH_DMATXDESC_FS | ETH_DMATXDESC_LS); - return HAL_ERROR; + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_WakeUpCallback could be implemented in the user file + */ + } + +/** + * @brief Read a PHY register + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param pRegValue: parameter to hold read value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ) + { + uint32_t tmpreg1; + uint32_t tickstart; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg1 = heth->Instance->MACMIIAR; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + /* Prepare the MII address register value */ + tmpreg1 |= ( ( PHYAddr << 11U ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */ + tmpreg1 |= ( ( ( uint32_t ) PHYReg << 6U ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */ + tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */ + tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ + + /* Write the result value into the MII Address register */ + heth->Instance->MACMIIAR = tmpreg1; + + + tickstart = HAL_GetTick(); + + /* Check for the Busy flag */ + while( ( tmpreg1 & ETH_MACMIIAR_MB ) == ETH_MACMIIAR_MB ) + { + /* Check for the Timeout */ + if( ( HAL_GetTick() - tickstart ) > PHY_READ_TO ) + { + return HAL_ERROR; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + /* Get MACMIIDR value */ + *pRegValue = ( uint16_t ) ( heth->Instance->MACMIIDR ); + + return HAL_OK; } - } - } - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in interrupt mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig) -{ - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Save the packet pointer to release. */ - heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData; - - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE) - { - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) - { - /* Clear TBUS ETHERNET DMA flag */ - (heth->Instance)->DMASR = ETH_DMASR_TBUS; - /* Resume DMA transmission*/ - (heth->Instance)->DMATPDR = 0U; - } - - return HAL_OK; - - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Read a received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pAppBuff: Pointer to an application buffer to receive the packet. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff) -{ - uint32_t descidx; - ETH_DMADescTypeDef *dmarxdesc; - uint32_t desccnt = 0U; - uint32_t desccntmax; - uint32_t bufflength; - uint8_t rxdataready = 0U; - - if (pAppBuff == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState != HAL_ETH_STATE_STARTED) - { - return HAL_ERROR; - } - - descidx = heth->RxDescList.RxDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; - - /* Check if descriptor is not owned by DMA */ - while ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (desccnt < desccntmax) - && (rxdataready == 0U)) - { - if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET) - { - /* Get timestamp high */ - heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC7; - /* Get timestamp low */ - heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC6; - } - if ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL)) - { - /* Check first descriptor */ - if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET) - { - heth->RxDescList.RxDescCnt = 0; - heth->RxDescList.RxDataLength = 0; - } - - /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ - bufflength = ((dmarxdesc->DESC0 & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U; - - /* Check if last descriptor */ - if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET) - { - /* Save Last descriptor index */ - heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC0; - - /* Packet ready */ - rxdataready = 1; - } - - /* Link data */ - WRITE_REG(dmarxdesc->BackupAddr0, dmarxdesc->DESC2); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Link callback*/ - heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, bufflength); -#else - /* Link callback */ - HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - heth->RxDescList.RxDescCnt++; - heth->RxDescList.RxDataLength += bufflength; - - /* Clear buffer pointer */ - dmarxdesc->BackupAddr0 = 0; - } - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccnt++; - } - - heth->RxDescList.RxBuildDescCnt += desccnt; - if ((heth->RxDescList.RxBuildDescCnt) != 0U) - { - /* Update Descriptors */ - ETH_UpdateDescriptor(heth); - } - - heth->RxDescList.RxDescIdx = descidx; - - if (rxdataready == 1U) - { - /* Return received packet */ - *pAppBuff = heth->RxDescList.pRxStart; - /* Reset first element */ - heth->RxDescList.pRxStart = NULL; - - return HAL_OK; - } - - /* Packet not ready */ - return HAL_ERROR; -} - -/** - * @brief This function gives back Rx Desc of the last received Packet - * to the DMA, so ETH DMA will be able to use these descriptors - * to receive next Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth) -{ - uint32_t tailidx; - uint32_t descidx; - uint32_t desccount; - ETH_DMADescTypeDef *dmarxdesc; - uint8_t *buff = NULL; - uint8_t allocStatus = 1U; - - descidx = heth->RxDescList.RxBuildDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount = heth->RxDescList.RxBuildDescCnt; - - while ((desccount > 0U) && (allocStatus != 0U)) - { - /* Check if a buffer's attached the descriptor */ - if (READ_REG(dmarxdesc->BackupAddr0) == 0U) - { - /* Get a new buffer. */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Allocate callback*/ - heth->rxAllocateCallback(&buff); -#else - /* Allocate callback */ - HAL_ETH_RxAllocateCallback(&buff); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - if (buff == NULL) - { - allocStatus = 0U; - } - else - { - WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff); - WRITE_REG(dmarxdesc->DESC2, (uint32_t)buff); - } - } - - if (allocStatus != 0U) - { - if (heth->RxDescList.ItMode == 0U) - { - WRITE_REG(dmarxdesc->DESC1, ETH_DMARXDESC_DIC | ETH_RX_BUF_SIZE | ETH_DMARXDESC_RCH); - } - else - { - WRITE_REG(dmarxdesc->DESC1, ETH_RX_BUF_SIZE | ETH_DMARXDESC_RCH); - } - - SET_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN); - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount--; - } - } - - if (heth->RxDescList.RxBuildDescCnt != desccount) - { - /* Set the tail pointer index */ - tailidx = (descidx + 1U) % ETH_RX_DESC_CNT; - - /* DMB instruction to avoid race condition */ - __DMB(); - - /* Set the Tail pointer address */ - WRITE_REG(heth->Instance->DMARPDR, ((uint32_t)(heth->Init.RxDesc + (tailidx)))); - - heth->RxDescList.RxBuildDescIdx = descidx; - heth->RxDescList.RxBuildDescCnt = desccount; - } -} - -/** - * @brief Register the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxAllocateCallback: pointer to function to alloc buffer - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback) -{ - if (rxAllocateCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to allocate buffer */ - heth->rxAllocateCallback = rxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Rx Allocate callback. - * @param buff: pointer to allocated buffer - * @retval None - */ -__weak void HAL_ETH_RxAllocateCallback(uint8_t **buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxAllocateCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Link callback. - * @param pStart: pointer to packet start - * @param pEnd: pointer to packet end - * @param buff: pointer to received data - * @param Length: received data length - * @retval None - */ -__weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(pStart); - UNUSED(pEnd); - UNUSED(buff); - UNUSED(Length); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxLinkCallback could be implemented in the user file - */ -} - -/** - * @brief Set the Rx link data function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxLinkCallback: pointer to function to link data - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback) -{ - if (rxLinkCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to link data */ - heth->rxLinkCallback = rxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx link callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Get the error state of the last received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pErrorCode: pointer to uint32_t to hold the error code - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef *heth, uint32_t *pErrorCode) -{ - /* Get error bits. */ - *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXDESC_ERRORS_MASK); - - return HAL_OK; -} - -/** - * @brief Set the Tx free function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txFreeCallback: pointer to function to release the packet - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback) -{ - if (txFreeCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to free transmmitted packet */ - heth->txFreeCallback = txFreeCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx free callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; - - return HAL_OK; -} - -/** - * @brief Tx Free callback. - * @param buff: pointer to buffer to free - * @retval None - */ -__weak void HAL_ETH_TxFreeCallback(uint32_t *buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxFreeCallback could be implemented in the user file - */ -} - -/** - * @brief Release transmitted Tx packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t numOfBuf = dmatxdesclist->BuffersInUse; - uint32_t idx = dmatxdesclist->releaseIndex; - uint8_t pktTxStatus = 1U; - uint8_t pktInUse; -#ifdef HAL_ETH_USE_PTP - ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp; -#endif /* HAL_ETH_USE_PTP */ - - /* Loop through buffers in use. */ - while ((numOfBuf != 0U) && (pktTxStatus != 0U)) - { - pktInUse = 1U; - numOfBuf--; - /* If no packet, just examine the next packet. */ - if (dmatxdesclist->PacketAddress[idx] == NULL) - { - /* No packet in use, skip to next. */ - idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U); - pktInUse = 0U; - } - - if (pktInUse != 0U) - { - /* Determine if the packet has been transmitted. */ - if ((heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_OWN) == 0U) - { -#ifdef HAL_ETH_USE_PTP - /* Get timestamp low */ - timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC6; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC7; -#endif /* HAL_ETH_USE_PTP */ - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered callbacks*/ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]); -#else - /* Call callbacks */ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - /* Clear the entry in the in-use array. */ - dmatxdesclist->PacketAddress[idx] = NULL; - - /* Update the transmit relesae index and number of buffers in use. */ - idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U); - dmatxdesclist->BuffersInUse = numOfBuf; - dmatxdesclist->releaseIndex = idx; - } - else - { - /* Get out of the loop! */ - pktTxStatus = 0U; - } - } - } - return HAL_OK; -} - -#ifdef HAL_ETH_USE_PTP -/** - * @brief Set the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - uint32_t tmpTSCR; - ETH_TimeTypeDef time; - - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - - tmpTSCR = ptpconfig->Timestamp | - ((uint32_t)ptpconfig->TimestampUpdate << ETH_PTPTSCR_TSFCU_Pos) | - ((uint32_t)ptpconfig->TimestampAll << ETH_PTPTSCR_TSSARFE_Pos) | - ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_PTPTSCR_TSSSR_Pos) | - ((uint32_t)ptpconfig->TimestampV2 << ETH_PTPTSCR_TSPTPPSV2E_Pos) | - ((uint32_t)ptpconfig->TimestampEthernet << ETH_PTPTSCR_TSSPTPOEFE_Pos) | - ((uint32_t)ptpconfig->TimestampIPv6 << ETH_PTPTSCR_TSSIPV6FE_Pos) | - ((uint32_t)ptpconfig->TimestampIPv4 << ETH_PTPTSCR_TSSIPV4FE_Pos) | - ((uint32_t)ptpconfig->TimestampEvent << ETH_PTPTSCR_TSSEME_Pos) | - ((uint32_t)ptpconfig->TimestampMaster << ETH_PTPTSCR_TSSMRME_Pos) | - ((uint32_t)ptpconfig->TimestampFilter << ETH_PTPTSCR_TSPFFMAE_Pos) | - ((uint32_t)ptpconfig->TimestampClockType << ETH_PTPTSCR_TSCNT_Pos); - - /* Write to MACTSCR */ - MODIFY_REG(heth->Instance->PTPTSCR, ETH_MACTSCR_MASK, tmpTSCR); - - /* Enable Timestamp */ - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE); - WRITE_REG(heth->Instance->PTPSSIR, ptpconfig->TimestampSubsecondInc); - WRITE_REG(heth->Instance->PTPTSAR, ptpconfig->TimestampAddend); - - /* Enable Timestamp */ - if (ptpconfig->TimestampAddendUpdate == ENABLE) - { - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU); - while ((heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU) != 0) {} - } - - /* Enable Update mode */ - if (ptpconfig->TimestampUpdateMode == ENABLE) - { - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSFCU); - } - - /* Initialize Time */ - time.Seconds = 0; - time.NanoSeconds = 0; - HAL_ETH_PTP_SetTime(heth, &time); - - /* Ptp Init */ - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTI); - - /* Set PTP Configuration done */ - heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Get the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - ptpconfig->Timestamp = READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE); - ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSFCU) >> ETH_PTPTSCR_TSFCU_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSARFE) >> ETH_PTPTSCR_TSSARFE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSSR) >> ETH_PTPTSCR_TSSSR_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSPTPPSV2E) >> ETH_PTPTSCR_TSPTPPSV2E_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSPTPOEFE) >> ETH_PTPTSCR_TSSPTPOEFE_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSIPV6FE) >> ETH_PTPTSCR_TSSIPV6FE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSIPV4FE) >> ETH_PTPTSCR_TSSIPV4FE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSEME) >> ETH_PTPTSCR_TSSEME_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSMRME) >> ETH_PTPTSCR_TSSMRME_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSPFFMAE) >> ETH_PTPTSCR_TSPFFMAE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampClockType = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSCNT) >> ETH_PTPTSCR_TSCNT_Pos) > 0U) ? ENABLE : DISABLE; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param heth: pointer to a ETH_TimeTypeDef structure that contains - * time to set - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) - { - /* Set Seconds */ - heth->Instance->PTPTSHUR = time->Seconds; - - /* Set NanoSeconds */ - heth->Instance->PTPTSLUR = time->NanoSeconds; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param heth: pointer to a ETH_TimeTypeDef structure that contains - * time to get - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) - { - /* Get Seconds */ - time->Seconds = heth->Instance->PTPTSHR; - - /* Get NanoSeconds */ - time->NanoSeconds = heth->Instance->PTPTSLR; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Update time for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timeupdate: pointer to a ETH_TIMEUPDATETypeDef structure that contains - * the time update information - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) - { - if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE) - { - /* Set Seconds update */ - heth->Instance->PTPTSHUR = ETH_PTPTSHR_VALUE - timeoffset->Seconds + 1U; - - if (READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSSR) == ETH_PTPTSCR_TSSSR) - { - /* Set nanoSeconds update */ - heth->Instance->PTPTSLUR = ETH_PTPTSLR_VALUE - timeoffset->NanoSeconds; - } - else - { - heth->Instance->PTPTSLUR = ETH_PTPTSHR_VALUE - timeoffset->NanoSeconds + 1U; - } - } - else - { - /* Set Seconds update */ - heth->Instance->PTPTSHUR = timeoffset->Seconds; - /* Set nanoSeconds update */ - heth->Instance->PTPTSLUR = timeoffset->NanoSeconds; - } - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Insert Timestamp in transmission. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txtimestampconf: Enable or Disable timestamp in transmission - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) - { - /* Enable Time Stamp transmission */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TTSE); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get transmission timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * transmission timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t idx = dmatxdesclist->releaseIndex; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = dmatxdesc->DESC0; - /* Get timestamp high */ - timestamp->TimeStampHigh = dmatxdesc->DESC1; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get receive timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * receive timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Register the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txPtpCallback: Function to handle Ptp transmission - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback) -{ - if (txPtpCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - /* Set Function to handle Tx Ptp */ - heth->txPtpCallback = txPtpCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txPtpCallback = HAL_ETH_TxPtpCallback; - - return HAL_OK; -} - -/** - * @brief Tx Ptp callback. - * @param buff: pointer to application buffer - * @retval None - */ -__weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxPtpCallback could be implemented in the user file - */ -} -#endif /* HAL_ETH_USE_PTP */ - -/** - * @brief This function handles ETH interrupt request. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) -{ - /* Packet received */ - if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_RS)) - { - if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_RIE)) - { - /* Clear the Eth DMA Rx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_RS | ETH_DMASR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Receive complete callback*/ - heth->RxCpltCallback(heth); -#else - /* Receive complete callback */ - HAL_ETH_RxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - } - - /* Packet transmitted */ - if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_TS)) - { - if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_TIE)) - { - /* Clear the Eth DMA Tx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_TS | ETH_DMASR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Transmit complete callback*/ - heth->TxCpltCallback(heth); -#else - /* Transfer complete callback */ - HAL_ETH_TxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - } - - /* ETH DMA Error */ - if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_AIS)) - { - if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_AISE)) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - /* if fatal bus error occurred */ - if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_FBES)) - { - /* Get DMA error code */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS)); - - /* Disable all interrupts */ - __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE); - - /* Set HAL state to ERROR */ - heth->gState = HAL_ETH_STATE_ERROR; - } - else - { - /* Get DMA error status */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_ETS | ETH_DMASR_RWTS | - ETH_DMASR_RBUS | ETH_DMASR_AIS)); - - /* Clear the interrupt summary flag */ - __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMASR_ETS | ETH_DMASR_RWTS | - ETH_DMASR_RBUS | ETH_DMASR_AIS)); - } -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered Error callback*/ - heth->ErrorCallback(heth); -#else - /* Ethernet DMA Error callback */ - HAL_ETH_ErrorCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - } - } - - - /* ETH PMT IT */ - if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_PMT_IT)) - { - /* Get MAC Wake-up source and clear the status register pending bit */ - heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPMTCSR, (ETH_MACPMTCSR_WFR | ETH_MACPMTCSR_MPR)); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered PMT callback*/ - heth->PMTCallback(heth); -#else - /* Ethernet PMT callback */ - HAL_ETH_PMTCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - heth->MACWakeUpEvent = (uint32_t)(0x0U); - } - - - /* check ETH WAKEUP exti flag */ - if (__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET) - { - /* Clear ETH WAKEUP Exti pending bit */ - __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered WakeUp callback*/ - heth->WakeUpCallback(heth); -#else - /* ETH WAKEUP callback */ - HAL_ETH_WakeUpCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } -} - -/** - * @brief Tx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet transfer error callbacks - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_ErrorCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet Power Management module IT callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_PMTCallback could be implemented in the user file - */ -} - - -/** - * @brief ETH WAKEUP interrupt callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_WakeUpCallback could be implemented in the user file - */ -} - -/** - * @brief Read a PHY register - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param pRegValue: parameter to hold read value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue) -{ - uint32_t tmpreg1; - uint32_t tickstart; - - /* Get the ETHERNET MACMIIAR value */ - tmpreg1 = heth->Instance->MACMIIAR; - - /* Keep only the CSR Clock Range CR[2:0] bits value */ - tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; - - /* Prepare the MII address register value */ - tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ - tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ - tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */ - tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ - - /* Write the result value into the MII Address register */ - heth->Instance->MACMIIAR = tmpreg1; - - - tickstart = HAL_GetTick(); - - /* Check for the Busy flag */ - while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) - { - /* Check for the Timeout */ - if ((HAL_GetTick() - tickstart) > PHY_READ_TO) - { - return HAL_ERROR; - } - - tmpreg1 = heth->Instance->MACMIIAR; - } - - /* Get MACMIIDR value */ - *pRegValue = (uint16_t)(heth->Instance->MACMIIDR); - - return HAL_OK; -} - - -/** - * @brief Writes to a PHY register. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param RegValue: the value to write - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue) -{ - uint32_t tmpreg1; - uint32_t tickstart; - - /* Get the ETHERNET MACMIIAR value */ - tmpreg1 = heth->Instance->MACMIIAR; - - /* Keep only the CSR Clock Range CR[2:0] bits value */ - tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; - - /* Prepare the MII register address value */ - tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ - tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ - tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */ - tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ - - /* Give the value to the MII data register */ - heth->Instance->MACMIIDR = (uint16_t)RegValue; - - /* Write the result value into the MII Address register */ - heth->Instance->MACMIIAR = tmpreg1; - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Check for the Busy flag */ - while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) - { - /* Check for the Timeout */ - if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO) - { - return HAL_ERROR; - } - tmpreg1 = heth->Instance->MACMIIAR; - } - return HAL_OK; -} - -/** - * @} - */ +/** + * @brief Writes to a PHY register. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param RegValue: the value to write + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ) + { + uint32_t tmpreg1; + uint32_t tickstart; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg1 = heth->Instance->MACMIIAR; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + /* Prepare the MII register address value */ + tmpreg1 |= ( ( PHYAddr << 11U ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */ + tmpreg1 |= ( ( ( uint32_t ) PHYReg << 6U ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */ + tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */ + tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ + + /* Give the value to the MII data register */ + heth->Instance->MACMIIDR = ( uint16_t ) RegValue; + + /* Write the result value into the MII Address register */ + heth->Instance->MACMIIAR = tmpreg1; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check for the Busy flag */ + while( ( tmpreg1 & ETH_MACMIIAR_MB ) == ETH_MACMIIAR_MB ) + { + /* Check for the Timeout */ + if( ( HAL_GetTick() - tickstart ) > PHY_WRITE_TO ) + { + return HAL_ERROR; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions - * @brief ETH control functions - * -@verbatim - ============================================================================== - ##### Peripheral Control functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to control the ETH - peripheral. - -@endverbatim - * @{ - */ -/** - * @brief Get the configuration of the MAC and MTL subsystems. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold - * the configuration of the MAC. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - /* Get MAC parameters */ - macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE; - macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL); - macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_RD) >> 9) == 0U) ? ENABLE : DISABLE; - macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSD) >> 16) > 0U) - ? ENABLE : DISABLE; - macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ROD) >> 13) == 0U) ? ENABLE : DISABLE; - macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE; - macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM); - macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES); - macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 22) == 0U) ? ENABLE : DISABLE; - macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 23) == 0U) ? ENABLE : DISABLE; - macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_APCS) >> 7) > 0U) ? ENABLE : DISABLE; - macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IFG); - macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPCO) >> 10U) > 0U) ? ENABLE : DISABLE; - - - macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_TFCE) >> 1) > 0U) ? ENABLE : DISABLE; - macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_ZQPD) >> 7) == 0U) ? ENABLE : DISABLE; - macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PLT); - macconf->PauseTime = (READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PT) >> 16); - macconf->ReceiveFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_RFCE) >> 2U) > 0U) ? ENABLE : DISABLE; - macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_UPFD) >> 3U) > 0U) - ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Get the configuration of the DMA. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMABMR, - (ETH_DMAARBITRATION_RXPRIORTX | ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1)); - dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_AAB) >> 25U) > 0U) ? ENABLE : DISABLE; - dmaconf->BurstMode = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_FB | ETH_DMABMR_MB); - dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_RDP); - dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_PBL); - dmaconf->EnhancedDescriptorFormat = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_EDE) >> 7) > 0U) ? ENABLE : DISABLE; - dmaconf->DescriptorSkipLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_DSL) >> 2; - - dmaconf->DropTCPIPChecksumErrorFrame = ((READ_BIT(heth->Instance->DMAOMR, - ETH_DMAOMR_DTCEFD) >> 26) > 0U) ? DISABLE : ENABLE; - dmaconf->ReceiveStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RSF) >> 25) > 0U) ? ENABLE : DISABLE; - dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FTF) >> 20) > 0U) ? DISABLE : ENABLE; - dmaconf->TransmitStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TSF) >> 21) > 0U) ? ENABLE : DISABLE; - dmaconf->TransmitThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TTC); - dmaconf->ForwardErrorFrames = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FEF) >> 7) > 0U) ? ENABLE : DISABLE; - dmaconf->ForwardUndersizedGoodFrames = ((READ_BIT(heth->Instance->DMAOMR, - ETH_DMAOMR_FUGF) >> 6) > 0U) ? ENABLE : DISABLE; - dmaconf->ReceiveThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RTC); - dmaconf->SecondFrameOperate = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_OSF) >> 2) > 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Set the MAC configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains - * the configuration of the MAC. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetMACConfig(heth, macconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Set the ETH DMA configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetDMAConfig(heth, dmaconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Configures the Clock range of ETH MDIO interface. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth) -{ - uint32_t hclk; - uint32_t tmpreg; - - /* Get the ETHERNET MACMIIAR value */ - tmpreg = (heth->Instance)->MACMIIAR; - /* Clear CSR Clock Range CR[2:0] bits */ - tmpreg &= ETH_MACMIIAR_CR_MASK; - - /* Get hclk frequency value */ - hclk = HAL_RCC_GetHCLKFreq(); - - /* Set CR bits depending on hclk value */ - if ((hclk >= 20000000U) && (hclk < 35000000U)) - { - /* CSR Clock Range between 20-35 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16; - } - else if ((hclk >= 35000000U) && (hclk < 60000000U)) - { - /* CSR Clock Range between 35-60 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26; - } - else if ((hclk >= 60000000U) && (hclk < 100000000U)) - { - /* CSR Clock Range between 60-100 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42; - } - else if ((hclk >= 100000000U) && (hclk < 150000000U)) - { - /* CSR Clock Range between 100-150 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62; - } - else /* ((hclk >= 150000000)&&(hclk <= 183000000))*/ - { - /* CSR Clock Range between 150-183 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102; - } - - /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ - (heth->Instance)->MACMIIAR = (uint32_t)tmpreg; -} - -/** - * @brief Set the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - uint32_t filterconfig; - uint32_t tmpreg1; - - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode | - ((uint32_t)pFilterConfig->HashUnicast << 1) | - ((uint32_t)pFilterConfig->HashMulticast << 2) | - ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) | - ((uint32_t)pFilterConfig->PassAllMulticast << 4) | - ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) | - ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) | - ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) | - ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) | - ((uint32_t)pFilterConfig->ReceiveAllMode << 31) | - pFilterConfig->ControlPacketsFilter); - - MODIFY_REG(heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFFR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFFR = tmpreg1; - - return HAL_OK; -} - -/** - * @brief Get the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PM)) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HU) >> 1) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HM) >> 2) > 0U) ? ENABLE : DISABLE; - pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR, - ETH_MACFFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE; - pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PAM) >> 4) > 0U) ? ENABLE : DISABLE; - pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_BFD) >> 5) == 0U) ? ENABLE : DISABLE; - pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PCF); - pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR, - ETH_MACFFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE; - pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HPF) >> 10) > 0U) - ? ENABLE : DISABLE; - pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_RA) >> 31) > 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Set the source MAC Address to be matched. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param AddrNbr: The MAC address to configure - * This parameter must be a value of the following: - * ETH_MAC_ADDRESS1 - * ETH_MAC_ADDRESS2 - * ETH_MAC_ADDRESS3 - * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr) -{ - uint32_t macaddrlr; - uint32_t macaddrhr; - - if (pMACAddr == NULL) - { - return HAL_ERROR; - } - - /* Get mac addr high reg offset */ - macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr); - /* Get mac addr low reg offset */ - macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr); - - /* Set MAC addr bits 32 to 47 */ - (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]); - /* Set MAC addr bits 0 to 31 */ - (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) | - ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]); - - /* Enable address and set source address bit */ - (*(__IO uint32_t *)macaddrhr) |= (ETH_MACA1HR_AE | ETH_MACA1HR_SA); - - return HAL_OK; -} - -/** - * @brief Set the ETH Hash Table Value. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pHashTable: pointer to a table of two 32 bit values, that contains - * the 64 bits of the hash table. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable) -{ - uint32_t tmpreg1; - if (pHashTable == NULL) - { - return HAL_ERROR; - } - - heth->Instance->MACHTHR = pHashTable[0]; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACHTHR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACHTHR = tmpreg1; - - heth->Instance->MACHTLR = pHashTable[1]; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACHTLR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACHTLR = tmpreg1; - - return HAL_OK; -} - -/** - * @brief Set the VLAN Identifier for Rx packets - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ComparisonBits: 12 or 16 bit comparison mode - must be a value of @ref ETH_VLAN_Tag_Comparison - * @param VLANIdentifier: VLAN Identifier value - * @retval None - */ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier) -{ - uint32_t tmpreg1; - MODIFY_REG(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier); - if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) - { - CLEAR_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC); - } - else - { - SET_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC); - } - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACVLANTR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACVLANTR = tmpreg1; -} - -/** - * @brief Enters the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure - * that contains the Power Down configuration - * @retval None. - */ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig) -{ - uint32_t powerdownconfig; - - powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << ETH_MACPMTCSR_MPE_Pos) | - ((uint32_t)pPowerDownConfig->WakeUpPacket << ETH_MACPMTCSR_WFE_Pos) | - ((uint32_t)pPowerDownConfig->GlobalUnicast << ETH_MACPMTCSR_GU_Pos) | - ETH_MACPMTCSR_PD); - - MODIFY_REG(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_MASK, powerdownconfig); -} - -/** - * @brief Exits from the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - /* clear wake up sources */ - CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACPMTCSR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACPMTCSR = tmpreg1; - - if (READ_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD) != 0U) - { - /* Exit power down mode */ - CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACPMTCSR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACPMTCSR = tmpreg1; - } - - /* Disable PMT interrupt */ - SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_PMTIM); -} - -/** - * @brief Set the WakeUp filter. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilter: pointer to filter registers values - * @param Count: number of filter registers, must be from 1 to 8. - * @retval None. - */ -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count) -{ - uint32_t regindex; - - if (pFilter == NULL) - { - return HAL_ERROR; - } - - /* Reset Filter Pointer */ - SET_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFFRPR); - - /* Wake up packet filter config */ - for (regindex = 0; regindex < Count; regindex++) - { - /* Write filter regs */ - WRITE_REG(heth->Instance->MACRWUFFR, pFilter[regindex]); - } - - return HAL_OK; -} - -/** - * @} - */ + * @brief ETH control functions + * + * @verbatim + * ============================================================================== + ##### Peripheral Control functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to control the ETH + #####peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Get the configuration of the MAC and MTL subsystems. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold + * the configuration of the MAC. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + /* Get MAC parameters */ + macconf->DeferralCheck = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DC ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + macconf->BackOffLimit = READ_BIT( heth->Instance->MACCR, ETH_MACCR_BL ); + macconf->RetryTransmission = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_RD ) >> 9 ) == 0U ) ? ENABLE : DISABLE; + macconf->CarrierSenseDuringTransmit = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_CSD ) >> 16 ) > 0U ) + ? ENABLE : DISABLE; + macconf->ReceiveOwn = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_ROD ) >> 13 ) == 0U ) ? ENABLE : DISABLE; + macconf->LoopbackMode = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_LM ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + macconf->DuplexMode = READ_BIT( heth->Instance->MACCR, ETH_MACCR_DM ); + macconf->Speed = READ_BIT( heth->Instance->MACCR, ETH_MACCR_FES ); + macconf->Jabber = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_JD ) >> 22 ) == 0U ) ? ENABLE : DISABLE; + macconf->Watchdog = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_WD ) >> 23 ) == 0U ) ? ENABLE : DISABLE; + macconf->AutomaticPadCRCStrip = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_APCS ) >> 7 ) > 0U ) ? ENABLE : DISABLE; + macconf->InterPacketGapVal = READ_BIT( heth->Instance->MACCR, ETH_MACCR_IFG ); + macconf->ChecksumOffload = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_IPCO ) >> 10U ) > 0U ) ? ENABLE : DISABLE; + + + macconf->TransmitFlowControl = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_TFCE ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + macconf->ZeroQuantaPause = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_ZQPD ) >> 7 ) == 0U ) ? ENABLE : DISABLE; + macconf->PauseLowThreshold = READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_PLT ); + macconf->PauseTime = ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_PT ) >> 16 ); + macconf->ReceiveFlowControl = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_RFCE ) >> 2U ) > 0U ) ? ENABLE : DISABLE; + macconf->UnicastPausePacketDetect = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_UPFD ) >> 3U ) > 0U ) + ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Get the configuration of the DMA. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + dmaconf->DMAArbitration = READ_BIT( heth->Instance->DMABMR, + ( ETH_DMAARBITRATION_RXPRIORTX | ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1 ) ); + dmaconf->AddressAlignedBeats = ( ( READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_AAB ) >> 25U ) > 0U ) ? ENABLE : DISABLE; + dmaconf->BurstMode = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_FB | ETH_DMABMR_MB ); + dmaconf->RxDMABurstLength = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_RDP ); + dmaconf->TxDMABurstLength = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_PBL ); + dmaconf->EnhancedDescriptorFormat = ( ( READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_EDE ) >> 7 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->DescriptorSkipLength = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_DSL ) >> 2; + + dmaconf->DropTCPIPChecksumErrorFrame = ( ( READ_BIT( heth->Instance->DMAOMR, + ETH_DMAOMR_DTCEFD ) >> 26 ) > 0U ) ? DISABLE : ENABLE; + dmaconf->ReceiveStoreForward = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_RSF ) >> 25 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->FlushRxPacket = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_FTF ) >> 20 ) > 0U ) ? DISABLE : ENABLE; + dmaconf->TransmitStoreForward = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_TSF ) >> 21 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->TransmitThresholdControl = READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_TTC ); + dmaconf->ForwardErrorFrames = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_FEF ) >> 7 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->ForwardUndersizedGoodFrames = ( ( READ_BIT( heth->Instance->DMAOMR, + ETH_DMAOMR_FUGF ) >> 6 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->ReceiveThresholdControl = READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_RTC ); + dmaconf->SecondFrameOperate = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_OSF ) >> 2 ) > 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Set the MAC configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains + * the configuration of the MAC. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetMACConfig( heth, macconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Set the ETH DMA configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetDMAConfig( heth, dmaconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Configures the Clock range of ETH MDIO interface. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ) + { + uint32_t hclk; + uint32_t tmpreg; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg = ( heth->Instance )->MACMIIAR; + /* Clear CSR Clock Range CR[2:0] bits */ + tmpreg &= ETH_MACMIIAR_CR_MASK; + + /* Get hclk frequency value */ + hclk = HAL_RCC_GetHCLKFreq(); + + /* Set CR bits depending on hclk value */ + if( ( hclk >= 20000000U ) && ( hclk < 35000000U ) ) + { + /* CSR Clock Range between 20-35 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div16; + } + else if( ( hclk >= 35000000U ) && ( hclk < 60000000U ) ) + { + /* CSR Clock Range between 35-60 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26; + } + else if( ( hclk >= 60000000U ) && ( hclk < 100000000U ) ) + { + /* CSR Clock Range between 60-100 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div42; + } + else if( ( hclk >= 100000000U ) && ( hclk < 150000000U ) ) + { + /* CSR Clock Range between 100-150 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div62; + } + else /* ((hclk >= 150000000)&&(hclk <= 183000000))*/ + { + /* CSR Clock Range between 150-183 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div102; + } + + /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ + ( heth->Instance )->MACMIIAR = ( uint32_t ) tmpreg; + } + +/** + * @brief Set the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + uint32_t filterconfig; + uint32_t tmpreg1; + + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + filterconfig = ( ( uint32_t ) pFilterConfig->PromiscuousMode | + ( ( uint32_t ) pFilterConfig->HashUnicast << 1 ) | + ( ( uint32_t ) pFilterConfig->HashMulticast << 2 ) | + ( ( uint32_t ) pFilterConfig->DestAddrInverseFiltering << 3 ) | + ( ( uint32_t ) pFilterConfig->PassAllMulticast << 4 ) | + ( ( uint32_t ) ( ( pFilterConfig->BroadcastFilter == DISABLE ) ? 1U : 0U ) << 5 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrInverseFiltering << 8 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrFiltering << 9 ) | + ( ( uint32_t ) pFilterConfig->HachOrPerfectFilter << 10 ) | + ( ( uint32_t ) pFilterConfig->ReceiveAllMode << 31 ) | + pFilterConfig->ControlPacketsFilter ); + + MODIFY_REG( heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACFFR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACFFR = tmpreg1; + + return HAL_OK; + } + +/** + * @brief Get the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + pFilterConfig->PromiscuousMode = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_PM ) ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashUnicast = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_HU ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashMulticast = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_HM ) >> 2 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->DestAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACFFR, + ETH_MACFFR_DAIF ) >> 3 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->PassAllMulticast = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_PAM ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->BroadcastFilter = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_BFD ) >> 5 ) == 0U ) ? ENABLE : DISABLE; + pFilterConfig->ControlPacketsFilter = READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_PCF ); + pFilterConfig->SrcAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACFFR, + ETH_MACFFR_SAIF ) >> 8 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->SrcAddrFiltering = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_SAF ) >> 9 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HachOrPerfectFilter = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_HPF ) >> 10 ) > 0U ) + ? ENABLE : DISABLE; + pFilterConfig->ReceiveAllMode = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_RA ) >> 31 ) > 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Set the source MAC Address to be matched. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param AddrNbr: The MAC address to configure + * This parameter must be a value of the following: + * ETH_MAC_ADDRESS1 + * ETH_MAC_ADDRESS2 + * ETH_MAC_ADDRESS3 + * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ) + { + uint32_t macaddrlr; + uint32_t macaddrhr; + + if( pMACAddr == NULL ) + { + return HAL_ERROR; + } + + /* Get mac addr high reg offset */ + macaddrhr = ( ( uint32_t ) &( heth->Instance->MACA0HR ) + AddrNbr ); + /* Get mac addr low reg offset */ + macaddrlr = ( ( uint32_t ) &( heth->Instance->MACA0LR ) + AddrNbr ); + + /* Set MAC addr bits 32 to 47 */ + ( *( __IO uint32_t * ) macaddrhr ) = ( ( ( uint32_t ) ( pMACAddr[ 5 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 4 ] ); + /* Set MAC addr bits 0 to 31 */ + ( *( __IO uint32_t * ) macaddrlr ) = ( ( ( uint32_t ) ( pMACAddr[ 3 ] ) << 24 ) | ( ( uint32_t ) ( pMACAddr[ 2 ] ) << 16 ) | + ( ( uint32_t ) ( pMACAddr[ 1 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 0 ] ); + + /* Enable address and set source address bit */ + ( *( __IO uint32_t * ) macaddrhr ) |= ( ETH_MACA1HR_AE | ETH_MACA1HR_SA ); + + return HAL_OK; + } + +/** + * @brief Set the ETH Hash Table Value. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pHashTable: pointer to a table of two 32 bit values, that contains + * the 64 bits of the hash table. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ) + { + uint32_t tmpreg1; + + if( pHashTable == NULL ) + { + return HAL_ERROR; + } + + heth->Instance->MACHTHR = pHashTable[ 0 ]; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACHTHR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACHTHR = tmpreg1; + + heth->Instance->MACHTLR = pHashTable[ 1 ]; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACHTLR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACHTLR = tmpreg1; + + return HAL_OK; + } + +/** + * @brief Set the VLAN Identifier for Rx packets + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ComparisonBits: 12 or 16 bit comparison mode + * must be a value of @ref ETH_VLAN_Tag_Comparison + * @param VLANIdentifier: VLAN Identifier value + * @retval None + */ + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ) + { + uint32_t tmpreg1; + + MODIFY_REG( heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier ); + + if( ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT ) + { + CLEAR_BIT( heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC ); + } + else + { + SET_BIT( heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC ); + } + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACVLANTR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACVLANTR = tmpreg1; + } + +/** + * @brief Enters the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure + * that contains the Power Down configuration + * @retval None. + */ + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ) + { + uint32_t powerdownconfig; + + powerdownconfig = ( ( ( uint32_t ) pPowerDownConfig->MagicPacket << ETH_MACPMTCSR_MPE_Pos ) | + ( ( uint32_t ) pPowerDownConfig->WakeUpPacket << ETH_MACPMTCSR_WFE_Pos ) | + ( ( uint32_t ) pPowerDownConfig->GlobalUnicast << ETH_MACPMTCSR_GU_Pos ) | + ETH_MACPMTCSR_PD ); + + MODIFY_REG( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_MASK, powerdownconfig ); + } + +/** + * @brief Exits from the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ) + { + uint32_t tmpreg1; + + /* clear wake up sources */ + CLEAR_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACPMTCSR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACPMTCSR = tmpreg1; + + if( READ_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD ) != 0U ) + { + /* Exit power down mode */ + CLEAR_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACPMTCSR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACPMTCSR = tmpreg1; + } + + /* Disable PMT interrupt */ + SET_BIT( heth->Instance->MACIMR, ETH_MACIMR_PMTIM ); + } + +/** + * @brief Set the WakeUp filter. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilter: pointer to filter registers values + * @param Count: number of filter registers, must be from 1 to 8. + * @retval None. + */ + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ) + { + uint32_t regindex; + + if( pFilter == NULL ) + { + return HAL_ERROR; + } + + /* Reset Filter Pointer */ + SET_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFFRPR ); + + /* Wake up packet filter config */ + for( regindex = 0; regindex < Count; regindex++ ) + { + /* Write filter regs */ + WRITE_REG( heth->Instance->MACRWUFFR, pFilter[ regindex ] ); + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions - * @brief ETH State and Errors functions - * -@verbatim - ============================================================================== - ##### Peripheral State and Errors functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to return the State of - ETH communication process, return Peripheral Errors occurred during communication - process - - -@endverbatim - * @{ - */ - -/** - * @brief Returns the ETH state. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL state - */ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth) -{ - return heth->gState; -} - -/** - * @brief Returns the ETH error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH Error Code - */ -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth) -{ - return heth->ErrorCode; -} - -/** - * @brief Returns the ETH DMA error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH DMA Error Code - */ -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth) -{ - return heth->DMAErrorCode; -} - -/** - * @brief Returns the ETH MAC error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC Error Code - */ -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth) -{ - return heth->MACErrorCode; -} - -/** - * @brief Returns the ETH MAC WakeUp event source - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC WakeUp event source - */ -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth) -{ - return heth->MACWakeUpEvent; -} - -/** - * @} - */ - -/** - * @} - */ + * @brief ETH State and Errors functions + * + * @verbatim + * ============================================================================== + ##### Peripheral State and Errors functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to return the State of + #####ETH communication process, return Peripheral Errors occurred during communication + #####process + ##### + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Returns the ETH state. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL state + */ + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ) + { + return heth->gState; + } + +/** + * @brief Returns the ETH error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH Error Code + */ + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ) + { + return heth->ErrorCode; + } + +/** + * @brief Returns the ETH DMA error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH DMA Error Code + */ + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ) + { + return heth->DMAErrorCode; + } + +/** + * @brief Returns the ETH MAC error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC Error Code + */ + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ) + { + return heth->MACErrorCode; + } + +/** + * @brief Returns the ETH MAC WakeUp event source + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event source + */ + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ) + { + return heth->MACWakeUpEvent; + } + +/** + * @} + */ + +/** + * @} + */ /** @addtogroup ETH_Private_Functions ETH Private Functions - * @{ - */ - -/** - * @brief Clears the ETHERNET transmit FIFO. - * @param heth pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth) -{ - __IO uint32_t tmpreg = 0; - - /* Set the Flush Transmit FIFO bit */ - (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF; - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg = (heth->Instance)->DMAOMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMAOMR = tmpreg; -} - -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - uint32_t tmpreg1; - - /*------------------------ ETHERNET MACCR Configuration --------------------*/ - /* Get the ETHERNET MACCR value */ - tmpreg1 = (heth->Instance)->MACCR; - /* Clear WD, PCE, PS, TE and RE bits */ - tmpreg1 &= ETH_MACCR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)(((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 23U) | - ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 22U) | - (uint32_t)macconf->InterPacketGapVal | - ((uint32_t)macconf->CarrierSenseDuringTransmit << 16U) | - macconf->Speed | - ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 13U) | - ((uint32_t)macconf->LoopbackMode << 12U) | - macconf->DuplexMode | - ((uint32_t)macconf->ChecksumOffload << 10U) | - ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 9U) | - ((uint32_t)macconf->AutomaticPadCRCStrip << 7U) | - macconf->BackOffLimit | - ((uint32_t)macconf->DeferralCheck << 4U)); - - /* Write to ETHERNET MACCR */ - (heth->Instance)->MACCR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /*----------------------- ETHERNET MACFCR Configuration --------------------*/ - - /* Get the ETHERNET MACFCR value */ - tmpreg1 = (heth->Instance)->MACFCR; - /* Clear xx bits */ - tmpreg1 &= ETH_MACFCR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) | - ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7U) | - macconf->PauseLowThreshold | - ((uint32_t)((macconf->UnicastPausePacketDetect == ENABLE) ? 1U : 0U) << 3U) | - ((uint32_t)((macconf->ReceiveFlowControl == ENABLE) ? 1U : 0U) << 2U) | - ((uint32_t)((macconf->TransmitFlowControl == ENABLE) ? 1U : 0U) << 1U)); - - /* Write to ETHERNET MACFCR */ - (heth->Instance)->MACFCR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFCR = tmpreg1; -} - -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - uint32_t tmpreg1; - - /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ - /* Get the ETHERNET DMAOMR value */ - tmpreg1 = (heth->Instance)->DMAOMR; - /* Clear xx bits */ - tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)(((uint32_t)((dmaconf->DropTCPIPChecksumErrorFrame == DISABLE) ? 1U : 0U) << 26U) | - ((uint32_t)dmaconf->ReceiveStoreForward << 25U) | - ((uint32_t)((dmaconf->FlushRxPacket == DISABLE) ? 1U : 0U) << 20U) | - ((uint32_t)dmaconf->TransmitStoreForward << 21U) | - dmaconf->TransmitThresholdControl | - ((uint32_t)dmaconf->ForwardErrorFrames << 7U) | - ((uint32_t)dmaconf->ForwardUndersizedGoodFrames << 6U) | - dmaconf->ReceiveThresholdControl | - ((uint32_t)dmaconf->SecondFrameOperate << 2U)); - - /* Write to ETHERNET DMAOMR */ - (heth->Instance)->DMAOMR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->DMAOMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMAOMR = tmpreg1; - - /*----------------------- ETHERNET DMABMR Configuration --------------------*/ - (heth->Instance)->DMABMR = (uint32_t)(((uint32_t)dmaconf->AddressAlignedBeats << 25U) | - dmaconf->BurstMode | - dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or - Rx it is applied for the other */ - dmaconf->TxDMABurstLength | - ((uint32_t)dmaconf->EnhancedDescriptorFormat << 7U) | - (dmaconf->DescriptorSkipLength << 2U) | - dmaconf->DMAArbitration | - ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->DMABMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMABMR = tmpreg1; -} - -/** - * @brief Configures Ethernet MAC and DMA with default parameters. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth) -{ - ETH_MACConfigTypeDef macDefaultConf; - ETH_DMAConfigTypeDef dmaDefaultConf; - - /*--------------- ETHERNET MAC registers default Configuration --------------*/ - macDefaultConf.Watchdog = ENABLE; - macDefaultConf.Jabber = ENABLE; - macDefaultConf.InterPacketGapVal = ETH_INTERFRAMEGAP_96BIT; - macDefaultConf.CarrierSenseDuringTransmit = DISABLE; - macDefaultConf.ReceiveOwn = ENABLE; - macDefaultConf.LoopbackMode = DISABLE; - macDefaultConf.ChecksumOffload = ENABLE; - macDefaultConf.RetryTransmission = DISABLE; - macDefaultConf.AutomaticPadCRCStrip = DISABLE; - macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; - macDefaultConf.DeferralCheck = DISABLE; - macDefaultConf.PauseTime = 0x0U; - macDefaultConf.ZeroQuantaPause = DISABLE; - macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4; - macDefaultConf.ReceiveFlowControl = DISABLE; - macDefaultConf.TransmitFlowControl = DISABLE; - macDefaultConf.Speed = ETH_SPEED_100M; - macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; - macDefaultConf.UnicastPausePacketDetect = DISABLE; - - /* MAC default configuration */ - ETH_SetMACConfig(heth, &macDefaultConf); - - /*--------------- ETHERNET DMA registers default Configuration --------------*/ - dmaDefaultConf.DropTCPIPChecksumErrorFrame = ENABLE; - dmaDefaultConf.ReceiveStoreForward = ENABLE; - dmaDefaultConf.FlushRxPacket = ENABLE; - dmaDefaultConf.TransmitStoreForward = ENABLE; - dmaDefaultConf.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; - dmaDefaultConf.ForwardErrorFrames = DISABLE; - dmaDefaultConf.ForwardUndersizedGoodFrames = DISABLE; - dmaDefaultConf.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; - dmaDefaultConf.SecondFrameOperate = ENABLE; - dmaDefaultConf.AddressAlignedBeats = ENABLE; - dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; - dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.EnhancedDescriptorFormat = ENABLE; - dmaDefaultConf.DescriptorSkipLength = 0x0U; - dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; - - /* DMA default configuration */ - ETH_SetDMAConfig(heth, &dmaDefaultConf); -} - -/** - * @brief Configures the selected MAC address. - * @param heth pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param MacAddr The MAC address to configure - * This parameter can be one of the following values: - * @arg ETH_MAC_Address0: MAC Address0 - * @arg ETH_MAC_Address1: MAC Address1 - * @arg ETH_MAC_Address2: MAC Address2 - * @arg ETH_MAC_Address3: MAC Address3 - * @param Addr Pointer to MAC address buffer data (6 bytes) - * @retval HAL status - */ -static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr) -{ - uint32_t tmpreg1; - - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - - /* Calculate the selected MAC address high register */ - tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U]; - /* Load the selected MAC address high register */ - (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1; - /* Calculate the selected MAC address low register */ - tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U]; - - /* Load the selected MAC address low register */ - (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1; -} - -/** - * @brief Initializes the DMA Tx descriptors. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmatxdesc; - uint32_t i; - - /* Fill each DMATxDesc descriptor with the right values */ - for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++) - { - dmatxdesc = heth->Init.TxDesc + i; - - WRITE_REG(dmatxdesc->DESC0, 0x0U); - WRITE_REG(dmatxdesc->DESC1, 0x0U); - WRITE_REG(dmatxdesc->DESC2, 0x0U); - WRITE_REG(dmatxdesc->DESC3, 0x0U); - - WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc); - - /* Set Second Address Chained bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TCH); - - if (i < ((uint32_t)ETH_TX_DESC_CNT - 1U)) - { - WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc + i + 1U)); - } - else - { - WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc)); - } - - /* Set the DMA Tx descriptors checksum insertion */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL); - } - - heth->TxDescList.CurTxDesc = 0; - - /* Set Transmit Descriptor List Address */ - WRITE_REG(heth->Instance->DMATDLAR, (uint32_t) heth->Init.TxDesc); -} - -/** - * @brief Initializes the DMA Rx descriptors in chain mode. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t i; - - for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) - { - dmarxdesc = heth->Init.RxDesc + i; - - WRITE_REG(dmarxdesc->DESC0, 0x0U); - WRITE_REG(dmarxdesc->DESC1, 0x0U); - WRITE_REG(dmarxdesc->DESC2, 0x0U); - WRITE_REG(dmarxdesc->DESC3, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr0, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr1, 0x0U); - - /* Set Own bit of the Rx descriptor Status */ - dmarxdesc->DESC0 = ETH_DMARXDESC_OWN; - - /* Set Buffer1 size and Second Address Chained bit */ - dmarxdesc->DESC1 = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE; - - /* Enable Ethernet DMA Rx Descriptor interrupt */ - dmarxdesc->DESC1 &= ~ETH_DMARXDESC_DIC; - - /* Set Rx descritors addresses */ - WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc); - - if (i < ((uint32_t)ETH_RX_DESC_CNT - 1U)) - { - WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc + i + 1U)); - } - else - { - WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc)); - } - } - - WRITE_REG(heth->RxDescList.RxDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxDescCnt, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U); - WRITE_REG(heth->RxDescList.ItMode, 0U); - - /* Set Receive Descriptor List Address */ - WRITE_REG(heth->Instance->DMARDLAR, (uint32_t) heth->Init.RxDesc); -} - -/** - * @brief Prepare Tx DMA descriptor before transmission. - * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Tx packet configuration - * @param ItMode: Enable or disable Tx EOT interrept - * @retval Status - */ -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - uint32_t firstdescidx = dmatxdesclist->CurTxDesc; - uint32_t idx; - uint32_t descnbr = 0; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer; - uint32_t bd_count = 0; - uint32_t primask_bit; - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - return HAL_ETH_ERROR_BUSY; - } - - - descnbr += 1U; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer); - - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len); - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U) - { - MODIFY_REG(dmatxdesc->DESC0, ETH_DMATXDESC_CIC, pTxConfig->ChecksumCtrl); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != 0U) - { - MODIFY_REG(dmatxdesc->DESC0, ETH_CRC_PAD_DISABLE, pTxConfig->CRCPadCtrl); - } - - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U) - { - /* Set Vlan Type */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_VF); - } - - /* Mark it as First Descriptor */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS); - - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* set OWN bit of FIRST descriptor */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN); - - /* only if the packet is split into more than one descriptors > 1 */ - while (txbuffer->next != NULL) - { - /* Clear the LD bit of previous descriptor */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS); - if (ItMode != ((uint32_t)RESET)) - { - /* Set Interrupt on completion bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - else - { - /* Clear Interrupt on completion bit */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* Clear the FD bit of new Descriptor */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS); - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - descidx = firstdescidx; - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* clear previous desc own bit */ - for (idx = 0; idx < descnbr; idx ++) - { - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN); - - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - } - - return HAL_ETH_ERROR_BUSY; - } - - descnbr += 1U; - - /* Get the next Tx buffer in the list */ - txbuffer = txbuffer->next; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer); - - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len); - - bd_count += 1U; - - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Set Own bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN); - } - - if (ItMode != ((uint32_t)RESET)) - { - /* Set Interrupt on completion bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - else - { - /* Clear Interrupt on completion bit */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - - /* Mark it as LAST descriptor */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS); - /* Save the current packet address to expose it to the application */ - dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress; - - dmatxdesclist->CurTxDesc = descidx; - - /* Enter critical section */ - primask_bit = __get_PRIMASK(); - __set_PRIMASK(1); - - dmatxdesclist->BuffersInUse += bd_count + 1U; - - /* Exit critical section: restore previous priority mask */ - __set_PRIMASK(primask_bit); - - /* Return function status */ - return HAL_ETH_ERROR_NONE; -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth) -{ - /* Init the ETH Callback settings */ - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ - heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ - heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ -#ifdef HAL_ETH_USE_PTP - heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ -#endif /* HAL_ETH_USE_PTP */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ + * @{ + */ + +/** + * @brief Clears the ETHERNET transmit FIFO. + * @param heth pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_FlushTransmitFIFO( ETH_HandleTypeDef * heth ) + { + __IO uint32_t tmpreg = 0; + + /* Set the Flush Transmit FIFO bit */ + ( heth->Instance )->DMAOMR |= ETH_DMAOMR_FTF; + + /* Wait until the write operation will be taken into account: + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg = ( heth->Instance )->DMAOMR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->DMAOMR = tmpreg; + } + + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + uint32_t tmpreg1; + + /*------------------------ ETHERNET MACCR Configuration --------------------*/ + /* Get the ETHERNET MACCR value */ + tmpreg1 = ( heth->Instance )->MACCR; + /* Clear WD, PCE, PS, TE and RE bits */ + tmpreg1 &= ETH_MACCR_CLEAR_MASK; + + tmpreg1 |= ( uint32_t ) ( ( ( uint32_t ) ( ( macconf->Watchdog == DISABLE ) ? 1U : 0U ) << 23U ) | + ( ( uint32_t ) ( ( macconf->Jabber == DISABLE ) ? 1U : 0U ) << 22U ) | + ( uint32_t ) macconf->InterPacketGapVal | + ( ( uint32_t ) macconf->CarrierSenseDuringTransmit << 16U ) | + macconf->Speed | + ( ( uint32_t ) ( ( macconf->ReceiveOwn == DISABLE ) ? 1U : 0U ) << 13U ) | + ( ( uint32_t ) macconf->LoopbackMode << 12U ) | + macconf->DuplexMode | + ( ( uint32_t ) macconf->ChecksumOffload << 10U ) | + ( ( uint32_t ) ( ( macconf->RetryTransmission == DISABLE ) ? 1U : 0U ) << 9U ) | + ( ( uint32_t ) macconf->AutomaticPadCRCStrip << 7U ) | + macconf->BackOffLimit | + ( ( uint32_t ) macconf->DeferralCheck << 4U ) ); + + /* Write to ETHERNET MACCR */ + ( heth->Instance )->MACCR = ( uint32_t ) tmpreg1; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /*----------------------- ETHERNET MACFCR Configuration --------------------*/ + + /* Get the ETHERNET MACFCR value */ + tmpreg1 = ( heth->Instance )->MACFCR; + /* Clear xx bits */ + tmpreg1 &= ETH_MACFCR_CLEAR_MASK; + + tmpreg1 |= ( uint32_t ) ( ( macconf->PauseTime << 16U ) | + ( ( uint32_t ) ( ( macconf->ZeroQuantaPause == DISABLE ) ? 1U : 0U ) << 7U ) | + macconf->PauseLowThreshold | + ( ( uint32_t ) ( ( macconf->UnicastPausePacketDetect == ENABLE ) ? 1U : 0U ) << 3U ) | + ( ( uint32_t ) ( ( macconf->ReceiveFlowControl == ENABLE ) ? 1U : 0U ) << 2U ) | + ( ( uint32_t ) ( ( macconf->TransmitFlowControl == ENABLE ) ? 1U : 0U ) << 1U ) ); + + /* Write to ETHERNET MACFCR */ + ( heth->Instance )->MACFCR = ( uint32_t ) tmpreg1; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACFCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACFCR = tmpreg1; + } + + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + uint32_t tmpreg1; + + /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ + /* Get the ETHERNET DMAOMR value */ + tmpreg1 = ( heth->Instance )->DMAOMR; + /* Clear xx bits */ + tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; + + tmpreg1 |= ( uint32_t ) ( ( ( uint32_t ) ( ( dmaconf->DropTCPIPChecksumErrorFrame == DISABLE ) ? 1U : 0U ) << 26U ) | + ( ( uint32_t ) dmaconf->ReceiveStoreForward << 25U ) | + ( ( uint32_t ) ( ( dmaconf->FlushRxPacket == DISABLE ) ? 1U : 0U ) << 20U ) | + ( ( uint32_t ) dmaconf->TransmitStoreForward << 21U ) | + dmaconf->TransmitThresholdControl | + ( ( uint32_t ) dmaconf->ForwardErrorFrames << 7U ) | + ( ( uint32_t ) dmaconf->ForwardUndersizedGoodFrames << 6U ) | + dmaconf->ReceiveThresholdControl | + ( ( uint32_t ) dmaconf->SecondFrameOperate << 2U ) ); + + /* Write to ETHERNET DMAOMR */ + ( heth->Instance )->DMAOMR = ( uint32_t ) tmpreg1; + + /* Wait until the write operation will be taken into account: + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->DMAOMR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->DMAOMR = tmpreg1; + + /*----------------------- ETHERNET DMABMR Configuration --------------------*/ + ( heth->Instance )->DMABMR = ( uint32_t ) ( ( ( uint32_t ) dmaconf->AddressAlignedBeats << 25U ) | + dmaconf->BurstMode | + dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or + * Rx it is applied for the other */ + dmaconf->TxDMABurstLength | + ( ( uint32_t ) dmaconf->EnhancedDescriptorFormat << 7U ) | + ( dmaconf->DescriptorSkipLength << 2U ) | + dmaconf->DMAArbitration | + ETH_DMABMR_USP ); /* Enable use of separate PBL for Rx and Tx */ + + /* Wait until the write operation will be taken into account: + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->DMABMR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->DMABMR = tmpreg1; + } + +/** + * @brief Configures Ethernet MAC and DMA with default parameters. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ) + { + ETH_MACConfigTypeDef macDefaultConf; + ETH_DMAConfigTypeDef dmaDefaultConf; + + /*--------------- ETHERNET MAC registers default Configuration --------------*/ + macDefaultConf.Watchdog = ENABLE; + macDefaultConf.Jabber = ENABLE; + macDefaultConf.InterPacketGapVal = ETH_INTERFRAMEGAP_96BIT; + macDefaultConf.CarrierSenseDuringTransmit = DISABLE; + macDefaultConf.ReceiveOwn = ENABLE; + macDefaultConf.LoopbackMode = DISABLE; + macDefaultConf.ChecksumOffload = ENABLE; + macDefaultConf.RetryTransmission = DISABLE; + macDefaultConf.AutomaticPadCRCStrip = DISABLE; + macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; + macDefaultConf.DeferralCheck = DISABLE; + macDefaultConf.PauseTime = 0x0U; + macDefaultConf.ZeroQuantaPause = DISABLE; + macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4; + macDefaultConf.ReceiveFlowControl = DISABLE; + macDefaultConf.TransmitFlowControl = DISABLE; + macDefaultConf.Speed = ETH_SPEED_100M; + macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; + macDefaultConf.UnicastPausePacketDetect = DISABLE; + + /* MAC default configuration */ + ETH_SetMACConfig( heth, &macDefaultConf ); + + /*--------------- ETHERNET DMA registers default Configuration --------------*/ + dmaDefaultConf.DropTCPIPChecksumErrorFrame = ENABLE; + dmaDefaultConf.ReceiveStoreForward = ENABLE; + dmaDefaultConf.FlushRxPacket = ENABLE; + dmaDefaultConf.TransmitStoreForward = ENABLE; + dmaDefaultConf.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; + dmaDefaultConf.ForwardErrorFrames = DISABLE; + dmaDefaultConf.ForwardUndersizedGoodFrames = DISABLE; + dmaDefaultConf.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; + dmaDefaultConf.SecondFrameOperate = ENABLE; + dmaDefaultConf.AddressAlignedBeats = ENABLE; + dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; + dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.EnhancedDescriptorFormat = ENABLE; + dmaDefaultConf.DescriptorSkipLength = 0x0U; + dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; + + /* DMA default configuration */ + ETH_SetDMAConfig( heth, &dmaDefaultConf ); + } + +/** + * @brief Configures the selected MAC address. + * @param heth pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param MacAddr The MAC address to configure + * This parameter can be one of the following values: + * @arg ETH_MAC_Address0: MAC Address0 + * @arg ETH_MAC_Address1: MAC Address1 + * @arg ETH_MAC_Address2: MAC Address2 + * @arg ETH_MAC_Address3: MAC Address3 + * @param Addr Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ + static void ETH_MACAddressConfig( ETH_HandleTypeDef * heth, + uint32_t MacAddr, + uint8_t * Addr ) + { + uint32_t tmpreg1; + + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* Calculate the selected MAC address high register */ + tmpreg1 = ( ( uint32_t ) Addr[ 5U ] << 8U ) | ( uint32_t ) Addr[ 4U ]; + /* Load the selected MAC address high register */ + ( *( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + MacAddr ) ) ) = tmpreg1; + /* Calculate the selected MAC address low register */ + tmpreg1 = ( ( uint32_t ) Addr[ 3U ] << 24U ) | ( ( uint32_t ) Addr[ 2U ] << 16U ) | ( ( uint32_t ) Addr[ 1U ] << 8U ) | Addr[ 0U ]; + + /* Load the selected MAC address low register */ + ( *( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + MacAddr ) ) ) = tmpreg1; + } + +/** + * @brief Initializes the DMA Tx descriptors. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmatxdesc; + uint32_t i; + + /* Fill each DMATxDesc descriptor with the right values */ + for( i = 0; i < ( uint32_t ) ETH_TX_DESC_CNT; i++ ) + { + dmatxdesc = heth->Init.TxDesc + i; + + WRITE_REG( dmatxdesc->DESC0, 0x0U ); + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + WRITE_REG( dmatxdesc->DESC2, 0x0U ); + WRITE_REG( dmatxdesc->DESC3, 0x0U ); + + WRITE_REG( heth->TxDescList.TxDesc[ i ], ( uint32_t ) dmatxdesc ); + + /* Set Second Address Chained bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_TCH ); + + if( i < ( ( uint32_t ) ETH_TX_DESC_CNT - 1U ) ) + { + WRITE_REG( dmatxdesc->DESC3, ( uint32_t ) ( heth->Init.TxDesc + i + 1U ) ); + } + else + { + WRITE_REG( dmatxdesc->DESC3, ( uint32_t ) ( heth->Init.TxDesc ) ); + } + + /* Set the DMA Tx descriptors checksum insertion */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL ); + } + + heth->TxDescList.CurTxDesc = 0; + + /* Set Transmit Descriptor List Address */ + WRITE_REG( heth->Instance->DMATDLAR, ( uint32_t ) heth->Init.TxDesc ); + } + +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmarxdesc; + uint32_t i; + + for( i = 0; i < ( uint32_t ) ETH_RX_DESC_CNT; i++ ) + { + dmarxdesc = heth->Init.RxDesc + i; + + WRITE_REG( dmarxdesc->DESC0, 0x0U ); + WRITE_REG( dmarxdesc->DESC1, 0x0U ); + WRITE_REG( dmarxdesc->DESC2, 0x0U ); + WRITE_REG( dmarxdesc->DESC3, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr0, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr1, 0x0U ); + + /* Set Own bit of the Rx descriptor Status */ + dmarxdesc->DESC0 = ETH_DMARXDESC_OWN; + + /* Set Buffer1 size and Second Address Chained bit */ + dmarxdesc->DESC1 = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE; + + /* Enable Ethernet DMA Rx Descriptor interrupt */ + dmarxdesc->DESC1 &= ~ETH_DMARXDESC_DIC; + + /* Set Rx descritors addresses */ + WRITE_REG( heth->RxDescList.RxDesc[ i ], ( uint32_t ) dmarxdesc ); + + if( i < ( ( uint32_t ) ETH_RX_DESC_CNT - 1U ) ) + { + WRITE_REG( dmarxdesc->DESC3, ( uint32_t ) ( heth->Init.RxDesc + i + 1U ) ); + } + else + { + WRITE_REG( dmarxdesc->DESC3, ( uint32_t ) ( heth->Init.RxDesc ) ); + } + } + + WRITE_REG( heth->RxDescList.RxDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxDescCnt, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescCnt, 0U ); + WRITE_REG( heth->RxDescList.ItMode, 0U ); + + /* Set Receive Descriptor List Address */ + WRITE_REG( heth->Instance->DMARDLAR, ( uint32_t ) heth->Init.RxDesc ); + } + +/** + * @brief Prepare Tx DMA descriptor before transmission. + * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Tx packet configuration + * @param ItMode: Enable or disable Tx EOT interrept + * @retval Status + */ + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + ETH_TxPacketConfig * pTxConfig, + uint32_t ItMode ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + uint32_t firstdescidx = dmatxdesclist->CurTxDesc; + uint32_t idx; + uint32_t descnbr = 0; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + ETH_BufferTypeDef * txbuffer = pTxConfig->TxBuffer; + uint32_t bd_count = 0; + uint32_t primask_bit; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ) == ETH_DMATXDESC_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + return HAL_ETH_ERROR_BUSY; + } + + descnbr += 1U; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC2, ( uint32_t ) txbuffer->buffer ); + + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len ); + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM ) != 0U ) + { + MODIFY_REG( dmatxdesc->DESC0, ETH_DMATXDESC_CIC, pTxConfig->ChecksumCtrl ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD ) != 0U ) + { + MODIFY_REG( dmatxdesc->DESC0, ETH_CRC_PAD_DISABLE, pTxConfig->CRCPadCtrl ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != 0U ) + { + /* Set Vlan Type */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_VF ); + } + + /* Mark it as First Descriptor */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_FS ); + + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* set OWN bit of FIRST descriptor */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ); + + /* only if the packet is split into more than one descriptors > 1 */ + while( txbuffer->next != NULL ) + { + /* Clear the LD bit of previous descriptor */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_LS ); + + if( ItMode != ( ( uint32_t ) RESET ) ) + { + /* Set Interrupt on completion bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + else + { + /* Clear Interrupt on completion bit */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* Clear the FD bit of new Descriptor */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_FS ); + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ) == ETH_DMATXDESC_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + descidx = firstdescidx; + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* clear previous desc own bit */ + for( idx = 0; idx < descnbr; idx++ ) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ); + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + } + + return HAL_ETH_ERROR_BUSY; + } + + descnbr += 1U; + + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC2, ( uint32_t ) txbuffer->buffer ); + + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len ); + + bd_count += 1U; + + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set Own bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ); + } + + if( ItMode != ( ( uint32_t ) RESET ) ) + { + /* Set Interrupt on completion bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + else + { + /* Clear Interrupt on completion bit */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + + /* Mark it as LAST descriptor */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_LS ); + /* Save the current packet address to expose it to the application */ + dmatxdesclist->PacketAddress[ descidx ] = dmatxdesclist->CurrentPacketAddress; + + dmatxdesclist->CurTxDesc = descidx; + + /* Enter critical section */ + primask_bit = __get_PRIMASK(); + __set_PRIMASK( 1 ); + + dmatxdesclist->BuffersInUse += bd_count + 1U; + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK( primask_bit ); + + /* Return function status */ + return HAL_ETH_ERROR_NONE; + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ) + { + /* Init the ETH Callback settings */ + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ + heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ + heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ + #ifdef HAL_ETH_USE_PTP + heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ + #endif /* HAL_ETH_USE_PTP */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ #endif /* HAL_ETH_MODULE_ENABLED */ /** - * @} - */ + * @} + */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.h b/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.h index 5410171dc1..92692ed52e 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.h +++ b/source/portable/NetworkInterface/STM32/Drivers/F4/stm32f4xx_hal_eth.h @@ -1,2019 +1,2160 @@ /** - ****************************************************************************** - * @file stm32f4xx_hal_eth.h - * @author MCD Application Team - * @brief Header file of ETH HAL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2016 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32f4xx_hal_eth.h + * @author MCD Application Team + * @brief Header file of ETH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32F4xx_HAL_ETH_H -#define STM32F4xx_HAL_ETH_H + #define STM32F4xx_HAL_ETH_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hal_def.h" + #include "stm32f4xx_hal_def.h" -#if defined(ETH) + #if defined( ETH ) /** @addtogroup STM32F4xx_HAL_Driver - * @{ - */ + * @{ + */ /** @addtogroup ETH - * @{ - */ + * @{ + */ /* Exported types ------------------------------------------------------------*/ -#ifndef ETH_TX_DESC_CNT -#define ETH_TX_DESC_CNT 4U -#endif /* ETH_TX_DESC_CNT */ + #ifndef ETH_TX_DESC_CNT + #define ETH_TX_DESC_CNT 4U + #endif /* ETH_TX_DESC_CNT */ -#ifndef ETH_RX_DESC_CNT -#define ETH_RX_DESC_CNT 4U -#endif /* ETH_RX_DESC_CNT */ + #ifndef ETH_RX_DESC_CNT + #define ETH_RX_DESC_CNT 4U + #endif /* ETH_RX_DESC_CNT */ /*********************** Descriptors struct def section ************************/ + /** @defgroup ETH_Exported_Types ETH Exported Types - * @{ - */ + * @{ + */ /** - * @brief ETH DMA Descriptor structure definition - */ -typedef struct -{ - __IO uint32_t DESC0; - __IO uint32_t DESC1; - __IO uint32_t DESC2; - __IO uint32_t DESC3; - __IO uint32_t DESC4; - __IO uint32_t DESC5; - __IO uint32_t DESC6; - __IO uint32_t DESC7; - uint32_t BackupAddr0; /* used to store rx buffer 1 address */ - uint32_t BackupAddr1; /* used to store rx buffer 2 address */ -} ETH_DMADescTypeDef; + * @brief ETH DMA Descriptor structure definition + */ + typedef struct + { + __IO uint32_t DESC0; + __IO uint32_t DESC1; + __IO uint32_t DESC2; + __IO uint32_t DESC3; + __IO uint32_t DESC4; + __IO uint32_t DESC5; + __IO uint32_t DESC6; + __IO uint32_t DESC7; + uint32_t BackupAddr0; /* used to store rx buffer 1 address */ + uint32_t BackupAddr1; /* used to store rx buffer 2 address */ + } ETH_DMADescTypeDef; + /** - * - */ + * + */ /** - * @brief ETH Buffers List structure definition - */ -typedef struct __ETH_BufferTypeDef -{ - uint8_t *buffer; /*gState = HAL_ETH_STATE_RESET; \ - (__HANDLE__)->MspInitCallback = NULL; \ - (__HANDLE__)->MspDeInitCallback = NULL; \ - } while(0) -#else -#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) do{ \ - (__HANDLE__)->gState = HAL_ETH_STATE_RESET; \ - } while(0) -#endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @brief Enables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * enabled @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER \ - |= (__INTERRUPT__)) - -/** - * @brief Disables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * disabled. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER \ - &= ~(__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT source enabled or disabled. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The ETH DMA IT Source enabled or disabled - */ -#define __HAL_ETH_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->DMAIER &\ - (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The state of ETH DMA IT (SET or RESET) - */ -#define __HAL_ETH_DMA_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->DMASR &\ - (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Clears the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMASR = (__INTERRUPT__)) - -/** - * @brief Checks whether the specified ETHERNET DMA flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMASR &\ - ( __FLAG__)) == ( __FLAG__)) - -/** - * @brief Clears the specified ETHERNET DMA flag. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMASR = ( __FLAG__)) - - - -/** - * @brief Checks whether the specified ETHERNET MAC flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts - * @retval The state of ETH MAC IT (SET or RESET). - */ -#define __HAL_ETH_MAC_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->MACSR &\ - ( __INTERRUPT__)) == ( __INTERRUPT__)) + * @param __HANDLE__: specifies the ETH handle. + * @retval None + */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + ( __HANDLE__ )->MspInitCallback = NULL; \ + ( __HANDLE__ )->MspDeInitCallback = NULL; \ + } while( 0 ) + #else + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + } while( 0 ) + #endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @brief Enables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * enabled @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_ENABLE_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( __HANDLE__ )->Instance->DMAIER \ + |= ( __INTERRUPT__ ) ) + +/** + * @brief Disables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * disabled. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_DISABLE_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( __HANDLE__ )->Instance->DMAIER \ + &= ~( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT source enabled or disabled. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The ETH DMA IT Source enabled or disabled + */ + #define __HAL_ETH_DMA_GET_IT_SOURCE( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMAIER & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The state of ETH DMA IT (SET or RESET) + */ + #define __HAL_ETH_DMA_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMASR & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Clears the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_CLEAR_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMASR = ( __INTERRUPT__ ) ) + +/** + * @brief Checks whether the specified ETHERNET DMA flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_GET_FLAG( __HANDLE__, __FLAG__ ) \ + ( ( ( __HANDLE__ )->Instance->DMASR & \ + ( __FLAG__ ) ) == ( __FLAG__ ) ) + +/** + * @brief Clears the specified ETHERNET DMA flag. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_CLEAR_FLAG( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->DMASR = ( __FLAG__ ) ) + + + +/** + * @brief Checks whether the specified ETHERNET MAC flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts + * @retval The state of ETH MAC IT (SET or RESET). + */ + #define __HAL_ETH_MAC_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->MACSR & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) /*!< External interrupt line 19 Connected to the ETH wakeup EXTI Line */ -#define ETH_WAKEUP_EXTI_LINE 0x00080000U + #define ETH_WAKEUP_EXTI_LINE 0x00080000U /** - * @brief Enable the ETH WAKEUP Exti Line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT(__EXTI_LINE__) (EXTI->IMR |= (__EXTI_LINE__)) + * @brief Enable the ETH WAKEUP Exti Line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT( __EXTI_LINE__ ) ( EXTI->IMR |= ( __EXTI_LINE__ ) ) /** - * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval EXTI ETH WAKEUP Line Status. - */ -#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval EXTI ETH WAKEUP Line Status. + */ + #define __HAL_ETH_WAKEUP_EXTI_GET_FLAG( __EXTI_LINE__ ) ( EXTI->PR & ( __EXTI_LINE__ ) ) /** - * @brief Clear the ETH WAKEUP Exti flag. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + * @brief Clear the ETH WAKEUP Exti flag. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( __EXTI_LINE__ ) ( EXTI->PR = ( __EXTI_LINE__ ) ) /** - * @brief enable rising edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE(__EXTI_LINE__) (EXTI->FTSR &= ~(__EXTI_LINE__)); \ - (EXTI->RTSR |= (__EXTI_LINE__)) + * @brief enable rising edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->FTSR &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->RTSR |= ( __EXTI_LINE__ ) ) /** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR &= ~(__EXTI_LINE__));\ - (EXTI->FTSR |= (__EXTI_LINE__)) + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR |= ( __EXTI_LINE__ ) ) /** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR |= (__EXTI_LINE__));\ - (EXTI->FTSR |= (__EXTI_LINE__)) + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR |= ( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR |= ( __EXTI_LINE__ ) ) /** - * @brief Generates a Software interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT( __EXTI_LINE__ ) ( EXTI->SWIER |= ( __EXTI_LINE__ ) ) -#define __HAL_ETH_GET_PTP_CONTROL(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->PTPTSCR) & \ - (__FLAG__)) == (__FLAG__)) ? SET : RESET) + #define __HAL_ETH_GET_PTP_CONTROL( __HANDLE__, __FLAG__ ) \ + ( ( ( ( ( __HANDLE__ )->Instance->PTPTSCR ) & \ + ( __FLAG__ ) ) == ( __FLAG__ ) ) ? SET : RESET ) -#define __HAL_ETH_SET_PTP_CONTROL(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->PTPTSCR |= (__FLAG__)) + #define __HAL_ETH_SET_PTP_CONTROL( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->PTPTSCR |= ( __FLAG__ ) ) /** - * @} - */ + * @} + */ /* Exported functions --------------------------------------------------------*/ /** @addtogroup ETH_Exported_Functions - * @{ - */ + * @{ + */ /** @addtogroup ETH_Exported_Functions_Group1 - * @{ - */ + * @{ + */ /* Initialization and de initialization functions **********************************/ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ); /* Callbacks Register/UnRegister functions ***********************************/ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group2 - * @{ - */ + * @{ + */ /* IO operation functions *******************************************************/ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth); - -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff); -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef *heth, uint32_t *pErrorCode); -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth); - -#ifdef HAL_ETH_USE_PTP -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset); -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth); -#endif /* HAL_ETH_USE_PTP */ - -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout); -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig); - -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue); -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue); - -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth); -void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxAllocateCallback(uint8_t **buff); -void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length); -void HAL_ETH_TxFreeCallback(uint32_t *buff); -void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp); -/** - * @} - */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ); + + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ); + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ); + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ); + + #ifdef HAL_ETH_USE_PTP + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ); + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ); + #endif /* HAL_ETH_USE_PTP */ + + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfig * pTxConfig, + uint32_t Timeout ); + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfig * pTxConfig ); + + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ); + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ); + + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ); + void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxAllocateCallback( uint8_t ** buff ); + void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ); + void HAL_ETH_TxFreeCallback( uint32_t * buff ); + void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ); + +/** + * @} + */ /** @addtogroup ETH_Exported_Functions_Group3 - * @{ - */ + * @{ + */ /* Peripheral Control functions **********************************************/ /* MAC & DMA Configuration APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_GetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ); /* MAC VLAN Processing APIs ************************************************/ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, - uint32_t VLANIdentifier); + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ); /* MAC L2 Packet Filtering APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable); -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr); + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ); + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ); /* MAC Power Down APIs *****************************************************/ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, - const ETH_PowerDownConfigTypeDef *pPowerDownConfig); -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count); + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ); + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ); /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group4 - * @{ - */ + * @{ + */ /* Peripheral State functions **************************************************/ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth); + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ); + /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* STM32F4xx_HAL_ETH_H */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.c b/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.c index 77d6f84e62..e976a83fca 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.c +++ b/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.c @@ -1,3238 +1,3318 @@ /** - ****************************************************************************** - * @file stm32f7xx_hal_eth.c - * @author MCD Application Team - * @brief ETH HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Ethernet (ETH) peripheral: - * + Initialization and deinitialization functions - * + IO operation functions - * + Peripheral Control functions - * + Peripheral State and Errors functions - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - The ETH HAL driver can be used as follows: - - (#)Declare a ETH_HandleTypeDef handle structure, for example: - ETH_HandleTypeDef heth; - - (#)Fill parameters of Init structure in heth handle - - (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) - - (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: - (##) Enable the Ethernet interface clock using - (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() - (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() - (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() - - (##) Initialize the related GPIO clocks - (##) Configure Ethernet pinout - (##) Configure Ethernet NVIC interrupt (in Interrupt mode) - - (#) Ethernet data reception is asynchronous, so call the following API - to start the listening mode: - (##) HAL_ETH_Start(): - This API starts the MAC and DMA transmission and reception process, - without enabling end of transfer interrupts, in this mode user - has to poll for data reception by calling HAL_ETH_ReadData() - (##) HAL_ETH_Start_IT(): - This API starts the MAC and DMA transmission and reception process, - end of transfer interrupts are enabled in this mode, - HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received - - (#) When data is received user can call the following API to get received data: - (##) HAL_ETH_ReadData(): Read a received packet - - (#) For transmission path, two APIs are available: - (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode - (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, - HAL_ETH_TxCpltCallback() will be executed when end of transfer occur - - (#) Communication with an external PHY device: - (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY - (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register - - (#) Configure the Ethernet MAC after ETH peripheral initialization - (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef - (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef - - (#) Configure the Ethernet DMA after ETH peripheral initialization - (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef - (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef - - (#) Configure the Ethernet PTP after ETH peripheral initialization - (##) Define HAL_ETH_USE_PTP to use PTP APIs. - (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers - (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission - (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp - (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp - - -@- The ARP offload feature is not supported in this driver. - - -@- The PTP offload feature is not supported in this driver. - - *** Callback registration *** - ============================================= - - The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 - allows the user to configure dynamically the driver callbacks. - Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. - - Function HAL_ETH_RegisterCallback() allows to register following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - This function takes as parameters the HAL peripheral handle, the Callback ID - and a pointer to the user callback function. - - For specific callbacks RxAllocateCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxPtpCallback(). - - Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default - weak function. - HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, - and the Callback ID. - This function allows to reset following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - For specific callbacks RxAllocateCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxPtpCallback(). - - By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET - all callbacks are set to the corresponding weak functions: - examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). - Exception done for MspInit and MspDeInit functions that are - reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when - these callbacks are null (not registered beforehand). - if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit - keep and use the user MspInit/MspDeInit callbacks (registered beforehand) - - Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. - Exception done MspInit/MspDeInit that can be registered/unregistered - in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, - thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. - In that case first register the MspInit/MspDeInit user callbacks - using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit - or HAL_ETH_Init function. - - When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or - not defined, the callback registration feature is not available and all callbacks - are set to the corresponding weak functions. - - @endverbatim - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32f7xx_hal_eth.c + * @author MCD Application Team + * @brief ETH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Ethernet (ETH) peripheral: + * + Initialization and deinitialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @verbatim + * ============================================================================== + ##### How to use this driver ##### + #####============================================================================== + #####[..] + #####The ETH HAL driver can be used as follows: + ##### + #####(#)Declare a ETH_HandleTypeDef handle structure, for example: + ##### ETH_HandleTypeDef heth; + ##### + #####(#)Fill parameters of Init structure in heth handle + ##### + #####(#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) + ##### + #####(#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: + ##### (##) Enable the Ethernet interface clock using + ##### (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() + ##### + ##### (##) Initialize the related GPIO clocks + ##### (##) Configure Ethernet pinout + ##### (##) Configure Ethernet NVIC interrupt (in Interrupt mode) + ##### + #####(#) Ethernet data reception is asynchronous, so call the following API + ##### to start the listening mode: + ##### (##) HAL_ETH_Start(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### without enabling end of transfer interrupts, in this mode user + ##### has to poll for data reception by calling HAL_ETH_ReadData() + ##### (##) HAL_ETH_Start_IT(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### end of transfer interrupts are enabled in this mode, + ##### HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received + ##### + #####(#) When data is received user can call the following API to get received data: + ##### (##) HAL_ETH_ReadData(): Read a received packet + ##### + #####(#) For transmission path, two APIs are available: + ##### (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode + ##### (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, + ##### HAL_ETH_TxCpltCallback() will be executed when end of transfer occur + ##### + #####(#) Communication with an external PHY device: + ##### (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY + ##### (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register + ##### + #####(#) Configure the Ethernet MAC after ETH peripheral initialization + ##### (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef + ##### (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef + ##### + #####(#) Configure the Ethernet DMA after ETH peripheral initialization + ##### (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef + ##### (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef + ##### + #####(#) Configure the Ethernet PTP after ETH peripheral initialization + ##### (##) Define HAL_ETH_USE_PTP to use PTP APIs. + ##### (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission + ##### (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp + ##### (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp + ##### + #####-@- The ARP offload feature is not supported in this driver. + ##### + #####-@- The PTP offload feature is not supported in this driver. + ##### + *** Callback registration *** + ***============================================= + *** + ***The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 + ***allows the user to configure dynamically the driver callbacks. + ***Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. + *** + ***Function HAL_ETH_RegisterCallback() allows to register following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***This function takes as parameters the HAL peripheral handle, the Callback ID + ***and a pointer to the user callback function. + *** + ***For specific callbacks RxAllocateCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxPtpCallback(). + *** + ***Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default + ***weak function. + ***HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, + ***and the Callback ID. + ***This function allows to reset following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***For specific callbacks RxAllocateCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxPtpCallback(). + *** + ***By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET + ***all callbacks are set to the corresponding weak functions: + ***examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). + ***Exception done for MspInit and MspDeInit functions that are + ***reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when + ***these callbacks are null (not registered beforehand). + ***if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit + ***keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + *** + ***Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. + ***Exception done MspInit/MspDeInit that can be registered/unregistered + ***in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, + ***thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + ***In that case first register the MspInit/MspDeInit user callbacks + ***using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit + ***or HAL_ETH_Init function. + *** + ***When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or + ***not defined, the callback registration feature is not available and all callbacks + ***are set to the corresponding weak functions. + *** + ***@endverbatim + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32f7xx_hal.h" /** @addtogroup STM32F7xx_HAL_Driver - * @{ - */ + * @{ + */ #ifdef HAL_ETH_MODULE_ENABLED -#if defined(ETH) + #if defined( ETH ) /** @defgroup ETH ETH - * @brief ETH HAL module driver - * @{ - */ + * @brief ETH HAL module driver + * @{ + */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ + /** @addtogroup ETH_Private_Constants ETH Private Constants - * @{ - */ -#define ETH_MACCR_MASK 0xFFFB7F7CU -#define ETH_MACECR_MASK 0x3F077FFFU -#define ETH_MACFFR_MASK 0x800007FFU -#define ETH_MACWTR_MASK 0x0000010FU -#define ETH_MACTFCR_MASK 0xFFFF00F2U -#define ETH_MACRFCR_MASK 0x00000003U -#define ETH_MTLTQOMR_MASK 0x00000072U -#define ETH_MTLRQOMR_MASK 0x0000007BU - -#define ETH_DMAMR_MASK 0x00007802U -#define ETH_DMASBMR_MASK 0x0000D001U -#define ETH_DMACCR_MASK 0x00013FFFU -#define ETH_DMACTCR_MASK 0x003F1010U -#define ETH_DMACRCR_MASK 0x803F0000U -#define ETH_MACPMTCSR_MASK (ETH_MACPMTCSR_PD | ETH_MACPMTCSR_WFE | \ - ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU) + * @{ + */ + #define ETH_MACCR_MASK 0xFFFB7F7CU + #define ETH_MACECR_MASK 0x3F077FFFU + #define ETH_MACFFR_MASK 0x800007FFU + #define ETH_MACWTR_MASK 0x0000010FU + #define ETH_MACTFCR_MASK 0xFFFF00F2U + #define ETH_MACRFCR_MASK 0x00000003U + #define ETH_MTLTQOMR_MASK 0x00000072U + #define ETH_MTLRQOMR_MASK 0x0000007BU + + #define ETH_DMAMR_MASK 0x00007802U + #define ETH_DMASBMR_MASK 0x0000D001U + #define ETH_DMACCR_MASK 0x00013FFFU + #define ETH_DMACTCR_MASK 0x003F1010U + #define ETH_DMACRCR_MASK 0x803F0000U + #define ETH_MACPMTCSR_MASK \ + ( ETH_MACPMTCSR_PD | ETH_MACPMTCSR_WFE | \ + ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU ) /* Timeout values */ -#define ETH_SWRESET_TIMEOUT 500U -#define ETH_MDIO_BUS_TIMEOUT 1000U + #define ETH_SWRESET_TIMEOUT 500U + #define ETH_MDIO_BUS_TIMEOUT 1000U -#define ETH_DMARXDESC_ERRORS_MASK ((uint32_t)(ETH_DMARXDESC_DBE | ETH_DMARXDESC_RE | \ - ETH_DMARXDESC_OE | ETH_DMARXDESC_RWT |\ - ETH_DMARXDESC_LC | ETH_DMARXDESC_CE |\ - ETH_DMARXDESC_DE | ETH_DMARXDESC_IPV4HCE)) + #define ETH_DMARXDESC_ERRORS_MASK \ + ( ( uint32_t ) ( ETH_DMARXDESC_DBE | ETH_DMARXDESC_RE | \ + ETH_DMARXDESC_OE | ETH_DMARXDESC_RWT | \ + ETH_DMARXDESC_LC | ETH_DMARXDESC_CE | \ + ETH_DMARXDESC_DE | ETH_DMARXDESC_IPV4HCE ) ) -#define ETH_MAC_US_TICK 1000000U + #define ETH_MAC_US_TICK 1000000U -#define ETH_MACTSCR_MASK 0x0087FF2FU + #define ETH_MACTSCR_MASK 0x0087FF2FU -#define ETH_PTPTSHR_VALUE 0xFFFFFFFFU -#define ETH_PTPTSLR_VALUE 0xBB9ACA00U + #define ETH_PTPTSHR_VALUE 0xFFFFFFFFU + #define ETH_PTPTSLR_VALUE 0xBB9ACA00U /* Ethernet MACMIIAR register Mask */ -#define ETH_MACMIIAR_CR_MASK 0xFFFFFFE3U + #define ETH_MACMIIAR_CR_MASK 0xFFFFFFE3U /* Delay to wait when writing to some Ethernet registers */ -#define ETH_REG_WRITE_DELAY 0x00000001U + #define ETH_REG_WRITE_DELAY 0x00000001U /* ETHERNET MACCR register Mask */ -#define ETH_MACCR_CLEAR_MASK 0xFD20810FU + #define ETH_MACCR_CLEAR_MASK 0xFD20810FU /* ETHERNET MACFCR register Mask */ -#define ETH_MACFCR_CLEAR_MASK 0x0000FF41U + #define ETH_MACFCR_CLEAR_MASK 0x0000FF41U /* ETHERNET DMAOMR register Mask */ -#define ETH_DMAOMR_CLEAR_MASK 0xF8DE3F23U + #define ETH_DMAOMR_CLEAR_MASK 0xF8DE3F23U /* ETHERNET MAC address offsets */ -#define ETH_MAC_ADDR_HBASE (uint32_t)(ETH_MAC_BASE + 0x40U) /* ETHERNET MAC address high offset */ -#define ETH_MAC_ADDR_LBASE (uint32_t)(ETH_MAC_BASE + 0x44U) /* ETHERNET MAC address low offset */ + #define ETH_MAC_ADDR_HBASE ( uint32_t ) ( ETH_MAC_BASE + 0x40U ) /* ETHERNET MAC address high offset */ + #define ETH_MAC_ADDR_LBASE ( uint32_t ) ( ETH_MAC_BASE + 0x44U ) /* ETHERNET MAC address low offset */ /* ETHERNET DMA Rx descriptors Frame length Shift */ -#define ETH_DMARXDESC_FRAMELENGTHSHIFT 16U + #define ETH_DMARXDESC_FRAMELENGTHSHIFT 16U + /** - * @} - */ + * @} + */ /* Private macros ------------------------------------------------------------*/ + /** @defgroup ETH_Private_Macros ETH Private Macros - * @{ - */ + * @{ + */ /* Helper macros for TX descriptor handling */ -#define INCR_TX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\ - } while (0) + #define INCR_TX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_TX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_TX_DESC_CNT ); } \ + } while( 0 ) /* Helper macros for RX descriptor handling */ -#define INCR_RX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\ - } while (0) -/** - * @} - */ + #define INCR_RX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_RX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_RX_DESC_CNT ); } \ + } while( 0 ) + +/** + * @} + */ /* Private function prototypes -----------------------------------------------*/ + /** @defgroup ETH_Private_Functions ETH Private Functions - * @{ - */ -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf); -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf); -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth); -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth); -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth); -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, - uint32_t ItMode); -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth); -static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth); -static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ -/** - * @} - */ + * @{ + */ + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + const ETH_MACConfigTypeDef * macconf ); + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + const ETH_DMAConfigTypeDef * dmaconf ); + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ); + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ); + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ); + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + const ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t ItMode ); + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ); + static void ETH_FlushTransmitFIFO( ETH_HandleTypeDef * heth ); + static void ETH_MACAddressConfig( ETH_HandleTypeDef * heth, + uint32_t MacAddr, + uint8_t * Addr ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /* Exported functions ---------------------------------------------------------*/ + /** @defgroup ETH_Exported_Functions ETH Exported Functions - * @{ - */ + * @{ + */ /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions - * @brief Initialization and Configuration functions - * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] This subsection provides a set of functions allowing to initialize and - deinitialize the ETH peripheral: - - (+) User must Implement HAL_ETH_MspInit() function in which he configures - all related peripherals resources (CLOCK, GPIO and NVIC ). - - (+) Call the function HAL_ETH_Init() to configure the selected device with - the selected configuration: - (++) MAC address - (++) Media interface (MII or RMII) - (++) Rx DMA Descriptors Tab - (++) Tx DMA Descriptors Tab - (++) Length of Rx Buffers - - (+) Call the function HAL_ETH_DeInit() to restore the default configuration - of the selected ETH peripheral. - -@endverbatim - * @{ - */ - -/** - * @brief Initialize the Ethernet peripheral registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) -{ - uint32_t tickstart; - - if (heth == NULL) - { - return HAL_ERROR; - } - if (heth->gState == HAL_ETH_STATE_RESET) - { - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - ETH_InitCallbacksToDefault(heth); - - if (heth->MspInitCallback == NULL) - { - heth->MspInitCallback = HAL_ETH_MspInit; - } - - /* Init the low level hardware */ - heth->MspInitCallback(heth); -#else - /* Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - } - - __HAL_RCC_SYSCFG_CLK_ENABLE(); - - /* Select MII or RMII Mode*/ - SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL); - SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface; - /* Dummy read to sync SYSCFG with ETH */ - (void)SYSCFG->PMC; - - /* Ethernet Software reset */ - /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ - /* After reset all the registers holds their respective reset values */ - SET_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Wait for software reset */ - while (READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)) - { - /* Set Error Code */ - heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; - /* Set State as Error */ - heth->gState = HAL_ETH_STATE_ERROR; - /* Return Error */ - return HAL_ERROR; - } - } - - - /*------------------ MAC, MTL and DMA default Configuration ----------------*/ - ETH_MACDMAConfig(heth); - - - /*------------------ DMA Tx Descriptors Configuration ----------------------*/ - ETH_DMATxDescListInit(heth); - - /*------------------ DMA Rx Descriptors Configuration ----------------------*/ - ETH_DMARxDescListInit(heth); - - /*--------------------- ETHERNET MAC Address Configuration ------------------*/ - ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr); - - /* Disable MMC Interrupts */ - SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM); - - /* Disable Rx MMC Interrupts */ - SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | \ - ETH_MMCRIMR_RFCEM); - - /* Disable Tx MMC Interrupts */ - SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | \ - ETH_MMCTIMR_TGFSCM); - - heth->ErrorCode = HAL_ETH_ERROR_NONE; - heth->gState = HAL_ETH_STATE_READY; - - return HAL_OK; -} - -/** - * @brief DeInitializes the ETH peripheral. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) -{ - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - if (heth->MspDeInitCallback == NULL) - { - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - } - /* DeInit the low level hardware */ - heth->MspDeInitCallback(heth); -#else - - /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspDeInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - - /* Set ETH HAL state to Disabled */ - heth->gState = HAL_ETH_STATE_RESET; - - /* 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 - * @retval None - */ -__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspInit could be implemented in the user file - */ -} - -/** - * @brief DeInitializes ETH MSP. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspDeInit could be implemented in the user file - */ -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -/** - * @brief Register a User ETH Callback - * To be used instead of the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be registered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @param pCallback pointer to the Callback function - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = pCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = pCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = pCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = pCallback; - break; - - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = pCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} - -/** - * @brief Unregister an ETH Callback - * ETH callback is redirected to the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be unregistered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = HAL_ETH_ErrorCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = HAL_ETH_PMTCallback; - break; - - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ + * @brief Initialization and Configuration functions + * + * @verbatim + * =============================================================================== + ##### Initialization and Configuration functions ##### + #####=============================================================================== + #####[..] This subsection provides a set of functions allowing to initialize and + ##### deinitialize the ETH peripheral: + ##### + #####(+) User must Implement HAL_ETH_MspInit() function in which he configures + ##### all related peripherals resources (CLOCK, GPIO and NVIC ). + ##### + #####(+) Call the function HAL_ETH_Init() to configure the selected device with + ##### the selected configuration: + ##### (++) MAC address + ##### (++) Media interface (MII or RMII) + ##### (++) Rx DMA Descriptors Tab + ##### (++) Tx DMA Descriptors Tab + ##### (++) Length of Rx Buffers + ##### + #####(+) Call the function HAL_ETH_DeInit() to restore the default configuration + ##### of the selected ETH peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Initialize the Ethernet peripheral registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ) + { + uint32_t tickstart; + + if( heth == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_RESET ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + ETH_InitCallbacksToDefault( heth ); + + if( heth->MspInitCallback == NULL ) + { + heth->MspInitCallback = HAL_ETH_MspInit; + } + + /* Init the low level hardware */ + heth->MspInitCallback( heth ); + #else + /* Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + } + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + /* Select MII or RMII Mode*/ + SYSCFG->PMC &= ~( SYSCFG_PMC_MII_RMII_SEL ); + SYSCFG->PMC |= ( uint32_t ) heth->Init.MediaInterface; + /* Dummy read to sync SYSCFG with ETH */ + ( void ) SYSCFG->PMC; + + /* Ethernet Software reset */ + /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ + /* After reset all the registers holds their respective reset values */ + SET_BIT( heth->Instance->DMABMR, ETH_DMABMR_SR ); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for software reset */ + while( READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_SR ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_SWRESET_TIMEOUT ) ) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + } + + /*------------------ MAC, MTL and DMA default Configuration ----------------*/ + ETH_MACDMAConfig( heth ); + + + /*------------------ DMA Tx Descriptors Configuration ----------------------*/ + ETH_DMATxDescListInit( heth ); + + /*------------------ DMA Rx Descriptors Configuration ----------------------*/ + ETH_DMARxDescListInit( heth ); + + /*--------------------- ETHERNET MAC Address Configuration ------------------*/ + ETH_MACAddressConfig( heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr ); + + /* Disable MMC Interrupts */ + SET_BIT( heth->Instance->MACIMR, ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM ); + + /* Disable Rx MMC Interrupts */ + SET_BIT( heth->Instance->MMCRIMR, ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | \ + ETH_MMCRIMR_RFCEM ); + + /* Disable Tx MMC Interrupts */ + SET_BIT( heth->Instance->MMCTIMR, ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | \ + ETH_MMCTIMR_TGFSCM ); + + heth->ErrorCode = HAL_ETH_ERROR_NONE; + heth->gState = HAL_ETH_STATE_READY; + + return HAL_OK; + } + +/** + * @brief DeInitializes the ETH peripheral. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + if( heth->MspDeInitCallback == NULL ) + { + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + } + + /* DeInit the low level hardware */ + heth->MspDeInitCallback( heth ); + #else + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspDeInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + + /* Set ETH HAL state to Disabled */ + heth->gState = HAL_ETH_STATE_RESET; + + /* 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 + * @retval None + */ + __weak void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspInit could be implemented in the user file + */ + } + +/** + * @brief DeInitializes ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspDeInit could be implemented in the user file + */ + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + +/** + * @brief Register a User ETH Callback + * To be used instead of the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( pCallback == NULL ) + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = pCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = pCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = pCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = pCallback; + break; + + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = pCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + +/** + * @brief Unregister an ETH Callback + * ETH callback is redirected to the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = HAL_ETH_ErrorCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = HAL_ETH_PMTCallback; + break; + + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group2 IO operation functions - * @brief ETH Transmit and Receive functions - * -@verbatim - ============================================================================== - ##### IO operation functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to manage the ETH - data transfer. + * @brief ETH Transmit and Receive functions + * + * @verbatim + * ============================================================================== + ##### IO operation functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to manage the ETH + #####data transfer. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Enables Ethernet MAC and DMA reception and transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ) + { + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + heth->gState = HAL_ETH_STATE_STARTED; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ) + { + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* save IT mode to ETH Handle */ + heth->RxDescList.ItMode = 1U; -@endverbatim - * @{ - */ + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Enable ETH DMA interrupts: + * - Tx complete interrupt + * - Rx complete interrupt + * - Fatal bus interrupt + */ + __HAL_ETH_DMA_ENABLE_IT( heth, ( ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | + ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE ) ); + + heth->gState = HAL_ETH_STATE_STARTED; + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } /** - * @brief Enables Ethernet MAC and DMA reception and transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - heth->gState = HAL_ETH_STATE_STARTED; - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* save IT mode to ETH Handle */ - heth->RxDescList.ItMode = 1U; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Enable ETH DMA interrupts: - - Tx complete interrupt - - Rx complete interrupt - - Fatal bus interrupt - */ - __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | - ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE)); - - heth->gState = HAL_ETH_STATE_STARTED; - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t descindex; - uint32_t tmpreg1; - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | - ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE)); - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Flush Transmit FIFO */ - ETH_FlushTransmitFIFO(heth); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /* Clear IOC bit to all Rx descriptors */ - for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++) - { - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; - SET_BIT(dmarxdesc->DESC1, ETH_DMARXDESC_DIC); - } - - heth->RxDescList.ItMode = 0U; - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in polling mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @param Timeout: timeout value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout) -{ - uint32_t tickstart; - ETH_DMADescTypeDef *dmatxdesc; - - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE) - { - /* Set the ETH error code */ - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc]; - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - WRITE_REG(heth->Instance->DMATPDR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); - - tickstart = HAL_GetTick(); - - /* Wait for data to be transmitted or timeout occurred */ - while ((dmatxdesc->DESC0 & ETH_DMATXDESC_OWN) != (uint32_t)RESET) - { - if ((heth->Instance->DMASR & ETH_DMASR_FBES) != (uint32_t)RESET) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - heth->DMAErrorCode = heth->Instance->DMASR; - /* Return function status */ - return HAL_ERROR; - } - - /* Check for the Timeout */ - if (Timeout != HAL_MAX_DELAY) - { - if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + * @brief Stop Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ) { - heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; - /* Clear TX descriptor so that we can proceed */ - dmatxdesc->DESC0 = (ETH_DMATXDESC_FS | ETH_DMATXDESC_LS); - return HAL_ERROR; + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } } - } - } - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in interrupt mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig) -{ - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Save the packet pointer to release. */ - heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData; - - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE) - { - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) - { - /* Clear TBUS ETHERNET DMA flag */ - (heth->Instance)->DMASR = ETH_DMASR_TBUS; - /* Resume DMA transmission*/ - (heth->Instance)->DMATPDR = 0U; - } - - return HAL_OK; - - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Read a received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pAppBuff: Pointer to an application buffer to receive the packet. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff) -{ - uint32_t descidx; - ETH_DMADescTypeDef *dmarxdesc; - uint32_t desccnt = 0U; - uint32_t desccntmax; - uint32_t bufflength; - uint8_t rxdataready = 0U; - - if (pAppBuff == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState != HAL_ETH_STATE_STARTED) - { - return HAL_ERROR; - } - - descidx = heth->RxDescList.RxDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; - - /* Check if descriptor is not owned by DMA */ - while ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (desccnt < desccntmax) - && (rxdataready == 0U)) - { - if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET) - { - /* Get timestamp high */ - heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC7; - /* Get timestamp low */ - heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC6; - } - if ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL)) - { - /* Check first descriptor */ - if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET) - { - heth->RxDescList.RxDescCnt = 0; - heth->RxDescList.RxDataLength = 0; - } - - /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ - bufflength = ((dmarxdesc->DESC0 & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT); - - /* Check if last descriptor */ - if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET) - { - /* Save Last descriptor index */ - heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC0; - - /* Packet ready */ - rxdataready = 1; - } - - /* Link data */ - WRITE_REG(dmarxdesc->BackupAddr0, dmarxdesc->DESC2); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Link callback*/ - heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, bufflength); -#else - /* Link callback */ - HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - heth->RxDescList.RxDescCnt++; - heth->RxDescList.RxDataLength += bufflength; - - /* Clear buffer pointer */ - dmarxdesc->BackupAddr0 = 0; - } - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccnt++; - } - - heth->RxDescList.RxBuildDescCnt += desccnt; - if ((heth->RxDescList.RxBuildDescCnt) != 0U) - { - /* Update Descriptors */ - ETH_UpdateDescriptor(heth); - } - - heth->RxDescList.RxDescIdx = descidx; - - if (rxdataready == 1U) - { - /* Return received packet */ - *pAppBuff = heth->RxDescList.pRxStart; - /* Reset first element */ - heth->RxDescList.pRxStart = NULL; - - return HAL_OK; - } - - /* Packet not ready */ - return HAL_ERROR; -} - -/** - * @brief This function gives back Rx Desc of the last received Packet - * to the DMA, so ETH DMA will be able to use these descriptors - * to receive next Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth) -{ - uint32_t descidx; - uint32_t tailidx; - uint32_t desccount; - ETH_DMADescTypeDef *dmarxdesc; - uint8_t *buff = NULL; - uint8_t allocStatus = 1U; - - descidx = heth->RxDescList.RxBuildDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount = heth->RxDescList.RxBuildDescCnt; - - while ((desccount > 0U) && (allocStatus != 0U)) - { - /* Check if a buffer's attached the descriptor */ - if (READ_REG(dmarxdesc->BackupAddr0) == 0U) - { - /* Get a new buffer. */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Allocate callback*/ - heth->rxAllocateCallback(&buff); -#else - /* Allocate callback */ - HAL_ETH_RxAllocateCallback(&buff); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - if (buff == NULL) - { - allocStatus = 0U; - } - else - { - WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff); - WRITE_REG(dmarxdesc->DESC2, (uint32_t)buff); - } - } - - if (allocStatus != 0U) - { - if (heth->RxDescList.ItMode == 0U) - { - WRITE_REG(dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_DIC | ETH_DMARXDESC_RCH); - } - else - { - WRITE_REG(dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_RCH); - } - - SET_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN); - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount--; - } - } - - if (heth->RxDescList.RxBuildDescCnt != desccount) - { - /* Set the tail pointer index */ - tailidx = (descidx + 1U) % ETH_RX_DESC_CNT; - - /* DMB instruction to avoid race condition */ - __DMB(); - - /* Set the Tail pointer address */ - WRITE_REG(heth->Instance->DMARPDR, ((uint32_t)(heth->Init.RxDesc + (tailidx)))); - - heth->RxDescList.RxBuildDescIdx = descidx; - heth->RxDescList.RxBuildDescCnt = desccount; - } -} - -/** - * @brief Register the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxAllocateCallback: pointer to function to alloc buffer - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback) -{ - if (rxAllocateCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to allocate buffer */ - heth->rxAllocateCallback = rxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Rx Allocate callback. - * @param buff: pointer to allocated buffer - * @retval None - */ -__weak void HAL_ETH_RxAllocateCallback(uint8_t **buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxAllocateCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Link callback. - * @param pStart: pointer to packet start - * @param pEnd: pointer to packet end - * @param buff: pointer to received data - * @param Length: received data length - * @retval None - */ -__weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(pStart); - UNUSED(pEnd); - UNUSED(buff); - UNUSED(Length); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxLinkCallback could be implemented in the user file - */ -} - -/** - * @brief Set the Rx link data function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxLinkCallback: pointer to function to link data - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback) -{ - if (rxLinkCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to link data */ - heth->rxLinkCallback = rxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx link callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Get the error state of the last received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pErrorCode: pointer to uint32_t to hold the error code - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode) -{ - /* Get error bits. */ - *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXDESC_ERRORS_MASK); - - return HAL_OK; -} - -/** - * @brief Set the Tx free function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txFreeCallback: pointer to function to release the packet - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback) -{ - if (txFreeCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to free transmmitted packet */ - heth->txFreeCallback = txFreeCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx free callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; - - return HAL_OK; -} - -/** - * @brief Tx Free callback. - * @param buff: pointer to buffer to free - * @retval None - */ -__weak void HAL_ETH_TxFreeCallback(uint32_t *buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxFreeCallback could be implemented in the user file - */ -} - -/** - * @brief Release transmitted Tx packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t numOfBuf = dmatxdesclist->BuffersInUse; - uint32_t idx = dmatxdesclist->releaseIndex; - uint8_t pktTxStatus = 1U; - uint8_t pktInUse; -#ifdef HAL_ETH_USE_PTP - ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp; -#endif /* HAL_ETH_USE_PTP */ - - /* Loop through buffers in use. */ - while ((numOfBuf != 0U) && (pktTxStatus != 0U)) - { - pktInUse = 1U; - numOfBuf--; - /* If no packet, just examine the next packet. */ - if (dmatxdesclist->PacketAddress[idx] == NULL) - { - /* No packet in use, skip to next. */ - INCR_TX_DESC_INDEX(idx, 1U); - pktInUse = 0U; - } - - if (pktInUse != 0U) - { - /* Determine if the packet has been transmitted. */ - if ((heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_OWN) == 0U) - { -#ifdef HAL_ETH_USE_PTP - if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXDESC_LS) - && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXDESC_TTSS)) + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ) { - /* Get timestamp low */ - timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC6; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC7; + ETH_DMADescTypeDef * dmarxdesc; + uint32_t descindex; + uint32_t tmpreg1; + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + __HAL_ETH_DMA_DISABLE_IT( heth, ( ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE | + ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE ) ); + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO( heth ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /* Clear IOC bit to all Rx descriptors */ + for( descindex = 0; descindex < ( uint32_t ) ETH_RX_DESC_CNT; descindex++ ) + { + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descindex ]; + SET_BIT( dmarxdesc->DESC1, ETH_DMARXDESC_DIC ); + } + + heth->RxDescList.ItMode = 0U; + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } } - else + +/** + * @brief Sends an Ethernet Packet in polling mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @param Timeout: timeout value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t Timeout ) { - timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX; + uint32_t tickstart; + ETH_DMADescTypeDef * dmatxdesc; + + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 0 ) != HAL_ETH_ERROR_NONE ) + { + /* Set the ETH error code */ + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + dmatxdesc = ( ETH_DMADescTypeDef * ) ( &heth->TxDescList )->TxDesc[ heth->TxDescList.CurTxDesc ]; + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG( heth->Instance->DMATPDR, ( uint32_t ) ( heth->TxDescList.TxDesc[ heth->TxDescList.CurTxDesc ] ) ); + + tickstart = HAL_GetTick(); + + /* Wait for data to be transmitted or timeout occurred */ + while( ( dmatxdesc->DESC0 & ETH_DMATXDESC_OWN ) != ( uint32_t ) RESET ) + { + if( ( heth->Instance->DMASR & ETH_DMASR_FBES ) != ( uint32_t ) RESET ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + heth->DMAErrorCode = heth->Instance->DMASR; + /* Return function status */ + return HAL_ERROR; + } + + /* Check for the Timeout */ + if( Timeout != HAL_MAX_DELAY ) + { + if( ( ( HAL_GetTick() - tickstart ) > Timeout ) || ( Timeout == 0U ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; + /* Clear TX descriptor so that we can proceed */ + dmatxdesc->DESC0 = ( ETH_DMATXDESC_FS | ETH_DMATXDESC_LS ); + return HAL_ERROR; + } + } + } + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } } -#endif /* HAL_ETH_USE_PTP */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered callbacks*/ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX) +/** + * @brief Sends an Ethernet Packet in interrupt mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig ) { - heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Save the packet pointer to release. */ + heth->TxDescList.CurrentPacketAddress = ( uint32_t * ) pTxConfig->pData; + + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 1 ) != HAL_ETH_ERROR_NONE ) + { + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + if( ( ( heth->Instance )->DMASR & ETH_DMASR_TBUS ) != ( uint32_t ) RESET ) + { + /* Clear TBUS ETHERNET DMA flag */ + ( heth->Instance )->DMASR = ETH_DMASR_TBUS; + /* Resume DMA transmission*/ + ( heth->Instance )->DMATPDR = 0U; + } + + return HAL_OK; + } + else + { + return HAL_ERROR; + } } -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]); -#else - /* Call callbacks */ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX) + +/** + * @brief Read a received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pAppBuff: Pointer to an application buffer to receive the packet. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ) { - HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); + uint32_t descidx; + ETH_DMADescTypeDef * dmarxdesc; + uint32_t desccnt = 0U; + uint32_t desccntmax; + uint32_t bufflength; + uint8_t rxdataready = 0U; + + if( pAppBuff == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState != HAL_ETH_STATE_STARTED ) + { + return HAL_ERROR; + } + + descidx = heth->RxDescList.RxDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; + + /* Check if descriptor is not owned by DMA */ + while( ( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_OWN ) == ( uint32_t ) RESET ) && ( desccnt < desccntmax ) && + ( rxdataready == 0U ) ) + { + if( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_LS ) != ( uint32_t ) RESET ) + { + /* Get timestamp high */ + heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC7; + /* Get timestamp low */ + heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC6; + } + + if( ( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_FS ) != ( uint32_t ) RESET ) || ( heth->RxDescList.pRxStart != NULL ) ) + { + /* Check first descriptor */ + if( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_FS ) != ( uint32_t ) RESET ) + { + heth->RxDescList.RxDescCnt = 0; + heth->RxDescList.RxDataLength = 0; + } + + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + bufflength = ( ( dmarxdesc->DESC0 & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ); + + /* Check if last descriptor */ + if( READ_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_LS ) != ( uint32_t ) RESET ) + { + /* Save Last descriptor index */ + heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC0; + + /* Packet ready */ + rxdataready = 1; + } + + /* Link data */ + WRITE_REG( dmarxdesc->BackupAddr0, dmarxdesc->DESC2 ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Link callback*/ + heth->rxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, bufflength ); + #else + /* Link callback */ + HAL_ETH_RxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, ( uint16_t ) bufflength ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->RxDescList.RxDescCnt++; + heth->RxDescList.RxDataLength += bufflength; + + /* Clear buffer pointer */ + dmarxdesc->BackupAddr0 = 0; + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccnt++; + } + + heth->RxDescList.RxBuildDescCnt += desccnt; + + if( ( heth->RxDescList.RxBuildDescCnt ) != 0U ) + { + /* Update Descriptors */ + ETH_UpdateDescriptor( heth ); + } + + heth->RxDescList.RxDescIdx = descidx; + + if( rxdataready == 1U ) + { + /* Return received packet */ + *pAppBuff = heth->RxDescList.pRxStart; + /* Reset first element */ + heth->RxDescList.pRxStart = NULL; + + return HAL_OK; + } + + /* Packet not ready */ + return HAL_ERROR; } -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - /* Clear the entry in the in-use array. */ - dmatxdesclist->PacketAddress[idx] = NULL; - - /* Update the transmit relesae index and number of buffers in use. */ - INCR_TX_DESC_INDEX(idx, 1U); - dmatxdesclist->BuffersInUse = numOfBuf; - dmatxdesclist->releaseIndex = idx; - } - else - { - /* Get out of the loop! */ - pktTxStatus = 0U; - } - } - } - return HAL_OK; -} - -#ifdef HAL_ETH_USE_PTP -/** - * @brief Set the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - uint32_t tmpTSCR; - ETH_TimeTypeDef time; - - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - - tmpTSCR = ptpconfig->Timestamp | - ((uint32_t)ptpconfig->TimestampUpdate << ETH_PTPTSCR_TSFCU_Pos) | - ((uint32_t)ptpconfig->TimestampAll << ETH_PTPTSCR_TSSARFE_Pos) | - ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_PTPTSCR_TSSSR_Pos) | - ((uint32_t)ptpconfig->TimestampV2 << ETH_PTPTSCR_TSPTPPSV2E_Pos) | - ((uint32_t)ptpconfig->TimestampEthernet << ETH_PTPTSCR_TSSPTPOEFE_Pos) | - ((uint32_t)ptpconfig->TimestampIPv6 << ETH_PTPTSCR_TSSIPV6FE_Pos) | - ((uint32_t)ptpconfig->TimestampIPv4 << ETH_PTPTSCR_TSSIPV4FE_Pos) | - ((uint32_t)ptpconfig->TimestampEvent << ETH_PTPTSCR_TSSEME_Pos) | - ((uint32_t)ptpconfig->TimestampMaster << ETH_PTPTSCR_TSSMRME_Pos) | - ((uint32_t)ptpconfig->TimestampFilter << ETH_PTPTSCR_TSPFFMAE_Pos) | - ((uint32_t)ptpconfig->TimestampClockType << ETH_PTPTSCR_TSCNT_Pos); - - /* Write to MACTSCR */ - MODIFY_REG(heth->Instance->PTPTSCR, ETH_MACTSCR_MASK, tmpTSCR); - - /* Enable Timestamp */ - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE); - WRITE_REG(heth->Instance->PTPSSIR, ptpconfig->TimestampSubsecondInc); - WRITE_REG(heth->Instance->PTPTSAR, ptpconfig->TimestampAddend); - - /* Enable Timestamp */ - if (ptpconfig->TimestampAddendUpdate == ENABLE) - { - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU); - while ((heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU) != 0) - { - - } - } - - /* Ptp Init */ - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTI); - - /* Set PTP Configuration done */ - heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED; - - /* Set Seconds */ - time.Seconds = heth->Instance->PTPTSHR; - /* Set NanoSeconds */ - time.NanoSeconds = heth->Instance->PTPTSLR; - - HAL_ETH_PTP_SetTime(heth, &time); - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Get the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - ptpconfig->Timestamp = READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE); - ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSFCU) >> ETH_PTPTSCR_TSFCU_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSARFE) >> ETH_PTPTSCR_TSSARFE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSSR) >> ETH_PTPTSCR_TSSSR_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSPTPPSV2E) >> ETH_PTPTSCR_TSPTPPSV2E_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSPTPOEFE) >> ETH_PTPTSCR_TSSPTPOEFE_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSIPV6FE) >> ETH_PTPTSCR_TSSIPV6FE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSIPV4FE) >> ETH_PTPTSCR_TSSIPV4FE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSEME) >> ETH_PTPTSCR_TSSEME_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSSMRME) >> ETH_PTPTSCR_TSSMRME_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSPFFMAE) >> ETH_PTPTSCR_TSPFFMAE_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampClockType = ((READ_BIT(heth->Instance->PTPTSCR, - ETH_PTPTSCR_TSCNT) >> ETH_PTPTSCR_TSCNT_Pos) > 0U) ? ENABLE : DISABLE; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param time: pointer to a ETH_TimeTypeDef structure that contains - * time to set - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Set Seconds */ - heth->Instance->PTPTSHUR = time->Seconds; - - /* Set NanoSeconds */ - heth->Instance->PTPTSLUR = time->NanoSeconds; - - /* the system time is updated */ - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param time: pointer to a ETH_TimeTypeDef structure that contains - * time to get - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get Seconds */ - time->Seconds = heth->Instance->PTPTSHR; - /* Get NanoSeconds */ - time->NanoSeconds = heth->Instance->PTPTSLR; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Update time for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains - * the time update information - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE) - { - /* Set Seconds update */ - heth->Instance->PTPTSHUR = ETH_PTPTSHR_VALUE - timeoffset->Seconds + 1U; - - if (READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSSR) == ETH_PTPTSCR_TSSSR) - { - /* Set nanoSeconds update */ - heth->Instance->PTPTSLUR = ETH_PTPTSLR_VALUE - timeoffset->NanoSeconds; - } - else - { - heth->Instance->PTPTSLUR = ETH_PTPTSHR_VALUE - timeoffset->NanoSeconds + 1U; - } - } - else - { - /* Set Seconds update */ - heth->Instance->PTPTSHUR = timeoffset->Seconds; - /* Set nanoSeconds update */ - heth->Instance->PTPTSLUR = timeoffset->NanoSeconds; - } - - SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Insert Timestamp in transmission. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Enable Time Stamp transmission */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TTSE); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get transmission timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * transmission timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t idx = dmatxdesclist->releaseIndex; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = dmatxdesc->DESC0; - /* Get timestamp high */ - timestamp->TimeStampHigh = dmatxdesc->DESC1; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get receive timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * receive timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Register the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txPtpCallback: Function to handle Ptp transmission - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback) -{ - if (txPtpCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - /* Set Function to handle Tx Ptp */ - heth->txPtpCallback = txPtpCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txPtpCallback = HAL_ETH_TxPtpCallback; - - return HAL_OK; -} - -/** - * @brief Tx Ptp callback. - * @param buff: pointer to application buffer - * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains - * transmission timestamp - * @retval None - */ -__weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxPtpCallback could be implemented in the user file - */ -} -#endif /* HAL_ETH_USE_PTP */ - -/** - * @brief This function handles ETH interrupt request. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) -{ - uint32_t mac_flag = READ_REG(heth->Instance->MACSR); - uint32_t dma_flag = READ_REG(heth->Instance->DMASR); - uint32_t dma_itsource = READ_REG(heth->Instance->DMAIER); - uint32_t exti_flag = READ_REG(EXTI->PR); - - /* Packet received */ - if (((dma_flag & ETH_DMASR_RS) != 0U) && ((dma_itsource & ETH_DMAIER_RIE) != 0U)) - { - /* Clear the Eth DMA Rx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_RS | ETH_DMASR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Receive complete callback*/ - heth->RxCpltCallback(heth); -#else - /* Receive complete callback */ - HAL_ETH_RxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* Packet transmitted */ - if (((dma_flag & ETH_DMASR_TS) != 0U) && ((dma_itsource & ETH_DMAIER_TIE) != 0U)) - { - /* Clear the Eth DMA Tx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_TS | ETH_DMASR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Transmit complete callback*/ - heth->TxCpltCallback(heth); -#else - /* Transfer complete callback */ - HAL_ETH_TxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* ETH DMA Error */ - if (((dma_flag & ETH_DMASR_AIS) != 0U) && ((dma_itsource & ETH_DMAIER_AISE) != 0U)) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - /* if fatal bus error occurred */ - if ((dma_flag & ETH_DMASR_FBES) != 0U) - { - /* Get DMA error code */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS)); - - /* Disable all interrupts */ - __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE); - - /* Set HAL state to ERROR */ - heth->gState = HAL_ETH_STATE_ERROR; - } - else - { - /* Get DMA error status */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_ETS | ETH_DMASR_RWTS | - ETH_DMASR_RBUS | ETH_DMASR_AIS)); - - /* Clear the interrupt summary flag */ - __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMASR_ETS | ETH_DMASR_RWTS | - ETH_DMASR_RBUS | ETH_DMASR_AIS)); - } -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered Error callback*/ - heth->ErrorCallback(heth); -#else - /* Ethernet DMA Error callback */ - HAL_ETH_ErrorCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - - /* ETH PMT IT */ - if ((mac_flag & ETH_MAC_PMT_IT) != 0U) - { - /* Get MAC Wake-up source and clear the status register pending bit */ - heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPMTCSR, (ETH_MACPMTCSR_WFR | ETH_MACPMTCSR_MPR)); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered PMT callback*/ - heth->PMTCallback(heth); -#else - /* Ethernet PMT callback */ - HAL_ETH_PMTCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - heth->MACWakeUpEvent = (uint32_t)(0x0U); - } - - - /* check ETH WAKEUP exti flag */ - if ((exti_flag & ETH_WAKEUP_EXTI_LINE) != 0U) - { - /* Clear ETH WAKEUP Exti pending bit */ - __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered WakeUp callback*/ - heth->WakeUpCallback(heth); -#else - /* ETH WAKEUP callback */ - HAL_ETH_WakeUpCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } -} - -/** - * @brief Tx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet transfer error callbacks - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_ErrorCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet Power Management module IT callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_PMTCallback could be implemented in the user file - */ -} - - -/** - * @brief ETH WAKEUP interrupt callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_WakeUpCallback could be implemented in the user file - */ -} - -/** - * @brief Read a PHY register - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param pRegValue: parameter to hold read value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue) -{ - uint32_t tmpreg1; - uint32_t tickstart; - - /* Get the ETHERNET MACMIIAR value */ - tmpreg1 = heth->Instance->MACMIIAR; - - /* Keep only the CSR Clock Range CR[2:0] bits value */ - tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; - - /* Prepare the MII address register value */ - tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ - tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ - tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */ - tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ - - /* Write the result value into the MII Address register */ - heth->Instance->MACMIIAR = tmpreg1; - - - tickstart = HAL_GetTick(); - - /* Check for the Busy flag */ - while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) - { - /* Check for the Timeout */ - if ((HAL_GetTick() - tickstart) > PHY_READ_TO) - { - return HAL_ERROR; - } - - tmpreg1 = heth->Instance->MACMIIAR; - } - - /* Get MACMIIDR value */ - *pRegValue = (uint16_t)(heth->Instance->MACMIIDR); - - return HAL_OK; -} - -/** - * @brief Writes to a PHY register. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param RegValue: the value to write - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue) -{ - uint32_t tmpreg1; - uint32_t tickstart; - - /* Get the ETHERNET MACMIIAR value */ - tmpreg1 = heth->Instance->MACMIIAR; - - /* Keep only the CSR Clock Range CR[2:0] bits value */ - tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; - - /* Prepare the MII register address value */ - tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ - tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ - tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */ - tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ - - /* Give the value to the MII data register */ - heth->Instance->MACMIIDR = (uint16_t)RegValue; - - /* Write the result value into the MII Address register */ - heth->Instance->MACMIIAR = tmpreg1; - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Check for the Busy flag */ - while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) - { - /* Check for the Timeout */ - if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO) - { - return HAL_ERROR; - } - - tmpreg1 = heth->Instance->MACMIIAR; - } - - return HAL_OK; -} - -/** - * @} - */ + +/** + * @brief This function gives back Rx Desc of the last received Packet + * to the DMA, so ETH DMA will be able to use these descriptors + * to receive next Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ) + { + uint32_t descidx; + uint32_t tailidx; + uint32_t desccount; + ETH_DMADescTypeDef * dmarxdesc; + uint8_t * buff = NULL; + uint8_t allocStatus = 1U; + + descidx = heth->RxDescList.RxBuildDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount = heth->RxDescList.RxBuildDescCnt; + + while( ( desccount > 0U ) && ( allocStatus != 0U ) ) + { + /* Check if a buffer's attached the descriptor */ + if( READ_REG( dmarxdesc->BackupAddr0 ) == 0U ) + { + /* Get a new buffer. */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Allocate callback*/ + heth->rxAllocateCallback( &buff ); + #else + /* Allocate callback */ + HAL_ETH_RxAllocateCallback( &buff ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + if( buff == NULL ) + { + allocStatus = 0U; + } + else + { + WRITE_REG( dmarxdesc->BackupAddr0, ( uint32_t ) buff ); + WRITE_REG( dmarxdesc->DESC2, ( uint32_t ) buff ); + } + } + + if( allocStatus != 0U ) + { + if( heth->RxDescList.ItMode == 0U ) + { + WRITE_REG( dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_DIC | ETH_DMARXDESC_RCH ); + } + else + { + WRITE_REG( dmarxdesc->DESC1, heth->Init.RxBuffLen | ETH_DMARXDESC_RCH ); + } + + SET_BIT( dmarxdesc->DESC0, ETH_DMARXDESC_OWN ); + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount--; + } + } + + if( heth->RxDescList.RxBuildDescCnt != desccount ) + { + /* Set the tail pointer index */ + tailidx = ( descidx + 1U ) % ETH_RX_DESC_CNT; + + /* DMB instruction to avoid race condition */ + __DMB(); + + /* Set the Tail pointer address */ + WRITE_REG( heth->Instance->DMARPDR, ( ( uint32_t ) ( heth->Init.RxDesc + ( tailidx ) ) ) ); + + heth->RxDescList.RxBuildDescIdx = descidx; + heth->RxDescList.RxBuildDescCnt = desccount; + } + } + +/** + * @brief Register the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxAllocateCallback: pointer to function to alloc buffer + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ) + { + if( rxAllocateCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to allocate buffer */ + heth->rxAllocateCallback = rxAllocateCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; + + return HAL_OK; + } + +/** + * @brief Rx Allocate callback. + * @param buff: pointer to allocated buffer + * @retval None + */ + __weak void HAL_ETH_RxAllocateCallback( uint8_t ** buff ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxAllocateCallback could be implemented in the user file + */ + } + +/** + * @brief Rx Link callback. + * @param pStart: pointer to packet start + * @param pEnd: pointer to packet end + * @param buff: pointer to received data + * @param Length: received data length + * @retval None + */ + __weak void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( pStart ); + UNUSED( pEnd ); + UNUSED( buff ); + UNUSED( Length ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxLinkCallback could be implemented in the user file + */ + } + +/** + * @brief Set the Rx link data function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxLinkCallback: pointer to function to link data + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ) + { + if( rxLinkCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to link data */ + heth->rxLinkCallback = rxLinkCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Rx link callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; + + return HAL_OK; + } + +/** + * @brief Get the error state of the last received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pErrorCode: pointer to uint32_t to hold the error code + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( const ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ) + { + /* Get error bits. */ + *pErrorCode = READ_BIT( heth->RxDescList.pRxLastRxDesc, ETH_DMARXDESC_ERRORS_MASK ); + + return HAL_OK; + } + +/** + * @brief Set the Tx free function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txFreeCallback: pointer to function to release the packet + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ) + { + if( txFreeCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to free transmmitted packet */ + heth->txFreeCallback = txFreeCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx free callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; + + return HAL_OK; + } + +/** + * @brief Tx Free callback. + * @param buff: pointer to buffer to free + * @retval None + */ + __weak void HAL_ETH_TxFreeCallback( uint32_t * buff ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxFreeCallback could be implemented in the user file + */ + } + +/** + * @brief Release transmitted Tx packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t numOfBuf = dmatxdesclist->BuffersInUse; + uint32_t idx = dmatxdesclist->releaseIndex; + uint8_t pktTxStatus = 1U; + uint8_t pktInUse; + + #ifdef HAL_ETH_USE_PTP + ETH_TimeStampTypeDef * timestamp = &heth->TxTimestamp; + #endif /* HAL_ETH_USE_PTP */ + + /* Loop through buffers in use. */ + while( ( numOfBuf != 0U ) && ( pktTxStatus != 0U ) ) + { + pktInUse = 1U; + numOfBuf--; + + /* If no packet, just examine the next packet. */ + if( dmatxdesclist->PacketAddress[ idx ] == NULL ) + { + /* No packet in use, skip to next. */ + INCR_TX_DESC_INDEX( idx, 1U ); + pktInUse = 0U; + } + + if( pktInUse != 0U ) + { + /* Determine if the packet has been transmitted. */ + if( ( heth->Init.TxDesc[ idx ].DESC0 & ETH_DMATXDESC_OWN ) == 0U ) + { + #ifdef HAL_ETH_USE_PTP + if( ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXDESC_LS ) && + ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXDESC_TTSS ) ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->Init.TxDesc[ idx ].DESC6; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->Init.TxDesc[ idx ].DESC7; + } + else + { + timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX; + } + #endif /* HAL_ETH_USE_PTP */ + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered callbacks*/ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + if( ( timestamp->TimeStampHigh != UINT32_MAX ) && ( timestamp->TimeStampLow != UINT32_MAX ) ) + { + heth->txPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + } + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + heth->txFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #else /* if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) */ + /* Call callbacks */ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + if( ( timestamp->TimeStampHigh != UINT32_MAX ) && ( timestamp->TimeStampLow != UINT32_MAX ) ) + { + HAL_ETH_TxPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + } + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + HAL_ETH_TxFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + /* Clear the entry in the in-use array. */ + dmatxdesclist->PacketAddress[ idx ] = NULL; + + /* Update the transmit relesae index and number of buffers in use. */ + INCR_TX_DESC_INDEX( idx, 1U ); + dmatxdesclist->BuffersInUse = numOfBuf; + dmatxdesclist->releaseIndex = idx; + } + else + { + /* Get out of the loop! */ + pktTxStatus = 0U; + } + } + } + + return HAL_OK; + } + + #ifdef HAL_ETH_USE_PTP + +/** + * @brief Set the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + uint32_t tmpTSCR; + ETH_TimeTypeDef time; + + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + tmpTSCR = ptpconfig->Timestamp | + ( ( uint32_t ) ptpconfig->TimestampUpdate << ETH_PTPTSCR_TSFCU_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampAll << ETH_PTPTSCR_TSSARFE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampRolloverMode << ETH_PTPTSCR_TSSSR_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampV2 << ETH_PTPTSCR_TSPTPPSV2E_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEthernet << ETH_PTPTSCR_TSSPTPOEFE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv6 << ETH_PTPTSCR_TSSIPV6FE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv4 << ETH_PTPTSCR_TSSIPV4FE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEvent << ETH_PTPTSCR_TSSEME_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampMaster << ETH_PTPTSCR_TSSMRME_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampFilter << ETH_PTPTSCR_TSPFFMAE_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampClockType << ETH_PTPTSCR_TSCNT_Pos ); + + /* Write to MACTSCR */ + MODIFY_REG( heth->Instance->PTPTSCR, ETH_MACTSCR_MASK, tmpTSCR ); + + /* Enable Timestamp */ + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE ); + WRITE_REG( heth->Instance->PTPSSIR, ptpconfig->TimestampSubsecondInc ); + WRITE_REG( heth->Instance->PTPTSAR, ptpconfig->TimestampAddend ); + + /* Enable Timestamp */ + if( ptpconfig->TimestampAddendUpdate == ENABLE ) + { + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU ); + + while( ( heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU ) != 0 ) + { + } + } + + /* Ptp Init */ + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTI ); + + /* Set PTP Configuration done */ + heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED; + + /* Set Seconds */ + time.Seconds = heth->Instance->PTPTSHR; + /* Set NanoSeconds */ + time.NanoSeconds = heth->Instance->PTPTSLR; + + HAL_ETH_PTP_SetTime( heth, &time ); + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Get the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + ptpconfig->Timestamp = READ_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE ); + ptpconfig->TimestampUpdate = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSFCU ) >> ETH_PTPTSCR_TSFCU_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampAll = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSARFE ) >> ETH_PTPTSCR_TSSARFE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampRolloverMode = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSSR ) >> ETH_PTPTSCR_TSSSR_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampV2 = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSPTPPSV2E ) >> ETH_PTPTSCR_TSPTPPSV2E_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEthernet = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSPTPOEFE ) >> ETH_PTPTSCR_TSSPTPOEFE_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampIPv6 = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSIPV6FE ) >> ETH_PTPTSCR_TSSIPV6FE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv4 = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSIPV4FE ) >> ETH_PTPTSCR_TSSIPV4FE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEvent = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSEME ) >> ETH_PTPTSCR_TSSEME_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampMaster = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSSMRME ) >> ETH_PTPTSCR_TSSMRME_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampFilter = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSPFFMAE ) >> ETH_PTPTSCR_TSPFFMAE_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampClockType = ( ( READ_BIT( heth->Instance->PTPTSCR, + ETH_PTPTSCR_TSCNT ) >> ETH_PTPTSCR_TSCNT_Pos ) > 0U ) ? ENABLE : DISABLE; + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to set + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Set Seconds */ + heth->Instance->PTPTSHUR = time->Seconds; + + /* Set NanoSeconds */ + heth->Instance->PTPTSLUR = time->NanoSeconds; + + /* the system time is updated */ + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to get + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get Seconds */ + time->Seconds = heth->Instance->PTPTSHR; + /* Get NanoSeconds */ + time->NanoSeconds = heth->Instance->PTPTSLR; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Update time for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains + * the time update information + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + if( ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE ) + { + /* Set Seconds update */ + heth->Instance->PTPTSHUR = ETH_PTPTSHR_VALUE - timeoffset->Seconds + 1U; + + if( READ_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSSR ) == ETH_PTPTSCR_TSSSR ) + { + /* Set nanoSeconds update */ + heth->Instance->PTPTSLUR = ETH_PTPTSLR_VALUE - timeoffset->NanoSeconds; + } + else + { + heth->Instance->PTPTSLUR = ETH_PTPTSHR_VALUE - timeoffset->NanoSeconds + 1U; + } + } + else + { + /* Set Seconds update */ + heth->Instance->PTPTSHUR = timeoffset->Seconds; + /* Set nanoSeconds update */ + heth->Instance->PTPTSLUR = timeoffset->NanoSeconds; + } + + SET_BIT( heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTU ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Insert Timestamp in transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Enable Time Stamp transmission */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_TTSE ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get transmission timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * transmission timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t idx = dmatxdesclist->releaseIndex; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ idx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = dmatxdesc->DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = dmatxdesc->DESC1; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get receive timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * receive timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Register the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txPtpCallback: Function to handle Ptp transmission + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ) + { + if( txPtpCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set Function to handle Tx Ptp */ + heth->txPtpCallback = txPtpCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txPtpCallback = HAL_ETH_TxPtpCallback; + + return HAL_OK; + } + +/** + * @brief Tx Ptp callback. + * @param buff: pointer to application buffer + * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains + * transmission timestamp + * @retval None + */ + __weak void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxPtpCallback could be implemented in the user file + */ + } + #endif /* HAL_ETH_USE_PTP */ + +/** + * @brief This function handles ETH interrupt request. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ) + { + uint32_t mac_flag = READ_REG( heth->Instance->MACSR ); + uint32_t dma_flag = READ_REG( heth->Instance->DMASR ); + uint32_t dma_itsource = READ_REG( heth->Instance->DMAIER ); + uint32_t exti_flag = READ_REG( EXTI->PR ); + + /* Packet received */ + if( ( ( dma_flag & ETH_DMASR_RS ) != 0U ) && ( ( dma_itsource & ETH_DMAIER_RIE ) != 0U ) ) + { + /* Clear the Eth DMA Rx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMASR_RS | ETH_DMASR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Receive complete callback*/ + heth->RxCpltCallback( heth ); + #else + /* Receive complete callback */ + HAL_ETH_RxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* Packet transmitted */ + if( ( ( dma_flag & ETH_DMASR_TS ) != 0U ) && ( ( dma_itsource & ETH_DMAIER_TIE ) != 0U ) ) + { + /* Clear the Eth DMA Tx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMASR_TS | ETH_DMASR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Transmit complete callback*/ + heth->TxCpltCallback( heth ); + #else + /* Transfer complete callback */ + HAL_ETH_TxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* ETH DMA Error */ + if( ( ( dma_flag & ETH_DMASR_AIS ) != 0U ) && ( ( dma_itsource & ETH_DMAIER_AISE ) != 0U ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + + /* if fatal bus error occurred */ + if( ( dma_flag & ETH_DMASR_FBES ) != 0U ) + { + /* Get DMA error code */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMASR, ( ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS ) ); + + /* Disable all interrupts */ + __HAL_ETH_DMA_DISABLE_IT( heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE ); + + /* Set HAL state to ERROR */ + heth->gState = HAL_ETH_STATE_ERROR; + } + else + { + /* Get DMA error status */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMASR, ( ETH_DMASR_ETS | ETH_DMASR_RWTS | + ETH_DMASR_RBUS | ETH_DMASR_AIS ) ); + + /* Clear the interrupt summary flag */ + __HAL_ETH_DMA_CLEAR_IT( heth, ( ETH_DMASR_ETS | ETH_DMASR_RWTS | + ETH_DMASR_RBUS | ETH_DMASR_AIS ) ); + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered Error callback*/ + heth->ErrorCallback( heth ); + #else + /* Ethernet DMA Error callback */ + HAL_ETH_ErrorCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* ETH PMT IT */ + if( ( mac_flag & ETH_MAC_PMT_IT ) != 0U ) + { + /* Get MAC Wake-up source and clear the status register pending bit */ + heth->MACWakeUpEvent = READ_BIT( heth->Instance->MACPMTCSR, ( ETH_MACPMTCSR_WFR | ETH_MACPMTCSR_MPR ) ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered PMT callback*/ + heth->PMTCallback( heth ); + #else + /* Ethernet PMT callback */ + HAL_ETH_PMTCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACWakeUpEvent = ( uint32_t ) ( 0x0U ); + } + + /* check ETH WAKEUP exti flag */ + if( ( exti_flag & ETH_WAKEUP_EXTI_LINE ) != 0U ) + { + /* Clear ETH WAKEUP Exti pending bit */ + __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( ETH_WAKEUP_EXTI_LINE ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered WakeUp callback*/ + heth->WakeUpCallback( heth ); + #else + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + +/** + * @brief Tx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Rx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet transfer error callbacks + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_ErrorCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet Power Management module IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_PMTCallback could be implemented in the user file + */ + } + + +/** + * @brief ETH WAKEUP interrupt callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_WakeUpCallback could be implemented in the user file + */ + } + +/** + * @brief Read a PHY register + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param pRegValue: parameter to hold read value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ) + { + uint32_t tmpreg1; + uint32_t tickstart; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg1 = heth->Instance->MACMIIAR; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + /* Prepare the MII address register value */ + tmpreg1 |= ( ( PHYAddr << 11U ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */ + tmpreg1 |= ( ( ( uint32_t ) PHYReg << 6U ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */ + tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */ + tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ + + /* Write the result value into the MII Address register */ + heth->Instance->MACMIIAR = tmpreg1; + + + tickstart = HAL_GetTick(); + + /* Check for the Busy flag */ + while( ( tmpreg1 & ETH_MACMIIAR_MB ) == ETH_MACMIIAR_MB ) + { + /* Check for the Timeout */ + if( ( HAL_GetTick() - tickstart ) > PHY_READ_TO ) + { + return HAL_ERROR; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + /* Get MACMIIDR value */ + *pRegValue = ( uint16_t ) ( heth->Instance->MACMIIDR ); + + return HAL_OK; + } + +/** + * @brief Writes to a PHY register. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param RegValue: the value to write + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ) + { + uint32_t tmpreg1; + uint32_t tickstart; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg1 = heth->Instance->MACMIIAR; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + /* Prepare the MII register address value */ + tmpreg1 |= ( ( PHYAddr << 11U ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */ + tmpreg1 |= ( ( ( uint32_t ) PHYReg << 6U ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */ + tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */ + tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ + + /* Give the value to the MII data register */ + heth->Instance->MACMIIDR = ( uint16_t ) RegValue; + + /* Write the result value into the MII Address register */ + heth->Instance->MACMIIAR = tmpreg1; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check for the Busy flag */ + while( ( tmpreg1 & ETH_MACMIIAR_MB ) == ETH_MACMIIAR_MB ) + { + /* Check for the Timeout */ + if( ( HAL_GetTick() - tickstart ) > PHY_WRITE_TO ) + { + return HAL_ERROR; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions - * @brief ETH control functions - * -@verbatim - ============================================================================== - ##### Peripheral Control functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to control the ETH - peripheral. - -@endverbatim - * @{ - */ -/** - * @brief Get the configuration of the MAC and MTL subsystems. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold - * the configuration of the MAC. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - /* Get MAC parameters */ - macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE; - macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL); - macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_RD) >> 9) == 0U) ? ENABLE : DISABLE; - macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSD) >> 16) > 0U) - ? ENABLE : DISABLE; - macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ROD) >> 13) == 0U) ? ENABLE : DISABLE; - macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE; - macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM); - macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES); - macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 22) == 0U) ? ENABLE : DISABLE; - macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 23) == 0U) ? ENABLE : DISABLE; - macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_APCS) >> 7) > 0U) ? ENABLE : DISABLE; - macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IFG); - macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPCO) >> 10U) > 0U) ? ENABLE : DISABLE; - macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSTF) >> 25U) > 0U) ? ENABLE : DISABLE; - - macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_TFCE) >> 1) > 0U) ? ENABLE : DISABLE; - macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_ZQPD) >> 7) == 0U) ? ENABLE : DISABLE; - macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PLT); - macconf->PauseTime = (READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PT) >> 16); - macconf->ReceiveFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_RFCE) >> 2U) > 0U) ? ENABLE : DISABLE; - macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_UPFD) >> 3U) > 0U) - ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Get the configuration of the DMA. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMABMR, - (ETH_DMAARBITRATION_RXPRIORTX | ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1)); - dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_AAB) >> 25U) > 0U) ? ENABLE : DISABLE; - dmaconf->BurstMode = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_FB | ETH_DMABMR_MB); - dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_RDP); - dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_PBL); - dmaconf->EnhancedDescriptorFormat = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_EDE) >> 7) > 0U) ? ENABLE : DISABLE; - dmaconf->DescriptorSkipLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_DSL) >> 2; - - dmaconf->DropTCPIPChecksumErrorFrame = ((READ_BIT(heth->Instance->DMAOMR, - ETH_DMAOMR_DTCEFD) >> 26) > 0U) ? DISABLE : ENABLE; - dmaconf->ReceiveStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RSF) >> 25) > 0U) ? ENABLE : DISABLE; - dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FTF) >> 20) > 0U) ? DISABLE : ENABLE; - dmaconf->TransmitStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TSF) >> 21) > 0U) ? ENABLE : DISABLE; - dmaconf->TransmitThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TTC); - dmaconf->ForwardErrorFrames = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FEF) >> 7) > 0U) ? ENABLE : DISABLE; - dmaconf->ForwardUndersizedGoodFrames = ((READ_BIT(heth->Instance->DMAOMR, - ETH_DMAOMR_FUGF) >> 6) > 0U) ? ENABLE : DISABLE; - dmaconf->ReceiveThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RTC); - dmaconf->SecondFrameOperate = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_OSF) >> 2) > 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Set the MAC configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains - * the configuration of the MAC. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetMACConfig(heth, macconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Set the ETH DMA configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetDMAConfig(heth, dmaconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Configures the Clock range of ETH MDIO interface. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth) -{ - uint32_t hclk; - uint32_t tmpreg; - - /* Get the ETHERNET MACMIIAR value */ - tmpreg = (heth->Instance)->MACMIIAR; - /* Clear CSR Clock Range CR[2:0] bits */ - tmpreg &= ETH_MACMIIAR_CR_MASK; - - /* Get hclk frequency value */ - hclk = HAL_RCC_GetHCLKFreq(); - - /* Set CR bits depending on hclk value */ - if (hclk < 35000000U) - { - /* CSR Clock Range between 0-35 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16; - } - else if (hclk < 60000000U) - { - /* CSR Clock Range between 35-60 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26; - } - else if (hclk < 100000000U) - { - /* CSR Clock Range between 60-100 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42; - } - else if (hclk < 150000000U) - { - /* CSR Clock Range between 100-150 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62; - } - else /* (hclk >= 150000000) */ - { - /* CSR Clock >= 150 MHz */ - tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102; - } - - /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ - (heth->Instance)->MACMIIAR = (uint32_t)tmpreg; -} - -/** - * @brief Set the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - uint32_t filterconfig; - uint32_t tmpreg1; - - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode | - ((uint32_t)pFilterConfig->HashUnicast << 1) | - ((uint32_t)pFilterConfig->HashMulticast << 2) | - ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) | - ((uint32_t)pFilterConfig->PassAllMulticast << 4) | - ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) | - ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) | - ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) | - ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) | - ((uint32_t)pFilterConfig->ReceiveAllMode << 31) | - pFilterConfig->ControlPacketsFilter); - - MODIFY_REG(heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFFR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFFR = tmpreg1; - - return HAL_OK; -} - -/** - * @brief Get the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PM)) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HU) >> 1) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HM) >> 2) > 0U) ? ENABLE : DISABLE; - pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR, - ETH_MACFFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE; - pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PAM) >> 4) > 0U) ? ENABLE : DISABLE; - pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_BFD) >> 5) == 0U) ? ENABLE : DISABLE; - pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PCF); - pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR, - ETH_MACFFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE; - pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HPF) >> 10) > 0U) - ? ENABLE : DISABLE; - pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_RA) >> 31) > 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Set the source MAC Address to be matched. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param AddrNbr: The MAC address to configure - * This parameter must be a value of the following: - * ETH_MAC_ADDRESS1 - * ETH_MAC_ADDRESS2 - * ETH_MAC_ADDRESS3 - * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr) -{ - uint32_t macaddrlr; - uint32_t macaddrhr; - - if (pMACAddr == NULL) - { - return HAL_ERROR; - } - - /* Get mac addr high reg offset */ - macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr); - /* Get mac addr low reg offset */ - macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr); - - /* Set MAC addr bits 32 to 47 */ - (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]); - /* Set MAC addr bits 0 to 31 */ - (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) | - ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]); - - /* Enable address and set source address bit */ - (*(__IO uint32_t *)macaddrhr) |= (ETH_MACA1HR_AE | ETH_MACA1HR_SA); - - return HAL_OK; -} - -/** - * @brief Set the ETH Hash Table Value. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pHashTable: pointer to a table of two 32 bit values, that contains - * the 64 bits of the hash table. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable) -{ - uint32_t tmpreg1; - if (pHashTable == NULL) - { - return HAL_ERROR; - } - - heth->Instance->MACHTHR = pHashTable[0]; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACHTHR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACHTHR = tmpreg1; - - heth->Instance->MACHTLR = pHashTable[1]; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACHTLR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACHTLR = tmpreg1; - - return HAL_OK; -} - -/** - * @brief Set the VLAN Identifier for Rx packets - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ComparisonBits: 12 or 16 bit comparison mode - must be a value of @ref ETH_VLAN_Tag_Comparison - * @param VLANIdentifier: VLAN Identifier value - * @retval None - */ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier) -{ - uint32_t tmpreg1; - MODIFY_REG(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier); - if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) - { - CLEAR_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC); - } - else - { - SET_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC); - } - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACVLANTR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACVLANTR = tmpreg1; -} - -/** - * @brief Enters the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure - * that contains the Power Down configuration - * @retval None. - */ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig) -{ - uint32_t powerdownconfig; - - powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << ETH_MACPMTCSR_MPE_Pos) | - ((uint32_t)pPowerDownConfig->WakeUpPacket << ETH_MACPMTCSR_WFE_Pos) | - ((uint32_t)pPowerDownConfig->GlobalUnicast << ETH_MACPMTCSR_GU_Pos) | - ETH_MACPMTCSR_PD); - - MODIFY_REG(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_MASK, powerdownconfig); -} - -/** - * @brief Exits from the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg1; - - /* clear wake up sources */ - CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACPMTCSR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACPMTCSR = tmpreg1; - - if (READ_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD) != 0U) - { - /* Exit power down mode */ - CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACPMTCSR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACPMTCSR = tmpreg1; - } - - /* Disable PMT interrupt */ - SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_PMTIM); -} - -/** - * @brief Set the WakeUp filter. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilter: pointer to filter registers values - * @param Count: number of filter registers, must be from 1 to 8. - * @retval None. - */ -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count) -{ - uint32_t regindex; - - if (pFilter == NULL) - { - return HAL_ERROR; - } - - /* Reset Filter Pointer */ - SET_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFFRPR); - - /* Wake up packet filter config */ - for (regindex = 0; regindex < Count; regindex++) - { - /* Write filter regs */ - WRITE_REG(heth->Instance->MACRWUFFR, pFilter[regindex]); - } - - return HAL_OK; -} - -/** - * @} - */ + * @brief ETH control functions + * + * @verbatim + * ============================================================================== + ##### Peripheral Control functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to control the ETH + #####peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Get the configuration of the MAC and MTL subsystems. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold + * the configuration of the MAC. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetMACConfig( const ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + /* Get MAC parameters */ + macconf->DeferralCheck = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DC ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + macconf->BackOffLimit = READ_BIT( heth->Instance->MACCR, ETH_MACCR_BL ); + macconf->RetryTransmission = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_RD ) >> 9 ) == 0U ) ? ENABLE : DISABLE; + macconf->CarrierSenseDuringTransmit = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_CSD ) >> 16 ) > 0U ) + ? ENABLE : DISABLE; + macconf->ReceiveOwn = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_ROD ) >> 13 ) == 0U ) ? ENABLE : DISABLE; + macconf->LoopbackMode = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_LM ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + macconf->DuplexMode = READ_BIT( heth->Instance->MACCR, ETH_MACCR_DM ); + macconf->Speed = READ_BIT( heth->Instance->MACCR, ETH_MACCR_FES ); + macconf->Jabber = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_JD ) >> 22 ) == 0U ) ? ENABLE : DISABLE; + macconf->Watchdog = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_WD ) >> 23 ) == 0U ) ? ENABLE : DISABLE; + macconf->AutomaticPadCRCStrip = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_APCS ) >> 7 ) > 0U ) ? ENABLE : DISABLE; + macconf->InterPacketGapVal = READ_BIT( heth->Instance->MACCR, ETH_MACCR_IFG ); + macconf->ChecksumOffload = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_IPCO ) >> 10U ) > 0U ) ? ENABLE : DISABLE; + macconf->CRCStripTypePacket = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_CSTF ) >> 25U ) > 0U ) ? ENABLE : DISABLE; + + macconf->TransmitFlowControl = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_TFCE ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + macconf->ZeroQuantaPause = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_ZQPD ) >> 7 ) == 0U ) ? ENABLE : DISABLE; + macconf->PauseLowThreshold = READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_PLT ); + macconf->PauseTime = ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_PT ) >> 16 ); + macconf->ReceiveFlowControl = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_RFCE ) >> 2U ) > 0U ) ? ENABLE : DISABLE; + macconf->UnicastPausePacketDetect = ( ( READ_BIT( heth->Instance->MACFCR, ETH_MACFCR_UPFD ) >> 3U ) > 0U ) + ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Get the configuration of the DMA. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( const ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + dmaconf->DMAArbitration = READ_BIT( heth->Instance->DMABMR, + ( ETH_DMAARBITRATION_RXPRIORTX | ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1 ) ); + dmaconf->AddressAlignedBeats = ( ( READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_AAB ) >> 25U ) > 0U ) ? ENABLE : DISABLE; + dmaconf->BurstMode = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_FB | ETH_DMABMR_MB ); + dmaconf->RxDMABurstLength = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_RDP ); + dmaconf->TxDMABurstLength = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_PBL ); + dmaconf->EnhancedDescriptorFormat = ( ( READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_EDE ) >> 7 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->DescriptorSkipLength = READ_BIT( heth->Instance->DMABMR, ETH_DMABMR_DSL ) >> 2; + + dmaconf->DropTCPIPChecksumErrorFrame = ( ( READ_BIT( heth->Instance->DMAOMR, + ETH_DMAOMR_DTCEFD ) >> 26 ) > 0U ) ? DISABLE : ENABLE; + dmaconf->ReceiveStoreForward = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_RSF ) >> 25 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->FlushRxPacket = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_FTF ) >> 20 ) > 0U ) ? DISABLE : ENABLE; + dmaconf->TransmitStoreForward = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_TSF ) >> 21 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->TransmitThresholdControl = READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_TTC ); + dmaconf->ForwardErrorFrames = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_FEF ) >> 7 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->ForwardUndersizedGoodFrames = ( ( READ_BIT( heth->Instance->DMAOMR, + ETH_DMAOMR_FUGF ) >> 6 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->ReceiveThresholdControl = READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_RTC ); + dmaconf->SecondFrameOperate = ( ( READ_BIT( heth->Instance->DMAOMR, ETH_DMAOMR_OSF ) >> 2 ) > 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Set the MAC configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains + * the configuration of the MAC. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetMACConfig( heth, macconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Set the ETH DMA configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetDMAConfig( heth, dmaconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Configures the Clock range of ETH MDIO interface. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ) + { + uint32_t hclk; + uint32_t tmpreg; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg = ( heth->Instance )->MACMIIAR; + /* Clear CSR Clock Range CR[2:0] bits */ + tmpreg &= ETH_MACMIIAR_CR_MASK; + + /* Get hclk frequency value */ + hclk = HAL_RCC_GetHCLKFreq(); + + /* Set CR bits depending on hclk value */ + if( hclk < 35000000U ) + { + /* CSR Clock Range between 0-35 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div16; + } + else if( hclk < 60000000U ) + { + /* CSR Clock Range between 35-60 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26; + } + else if( hclk < 100000000U ) + { + /* CSR Clock Range between 60-100 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div42; + } + else if( hclk < 150000000U ) + { + /* CSR Clock Range between 100-150 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div62; + } + else /* (hclk >= 150000000) */ + { + /* CSR Clock >= 150 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div102; + } + + /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ + ( heth->Instance )->MACMIIAR = ( uint32_t ) tmpreg; + } + +/** + * @brief Set the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + uint32_t filterconfig; + uint32_t tmpreg1; + + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + filterconfig = ( ( uint32_t ) pFilterConfig->PromiscuousMode | + ( ( uint32_t ) pFilterConfig->HashUnicast << 1 ) | + ( ( uint32_t ) pFilterConfig->HashMulticast << 2 ) | + ( ( uint32_t ) pFilterConfig->DestAddrInverseFiltering << 3 ) | + ( ( uint32_t ) pFilterConfig->PassAllMulticast << 4 ) | + ( ( uint32_t ) ( ( pFilterConfig->BroadcastFilter == DISABLE ) ? 1U : 0U ) << 5 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrInverseFiltering << 8 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrFiltering << 9 ) | + ( ( uint32_t ) pFilterConfig->HachOrPerfectFilter << 10 ) | + ( ( uint32_t ) pFilterConfig->ReceiveAllMode << 31 ) | + pFilterConfig->ControlPacketsFilter ); + + MODIFY_REG( heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACFFR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACFFR = tmpreg1; + + return HAL_OK; + } + +/** + * @brief Get the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( const ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + pFilterConfig->PromiscuousMode = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_PM ) ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashUnicast = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_HU ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashMulticast = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_HM ) >> 2 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->DestAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACFFR, + ETH_MACFFR_DAIF ) >> 3 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->PassAllMulticast = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_PAM ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->BroadcastFilter = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_BFD ) >> 5 ) == 0U ) ? ENABLE : DISABLE; + pFilterConfig->ControlPacketsFilter = READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_PCF ); + pFilterConfig->SrcAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACFFR, + ETH_MACFFR_SAIF ) >> 8 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->SrcAddrFiltering = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_SAF ) >> 9 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HachOrPerfectFilter = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_HPF ) >> 10 ) > 0U ) + ? ENABLE : DISABLE; + pFilterConfig->ReceiveAllMode = ( ( READ_BIT( heth->Instance->MACFFR, ETH_MACFFR_RA ) >> 31 ) > 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Set the source MAC Address to be matched. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param AddrNbr: The MAC address to configure + * This parameter must be a value of the following: + * ETH_MAC_ADDRESS1 + * ETH_MAC_ADDRESS2 + * ETH_MAC_ADDRESS3 + * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ) + { + uint32_t macaddrlr; + uint32_t macaddrhr; + + if( pMACAddr == NULL ) + { + return HAL_ERROR; + } + + /* Get mac addr high reg offset */ + macaddrhr = ( ( uint32_t ) &( heth->Instance->MACA0HR ) + AddrNbr ); + /* Get mac addr low reg offset */ + macaddrlr = ( ( uint32_t ) &( heth->Instance->MACA0LR ) + AddrNbr ); + + /* Set MAC addr bits 32 to 47 */ + ( *( __IO uint32_t * ) macaddrhr ) = ( ( ( uint32_t ) ( pMACAddr[ 5 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 4 ] ); + /* Set MAC addr bits 0 to 31 */ + ( *( __IO uint32_t * ) macaddrlr ) = ( ( ( uint32_t ) ( pMACAddr[ 3 ] ) << 24 ) | ( ( uint32_t ) ( pMACAddr[ 2 ] ) << 16 ) | + ( ( uint32_t ) ( pMACAddr[ 1 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 0 ] ); + + /* Enable address and set source address bit */ + ( *( __IO uint32_t * ) macaddrhr ) |= ( ETH_MACA1HR_AE | ETH_MACA1HR_SA ); + + return HAL_OK; + } + +/** + * @brief Set the ETH Hash Table Value. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pHashTable: pointer to a table of two 32 bit values, that contains + * the 64 bits of the hash table. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ) + { + uint32_t tmpreg1; + + if( pHashTable == NULL ) + { + return HAL_ERROR; + } + + heth->Instance->MACHTHR = pHashTable[ 0 ]; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACHTHR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACHTHR = tmpreg1; + + heth->Instance->MACHTLR = pHashTable[ 1 ]; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACHTLR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACHTLR = tmpreg1; + + return HAL_OK; + } + +/** + * @brief Set the VLAN Identifier for Rx packets + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ComparisonBits: 12 or 16 bit comparison mode + * must be a value of @ref ETH_VLAN_Tag_Comparison + * @param VLANIdentifier: VLAN Identifier value + * @retval None + */ + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ) + { + uint32_t tmpreg1; + + MODIFY_REG( heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier ); + + if( ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT ) + { + CLEAR_BIT( heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC ); + } + else + { + SET_BIT( heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC ); + } + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACVLANTR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACVLANTR = tmpreg1; + } + +/** + * @brief Enters the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure + * that contains the Power Down configuration + * @retval None. + */ + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ) + { + uint32_t powerdownconfig; + + powerdownconfig = ( ( ( uint32_t ) pPowerDownConfig->MagicPacket << ETH_MACPMTCSR_MPE_Pos ) | + ( ( uint32_t ) pPowerDownConfig->WakeUpPacket << ETH_MACPMTCSR_WFE_Pos ) | + ( ( uint32_t ) pPowerDownConfig->GlobalUnicast << ETH_MACPMTCSR_GU_Pos ) | + ETH_MACPMTCSR_PD ); + + MODIFY_REG( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_MASK, powerdownconfig ); + } + +/** + * @brief Exits from the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ) + { + uint32_t tmpreg1; + + /* clear wake up sources */ + CLEAR_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACPMTCSR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACPMTCSR = tmpreg1; + + if( READ_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD ) != 0U ) + { + /* Exit power down mode */ + CLEAR_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD ); + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACPMTCSR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACPMTCSR = tmpreg1; + } + + /* Disable PMT interrupt */ + SET_BIT( heth->Instance->MACIMR, ETH_MACIMR_PMTIM ); + } + +/** + * @brief Set the WakeUp filter. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilter: pointer to filter registers values + * @param Count: number of filter registers, must be from 1 to 8. + * @retval None. + */ + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ) + { + uint32_t regindex; + + if( pFilter == NULL ) + { + return HAL_ERROR; + } + + /* Reset Filter Pointer */ + SET_BIT( heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFFRPR ); + + /* Wake up packet filter config */ + for( regindex = 0; regindex < Count; regindex++ ) + { + /* Write filter regs */ + WRITE_REG( heth->Instance->MACRWUFFR, pFilter[ regindex ] ); + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions - * @brief ETH State and Errors functions - * -@verbatim - ============================================================================== - ##### Peripheral State and Errors functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to return the State of - ETH communication process, return Peripheral Errors occurred during communication - process - - -@endverbatim - * @{ - */ - -/** - * @brief Returns the ETH state. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL state - */ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth) -{ - return heth->gState; -} - -/** - * @brief Returns the ETH error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH Error Code - */ -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth) -{ - return heth->ErrorCode; -} - -/** - * @brief Returns the ETH DMA error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH DMA Error Code - */ -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth) -{ - return heth->DMAErrorCode; -} - -/** - * @brief Returns the ETH MAC error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC Error Code - */ -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth) -{ - return heth->MACErrorCode; -} - -/** - * @brief Returns the ETH MAC WakeUp event source - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC WakeUp event source - */ -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth) -{ - return heth->MACWakeUpEvent; -} - -/** - * @} - */ - -/** - * @} - */ + * @brief ETH State and Errors functions + * + * @verbatim + * ============================================================================== + ##### Peripheral State and Errors functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to return the State of + #####ETH communication process, return Peripheral Errors occurred during communication + #####process + ##### + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Returns the ETH state. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL state + */ + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ) + { + return heth->gState; + } + +/** + * @brief Returns the ETH error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH Error Code + */ + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ) + { + return heth->ErrorCode; + } + +/** + * @brief Returns the ETH DMA error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH DMA Error Code + */ + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ) + { + return heth->DMAErrorCode; + } + +/** + * @brief Returns the ETH MAC error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC Error Code + */ + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ) + { + return heth->MACErrorCode; + } + +/** + * @brief Returns the ETH MAC WakeUp event source + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event source + */ + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ) + { + return heth->MACWakeUpEvent; + } + +/** + * @} + */ + +/** + * @} + */ /** @addtogroup ETH_Private_Functions ETH Private Functions - * @{ - */ - -/** - * @brief Clears the ETHERNET transmit FIFO. - * @param heth pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth) -{ - __IO uint32_t tmpreg = 0; - - /* Set the Flush Transmit FIFO bit */ - (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF; - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg = (heth->Instance)->DMAOMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMAOMR = tmpreg; -} - -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf) -{ - uint32_t tmpreg1; - - /*------------------------ ETHERNET MACCR Configuration --------------------*/ - /* Get the ETHERNET MACCR value */ - tmpreg1 = (heth->Instance)->MACCR; - /* Clear CSTF, WD, PCE, PS, TE and RE bits */ - tmpreg1 &= ETH_MACCR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)(((uint32_t)macconf->CRCStripTypePacket << 25U) | - ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 23U) | - ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 22U) | - (uint32_t)macconf->InterPacketGapVal | - ((uint32_t)macconf->CarrierSenseDuringTransmit << 16U) | - macconf->Speed | - ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 13U) | - ((uint32_t)macconf->LoopbackMode << 12U) | - macconf->DuplexMode | - ((uint32_t)macconf->ChecksumOffload << 10U) | - ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 9U) | - ((uint32_t)macconf->AutomaticPadCRCStrip << 7U) | - macconf->BackOffLimit | - ((uint32_t)macconf->DeferralCheck << 4U)); - - /* Write to ETHERNET MACCR */ - (heth->Instance)->MACCR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /*----------------------- ETHERNET MACFCR Configuration --------------------*/ - - /* Get the ETHERNET MACFCR value */ - tmpreg1 = (heth->Instance)->MACFCR; - /* Clear xx bits */ - tmpreg1 &= ETH_MACFCR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) | - ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7U) | - macconf->PauseLowThreshold | - ((uint32_t)((macconf->UnicastPausePacketDetect == ENABLE) ? 1U : 0U) << 3U) | - ((uint32_t)((macconf->ReceiveFlowControl == ENABLE) ? 1U : 0U) << 2U) | - ((uint32_t)((macconf->TransmitFlowControl == ENABLE) ? 1U : 0U) << 1U)); - - /* Write to ETHERNET MACFCR */ - (heth->Instance)->MACFCR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFCR = tmpreg1; -} - -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf) -{ - uint32_t tmpreg1; - - /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ - /* Get the ETHERNET DMAOMR value */ - tmpreg1 = (heth->Instance)->DMAOMR; - /* Clear xx bits */ - tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)(((uint32_t)((dmaconf->DropTCPIPChecksumErrorFrame == DISABLE) ? 1U : 0U) << 26U) | - ((uint32_t)dmaconf->ReceiveStoreForward << 25U) | - ((uint32_t)((dmaconf->FlushRxPacket == DISABLE) ? 1U : 0U) << 20U) | - ((uint32_t)dmaconf->TransmitStoreForward << 21U) | - dmaconf->TransmitThresholdControl | - ((uint32_t)dmaconf->ForwardErrorFrames << 7U) | - ((uint32_t)dmaconf->ForwardUndersizedGoodFrames << 6U) | - dmaconf->ReceiveThresholdControl | - ((uint32_t)dmaconf->SecondFrameOperate << 2U)); - - /* Write to ETHERNET DMAOMR */ - (heth->Instance)->DMAOMR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->DMAOMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMAOMR = tmpreg1; - - /*----------------------- ETHERNET DMABMR Configuration --------------------*/ - (heth->Instance)->DMABMR = (uint32_t)(((uint32_t)dmaconf->AddressAlignedBeats << 25U) | - dmaconf->BurstMode | - dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or - Rx it is applied for the other */ - dmaconf->TxDMABurstLength | - ((uint32_t)dmaconf->EnhancedDescriptorFormat << 7U) | - (dmaconf->DescriptorSkipLength << 2U) | - dmaconf->DMAArbitration | - ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->DMABMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMABMR = tmpreg1; -} - -/** - * @brief Configures Ethernet MAC and DMA with default parameters. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth) -{ - ETH_MACConfigTypeDef macDefaultConf; - ETH_DMAConfigTypeDef dmaDefaultConf; - - /*--------------- ETHERNET MAC registers default Configuration --------------*/ - macDefaultConf.Watchdog = ENABLE; - macDefaultConf.Jabber = ENABLE; - macDefaultConf.InterPacketGapVal = ETH_INTERFRAMEGAP_96BIT; - macDefaultConf.CarrierSenseDuringTransmit = DISABLE; - macDefaultConf.ReceiveOwn = ENABLE; - macDefaultConf.LoopbackMode = DISABLE; - macDefaultConf.CRCStripTypePacket = ENABLE; - macDefaultConf.ChecksumOffload = ENABLE; - macDefaultConf.RetryTransmission = DISABLE; - macDefaultConf.AutomaticPadCRCStrip = DISABLE; - macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; - macDefaultConf.DeferralCheck = DISABLE; - macDefaultConf.PauseTime = 0x0U; - macDefaultConf.ZeroQuantaPause = DISABLE; - macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4; - macDefaultConf.ReceiveFlowControl = DISABLE; - macDefaultConf.TransmitFlowControl = DISABLE; - macDefaultConf.Speed = ETH_SPEED_100M; - macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; - macDefaultConf.UnicastPausePacketDetect = DISABLE; - - /* MAC default configuration */ - ETH_SetMACConfig(heth, &macDefaultConf); - - /*--------------- ETHERNET DMA registers default Configuration --------------*/ - dmaDefaultConf.DropTCPIPChecksumErrorFrame = ENABLE; - dmaDefaultConf.ReceiveStoreForward = ENABLE; - dmaDefaultConf.FlushRxPacket = ENABLE; - dmaDefaultConf.TransmitStoreForward = ENABLE; - dmaDefaultConf.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; - dmaDefaultConf.ForwardErrorFrames = DISABLE; - dmaDefaultConf.ForwardUndersizedGoodFrames = DISABLE; - dmaDefaultConf.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; - dmaDefaultConf.SecondFrameOperate = ENABLE; - dmaDefaultConf.AddressAlignedBeats = ENABLE; - dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; - dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.EnhancedDescriptorFormat = ENABLE; - dmaDefaultConf.DescriptorSkipLength = 0x0U; - dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; - - /* DMA default configuration */ - ETH_SetDMAConfig(heth, &dmaDefaultConf); -} -/** - * @brief Configures the selected MAC address. - * @param heth pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param MacAddr The MAC address to configure - * This parameter can be one of the following values: - * @arg ETH_MAC_Address0: MAC Address0 - * @arg ETH_MAC_Address1: MAC Address1 - * @arg ETH_MAC_Address2: MAC Address2 - * @arg ETH_MAC_Address3: MAC Address3 - * @param Addr Pointer to MAC address buffer data (6 bytes) - * @retval HAL status - */ -static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr) -{ - uint32_t tmpreg1; - - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - - /* Calculate the selected MAC address high register */ - tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U]; - /* Load the selected MAC address high register */ - (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1; - /* Calculate the selected MAC address low register */ - tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U]; - - /* Load the selected MAC address low register */ - (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1; -} - -/** - * @brief Initializes the DMA Tx descriptors. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmatxdesc; - uint32_t i; - - /* Fill each DMATxDesc descriptor with the right values */ - for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++) - { - dmatxdesc = heth->Init.TxDesc + i; - - WRITE_REG(dmatxdesc->DESC0, 0x0U); - WRITE_REG(dmatxdesc->DESC1, 0x0U); - WRITE_REG(dmatxdesc->DESC2, 0x0U); - WRITE_REG(dmatxdesc->DESC3, 0x0U); - - WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc); - - /* Set Second Address Chained bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TCH); - - if (i < ((uint32_t)ETH_TX_DESC_CNT - 1U)) - { - WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc + i + 1U)); - } - else - { - WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc)); - } - - /* Set the DMA Tx descriptors checksum insertion */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL); - } - - heth->TxDescList.CurTxDesc = 0; - - /* Set Transmit Descriptor List Address */ - WRITE_REG(heth->Instance->DMATDLAR, (uint32_t) heth->Init.TxDesc); -} - -/** - * @brief Initializes the DMA Rx descriptors in chain mode. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t i; - - for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) - { - dmarxdesc = heth->Init.RxDesc + i; - - WRITE_REG(dmarxdesc->DESC0, 0x0U); - WRITE_REG(dmarxdesc->DESC1, 0x0U); - WRITE_REG(dmarxdesc->DESC2, 0x0U); - WRITE_REG(dmarxdesc->DESC3, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr0, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr1, 0x0U); - - /* Set Own bit of the Rx descriptor Status */ - dmarxdesc->DESC0 = ETH_DMARXDESC_OWN; - - /* Set Buffer1 size and Second Address Chained bit */ - dmarxdesc->DESC1 = heth->Init.RxBuffLen | ETH_DMARXDESC_RCH; - - /* Enable Ethernet DMA Rx Descriptor interrupt */ - dmarxdesc->DESC1 &= ~ETH_DMARXDESC_DIC; - /* Set Rx descritors addresses */ - WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc); - - if (i < ((uint32_t)ETH_RX_DESC_CNT - 1U)) - { - WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc + i + 1U)); - } - else - { - WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc)); - } - } - - WRITE_REG(heth->RxDescList.RxDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxDescCnt, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U); - WRITE_REG(heth->RxDescList.ItMode, 0U); - - /* Set Receive Descriptor List Address */ - WRITE_REG(heth->Instance->DMARDLAR, (uint32_t) heth->Init.RxDesc); -} - -/** - * @brief Prepare Tx DMA descriptor before transmission. - * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Tx packet configuration - * @param ItMode: Enable or disable Tx EOT interrept - * @retval Status - */ -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, - uint32_t ItMode) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - uint32_t firstdescidx = dmatxdesclist->CurTxDesc; - uint32_t idx; - uint32_t descnbr = 0; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer; - uint32_t bd_count = 0; - uint32_t primask_bit; - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - return HAL_ETH_ERROR_BUSY; - } - - - descnbr += 1U; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer); - - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len); - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U) - { - MODIFY_REG(dmatxdesc->DESC0, ETH_DMATXDESC_CIC, pTxConfig->ChecksumCtrl); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != 0U) - { - MODIFY_REG(dmatxdesc->DESC0, ETH_CRC_PAD_DISABLE, pTxConfig->CRCPadCtrl); - } - - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U) - { - /* Set Vlan Type */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_VF); - } - - /* Mark it as First Descriptor */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS); - - /* only if the packet is split into more than one descriptors > 1 */ - while (txbuffer->next != NULL) - { - /* Clear the LD bit of previous descriptor */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS); - if (ItMode != ((uint32_t)RESET)) - { - /* Set Interrupt on completion bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - else - { - /* Clear Interrupt on completion bit */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - descidx = firstdescidx; - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* clear previous desc own bit */ - for (idx = 0; idx < descnbr; idx ++) - { - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN); - - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - } - - return HAL_ETH_ERROR_BUSY; - } - - /* Clear the FD bit of new Descriptor */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS); - - descnbr += 1U; - - /* Get the next Tx buffer in the list */ - txbuffer = txbuffer->next; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer); - - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len); - - bd_count += 1U; - - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Set Own bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN); - } - - if (ItMode != ((uint32_t)RESET)) - { - /* Set Interrupt on completion bit */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - else - { - /* Clear Interrupt on completion bit */ - CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC); - } - - /* Mark it as LAST descriptor */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS); - - /* Get address of first descriptor */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx]; - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* set OWN bit of FIRST descriptor */ - SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN); - /* Save the current packet address to expose it to the application */ - dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress; - - dmatxdesclist->CurTxDesc = descidx; - - /* Enter critical section */ - primask_bit = __get_PRIMASK(); - __set_PRIMASK(1); - - dmatxdesclist->BuffersInUse += bd_count + 1U; - - /* Exit critical section: restore previous priority mask */ - __set_PRIMASK(primask_bit); - - /* Return function status */ - return HAL_ETH_ERROR_NONE; -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth) -{ - /* Init the ETH Callback settings */ - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ - heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ - heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ -#ifdef HAL_ETH_USE_PTP - heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ -#endif /* HAL_ETH_USE_PTP */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ + * @{ + */ + +/** + * @brief Clears the ETHERNET transmit FIFO. + * @param heth pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_FlushTransmitFIFO( ETH_HandleTypeDef * heth ) + { + __IO uint32_t tmpreg = 0; + + /* Set the Flush Transmit FIFO bit */ + ( heth->Instance )->DMAOMR |= ETH_DMAOMR_FTF; + + /* Wait until the write operation will be taken into account: + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg = ( heth->Instance )->DMAOMR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->DMAOMR = tmpreg; + } + + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + const ETH_MACConfigTypeDef * macconf ) + { + uint32_t tmpreg1; + + /*------------------------ ETHERNET MACCR Configuration --------------------*/ + /* Get the ETHERNET MACCR value */ + tmpreg1 = ( heth->Instance )->MACCR; + /* Clear CSTF, WD, PCE, PS, TE and RE bits */ + tmpreg1 &= ETH_MACCR_CLEAR_MASK; + + tmpreg1 |= ( uint32_t ) ( ( ( uint32_t ) macconf->CRCStripTypePacket << 25U ) | + ( ( uint32_t ) ( ( macconf->Watchdog == DISABLE ) ? 1U : 0U ) << 23U ) | + ( ( uint32_t ) ( ( macconf->Jabber == DISABLE ) ? 1U : 0U ) << 22U ) | + ( uint32_t ) macconf->InterPacketGapVal | + ( ( uint32_t ) macconf->CarrierSenseDuringTransmit << 16U ) | + macconf->Speed | + ( ( uint32_t ) ( ( macconf->ReceiveOwn == DISABLE ) ? 1U : 0U ) << 13U ) | + ( ( uint32_t ) macconf->LoopbackMode << 12U ) | + macconf->DuplexMode | + ( ( uint32_t ) macconf->ChecksumOffload << 10U ) | + ( ( uint32_t ) ( ( macconf->RetryTransmission == DISABLE ) ? 1U : 0U ) << 9U ) | + ( ( uint32_t ) macconf->AutomaticPadCRCStrip << 7U ) | + macconf->BackOffLimit | + ( ( uint32_t ) macconf->DeferralCheck << 4U ) ); + + /* Write to ETHERNET MACCR */ + ( heth->Instance )->MACCR = ( uint32_t ) tmpreg1; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACCR = tmpreg1; + + /*----------------------- ETHERNET MACFCR Configuration --------------------*/ + + /* Get the ETHERNET MACFCR value */ + tmpreg1 = ( heth->Instance )->MACFCR; + /* Clear xx bits */ + tmpreg1 &= ETH_MACFCR_CLEAR_MASK; + + tmpreg1 |= ( uint32_t ) ( ( macconf->PauseTime << 16U ) | + ( ( uint32_t ) ( ( macconf->ZeroQuantaPause == DISABLE ) ? 1U : 0U ) << 7U ) | + macconf->PauseLowThreshold | + ( ( uint32_t ) ( ( macconf->UnicastPausePacketDetect == ENABLE ) ? 1U : 0U ) << 3U ) | + ( ( uint32_t ) ( ( macconf->ReceiveFlowControl == ENABLE ) ? 1U : 0U ) << 2U ) | + ( ( uint32_t ) ( ( macconf->TransmitFlowControl == ENABLE ) ? 1U : 0U ) << 1U ) ); + + /* Write to ETHERNET MACFCR */ + ( heth->Instance )->MACFCR = ( uint32_t ) tmpreg1; + + /* Wait until the write operation will be taken into account : + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->MACFCR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->MACFCR = tmpreg1; + } + + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + const ETH_DMAConfigTypeDef * dmaconf ) + { + uint32_t tmpreg1; + + /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ + /* Get the ETHERNET DMAOMR value */ + tmpreg1 = ( heth->Instance )->DMAOMR; + /* Clear xx bits */ + tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; + + tmpreg1 |= ( uint32_t ) ( ( ( uint32_t ) ( ( dmaconf->DropTCPIPChecksumErrorFrame == DISABLE ) ? 1U : 0U ) << 26U ) | + ( ( uint32_t ) dmaconf->ReceiveStoreForward << 25U ) | + ( ( uint32_t ) ( ( dmaconf->FlushRxPacket == DISABLE ) ? 1U : 0U ) << 20U ) | + ( ( uint32_t ) dmaconf->TransmitStoreForward << 21U ) | + dmaconf->TransmitThresholdControl | + ( ( uint32_t ) dmaconf->ForwardErrorFrames << 7U ) | + ( ( uint32_t ) dmaconf->ForwardUndersizedGoodFrames << 6U ) | + dmaconf->ReceiveThresholdControl | + ( ( uint32_t ) dmaconf->SecondFrameOperate << 2U ) ); + + /* Write to ETHERNET DMAOMR */ + ( heth->Instance )->DMAOMR = ( uint32_t ) tmpreg1; + + /* Wait until the write operation will be taken into account: + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->DMAOMR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->DMAOMR = tmpreg1; + + /*----------------------- ETHERNET DMABMR Configuration --------------------*/ + ( heth->Instance )->DMABMR = ( uint32_t ) ( ( ( uint32_t ) dmaconf->AddressAlignedBeats << 25U ) | + dmaconf->BurstMode | + dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or + * Rx it is applied for the other */ + dmaconf->TxDMABurstLength | + ( ( uint32_t ) dmaconf->EnhancedDescriptorFormat << 7U ) | + ( dmaconf->DescriptorSkipLength << 2U ) | + dmaconf->DMAArbitration | + ETH_DMABMR_USP ); /* Enable use of separate PBL for Rx and Tx */ + + /* Wait until the write operation will be taken into account: + * at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = ( heth->Instance )->DMABMR; + HAL_Delay( ETH_REG_WRITE_DELAY ); + ( heth->Instance )->DMABMR = tmpreg1; + } + +/** + * @brief Configures Ethernet MAC and DMA with default parameters. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ) + { + ETH_MACConfigTypeDef macDefaultConf; + ETH_DMAConfigTypeDef dmaDefaultConf; + + /*--------------- ETHERNET MAC registers default Configuration --------------*/ + macDefaultConf.Watchdog = ENABLE; + macDefaultConf.Jabber = ENABLE; + macDefaultConf.InterPacketGapVal = ETH_INTERFRAMEGAP_96BIT; + macDefaultConf.CarrierSenseDuringTransmit = DISABLE; + macDefaultConf.ReceiveOwn = ENABLE; + macDefaultConf.LoopbackMode = DISABLE; + macDefaultConf.CRCStripTypePacket = ENABLE; + macDefaultConf.ChecksumOffload = ENABLE; + macDefaultConf.RetryTransmission = DISABLE; + macDefaultConf.AutomaticPadCRCStrip = DISABLE; + macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; + macDefaultConf.DeferralCheck = DISABLE; + macDefaultConf.PauseTime = 0x0U; + macDefaultConf.ZeroQuantaPause = DISABLE; + macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4; + macDefaultConf.ReceiveFlowControl = DISABLE; + macDefaultConf.TransmitFlowControl = DISABLE; + macDefaultConf.Speed = ETH_SPEED_100M; + macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; + macDefaultConf.UnicastPausePacketDetect = DISABLE; + + /* MAC default configuration */ + ETH_SetMACConfig( heth, &macDefaultConf ); + + /*--------------- ETHERNET DMA registers default Configuration --------------*/ + dmaDefaultConf.DropTCPIPChecksumErrorFrame = ENABLE; + dmaDefaultConf.ReceiveStoreForward = ENABLE; + dmaDefaultConf.FlushRxPacket = ENABLE; + dmaDefaultConf.TransmitStoreForward = ENABLE; + dmaDefaultConf.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; + dmaDefaultConf.ForwardErrorFrames = DISABLE; + dmaDefaultConf.ForwardUndersizedGoodFrames = DISABLE; + dmaDefaultConf.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; + dmaDefaultConf.SecondFrameOperate = ENABLE; + dmaDefaultConf.AddressAlignedBeats = ENABLE; + dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; + dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.EnhancedDescriptorFormat = ENABLE; + dmaDefaultConf.DescriptorSkipLength = 0x0U; + dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; + + /* DMA default configuration */ + ETH_SetDMAConfig( heth, &dmaDefaultConf ); + } + +/** + * @brief Configures the selected MAC address. + * @param heth pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param MacAddr The MAC address to configure + * This parameter can be one of the following values: + * @arg ETH_MAC_Address0: MAC Address0 + * @arg ETH_MAC_Address1: MAC Address1 + * @arg ETH_MAC_Address2: MAC Address2 + * @arg ETH_MAC_Address3: MAC Address3 + * @param Addr Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ + static void ETH_MACAddressConfig( ETH_HandleTypeDef * heth, + uint32_t MacAddr, + uint8_t * Addr ) + { + uint32_t tmpreg1; + + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* Calculate the selected MAC address high register */ + tmpreg1 = ( ( uint32_t ) Addr[ 5U ] << 8U ) | ( uint32_t ) Addr[ 4U ]; + /* Load the selected MAC address high register */ + ( *( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + MacAddr ) ) ) = tmpreg1; + /* Calculate the selected MAC address low register */ + tmpreg1 = ( ( uint32_t ) Addr[ 3U ] << 24U ) | ( ( uint32_t ) Addr[ 2U ] << 16U ) | ( ( uint32_t ) Addr[ 1U ] << 8U ) | Addr[ 0U ]; + + /* Load the selected MAC address low register */ + ( *( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + MacAddr ) ) ) = tmpreg1; + } + +/** + * @brief Initializes the DMA Tx descriptors. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmatxdesc; + uint32_t i; + + /* Fill each DMATxDesc descriptor with the right values */ + for( i = 0; i < ( uint32_t ) ETH_TX_DESC_CNT; i++ ) + { + dmatxdesc = heth->Init.TxDesc + i; + + WRITE_REG( dmatxdesc->DESC0, 0x0U ); + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + WRITE_REG( dmatxdesc->DESC2, 0x0U ); + WRITE_REG( dmatxdesc->DESC3, 0x0U ); + + WRITE_REG( heth->TxDescList.TxDesc[ i ], ( uint32_t ) dmatxdesc ); + + /* Set Second Address Chained bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_TCH ); + + if( i < ( ( uint32_t ) ETH_TX_DESC_CNT - 1U ) ) + { + WRITE_REG( dmatxdesc->DESC3, ( uint32_t ) ( heth->Init.TxDesc + i + 1U ) ); + } + else + { + WRITE_REG( dmatxdesc->DESC3, ( uint32_t ) ( heth->Init.TxDesc ) ); + } + + /* Set the DMA Tx descriptors checksum insertion */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL ); + } + + heth->TxDescList.CurTxDesc = 0; + + /* Set Transmit Descriptor List Address */ + WRITE_REG( heth->Instance->DMATDLAR, ( uint32_t ) heth->Init.TxDesc ); + } + +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmarxdesc; + uint32_t i; + + for( i = 0; i < ( uint32_t ) ETH_RX_DESC_CNT; i++ ) + { + dmarxdesc = heth->Init.RxDesc + i; + + WRITE_REG( dmarxdesc->DESC0, 0x0U ); + WRITE_REG( dmarxdesc->DESC1, 0x0U ); + WRITE_REG( dmarxdesc->DESC2, 0x0U ); + WRITE_REG( dmarxdesc->DESC3, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr0, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr1, 0x0U ); + + /* Set Own bit of the Rx descriptor Status */ + dmarxdesc->DESC0 = ETH_DMARXDESC_OWN; + + /* Set Buffer1 size and Second Address Chained bit */ + dmarxdesc->DESC1 = heth->Init.RxBuffLen | ETH_DMARXDESC_RCH; + + /* Enable Ethernet DMA Rx Descriptor interrupt */ + dmarxdesc->DESC1 &= ~ETH_DMARXDESC_DIC; + /* Set Rx descritors addresses */ + WRITE_REG( heth->RxDescList.RxDesc[ i ], ( uint32_t ) dmarxdesc ); + + if( i < ( ( uint32_t ) ETH_RX_DESC_CNT - 1U ) ) + { + WRITE_REG( dmarxdesc->DESC3, ( uint32_t ) ( heth->Init.RxDesc + i + 1U ) ); + } + else + { + WRITE_REG( dmarxdesc->DESC3, ( uint32_t ) ( heth->Init.RxDesc ) ); + } + } + + WRITE_REG( heth->RxDescList.RxDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxDescCnt, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescCnt, 0U ); + WRITE_REG( heth->RxDescList.ItMode, 0U ); + + /* Set Receive Descriptor List Address */ + WRITE_REG( heth->Instance->DMARDLAR, ( uint32_t ) heth->Init.RxDesc ); + } + +/** + * @brief Prepare Tx DMA descriptor before transmission. + * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Tx packet configuration + * @param ItMode: Enable or disable Tx EOT interrept + * @retval Status + */ + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + const ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t ItMode ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + uint32_t firstdescidx = dmatxdesclist->CurTxDesc; + uint32_t idx; + uint32_t descnbr = 0; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + ETH_BufferTypeDef * txbuffer = pTxConfig->TxBuffer; + uint32_t bd_count = 0; + uint32_t primask_bit; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ) == ETH_DMATXDESC_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + return HAL_ETH_ERROR_BUSY; + } + + descnbr += 1U; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC2, ( uint32_t ) txbuffer->buffer ); + + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len ); + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM ) != 0U ) + { + MODIFY_REG( dmatxdesc->DESC0, ETH_DMATXDESC_CIC, pTxConfig->ChecksumCtrl ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD ) != 0U ) + { + MODIFY_REG( dmatxdesc->DESC0, ETH_CRC_PAD_DISABLE, pTxConfig->CRCPadCtrl ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != 0U ) + { + /* Set Vlan Type */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_VF ); + } + + /* Mark it as First Descriptor */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_FS ); + + /* only if the packet is split into more than one descriptors > 1 */ + while( txbuffer->next != NULL ) + { + /* Clear the LD bit of previous descriptor */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_LS ); + + if( ItMode != ( ( uint32_t ) RESET ) ) + { + /* Set Interrupt on completion bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + else + { + /* Clear Interrupt on completion bit */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ) == ETH_DMATXDESC_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + descidx = firstdescidx; + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* clear previous desc own bit */ + for( idx = 0; idx < descnbr; idx++ ) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ); + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + } + + return HAL_ETH_ERROR_BUSY; + } + + /* Clear the FD bit of new Descriptor */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_FS ); + + descnbr += 1U; + + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC2, ( uint32_t ) txbuffer->buffer ); + + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len ); + + bd_count += 1U; + + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set Own bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ); + } + + if( ItMode != ( ( uint32_t ) RESET ) ) + { + /* Set Interrupt on completion bit */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + else + { + /* Clear Interrupt on completion bit */ + CLEAR_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_IC ); + } + + /* Mark it as LAST descriptor */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_LS ); + + /* Get address of first descriptor */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ firstdescidx ]; + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* set OWN bit of FIRST descriptor */ + SET_BIT( dmatxdesc->DESC0, ETH_DMATXDESC_OWN ); + /* Save the current packet address to expose it to the application */ + dmatxdesclist->PacketAddress[ descidx ] = dmatxdesclist->CurrentPacketAddress; + + dmatxdesclist->CurTxDesc = descidx; + + /* Enter critical section */ + primask_bit = __get_PRIMASK(); + __set_PRIMASK( 1 ); + + dmatxdesclist->BuffersInUse += bd_count + 1U; + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK( primask_bit ); + + /* Return function status */ + return HAL_ETH_ERROR_NONE; + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ) + { + /* Init the ETH Callback settings */ + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ + heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ + heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ + #ifdef HAL_ETH_USE_PTP + heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ + #endif /* HAL_ETH_USE_PTP */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ #endif /* HAL_ETH_MODULE_ENABLED */ /** - * @} - */ + * @} + */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.h b/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.h index 3c7035d82e..d46fe251dc 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.h +++ b/source/portable/NetworkInterface/STM32/Drivers/F7/stm32f7xx_hal_eth.h @@ -1,2017 +1,2157 @@ /** - ****************************************************************************** - * @file stm32f7xx_hal_eth.h - * @author MCD Application Team - * @brief Header file of ETH HAL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32f7xx_hal_eth.h + * @author MCD Application Team + * @brief Header file of ETH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32F7xx_HAL_ETH_H -#define STM32F7xx_HAL_ETH_H + #define STM32F7xx_HAL_ETH_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32f7xx_hal_def.h" + #include "stm32f7xx_hal_def.h" -#if defined(ETH) + #if defined( ETH ) /** @addtogroup STM32F7xx_HAL_Driver - * @{ - */ + * @{ + */ /** @addtogroup ETH - * @{ - */ + * @{ + */ /* Exported types ------------------------------------------------------------*/ -#ifndef ETH_TX_DESC_CNT -#define ETH_TX_DESC_CNT 4U -#endif /* ETH_TX_DESC_CNT */ + #ifndef ETH_TX_DESC_CNT + #define ETH_TX_DESC_CNT 4U + #endif /* ETH_TX_DESC_CNT */ -#ifndef ETH_RX_DESC_CNT -#define ETH_RX_DESC_CNT 4U -#endif /* ETH_RX_DESC_CNT */ + #ifndef ETH_RX_DESC_CNT + #define ETH_RX_DESC_CNT 4U + #endif /* ETH_RX_DESC_CNT */ /*********************** Descriptors struct def section ************************/ + /** @defgroup ETH_Exported_Types ETH Exported Types - * @{ - */ + * @{ + */ /** - * @brief ETH DMA Descriptor structure definition - */ -typedef struct -{ - __IO uint32_t DESC0; - __IO uint32_t DESC1; - __IO uint32_t DESC2; - __IO uint32_t DESC3; - __IO uint32_t DESC4; - __IO uint32_t DESC5; - __IO uint32_t DESC6; - __IO uint32_t DESC7; - uint32_t BackupAddr0; /* used to store rx buffer 1 address */ - uint32_t BackupAddr1; /* used to store rx buffer 2 address */ -} ETH_DMADescTypeDef; + * @brief ETH DMA Descriptor structure definition + */ + typedef struct + { + __IO uint32_t DESC0; + __IO uint32_t DESC1; + __IO uint32_t DESC2; + __IO uint32_t DESC3; + __IO uint32_t DESC4; + __IO uint32_t DESC5; + __IO uint32_t DESC6; + __IO uint32_t DESC7; + uint32_t BackupAddr0; /* used to store rx buffer 1 address */ + uint32_t BackupAddr1; /* used to store rx buffer 2 address */ + } ETH_DMADescTypeDef; + /** - * - */ + * + */ /** - * @brief ETH Buffers List structure definition - */ -typedef struct __ETH_BufferTypeDef -{ - uint8_t *buffer; /*gState = HAL_ETH_STATE_RESET; \ - (__HANDLE__)->MspInitCallback = NULL; \ - (__HANDLE__)->MspDeInitCallback = NULL; \ - } while(0) -#else -#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) do{ \ - (__HANDLE__)->gState = HAL_ETH_STATE_RESET; \ - } while(0) -#endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @brief Enables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * enabled @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER \ - |= (__INTERRUPT__)) - -/** - * @brief Disables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * disabled. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER \ - &= ~(__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT source enabled or disabled. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The ETH DMA IT Source enabled or disabled - */ -#define __HAL_ETH_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->DMAIER &\ - (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The state of ETH DMA IT (SET or RESET) - */ -#define __HAL_ETH_DMA_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->DMASR &\ - (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Clears the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMASR = (__INTERRUPT__)) - -/** - * @brief Checks whether the specified ETHERNET DMA flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMASR &\ - ( __FLAG__)) == ( __FLAG__)) - -/** - * @brief Clears the specified ETHERNET DMA flag. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMASR = ( __FLAG__)) - - - -/** - * @brief Checks whether the specified ETHERNET MAC flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts - * @retval The state of ETH MAC IT (SET or RESET). - */ -#define __HAL_ETH_MAC_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->MACSR &\ - ( __INTERRUPT__)) == ( __INTERRUPT__)) + * @param __HANDLE__: specifies the ETH handle. + * @retval None + */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + ( __HANDLE__ )->MspInitCallback = NULL; \ + ( __HANDLE__ )->MspDeInitCallback = NULL; \ + } while( 0 ) + #else + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + } while( 0 ) + #endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @brief Enables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * enabled @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_ENABLE_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( __HANDLE__ )->Instance->DMAIER \ + |= ( __INTERRUPT__ ) ) + +/** + * @brief Disables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * disabled. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_DISABLE_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( __HANDLE__ )->Instance->DMAIER \ + &= ~( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT source enabled or disabled. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The ETH DMA IT Source enabled or disabled + */ + #define __HAL_ETH_DMA_GET_IT_SOURCE( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMAIER & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The state of ETH DMA IT (SET or RESET) + */ + #define __HAL_ETH_DMA_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMASR & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Clears the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_CLEAR_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMASR = ( __INTERRUPT__ ) ) + +/** + * @brief Checks whether the specified ETHERNET DMA flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_GET_FLAG( __HANDLE__, __FLAG__ ) \ + ( ( ( __HANDLE__ )->Instance->DMASR & \ + ( __FLAG__ ) ) == ( __FLAG__ ) ) + +/** + * @brief Clears the specified ETHERNET DMA flag. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_CLEAR_FLAG( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->DMASR = ( __FLAG__ ) ) + + + +/** + * @brief Checks whether the specified ETHERNET MAC flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts + * @retval The state of ETH MAC IT (SET or RESET). + */ + #define __HAL_ETH_MAC_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->MACSR & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) /*!< External interrupt line 19 Connected to the ETH wakeup EXTI Line */ -#define ETH_WAKEUP_EXTI_LINE 0x00080000U + #define ETH_WAKEUP_EXTI_LINE 0x00080000U /** - * @brief Enable the ETH WAKEUP Exti Line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT(__EXTI_LINE__) (EXTI->IMR |= (__EXTI_LINE__)) + * @brief Enable the ETH WAKEUP Exti Line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT( __EXTI_LINE__ ) ( EXTI->IMR |= ( __EXTI_LINE__ ) ) /** - * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval EXTI ETH WAKEUP Line Status. - */ -#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval EXTI ETH WAKEUP Line Status. + */ + #define __HAL_ETH_WAKEUP_EXTI_GET_FLAG( __EXTI_LINE__ ) ( EXTI->PR & ( __EXTI_LINE__ ) ) /** - * @brief Clear the ETH WAKEUP Exti flag. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + * @brief Clear the ETH WAKEUP Exti flag. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( __EXTI_LINE__ ) ( EXTI->PR = ( __EXTI_LINE__ ) ) /** - * @brief enable rising edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE(__EXTI_LINE__) (EXTI->FTSR &= ~(__EXTI_LINE__)); \ - (EXTI->RTSR |= (__EXTI_LINE__)) + * @brief enable rising edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->FTSR &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->RTSR |= ( __EXTI_LINE__ ) ) /** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR &= ~(__EXTI_LINE__));\ - (EXTI->FTSR |= (__EXTI_LINE__)) + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR |= ( __EXTI_LINE__ ) ) /** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR |= (__EXTI_LINE__));\ - (EXTI->FTSR |= (__EXTI_LINE__)) + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR |= ( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR |= ( __EXTI_LINE__ ) ) /** - * @brief Generates a Software interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT( __EXTI_LINE__ ) ( EXTI->SWIER |= ( __EXTI_LINE__ ) ) -#define __HAL_ETH_GET_PTP_CONTROL(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->PTPTSCR) & \ - (__FLAG__)) == (__FLAG__)) ? SET : RESET) + #define __HAL_ETH_GET_PTP_CONTROL( __HANDLE__, __FLAG__ ) \ + ( ( ( ( ( __HANDLE__ )->Instance->PTPTSCR ) & \ + ( __FLAG__ ) ) == ( __FLAG__ ) ) ? SET : RESET ) -#define __HAL_ETH_SET_PTP_CONTROL(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->PTPTSCR |= (__FLAG__)) + #define __HAL_ETH_SET_PTP_CONTROL( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->PTPTSCR |= ( __FLAG__ ) ) /** - * @} - */ + * @} + */ /* Exported functions --------------------------------------------------------*/ /** @addtogroup ETH_Exported_Functions - * @{ - */ + * @{ + */ /** @addtogroup ETH_Exported_Functions_Group1 - * @{ - */ + * @{ + */ /* Initialization and de initialization functions **********************************/ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ); /* Callbacks Register/UnRegister functions ***********************************/ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group2 - * @{ - */ + * @{ + */ /* IO operation functions *******************************************************/ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth); - -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff); -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode); -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth); - -#ifdef HAL_ETH_USE_PTP -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset); -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth); -#endif /* HAL_ETH_USE_PTP */ - -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout); -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig); - -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue); -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue); - -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth); -void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxAllocateCallback(uint8_t **buff); -void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length); -void HAL_ETH_TxFreeCallback(uint32_t *buff); -void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp); -/** - * @} - */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ); + + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ); + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( const ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ); + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ); + + #ifdef HAL_ETH_USE_PTP + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ); + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ); + #endif /* HAL_ETH_USE_PTP */ + + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t Timeout ); + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig ); + + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ); + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ); + + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ); + void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxAllocateCallback( uint8_t ** buff ); + void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ); + void HAL_ETH_TxFreeCallback( uint32_t * buff ); + void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ); + +/** + * @} + */ /** @addtogroup ETH_Exported_Functions_Group3 - * @{ - */ + * @{ + */ /* Peripheral Control functions **********************************************/ /* MAC & DMA Configuration APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_GetMACConfig( const ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( const ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ); /* MAC VLAN Processing APIs ************************************************/ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, - uint32_t VLANIdentifier); + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ); /* MAC L2 Packet Filtering APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable); -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr); + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( const ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ); + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ); /* MAC Power Down APIs *****************************************************/ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, - const ETH_PowerDownConfigTypeDef *pPowerDownConfig); -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count); + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ); + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ); /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group4 - * @{ - */ + * @{ + */ /* Peripheral State functions **************************************************/ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth); + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ); + /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* STM32F7xx_HAL_ETH_H */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.c b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.c index d04ecc6f43..6c548f14b9 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.c +++ b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.c @@ -1,3341 +1,3413 @@ /** - ****************************************************************************** - * @file stm32h5xx_hal_eth.c - * @author MCD Application Team - * @brief ETH HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Ethernet (ETH) peripheral: - * + Initialization and deinitialization functions - * + IO operation functions - * + Peripheral Control functions - * + Peripheral State and Errors functions - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - The ETH HAL driver can be used as follows: - - (#)Declare a ETH_HandleTypeDef handle structure, for example: - ETH_HandleTypeDef heth; - - (#)Fill parameters of Init structure in heth handle - - (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) - - (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: - (##) Enable the Ethernet interface clock using - (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() - (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() - (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() - - (##) Initialize the related GPIO clocks - (##) Configure Ethernet pinout - (##) Configure Ethernet NVIC interrupt (in Interrupt mode) - - (#) Ethernet data reception is asynchronous, so call the following API - to start the listening mode: - (##) HAL_ETH_Start(): - This API starts the MAC and DMA transmission and reception process, - without enabling end of transfer interrupts, in this mode user - has to poll for data reception by calling HAL_ETH_ReadData() - (##) HAL_ETH_Start_IT(): - This API starts the MAC and DMA transmission and reception process, - end of transfer interrupts are enabled in this mode, - HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received - - (#) When data is received user can call the following API to get received data: - (##) HAL_ETH_ReadData(): Read a received packet - - (#) For transmission path, two APIs are available: - (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode - (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, - HAL_ETH_TxCpltCallback() will be executed when end of transfer occur - - (#) Communication with an external PHY device: - (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY - (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register - - (#) Configure the Ethernet MAC after ETH peripheral initialization - (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef - (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef - - (#) Configure the Ethernet DMA after ETH peripheral initialization - (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef - (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef - - (#) Configure the Ethernet PTP after ETH peripheral initialization - (##) Define HAL_ETH_USE_PTP to use PTP APIs. - (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers - (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission - (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp - (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp - - -@- The ARP offload feature is not supported in this driver. - - -@- The PTP offload feature is not supported in this driver. - - *** Callback registration *** - ============================================= - - The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 - allows the user to configure dynamically the driver callbacks. - Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. - - Function HAL_ETH_RegisterCallback() allows to register following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - This function takes as parameters the HAL peripheral handle, the Callback ID - and a pointer to the user callback function. - - For specific callbacks RxAllocateCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxPtpCallback(). - - Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default - weak function. - HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, - and the Callback ID. - This function allows to reset following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - For specific callbacks RxAllocateCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxPtpCallback(). - - By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET - all callbacks are set to the corresponding weak functions: - examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). - Exception done for MspInit and MspDeInit functions that are - reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when - these callbacks are null (not registered beforehand). - if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit - keep and use the user MspInit/MspDeInit callbacks (registered beforehand) - - Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. - Exception done MspInit/MspDeInit that can be registered/unregistered - in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, - thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. - In that case first register the MspInit/MspDeInit user callbacks - using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit - or HAL_ETH_Init function. - - When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or - not defined, the callback registration feature is not available and all callbacks - are set to the corresponding weak functions. - - @endverbatim - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h5xx_hal_eth.c + * @author MCD Application Team + * @brief ETH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Ethernet (ETH) peripheral: + * + Initialization and deinitialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @verbatim + * ============================================================================== + ##### How to use this driver ##### + #####============================================================================== + #####[..] + #####The ETH HAL driver can be used as follows: + ##### + #####(#)Declare a ETH_HandleTypeDef handle structure, for example: + ##### ETH_HandleTypeDef heth; + ##### + #####(#)Fill parameters of Init structure in heth handle + ##### + #####(#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) + ##### + #####(#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: + ##### (##) Enable the Ethernet interface clock using + ##### (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() + ##### + ##### (##) Initialize the related GPIO clocks + ##### (##) Configure Ethernet pinout + ##### (##) Configure Ethernet NVIC interrupt (in Interrupt mode) + ##### + #####(#) Ethernet data reception is asynchronous, so call the following API + ##### to start the listening mode: + ##### (##) HAL_ETH_Start(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### without enabling end of transfer interrupts, in this mode user + ##### has to poll for data reception by calling HAL_ETH_ReadData() + ##### (##) HAL_ETH_Start_IT(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### end of transfer interrupts are enabled in this mode, + ##### HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received + ##### + #####(#) When data is received user can call the following API to get received data: + ##### (##) HAL_ETH_ReadData(): Read a received packet + ##### + #####(#) For transmission path, two APIs are available: + ##### (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode + ##### (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, + ##### HAL_ETH_TxCpltCallback() will be executed when end of transfer occur + ##### + #####(#) Communication with an external PHY device: + ##### (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY + ##### (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register + ##### + #####(#) Configure the Ethernet MAC after ETH peripheral initialization + ##### (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef + ##### (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef + ##### + #####(#) Configure the Ethernet DMA after ETH peripheral initialization + ##### (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef + ##### (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef + ##### + #####(#) Configure the Ethernet PTP after ETH peripheral initialization + ##### (##) Define HAL_ETH_USE_PTP to use PTP APIs. + ##### (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission + ##### (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp + ##### (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp + ##### + #####-@- The ARP offload feature is not supported in this driver. + ##### + #####-@- The PTP offload feature is not supported in this driver. + ##### + *** Callback registration *** + ***============================================= + *** + ***The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 + ***allows the user to configure dynamically the driver callbacks. + ***Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. + *** + ***Function HAL_ETH_RegisterCallback() allows to register following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***This function takes as parameters the HAL peripheral handle, the Callback ID + ***and a pointer to the user callback function. + *** + ***For specific callbacks RxAllocateCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxPtpCallback(). + *** + ***Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default + ***weak function. + ***HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, + ***and the Callback ID. + ***This function allows to reset following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***For specific callbacks RxAllocateCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxPtpCallback(). + *** + ***By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET + ***all callbacks are set to the corresponding weak functions: + ***examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). + ***Exception done for MspInit and MspDeInit functions that are + ***reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when + ***these callbacks are null (not registered beforehand). + ***if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit + ***keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + *** + ***Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. + ***Exception done MspInit/MspDeInit that can be registered/unregistered + ***in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, + ***thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + ***In that case first register the MspInit/MspDeInit user callbacks + ***using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit + ***or HAL_ETH_Init function. + *** + ***When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or + ***not defined, the callback registration feature is not available and all callbacks + ***are set to the corresponding weak functions. + *** + ***@endverbatim + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32h5xx_hal.h" /** @addtogroup STM32H5xx_HAL_Driver - * @{ - */ + * @{ + */ #ifdef HAL_ETH_MODULE_ENABLED -#if defined(ETH) + #if defined( ETH ) /** @defgroup ETH ETH - * @brief ETH HAL module driver - * @{ - */ + * @brief ETH HAL module driver + * @{ + */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ + /** @addtogroup ETH_Private_Constants ETH Private Constants - * @{ - */ -#define ETH_MACCR_MASK 0xFFFB7F7CU -#define ETH_MACECR_MASK 0x3F077FFFU -#define ETH_MACPFR_MASK 0x800007FFU -#define ETH_MACWTR_MASK 0x0000010FU -#define ETH_MACTFCR_MASK 0xFFFF00F2U -#define ETH_MACRFCR_MASK 0x00000003U -#define ETH_MTLTQOMR_MASK 0x00000072U -#define ETH_MTLRQOMR_MASK 0x0000007BU - -#define ETH_DMAMR_MASK 0x00007802U -#define ETH_DMASBMR_MASK 0x0000D001U -#define ETH_DMACCR_MASK 0x00013FFFU -#define ETH_DMACTCR_MASK 0x003F1010U -#define ETH_DMACRCR_MASK 0x803F0000U -#define ETH_MACPCSR_MASK (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \ - ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \ - ETH_MACPCSR_RWKPFE) + * @{ + */ + #define ETH_MACCR_MASK 0xFFFB7F7CU + #define ETH_MACECR_MASK 0x3F077FFFU + #define ETH_MACPFR_MASK 0x800007FFU + #define ETH_MACWTR_MASK 0x0000010FU + #define ETH_MACTFCR_MASK 0xFFFF00F2U + #define ETH_MACRFCR_MASK 0x00000003U + #define ETH_MTLTQOMR_MASK 0x00000072U + #define ETH_MTLRQOMR_MASK 0x0000007BU + + #define ETH_DMAMR_MASK 0x00007802U + #define ETH_DMASBMR_MASK 0x0000D001U + #define ETH_DMACCR_MASK 0x00013FFFU + #define ETH_DMACTCR_MASK 0x003F1010U + #define ETH_DMACRCR_MASK 0x803F0000U + #define ETH_MACPCSR_MASK \ + ( ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \ + ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \ + ETH_MACPCSR_RWKPFE ) /* Timeout values */ -#define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \ - ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\ - ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE)) + #define ETH_DMARXNDESCWBF_ERRORS_MASK \ + ( ( uint32_t ) ( ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \ + ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT | \ + ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE ) ) + + #define ETH_MACTSCR_MASK 0x0087FF2FU -#define ETH_MACTSCR_MASK 0x0087FF2FU + #define ETH_MACSTSUR_VALUE 0xFFFFFFFFU + #define ETH_MACSTNUR_VALUE 0xBB9ACA00U + #define ETH_SEGMENT_SIZE_DEFAULT 0x218U -#define ETH_MACSTSUR_VALUE 0xFFFFFFFFU -#define ETH_MACSTNUR_VALUE 0xBB9ACA00U -#define ETH_SEGMENT_SIZE_DEFAULT 0x218U /** - * @} - */ + * @} + */ /* Private macros ------------------------------------------------------------*/ + /** @defgroup ETH_Private_Macros ETH Private Macros - * @{ - */ + * @{ + */ /* Helper macros for TX descriptor handling */ -#define INCR_TX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\ - } while (0) + #define INCR_TX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_TX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_TX_DESC_CNT ); } \ + } while( 0 ) /* Helper macros for RX descriptor handling */ -#define INCR_RX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\ - } while (0) -/** - * @} - */ + #define INCR_RX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_RX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_RX_DESC_CNT ); } \ + } while( 0 ) + +/** + * @} + */ /* Private function prototypes -----------------------------------------------*/ + /** @defgroup ETH_Private_Functions ETH Private Functions - * @{ - */ -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf); -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf); -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth); -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth); -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth); -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, - uint32_t ItMode); -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ -/** - * @} - */ + * @{ + */ + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + const ETH_MACConfigTypeDef * macconf ); + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + const ETH_DMAConfigTypeDef * dmaconf ); + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ); + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ); + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ); + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + const ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t ItMode ); + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /* Exported functions ---------------------------------------------------------*/ + /** @defgroup ETH_Exported_Functions ETH Exported Functions - * @{ - */ + * @{ + */ /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions - * @brief Initialization and Configuration functions - * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] This subsection provides a set of functions allowing to initialize and - deinitialize the ETH peripheral: - - (+) User must Implement HAL_ETH_MspInit() function in which he configures - all related peripherals resources (CLOCK, GPIO and NVIC ). - - (+) Call the function HAL_ETH_Init() to configure the selected device with - the selected configuration: - (++) MAC address - (++) Media interface (MII or RMII) - (++) Rx DMA Descriptors Tab - (++) Tx DMA Descriptors Tab - (++) Length of Rx Buffers - - (+) Call the function HAL_ETH_DeInit() to restore the default configuration - of the selected ETH peripheral. - -@endverbatim - * @{ - */ - -/** - * @brief Initialize the Ethernet peripheral registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) -{ - uint32_t tickstart; - - if (heth == NULL) - { - return HAL_ERROR; - } - if (heth->gState == HAL_ETH_STATE_RESET) - { - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - ETH_InitCallbacksToDefault(heth); - - if (heth->MspInitCallback == NULL) - { - heth->MspInitCallback = HAL_ETH_MspInit; - } - - /* Init the low level hardware */ - heth->MspInitCallback(heth); -#else - /* Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - } - - __HAL_RCC_SBS_CLK_ENABLE(); - - if (heth->Init.MediaInterface == HAL_ETH_MII_MODE) - { - HAL_SBS_ETHInterfaceSelect(SBS_ETH_MII); - } - else - { - HAL_SBS_ETHInterfaceSelect(SBS_ETH_RMII); - } - - /* Dummy read to sync with ETH */ - (void)SBS->PMCR; - - /* Ethernet Software reset */ - /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ - /* After reset all the registers holds their respective reset values */ - SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Wait for software reset */ - while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)) - { - /* Set Error Code */ - heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; - /* Set State as Error */ - heth->gState = HAL_ETH_STATE_ERROR; - /* Return Error */ - return HAL_ERROR; - } - } - - /*------------------ MDIO CSR Clock Range Configuration --------------------*/ - HAL_ETH_SetMDIOClockRange(heth); - - /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/ - WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U)); - - /*------------------ MAC, MTL and DMA default Configuration ----------------*/ - ETH_MACDMAConfig(heth); - - /* SET DSL to 64 bit */ - MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT); - - /* Set Receive Buffers Length (must be a multiple of 4) */ - if ((heth->Init.RxBuffLen % 0x4U) != 0x0U) - { - /* Set Error Code */ - heth->ErrorCode = HAL_ETH_ERROR_PARAM; - /* Set State as Error */ - heth->gState = HAL_ETH_STATE_ERROR; - /* Return Error */ - return HAL_ERROR; - } - else - { - MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1)); - } - - /*------------------ DMA Tx Descriptors Configuration ----------------------*/ - ETH_DMATxDescListInit(heth); - - /*------------------ DMA Rx Descriptors Configuration ----------------------*/ - ETH_DMARxDescListInit(heth); - - /*--------------------- ETHERNET MAC Address Configuration ------------------*/ - /* Set MAC addr bits 32 to 47 */ - heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]); - /* Set MAC addr bits 0 to 31 */ - heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) | - ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]); - - /* Disable Rx MMC Interrupts */ - SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \ - ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM); - - /* Disable Tx MMC Interrupts */ - SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \ - ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM); - - heth->ErrorCode = HAL_ETH_ERROR_NONE; - heth->gState = HAL_ETH_STATE_READY; - - return HAL_OK; -} - -/** - * @brief DeInitializes the ETH peripheral. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) -{ - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - if (heth->MspDeInitCallback == NULL) - { - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - } - /* DeInit the low level hardware */ - heth->MspDeInitCallback(heth); -#else - - /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspDeInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - - /* Set ETH HAL state to Disabled */ - heth->gState = HAL_ETH_STATE_RESET; - - /* 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 - * @retval None - */ -__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspInit could be implemented in the user file - */ -} - -/** - * @brief DeInitializes ETH MSP. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspDeInit could be implemented in the user file - */ -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -/** - * @brief Register a User ETH Callback - * To be used instead of the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be registered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @param pCallback pointer to the Callback function - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = pCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = pCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = pCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = pCallback; - break; - - case HAL_ETH_EEE_CB_ID : - heth->EEECallback = pCallback; - break; - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = pCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} - -/** - * @brief Unregister an ETH Callback - * ETH callback is redirected to the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be unregistered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = HAL_ETH_ErrorCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = HAL_ETH_PMTCallback; - break; - - case HAL_ETH_EEE_CB_ID : - heth->EEECallback = HAL_ETH_EEECallback; - break; - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ + * @brief Initialization and Configuration functions + * + * @verbatim + * =============================================================================== + ##### Initialization and Configuration functions ##### + #####=============================================================================== + #####[..] This subsection provides a set of functions allowing to initialize and + ##### deinitialize the ETH peripheral: + ##### + #####(+) User must Implement HAL_ETH_MspInit() function in which he configures + ##### all related peripherals resources (CLOCK, GPIO and NVIC ). + ##### + #####(+) Call the function HAL_ETH_Init() to configure the selected device with + ##### the selected configuration: + ##### (++) MAC address + ##### (++) Media interface (MII or RMII) + ##### (++) Rx DMA Descriptors Tab + ##### (++) Tx DMA Descriptors Tab + ##### (++) Length of Rx Buffers + ##### + #####(+) Call the function HAL_ETH_DeInit() to restore the default configuration + ##### of the selected ETH peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Initialize the Ethernet peripheral registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ) + { + uint32_t tickstart; + + if( heth == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_RESET ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + ETH_InitCallbacksToDefault( heth ); + + if( heth->MspInitCallback == NULL ) + { + heth->MspInitCallback = HAL_ETH_MspInit; + } + + /* Init the low level hardware */ + heth->MspInitCallback( heth ); + #else + /* Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + } + + __HAL_RCC_SBS_CLK_ENABLE(); + + if( heth->Init.MediaInterface == HAL_ETH_MII_MODE ) + { + HAL_SBS_ETHInterfaceSelect( SBS_ETH_MII ); + } + else + { + HAL_SBS_ETHInterfaceSelect( SBS_ETH_RMII ); + } + + /* Dummy read to sync with ETH */ + ( void ) SBS->PMCR; + + /* Ethernet Software reset */ + /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ + /* After reset all the registers holds their respective reset values */ + SET_BIT( heth->Instance->DMAMR, ETH_DMAMR_SWR ); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for software reset */ + while( READ_BIT( heth->Instance->DMAMR, ETH_DMAMR_SWR ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_SWRESET_TIMEOUT ) ) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + } + + /*------------------ MDIO CSR Clock Range Configuration --------------------*/ + HAL_ETH_SetMDIOClockRange( heth ); + + /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/ + WRITE_REG( heth->Instance->MAC1USTCR, ( ( ( uint32_t ) HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK ) - 1U ) ); + + /*------------------ MAC, MTL and DMA default Configuration ----------------*/ + ETH_MACDMAConfig( heth ); + + /* SET DSL to 64 bit */ + MODIFY_REG( heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT ); + + /* Set Receive Buffers Length (must be a multiple of 4) */ + if( ( heth->Init.RxBuffLen % 0x4U ) != 0x0U ) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_PARAM; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + else + { + MODIFY_REG( heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ( ( heth->Init.RxBuffLen ) << 1 ) ); + } + + /*------------------ DMA Tx Descriptors Configuration ----------------------*/ + ETH_DMATxDescListInit( heth ); + + /*------------------ DMA Rx Descriptors Configuration ----------------------*/ + ETH_DMARxDescListInit( heth ); + + /*--------------------- ETHERNET MAC Address Configuration ------------------*/ + /* Set MAC addr bits 32 to 47 */ + heth->Instance->MACA0HR = ( ( ( uint32_t ) ( heth->Init.MACAddr[ 5 ] ) << 8 ) | ( uint32_t ) heth->Init.MACAddr[ 4 ] ); + /* Set MAC addr bits 0 to 31 */ + heth->Instance->MACA0LR = ( ( ( uint32_t ) ( heth->Init.MACAddr[ 3 ] ) << 24 ) | ( ( uint32_t ) ( heth->Init.MACAddr[ 2 ] ) << 16 ) | + ( ( uint32_t ) ( heth->Init.MACAddr[ 1 ] ) << 8 ) | ( uint32_t ) heth->Init.MACAddr[ 0 ] ); + + /* Disable Rx MMC Interrupts */ + SET_BIT( heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \ + ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM ); + + /* Disable Tx MMC Interrupts */ + SET_BIT( heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \ + ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM ); + + heth->ErrorCode = HAL_ETH_ERROR_NONE; + heth->gState = HAL_ETH_STATE_READY; + + return HAL_OK; + } + +/** + * @brief DeInitializes the ETH peripheral. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + if( heth->MspDeInitCallback == NULL ) + { + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + } + + /* DeInit the low level hardware */ + heth->MspDeInitCallback( heth ); + #else + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspDeInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + + /* Set ETH HAL state to Disabled */ + heth->gState = HAL_ETH_STATE_RESET; + + /* 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 + * @retval None + */ + __weak void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspInit could be implemented in the user file + */ + } + +/** + * @brief DeInitializes ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspDeInit could be implemented in the user file + */ + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + +/** + * @brief Register a User ETH Callback + * To be used instead of the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( pCallback == NULL ) + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = pCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = pCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = pCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = pCallback; + break; + + case HAL_ETH_EEE_CB_ID: + heth->EEECallback = pCallback; + break; + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = pCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + +/** + * @brief Unregister an ETH Callback + * ETH callback is redirected to the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = HAL_ETH_ErrorCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = HAL_ETH_PMTCallback; + break; + + case HAL_ETH_EEE_CB_ID: + heth->EEECallback = HAL_ETH_EEECallback; + break; + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group2 IO operation functions - * @brief ETH Transmit and Receive functions - * -@verbatim - ============================================================================== - ##### IO operation functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to manage the ETH - data transfer. - -@endverbatim - * @{ - */ - -/** - * @brief Enables Ethernet MAC and DMA reception and transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) -{ - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Clear Tx and Rx process stopped flags */ - heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); - - heth->gState = HAL_ETH_STATE_STARTED; - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) -{ - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* save IT mode to ETH Handle */ - heth->RxDescList.ItMode = 1U; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Clear Tx and Rx process stopped flags */ - heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Enable ETH DMA interrupts: - - Tx complete interrupt - - Rx complete interrupt - - Fatal bus interrupt - */ - __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | - ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE)); - - heth->gState = HAL_ETH_STATE_STARTED; - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) -{ - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t descindex; - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - /* Disable interrupts: - - Tx complete interrupt - - Rx complete interrupt - - Fatal bus interrupt - */ - __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | - ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE)); - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Clear IOC bit to all Rx descriptors */ - for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++) - { - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; - CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC); - } - - heth->RxDescList.ItMode = 0U; - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in polling mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @param Timeout: timeout value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout) -{ - uint32_t tickstart; - ETH_DMADescTypeDef *dmatxdesc; - - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE) - { - /* Set the ETH error code */ - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc]; - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); - - tickstart = HAL_GetTick(); - - /* Wait for data to be transmitted or timeout occurred */ - while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET) - { - if ((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - heth->DMAErrorCode = heth->Instance->DMACSR; - /* Return function status */ - return HAL_ERROR; - } - - /* Check for the Timeout */ - if (Timeout != HAL_MAX_DELAY) - { - if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + * @brief ETH Transmit and Receive functions + * + * @verbatim + * ============================================================================== + ##### IO operation functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to manage the ETH + #####data transfer. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Enables Ethernet MAC and DMA reception and transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ) + { + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->DMACSR |= ( ETH_DMACSR_TPS | ETH_DMACSR_RPS ); + + heth->gState = HAL_ETH_STATE_STARTED; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ) + { + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* save IT mode to ETH Handle */ + heth->RxDescList.ItMode = 1U; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->DMACSR |= ( ETH_DMACSR_TPS | ETH_DMACSR_RPS ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Enable ETH DMA interrupts: + * - Tx complete interrupt + * - Rx complete interrupt + * - Fatal bus interrupt + */ + __HAL_ETH_DMA_ENABLE_IT( heth, ( ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | + ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE ) ); + + heth->gState = HAL_ETH_STATE_STARTED; + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ) + { + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmarxdesc; + uint32_t descindex; + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable interrupts: + * - Tx complete interrupt + * - Rx complete interrupt + * - Fatal bus interrupt + */ + __HAL_ETH_DMA_DISABLE_IT( heth, ( ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | + ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE ) ); + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Clear IOC bit to all Rx descriptors */ + for( descindex = 0; descindex < ( uint32_t ) ETH_RX_DESC_CNT; descindex++ ) + { + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descindex ]; + CLEAR_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC ); + } + + heth->RxDescList.ItMode = 0U; + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Sends an Ethernet Packet in polling mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @param Timeout: timeout value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t Timeout ) + { + uint32_t tickstart; + ETH_DMADescTypeDef * dmatxdesc; + + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 0 ) != HAL_ETH_ERROR_NONE ) + { + /* Set the ETH error code */ + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + dmatxdesc = ( ETH_DMADescTypeDef * ) ( &heth->TxDescList )->TxDesc[ heth->TxDescList.CurTxDesc ]; + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG( heth->Instance->DMACTDTPR, ( uint32_t ) ( heth->TxDescList.TxDesc[ heth->TxDescList.CurTxDesc ] ) ); + + tickstart = HAL_GetTick(); + + /* Wait for data to be transmitted or timeout occurred */ + while( ( dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN ) != ( uint32_t ) RESET ) + { + if( ( heth->Instance->DMACSR & ETH_DMACSR_FBE ) != ( uint32_t ) RESET ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + heth->DMAErrorCode = heth->Instance->DMACSR; + /* Return function status */ + return HAL_ERROR; + } + + /* Check for the Timeout */ + if( Timeout != HAL_MAX_DELAY ) + { + if( ( ( HAL_GetTick() - tickstart ) > Timeout ) || ( Timeout == 0U ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; + /* Clear TX descriptor so that we can proceed */ + dmatxdesc->DESC3 = ( ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD ); + return HAL_ERROR; + } + } + } + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Sends an Ethernet Packet in interrupt mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig ) + { + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Save the packet pointer to release. */ + heth->TxDescList.CurrentPacketAddress = ( uint32_t * ) pTxConfig->pData; + + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 1 ) != HAL_ETH_ERROR_NONE ) + { + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG( heth->Instance->DMACTDTPR, ( uint32_t ) ( heth->TxDescList.TxDesc[ heth->TxDescList.CurTxDesc ] ) ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Read a received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pAppBuff: Pointer to an application buffer to receive the packet. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ) + { + uint32_t descidx; + ETH_DMADescTypeDef * dmarxdesc; + uint32_t desccnt = 0U; + uint32_t desccntmax; + uint32_t bufflength; + uint8_t rxdataready = 0U; + + if( pAppBuff == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState != HAL_ETH_STATE_STARTED ) + { + return HAL_ERROR; + } + + descidx = heth->RxDescList.RxDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; + + /* Check if descriptor is not owned by DMA */ + while( ( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN ) == ( uint32_t ) RESET ) && ( desccnt < desccntmax ) && + ( rxdataready == 0U ) ) + { + if( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT ) != ( uint32_t ) RESET ) + { + /* Get timestamp high */ + heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1; + /* Get timestamp low */ + heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC0; + } + + if( ( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD ) != ( uint32_t ) RESET ) || ( heth->RxDescList.pRxStart != NULL ) ) + { + /* Check if first descriptor */ + if( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD ) != ( uint32_t ) RESET ) + { + heth->RxDescList.RxDescCnt = 0; + heth->RxDescList.RxDataLength = 0; + } + + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + bufflength = READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL ) - heth->RxDescList.RxDataLength; + + /* Check if last descriptor */ + if( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD ) != ( uint32_t ) RESET ) + { + /* Save Last descriptor index */ + heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3; + + /* Packet ready */ + rxdataready = 1; + } + + /* Link data */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Link callback*/ + heth->rxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, bufflength ); + #else + /* Link callback */ + HAL_ETH_RxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, ( uint16_t ) bufflength ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->RxDescList.RxDescCnt++; + heth->RxDescList.RxDataLength += bufflength; + + /* Clear buffer pointer */ + dmarxdesc->BackupAddr0 = 0; + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccnt++; + } + + heth->RxDescList.RxBuildDescCnt += desccnt; + + if( ( heth->RxDescList.RxBuildDescCnt ) != 0U ) + { + /* Update Descriptors */ + ETH_UpdateDescriptor( heth ); + } + + heth->RxDescList.RxDescIdx = descidx; + + if( rxdataready == 1U ) + { + /* Return received packet */ + *pAppBuff = heth->RxDescList.pRxStart; + /* Reset first element */ + heth->RxDescList.pRxStart = NULL; + + return HAL_OK; + } + + /* Packet not ready */ + return HAL_ERROR; + } + +/** + * @brief This function gives back Rx Desc of the last received Packet + * to the DMA, so ETH DMA will be able to use these descriptors + * to receive next Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ) + { + uint32_t descidx; + uint32_t tailidx; + uint32_t desccount; + ETH_DMADescTypeDef * dmarxdesc; + uint8_t * buff = NULL; + uint8_t allocStatus = 1U; + + descidx = heth->RxDescList.RxBuildDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount = heth->RxDescList.RxBuildDescCnt; + + while( ( desccount > 0U ) && ( allocStatus != 0U ) ) + { + /* Check if a buffer's attached the descriptor */ + if( READ_REG( dmarxdesc->BackupAddr0 ) == 0U ) + { + /* Get a new buffer. */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Allocate callback*/ + heth->rxAllocateCallback( &buff ); + #else + /* Allocate callback */ + HAL_ETH_RxAllocateCallback( &buff ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + if( buff == NULL ) + { + allocStatus = 0U; + } + else + { + WRITE_REG( dmarxdesc->BackupAddr0, ( uint32_t ) buff ); + WRITE_REG( dmarxdesc->DESC0, ( uint32_t ) buff ); + } + } + + if( allocStatus != 0U ) + { + if( heth->RxDescList.ItMode != 0U ) + { + WRITE_REG( dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC ); + } + else + { + WRITE_REG( dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V ); + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount--; + } + } + + if( heth->RxDescList.RxBuildDescCnt != desccount ) + { + /* Set the tail pointer index */ + tailidx = ( descidx + 1U ) % ETH_RX_DESC_CNT; + + /* DMB instruction to avoid race condition */ + __DMB(); + + /* Set the Tail pointer address */ + WRITE_REG( heth->Instance->DMACRDTPR, ( ( uint32_t ) ( heth->Init.RxDesc + ( tailidx ) ) ) ); + + heth->RxDescList.RxBuildDescIdx = descidx; + heth->RxDescList.RxBuildDescCnt = desccount; + } + } + +/** + * @brief Register the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxAllocateCallback: pointer to function to alloc buffer + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ) { - heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; - /* Clear TX descriptor so that we can proceed */ - dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD); - return HAL_ERROR; + if( rxAllocateCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to allocate buffer */ + heth->rxAllocateCallback = rxAllocateCallback; + + return HAL_OK; } - } - } - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in interrupt mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig) -{ - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Save the packet pointer to release. */ - heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData; - - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE) - { - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); - - return HAL_OK; - - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Read a received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pAppBuff: Pointer to an application buffer to receive the packet. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff) -{ - uint32_t descidx; - ETH_DMADescTypeDef *dmarxdesc; - uint32_t desccnt = 0U; - uint32_t desccntmax; - uint32_t bufflength; - uint8_t rxdataready = 0U; - - if (pAppBuff == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState != HAL_ETH_STATE_STARTED) - { - return HAL_ERROR; - } - - descidx = heth->RxDescList.RxDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; - - /* Check if descriptor is not owned by DMA */ - while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax) - && (rxdataready == 0U)) - { - if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET) - { - /* Get timestamp high */ - heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1; - /* Get timestamp low */ - heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC0; - } - if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL)) - { - /* Check if first descriptor */ - if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) - { - heth->RxDescList.RxDescCnt = 0; - heth->RxDescList.RxDataLength = 0; - } - - /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ - bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength; - - /* Check if last descriptor */ - if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET) - { - /* Save Last descriptor index */ - heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3; - - /* Packet ready */ - rxdataready = 1; - } - - /* Link data */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Link callback*/ - heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, bufflength); -#else - /* Link callback */ - HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - heth->RxDescList.RxDescCnt++; - heth->RxDescList.RxDataLength += bufflength; - - /* Clear buffer pointer */ - dmarxdesc->BackupAddr0 = 0; - } - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccnt++; - } - - heth->RxDescList.RxBuildDescCnt += desccnt; - if ((heth->RxDescList.RxBuildDescCnt) != 0U) - { - /* Update Descriptors */ - ETH_UpdateDescriptor(heth); - } - - heth->RxDescList.RxDescIdx = descidx; - - if (rxdataready == 1U) - { - /* Return received packet */ - *pAppBuff = heth->RxDescList.pRxStart; - /* Reset first element */ - heth->RxDescList.pRxStart = NULL; - - return HAL_OK; - } - - /* Packet not ready */ - return HAL_ERROR; -} - -/** - * @brief This function gives back Rx Desc of the last received Packet - * to the DMA, so ETH DMA will be able to use these descriptors - * to receive next Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth) -{ - uint32_t descidx; - uint32_t tailidx; - uint32_t desccount; - ETH_DMADescTypeDef *dmarxdesc; - uint8_t *buff = NULL; - uint8_t allocStatus = 1U; - - descidx = heth->RxDescList.RxBuildDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount = heth->RxDescList.RxBuildDescCnt; - - while ((desccount > 0U) && (allocStatus != 0U)) - { - /* Check if a buffer's attached the descriptor */ - if (READ_REG(dmarxdesc->BackupAddr0) == 0U) - { - /* Get a new buffer. */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Allocate callback*/ - heth->rxAllocateCallback(&buff); -#else - /* Allocate callback */ - HAL_ETH_RxAllocateCallback(&buff); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - if (buff == NULL) - { - allocStatus = 0U; - } - else - { - WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff); - WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff); - } - } - - if (allocStatus != 0U) - { - - if (heth->RxDescList.ItMode != 0U) - { - WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC); - } - else - { - WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V); - } - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount--; - } - } - - if (heth->RxDescList.RxBuildDescCnt != desccount) - { - /* Set the tail pointer index */ - tailidx = (descidx + 1U) % ETH_RX_DESC_CNT; - - /* DMB instruction to avoid race condition */ - __DMB(); - - /* Set the Tail pointer address */ - WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (tailidx)))); - - heth->RxDescList.RxBuildDescIdx = descidx; - heth->RxDescList.RxBuildDescCnt = desccount; - } -} - -/** - * @brief Register the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxAllocateCallback: pointer to function to alloc buffer - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback) -{ - if (rxAllocateCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to allocate buffer */ - heth->rxAllocateCallback = rxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Rx Allocate callback. - * @param buff: pointer to allocated buffer - * @retval None - */ -__weak void HAL_ETH_RxAllocateCallback(uint8_t **buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxAllocateCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Link callback. - * @param pStart: pointer to packet start - * @param pEnd: pointer to packet end - * @param buff: pointer to received data - * @param Length: received data length - * @retval None - */ -__weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(pStart); - UNUSED(pEnd); - UNUSED(buff); - UNUSED(Length); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxLinkCallback could be implemented in the user file - */ -} - -/** - * @brief Set the Rx link data function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxLinkCallback: pointer to function to link data - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback) -{ - if (rxLinkCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to link data */ - heth->rxLinkCallback = rxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx link callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Get the error state of the last received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pErrorCode: pointer to uint32_t to hold the error code - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode) -{ - /* Get error bits. */ - *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK); - - return HAL_OK; -} - -/** - * @brief Set the Tx free function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txFreeCallback: pointer to function to release the packet - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback) -{ - if (txFreeCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to free transmmitted packet */ - heth->txFreeCallback = txFreeCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx free callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; - - return HAL_OK; -} - -/** - * @brief Tx Free callback. - * @param buff: pointer to buffer to free - * @retval None - */ -__weak void HAL_ETH_TxFreeCallback(uint32_t *buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxFreeCallback could be implemented in the user file - */ -} - -/** - * @brief Release transmitted Tx packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t numOfBuf = dmatxdesclist->BuffersInUse; - uint32_t idx = dmatxdesclist->releaseIndex; - uint8_t pktTxStatus = 1U; - uint8_t pktInUse; -#ifdef HAL_ETH_USE_PTP - ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp; -#endif /* HAL_ETH_USE_PTP */ - - /* Loop through buffers in use. */ - while ((numOfBuf != 0U) && (pktTxStatus != 0U)) - { - pktInUse = 1U; - numOfBuf--; - /* If no packet, just examine the next packet. */ - if (dmatxdesclist->PacketAddress[idx] == NULL) - { - /* No packet in use, skip to next. */ - INCR_TX_DESC_INDEX(idx, 1U); - pktInUse = 0U; - } - - if (pktInUse != 0U) - { - /* Determine if the packet has been transmitted. */ - if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U) - { -#ifdef HAL_ETH_USE_PTP - - /* Disable Ptp transmission */ - CLEAR_BIT(heth->Init.TxDesc[idx].DESC3, (0x40000000U)); - - if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_LD) - && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_TTSS)) + +/** + * @brief Unregister the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ) { - /* Get timestamp low */ - timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1; + /* Set function to allocate buffer */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; + + return HAL_OK; } - else + +/** + * @brief Rx Allocate callback. + * @param buff: pointer to allocated buffer + * @retval None + */ + __weak void HAL_ETH_RxAllocateCallback( uint8_t ** buff ) { - timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX; + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxAllocateCallback could be implemented in the user file + */ } -#endif /* HAL_ETH_USE_PTP */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered callbacks*/ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX) +/** + * @brief Rx Link callback. + * @param pStart: pointer to packet start + * @param pEnd: pointer to packet end + * @param buff: pointer to received data + * @param Length: received data length + * @retval None + */ + __weak void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ) { - heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); + /* Prevent unused argument(s) compilation warning */ + UNUSED( pStart ); + UNUSED( pEnd ); + UNUSED( buff ); + UNUSED( Length ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxLinkCallback could be implemented in the user file + */ } -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]); -#else - /* Call callbacks */ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX) + +/** + * @brief Set the Rx link data function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxLinkCallback: pointer to function to link data + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ) { - HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); + if( rxLinkCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to link data */ + heth->rxLinkCallback = rxLinkCallback; + + return HAL_OK; } -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - /* Clear the entry in the in-use array. */ - dmatxdesclist->PacketAddress[idx] = NULL; - - /* Update the transmit relesae index and number of buffers in use. */ - INCR_TX_DESC_INDEX(idx, 1U); - dmatxdesclist->BuffersInUse = numOfBuf; - dmatxdesclist->releaseIndex = idx; - } - else - { - /* Get out of the loop! */ - pktTxStatus = 0U; - } - } - } - return HAL_OK; -} - -#ifdef HAL_ETH_USE_PTP -/** - * @brief Set the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - uint32_t tmpTSCR; - ETH_TimeTypeDef time; - - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - - tmpTSCR = ptpconfig->Timestamp | - ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) | - ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) | - ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) | - ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) | - ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) | - ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) | - ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) | - ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) | - ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) | - ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) | - ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) | - ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) | - ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos); - - /* Write to MACTSCR */ - MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR); - - /* Enable Timestamp */ - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA); - WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc); - WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend); - - /* Enable Timestamp */ - if (ptpconfig->TimestampAddendUpdate == ENABLE) - { - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG); - while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0) - { - - } - } - - /* Ptp Init */ - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT); - - /* Set PTP Configuration done */ - heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED; - - /* Set Seconds */ - time.Seconds = heth->Instance->MACSTSR; - /* Set NanoSeconds */ - time.NanoSeconds = heth->Instance->MACSTNR; - - HAL_ETH_PTP_SetTime(heth, &time); - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Get the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA); - ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U) - ? ENABLE : DISABLE; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param time: pointer to a ETH_TimeTypeDef structure that contains - * time to set - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Set Seconds */ - heth->Instance->MACSTSUR = time->Seconds; - - /* Set NanoSeconds */ - heth->Instance->MACSTNUR = time->NanoSeconds; - - /* the system time is updated */ - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param time: pointer to a ETH_TimeTypeDef structure that contains - * time to get - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get Seconds */ - time->Seconds = heth->Instance->MACSTSR; - /* Get NanoSeconds */ - time->NanoSeconds = heth->Instance->MACSTNR; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Update time for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains - * the time update information - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE) - { - /* Set Seconds update */ - heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U; - - if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR) - { - /* Set nanoSeconds update */ - heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds; - } - else - { - /* Set nanoSeconds update */ - heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U; - } - } - else - { - /* Set Seconds update */ - heth->Instance->MACSTSUR = timeoffset->Seconds; - /* Set nanoSeconds update */ - heth->Instance->MACSTNUR = timeoffset->NanoSeconds; - } - - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Insert Timestamp in transmission. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Enable Time Stamp transmission */ - SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get transmission timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * transmission timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t idx = dmatxdesclist->releaseIndex; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = dmatxdesc->DESC0; - /* Get timestamp high */ - timestamp->TimeStampHigh = dmatxdesc->DESC1; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get receive timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * receive timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Register the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txPtpCallback: Function to handle Ptp transmission - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback) -{ - if (txPtpCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - /* Set Function to handle Tx Ptp */ - heth->txPtpCallback = txPtpCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txPtpCallback = HAL_ETH_TxPtpCallback; - - return HAL_OK; -} - -/** - * @brief Tx Ptp callback. - * @param buff: pointer to application buffer - * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains - * transmission timestamp - * @retval None - */ -__weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxPtpCallback could be implemented in the user file - */ -} -#endif /* HAL_ETH_USE_PTP */ - -/** - * @brief This function handles ETH interrupt request. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) -{ - uint32_t mac_flag = READ_REG(heth->Instance->MACISR); - uint32_t dma_flag = READ_REG(heth->Instance->DMACSR); - uint32_t dma_itsource = READ_REG(heth->Instance->DMACIER); - uint32_t exti_flag = READ_REG(EXTI->RPR2); - - /* Packet received */ - if (((dma_flag & ETH_DMACSR_RI) != 0U) && ((dma_itsource & ETH_DMACIER_RIE) != 0U)) - { - /* Clear the Eth DMA Rx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Receive complete callback*/ - heth->RxCpltCallback(heth); -#else - /* Receive complete callback */ - HAL_ETH_RxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* Packet transmitted */ - if (((dma_flag & ETH_DMACSR_TI) != 0U) && ((dma_itsource & ETH_DMACIER_TIE) != 0U)) - { - /* Clear the Eth DMA Tx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Transmit complete callback*/ - heth->TxCpltCallback(heth); -#else - /* Transfer complete callback */ - HAL_ETH_TxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* ETH DMA Error */ - if (((dma_flag & ETH_DMACSR_AIS) != 0U) && ((dma_itsource & ETH_DMACIER_AIE) != 0U)) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - /* if fatal bus error occurred */ - if ((dma_flag & ETH_DMACSR_FBE) != 0U) - { - /* Get DMA error code */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS)); - - /* Disable all interrupts */ - __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE); - - /* Set HAL state to ERROR */ - heth->gState = HAL_ETH_STATE_ERROR; - } - else - { - /* Get DMA error status */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | - ETH_DMACSR_RBU | ETH_DMACSR_AIS)); - - /* Clear the interrupt summary flag */ - __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | - ETH_DMACSR_RBU | ETH_DMACSR_AIS)); - } -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered Error callback*/ - heth->ErrorCallback(heth); -#else - /* Ethernet DMA Error callback */ - HAL_ETH_ErrorCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* ETH MAC Error IT */ - if (((mac_flag & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \ - ((mac_flag & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE)) - { - heth->ErrorCode |= HAL_ETH_ERROR_MAC; - - /* Get MAC Rx Tx status and clear Status register pending bit */ - heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR); - - heth->gState = HAL_ETH_STATE_ERROR; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered Error callback*/ - heth->ErrorCallback(heth); -#else - /* Ethernet Error callback */ - HAL_ETH_ErrorCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - heth->MACErrorCode = (uint32_t)(0x0U); - } - - /* ETH PMT IT */ - if ((mac_flag & ETH_MAC_PMT_IT) != 0U) - { - /* Get MAC Wake-up source and clear the status register pending bit */ - heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD)); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered PMT callback*/ - heth->PMTCallback(heth); -#else - /* Ethernet PMT callback */ - HAL_ETH_PMTCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - heth->MACWakeUpEvent = (uint32_t)(0x0U); - } - - /* ETH EEE IT */ - if ((mac_flag & ETH_MAC_LPI_IT) != 0U) - { - /* Get MAC LPI interrupt source and clear the status register pending bit */ - heth->MACLPIEvent = READ_BIT(heth->Instance->MACPCSR, 0x0000000FU); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered EEE callback*/ - heth->EEECallback(heth); -#else - /* Ethernet EEE callback */ - HAL_ETH_EEECallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - heth->MACLPIEvent = (uint32_t)(0x0U); - } - - /* check ETH WAKEUP exti flag */ - if ((exti_flag & ETH_WAKEUP_EXTI_LINE) != 0U) - { - /* Clear ETH WAKEUP Exti pending bit */ - __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered WakeUp callback*/ - heth->WakeUpCallback(heth); -#else - /* ETH WAKEUP callback */ - HAL_ETH_WakeUpCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } -} - -/** - * @brief Tx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet transfer error callbacks - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_ErrorCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet Power Management module IT callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_PMTCallback could be implemented in the user file - */ -} - -/** - * @brief Energy Efficient Etherent IT callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_EEECallback could be implemented in the user file - */ -} - -/** - * @brief ETH WAKEUP interrupt callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_WakeUpCallback could be implemented in the user file - */ -} - -/** - * @brief Read a PHY register - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param pRegValue: parameter to hold read value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue) -{ - uint32_t tickstart; - uint32_t tmpreg; - - /* Check for the Busy flag */ - if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) - { - return HAL_ERROR; - } - - /* Get the MACMDIOAR value */ - WRITE_REG(tmpreg, heth->Instance->MACMDIOAR); - - /* Prepare the MDIO Address Register value - - Set the PHY device address - - Set the PHY register address - - Set the read mode - - Set the MII Busy bit */ - - MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD); - SET_BIT(tmpreg, ETH_MACMDIOAR_MB); - - /* Write the result value into the MDII Address register */ - WRITE_REG(heth->Instance->MACMDIOAR, tmpreg); - - tickstart = HAL_GetTick(); - - /* Wait for the Busy flag */ - while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) - { - return HAL_ERROR; - } - } - - /* Get MACMIIDR value */ - WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR); - - return HAL_OK; -} - -/** - * @brief Writes to a PHY register. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param RegValue: the value to write - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue) -{ - uint32_t tickstart; - uint32_t tmpreg; - - /* Check for the Busy flag */ - if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) - { - return HAL_ERROR; - } - - /* Get the MACMDIOAR value */ - WRITE_REG(tmpreg, heth->Instance->MACMDIOAR); - - /* Prepare the MDIO Address Register value - - Set the PHY device address - - Set the PHY register address - - Set the write mode - - Set the MII Busy bit */ - - MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR); - SET_BIT(tmpreg, ETH_MACMDIOAR_MB); - - /* Give the value to the MII data register */ - WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue); - - /* Write the result value into the MII Address register */ - WRITE_REG(ETH->MACMDIOAR, tmpreg); - - tickstart = HAL_GetTick(); - - /* Wait for the Busy flag */ - while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) - { - return HAL_ERROR; - } - } - - return HAL_OK; -} - -/** - * @} - */ + +/** + * @brief Unregister the Rx link callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; + + return HAL_OK; + } + +/** + * @brief Get the error state of the last received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pErrorCode: pointer to uint32_t to hold the error code + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( const ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ) + { + /* Get error bits. */ + *pErrorCode = READ_BIT( heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK ); + + return HAL_OK; + } + +/** + * @brief Set the Tx free function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txFreeCallback: pointer to function to release the packet + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ) + { + if( txFreeCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to free transmmitted packet */ + heth->txFreeCallback = txFreeCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx free callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; + + return HAL_OK; + } + +/** + * @brief Tx Free callback. + * @param buff: pointer to buffer to free + * @retval None + */ + __weak void HAL_ETH_TxFreeCallback( uint32_t * buff ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxFreeCallback could be implemented in the user file + */ + } + +/** + * @brief Release transmitted Tx packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t numOfBuf = dmatxdesclist->BuffersInUse; + uint32_t idx = dmatxdesclist->releaseIndex; + uint8_t pktTxStatus = 1U; + uint8_t pktInUse; + + #ifdef HAL_ETH_USE_PTP + ETH_TimeStampTypeDef * timestamp = &heth->TxTimestamp; + #endif /* HAL_ETH_USE_PTP */ + + /* Loop through buffers in use. */ + while( ( numOfBuf != 0U ) && ( pktTxStatus != 0U ) ) + { + pktInUse = 1U; + numOfBuf--; + + /* If no packet, just examine the next packet. */ + if( dmatxdesclist->PacketAddress[ idx ] == NULL ) + { + /* No packet in use, skip to next. */ + INCR_TX_DESC_INDEX( idx, 1U ); + pktInUse = 0U; + } + + if( pktInUse != 0U ) + { + /* Determine if the packet has been transmitted. */ + if( ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXNDESCRF_OWN ) == 0U ) + { + #ifdef HAL_ETH_USE_PTP + /* Disable Ptp transmission */ + CLEAR_BIT( heth->Init.TxDesc[ idx ].DESC3, ( 0x40000000U ) ); + + if( ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXNDESCWBF_LD ) && + ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXNDESCWBF_TTSS ) ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->Init.TxDesc[ idx ].DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->Init.TxDesc[ idx ].DESC1; + } + else + { + timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX; + } + #endif /* HAL_ETH_USE_PTP */ + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered callbacks*/ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + if( ( timestamp->TimeStampHigh != UINT32_MAX ) && ( timestamp->TimeStampLow != UINT32_MAX ) ) + { + heth->txPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + } + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + heth->txFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #else /* if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) */ + /* Call callbacks */ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + if( ( timestamp->TimeStampHigh != UINT32_MAX ) && ( timestamp->TimeStampLow != UINT32_MAX ) ) + { + HAL_ETH_TxPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + } + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + HAL_ETH_TxFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + /* Clear the entry in the in-use array. */ + dmatxdesclist->PacketAddress[ idx ] = NULL; + + /* Update the transmit relesae index and number of buffers in use. */ + INCR_TX_DESC_INDEX( idx, 1U ); + dmatxdesclist->BuffersInUse = numOfBuf; + dmatxdesclist->releaseIndex = idx; + } + else + { + /* Get out of the loop! */ + pktTxStatus = 0U; + } + } + } + + return HAL_OK; + } + + #ifdef HAL_ETH_USE_PTP + +/** + * @brief Set the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + uint32_t tmpTSCR; + ETH_TimeTypeDef time; + + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + tmpTSCR = ptpconfig->Timestamp | + ( ( uint32_t ) ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos ); + + /* Write to MACTSCR */ + MODIFY_REG( heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR ); + + /* Enable Timestamp */ + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSENA ); + WRITE_REG( heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc ); + WRITE_REG( heth->Instance->MACTSAR, ptpconfig->TimestampAddend ); + + /* Enable Timestamp */ + if( ptpconfig->TimestampAddendUpdate == ENABLE ) + { + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG ); + + while( ( heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG ) != 0 ) + { + } + } + + /* Ptp Init */ + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT ); + + /* Set PTP Configuration done */ + heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED; + + /* Set Seconds */ + time.Seconds = heth->Instance->MACSTSR; + /* Set NanoSeconds */ + time.NanoSeconds = heth->Instance->MACSTNR; + + HAL_ETH_PTP_SetTime( heth, &time ); + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Get the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + ptpconfig->Timestamp = READ_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSENA ); + ptpconfig->TimestampUpdate = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSCFUPDT ) >> ETH_MACTSCR_TSUPDT_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampAll = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSENALL ) >> ETH_MACTSCR_TSENALL_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampRolloverMode = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSCTRLSSR ) >> ETH_MACTSCR_TSCTRLSSR_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampV2 = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSVER2ENA ) >> ETH_MACTSCR_TSVER2ENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEthernet = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPENA ) >> ETH_MACTSCR_TSIPENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv6 = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPV6ENA ) >> ETH_MACTSCR_TSIPV6ENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv4 = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPV4ENA ) >> ETH_MACTSCR_TSIPV4ENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEvent = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSEVNTENA ) >> ETH_MACTSCR_TSEVNTENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampMaster = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSMSTRENA ) >> ETH_MACTSCR_TSMSTRENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampSnapshots = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_SNAPTYPSEL ) >> ETH_MACTSCR_SNAPTYPSEL_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampFilter = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSENMACADDR ) >> ETH_MACTSCR_TSENMACADDR_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampChecksumCorrection = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_CSC ) >> ETH_MACTSCR_CSC_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampStatusMode = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TXTSSTSM ) >> ETH_MACTSCR_TXTSSTSM_Pos ) > 0U ) + ? ENABLE : DISABLE; + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to set + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Set Seconds */ + heth->Instance->MACSTSUR = time->Seconds; + + /* Set NanoSeconds */ + heth->Instance->MACSTNUR = time->NanoSeconds; + + /* the system time is updated */ + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to get + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get Seconds */ + time->Seconds = heth->Instance->MACSTSR; + /* Get NanoSeconds */ + time->NanoSeconds = heth->Instance->MACSTNR; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Update time for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains + * the time update information + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + if( ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE ) + { + /* Set Seconds update */ + heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U; + + if( READ_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR ) == ETH_MACTSCR_TSCTRLSSR ) + { + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds; + } + else + { + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U; + } + } + else + { + /* Set Seconds update */ + heth->Instance->MACSTSUR = timeoffset->Seconds; + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = timeoffset->NanoSeconds; + } + + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Insert Timestamp in transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Enable Time Stamp transmission */ + SET_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get transmission timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * transmission timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t idx = dmatxdesclist->releaseIndex; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ idx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = dmatxdesc->DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = dmatxdesc->DESC1; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get receive timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * receive timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Register the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txPtpCallback: Function to handle Ptp transmission + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ) + { + if( txPtpCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set Function to handle Tx Ptp */ + heth->txPtpCallback = txPtpCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txPtpCallback = HAL_ETH_TxPtpCallback; + + return HAL_OK; + } + +/** + * @brief Tx Ptp callback. + * @param buff: pointer to application buffer + * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains + * transmission timestamp + * @retval None + */ + __weak void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxPtpCallback could be implemented in the user file + */ + } + #endif /* HAL_ETH_USE_PTP */ + +/** + * @brief This function handles ETH interrupt request. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ) + { + uint32_t mac_flag = READ_REG( heth->Instance->MACISR ); + uint32_t dma_flag = READ_REG( heth->Instance->DMACSR ); + uint32_t dma_itsource = READ_REG( heth->Instance->DMACIER ); + uint32_t exti_flag = READ_REG( EXTI->RPR2 ); + + /* Packet received */ + if( ( ( dma_flag & ETH_DMACSR_RI ) != 0U ) && ( ( dma_itsource & ETH_DMACIER_RIE ) != 0U ) ) + { + /* Clear the Eth DMA Rx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMACSR_RI | ETH_DMACSR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Receive complete callback*/ + heth->RxCpltCallback( heth ); + #else + /* Receive complete callback */ + HAL_ETH_RxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* Packet transmitted */ + if( ( ( dma_flag & ETH_DMACSR_TI ) != 0U ) && ( ( dma_itsource & ETH_DMACIER_TIE ) != 0U ) ) + { + /* Clear the Eth DMA Tx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMACSR_TI | ETH_DMACSR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Transmit complete callback*/ + heth->TxCpltCallback( heth ); + #else + /* Transfer complete callback */ + HAL_ETH_TxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* ETH DMA Error */ + if( ( ( dma_flag & ETH_DMACSR_AIS ) != 0U ) && ( ( dma_itsource & ETH_DMACIER_AIE ) != 0U ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + + /* if fatal bus error occurred */ + if( ( dma_flag & ETH_DMACSR_FBE ) != 0U ) + { + /* Get DMA error code */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMACSR, ( ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS ) ); + + /* Disable all interrupts */ + __HAL_ETH_DMA_DISABLE_IT( heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE ); + + /* Set HAL state to ERROR */ + heth->gState = HAL_ETH_STATE_ERROR; + } + else + { + /* Get DMA error status */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMACSR, ( ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | + ETH_DMACSR_RBU | ETH_DMACSR_AIS ) ); + + /* Clear the interrupt summary flag */ + __HAL_ETH_DMA_CLEAR_IT( heth, ( ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | + ETH_DMACSR_RBU | ETH_DMACSR_AIS ) ); + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered Error callback*/ + heth->ErrorCallback( heth ); + #else + /* Ethernet DMA Error callback */ + HAL_ETH_ErrorCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* ETH MAC Error IT */ + if( ( ( mac_flag & ETH_MACIER_RXSTSIE ) == ETH_MACIER_RXSTSIE ) || \ + ( ( mac_flag & ETH_MACIER_TXSTSIE ) == ETH_MACIER_TXSTSIE ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_MAC; + + /* Get MAC Rx Tx status and clear Status register pending bit */ + heth->MACErrorCode = READ_REG( heth->Instance->MACRXTXSR ); + + heth->gState = HAL_ETH_STATE_ERROR; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered Error callback*/ + heth->ErrorCallback( heth ); + #else + /* Ethernet Error callback */ + HAL_ETH_ErrorCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->MACErrorCode = ( uint32_t ) ( 0x0U ); + } + + /* ETH PMT IT */ + if( ( mac_flag & ETH_MAC_PMT_IT ) != 0U ) + { + /* Get MAC Wake-up source and clear the status register pending bit */ + heth->MACWakeUpEvent = READ_BIT( heth->Instance->MACPCSR, ( ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD ) ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered PMT callback*/ + heth->PMTCallback( heth ); + #else + /* Ethernet PMT callback */ + HAL_ETH_PMTCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACWakeUpEvent = ( uint32_t ) ( 0x0U ); + } + + /* ETH EEE IT */ + if( ( mac_flag & ETH_MAC_LPI_IT ) != 0U ) + { + /* Get MAC LPI interrupt source and clear the status register pending bit */ + heth->MACLPIEvent = READ_BIT( heth->Instance->MACPCSR, 0x0000000FU ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered EEE callback*/ + heth->EEECallback( heth ); + #else + /* Ethernet EEE callback */ + HAL_ETH_EEECallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACLPIEvent = ( uint32_t ) ( 0x0U ); + } + + /* check ETH WAKEUP exti flag */ + if( ( exti_flag & ETH_WAKEUP_EXTI_LINE ) != 0U ) + { + /* Clear ETH WAKEUP Exti pending bit */ + __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( ETH_WAKEUP_EXTI_LINE ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered WakeUp callback*/ + heth->WakeUpCallback( heth ); + #else + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + +/** + * @brief Tx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Rx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet transfer error callbacks + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_ErrorCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet Power Management module IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_PMTCallback could be implemented in the user file + */ + } + +/** + * @brief Energy Efficient Etherent IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_EEECallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_EEECallback could be implemented in the user file + */ + } + +/** + * @brief ETH WAKEUP interrupt callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_WakeUpCallback could be implemented in the user file + */ + } + +/** + * @brief Read a PHY register + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param pRegValue: parameter to hold read value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ) + { + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) != ( uint32_t ) RESET ) + { + return HAL_ERROR; + } + + /* Get the MACMDIOAR value */ + WRITE_REG( tmpreg, heth->Instance->MACMDIOAR ); + + /* Prepare the MDIO Address Register value + * - Set the PHY device address + * - Set the PHY register address + * - Set the read mode + * - Set the MII Busy bit */ + + MODIFY_REG( tmpreg, ETH_MACMDIOAR_PA, ( PHYAddr << 21 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_RDA, ( PHYReg << 16 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD ); + SET_BIT( tmpreg, ETH_MACMDIOAR_MB ); + + /* Write the result value into the MDII Address register */ + WRITE_REG( heth->Instance->MACMDIOAR, tmpreg ); + + tickstart = HAL_GetTick(); + + /* Wait for the Busy flag */ + while( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT ) ) + { + return HAL_ERROR; + } + } + + /* Get MACMIIDR value */ + WRITE_REG( *pRegValue, ( uint16_t ) heth->Instance->MACMDIODR ); + + return HAL_OK; + } + +/** + * @brief Writes to a PHY register. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param RegValue: the value to write + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ) + { + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) != ( uint32_t ) RESET ) + { + return HAL_ERROR; + } + + /* Get the MACMDIOAR value */ + WRITE_REG( tmpreg, heth->Instance->MACMDIOAR ); + + /* Prepare the MDIO Address Register value + * - Set the PHY device address + * - Set the PHY register address + * - Set the write mode + * - Set the MII Busy bit */ + + MODIFY_REG( tmpreg, ETH_MACMDIOAR_PA, ( PHYAddr << 21 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_RDA, ( PHYReg << 16 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR ); + SET_BIT( tmpreg, ETH_MACMDIOAR_MB ); + + /* Give the value to the MII data register */ + WRITE_REG( ETH->MACMDIODR, ( uint16_t ) RegValue ); + + /* Write the result value into the MII Address register */ + WRITE_REG( ETH->MACMDIOAR, tmpreg ); + + tickstart = HAL_GetTick(); + + /* Wait for the Busy flag */ + while( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT ) ) + { + return HAL_ERROR; + } + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions - * @brief ETH control functions - * -@verbatim - ============================================================================== - ##### Peripheral Control functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to control the ETH - peripheral. - -@endverbatim - * @{ - */ -/** - * @brief Get the configuration of the MAC and MTL subsystems. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold - * the configuration of the MAC. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - /* Get MAC parameters */ - macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN); - macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE; - macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL); - macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE; - macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U) - ? ENABLE : DISABLE; - macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE; - macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR, - ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE; - macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE; - macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM); - macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES); - macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE; - macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE; - macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE; - macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE; - macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE; - macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE; - macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR, - ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE; - macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG); - macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE; - macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC); - - macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL); - macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE; - macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE; - macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR, - ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE; - macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U) - ? ENABLE : DISABLE; - macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25; - - macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE; - macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO); - - macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE; - macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE; - macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT); - macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16); - macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE; - macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U) - ? ENABLE : DISABLE; - - macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF)); - - macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF)); - macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR, - ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE; - macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE; - macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, - ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Get the configuration of the DMA. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE; - dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB); - dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE; - - dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA)); - - dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE; - dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS); - - dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE; - dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL); - - dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE; - dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE; - dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL); - - return HAL_OK; -} - -/** - * @brief Set the MAC configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains - * the configuration of the MAC. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetMACConfig(heth, macconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Set the ETH DMA configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetDMAConfig(heth, dmaconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Configures the Clock range of ETH MDIO interface. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth) -{ - uint32_t hclk; - uint32_t tmpreg; - - /* Get the ETHERNET MACMDIOAR value */ - tmpreg = (heth->Instance)->MACMDIOAR; - - /* Clear CSR Clock Range bits */ - tmpreg &= ~ETH_MACMDIOAR_CR; - - /* Get hclk frequency value */ - hclk = HAL_RCC_GetHCLKFreq(); - - /* Set CR bits depending on hclk value */ - if (hclk < 35000000U) - { - /* CSR Clock Range between 0-35 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16; - } - else if (hclk < 60000000U) - { - /* CSR Clock Range between 35-60 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26; - } - else if (hclk < 100000000U) - { - /* CSR Clock Range between 60-100 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42; - } - else if (hclk < 150000000U) - { - /* CSR Clock Range between 100-150 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62; - } - else if (hclk < 250000000U) - { - /* CSR Clock Range between 150-250 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102; - } - else /* (hclk >= 250000000U) */ - { - /* CSR Clock >= 250 MHz */ - tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV124); - } - - /* Configure the CSR Clock Range */ - (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg; -} - -/** - * @brief Set the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - uint32_t filterconfig; - - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode | - ((uint32_t)pFilterConfig->HashUnicast << 1) | - ((uint32_t)pFilterConfig->HashMulticast << 2) | - ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) | - ((uint32_t)pFilterConfig->PassAllMulticast << 4) | - ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) | - ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) | - ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) | - ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) | - ((uint32_t)pFilterConfig->ReceiveAllMode << 31) | - pFilterConfig->ControlPacketsFilter); - - MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig); - - return HAL_OK; -} - -/** - * @brief Get the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE; - pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, - ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE; - pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE; - pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE; - pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF); - pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, - ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE; - pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U) - ? ENABLE : DISABLE; - pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Set the source MAC Address to be matched. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param AddrNbr: The MAC address to configure - * This parameter must be a value of the following: - * ETH_MAC_ADDRESS1 - * ETH_MAC_ADDRESS2 - * ETH_MAC_ADDRESS3 - * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr) -{ - uint32_t macaddrlr; - uint32_t macaddrhr; - - if (pMACAddr == NULL) - { - return HAL_ERROR; - } - - /* Get mac addr high reg offset */ - macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr); - /* Get mac addr low reg offset */ - macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr); - - /* Set MAC addr bits 32 to 47 */ - (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]); - /* Set MAC addr bits 0 to 31 */ - (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) | - ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]); - - /* Enable address and set source address bit */ - (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE); - - return HAL_OK; -} - -/** - * @brief Set the ETH Hash Table Value. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pHashTable: pointer to a table of two 32 bit values, that contains - * the 64 bits of the hash table. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable) -{ - if (pHashTable == NULL) - { - return HAL_ERROR; - } - - heth->Instance->MACHT0R = pHashTable[0]; - heth->Instance->MACHT1R = pHashTable[1]; - - return HAL_OK; -} - -/** - * @brief Set the VLAN Identifier for Rx packets - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ComparisonBits: 12 or 16 bit comparison mode - must be a value of @ref ETH_VLAN_Tag_Comparison - * @param VLANIdentifier: VLAN Identifier value - * @retval None - */ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier) -{ - if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) - { - MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier); - CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV); - } - else - { - MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier); - SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV); - } -} - -/** - * @brief Enters the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure - * that contains the Power Down configuration - * @retval None. - */ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig) -{ - uint32_t powerdownconfig; - - powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) | - ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) | - ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) | - ((uint32_t)pPowerDownConfig->WakeUpForward << 10) | - ETH_MACPCSR_PWRDWN); - - /* Enable PMT interrupt */ - __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE); - - MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig); -} - -/** - * @brief Exits from the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth) -{ - /* clear wake up sources */ - CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | - ETH_MACPCSR_RWKPFE); - - if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET) - { - /* Exit power down mode */ - CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN); - } - - /* Disable PMT interrupt */ - __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE); -} - -/** - * @brief Set the WakeUp filter. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilter: pointer to filter registers values - * @param Count: number of filter registers, must be from 1 to 8. - * @retval None. - */ -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count) -{ - uint32_t regindex; - - if (pFilter == NULL) - { - return HAL_ERROR; - } - - /* Reset Filter Pointer */ - SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST); - - /* Wake up packet filter config */ - for (regindex = 0; regindex < Count; regindex++) - { - /* Write filter regs */ - WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]); - } - - return HAL_OK; -} - -/** - * @} - */ + * @brief ETH control functions + * + * @verbatim + * ============================================================================== + ##### Peripheral Control functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to control the ETH + #####peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Get the configuration of the MAC and MTL subsystems. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold + * the configuration of the MAC. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetMACConfig( const ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + /* Get MAC parameters */ + macconf->PreambleLength = READ_BIT( heth->Instance->MACCR, ETH_MACCR_PRELEN ); + macconf->DeferralCheck = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DC ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + macconf->BackOffLimit = READ_BIT( heth->Instance->MACCR, ETH_MACCR_BL ); + macconf->RetryTransmission = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DR ) >> 8 ) == 0U ) ? ENABLE : DISABLE; + macconf->CarrierSenseDuringTransmit = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DCRS ) >> 9 ) > 0U ) + ? ENABLE : DISABLE; + macconf->ReceiveOwn = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DO ) >> 10 ) == 0U ) ? ENABLE : DISABLE; + macconf->CarrierSenseBeforeTransmit = ( ( READ_BIT( heth->Instance->MACCR, + ETH_MACCR_ECRSFD ) >> 11 ) > 0U ) ? ENABLE : DISABLE; + macconf->LoopbackMode = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_LM ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + macconf->DuplexMode = READ_BIT( heth->Instance->MACCR, ETH_MACCR_DM ); + macconf->Speed = READ_BIT( heth->Instance->MACCR, ETH_MACCR_FES ); + macconf->JumboPacket = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_JE ) >> 16 ) > 0U ) ? ENABLE : DISABLE; + macconf->Jabber = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_JD ) >> 17 ) == 0U ) ? ENABLE : DISABLE; + macconf->Watchdog = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_WD ) >> 19 ) == 0U ) ? ENABLE : DISABLE; + macconf->AutomaticPadCRCStrip = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_ACS ) >> 20 ) > 0U ) ? ENABLE : DISABLE; + macconf->CRCStripTypePacket = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_CST ) >> 21 ) > 0U ) ? ENABLE : DISABLE; + macconf->Support2KPacket = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_S2KP ) >> 22 ) > 0U ) ? ENABLE : DISABLE; + macconf->GiantPacketSizeLimitControl = ( ( READ_BIT( heth->Instance->MACCR, + ETH_MACCR_GPSLCE ) >> 23 ) > 0U ) ? ENABLE : DISABLE; + macconf->InterPacketGapVal = READ_BIT( heth->Instance->MACCR, ETH_MACCR_IPG ); + macconf->ChecksumOffload = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_IPC ) >> 27 ) > 0U ) ? ENABLE : DISABLE; + macconf->SourceAddrControl = READ_BIT( heth->Instance->MACCR, ETH_MACCR_SARC ); + + macconf->GiantPacketSizeLimit = READ_BIT( heth->Instance->MACECR, ETH_MACECR_GPSL ); + macconf->CRCCheckingRxPackets = ( ( READ_BIT( heth->Instance->MACECR, ETH_MACECR_DCRCC ) >> 16 ) == 0U ) ? ENABLE : DISABLE; + macconf->SlowProtocolDetect = ( ( READ_BIT( heth->Instance->MACECR, ETH_MACECR_SPEN ) >> 17 ) > 0U ) ? ENABLE : DISABLE; + macconf->UnicastSlowProtocolPacketDetect = ( ( READ_BIT( heth->Instance->MACECR, + ETH_MACECR_USP ) >> 18 ) > 0U ) ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGap = ( ( READ_BIT( heth->Instance->MACECR, ETH_MACECR_EIPGEN ) >> 24 ) > 0U ) + ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGapVal = READ_BIT( heth->Instance->MACECR, ETH_MACECR_EIPG ) >> 25; + + macconf->ProgrammableWatchdog = ( ( READ_BIT( heth->Instance->MACWTR, ETH_MACWTR_PWE ) >> 8 ) > 0U ) ? ENABLE : DISABLE; + macconf->WatchdogTimeout = READ_BIT( heth->Instance->MACWTR, ETH_MACWTR_WTO ); + + macconf->TransmitFlowControl = ( ( READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_TFE ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + macconf->ZeroQuantaPause = ( ( READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ ) >> 7 ) == 0U ) ? ENABLE : DISABLE; + macconf->PauseLowThreshold = READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_PLT ); + macconf->PauseTime = ( READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_PT ) >> 16 ); + macconf->ReceiveFlowControl = ( READ_BIT( heth->Instance->MACRFCR, ETH_MACRFCR_RFE ) > 0U ) ? ENABLE : DISABLE; + macconf->UnicastPausePacketDetect = ( ( READ_BIT( heth->Instance->MACRFCR, ETH_MACRFCR_UP ) >> 1 ) > 0U ) + ? ENABLE : DISABLE; + + macconf->TransmitQueueMode = READ_BIT( heth->Instance->MTLTQOMR, ( ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF ) ); + + macconf->ReceiveQueueMode = READ_BIT( heth->Instance->MTLRQOMR, ( ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF ) ); + macconf->ForwardRxUndersizedGoodPacket = ( ( READ_BIT( heth->Instance->MTLRQOMR, + ETH_MTLRQOMR_FUP ) >> 3 ) > 0U ) ? ENABLE : DISABLE; + macconf->ForwardRxErrorPacket = ( ( READ_BIT( heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + macconf->DropTCPIPChecksumErrorPacket = ( ( READ_BIT( heth->Instance->MTLRQOMR, + ETH_MTLRQOMR_DISTCPEF ) >> 6 ) == 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Get the configuration of the DMA. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( const ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + dmaconf->AddressAlignedBeats = ( ( READ_BIT( heth->Instance->DMASBMR, ETH_DMASBMR_AAL ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->BurstMode = READ_BIT( heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB ); + dmaconf->RebuildINCRxBurst = ( ( READ_BIT( heth->Instance->DMASBMR, ETH_DMASBMR_RB ) >> 15 ) > 0U ) ? ENABLE : DISABLE; + + dmaconf->DMAArbitration = READ_BIT( heth->Instance->DMAMR, ( ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA ) ); + + dmaconf->PBLx8Mode = ( ( READ_BIT( heth->Instance->DMACCR, ETH_DMACCR_8PBL ) >> 16 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->MaximumSegmentSize = READ_BIT( heth->Instance->DMACCR, ETH_DMACCR_MSS ); + + dmaconf->FlushRxPacket = ( ( READ_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_RPF ) >> 31 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->RxDMABurstLength = READ_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_RPBL ); + + dmaconf->SecondPacketOperate = ( ( READ_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_OSP ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->TCPSegmentation = ( ( READ_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_TSE ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->TxDMABurstLength = READ_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_TPBL ); + + return HAL_OK; + } + +/** + * @brief Set the MAC configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains + * the configuration of the MAC. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetMACConfig( heth, macconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Set the ETH DMA configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetDMAConfig( heth, dmaconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Configures the Clock range of ETH MDIO interface. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ) + { + uint32_t hclk; + uint32_t tmpreg; + + /* Get the ETHERNET MACMDIOAR value */ + tmpreg = ( heth->Instance )->MACMDIOAR; + + /* Clear CSR Clock Range bits */ + tmpreg &= ~ETH_MACMDIOAR_CR; + + /* Get hclk frequency value */ + hclk = HAL_RCC_GetHCLKFreq(); + + /* Set CR bits depending on hclk value */ + if( hclk < 35000000U ) + { + /* CSR Clock Range between 0-35 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV16; + } + else if( hclk < 60000000U ) + { + /* CSR Clock Range between 35-60 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV26; + } + else if( hclk < 100000000U ) + { + /* CSR Clock Range between 60-100 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV42; + } + else if( hclk < 150000000U ) + { + /* CSR Clock Range between 100-150 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV62; + } + else if( hclk < 250000000U ) + { + /* CSR Clock Range between 150-250 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV102; + } + else /* (hclk >= 250000000U) */ + { + /* CSR Clock >= 250 MHz */ + tmpreg |= ( uint32_t ) ( ETH_MACMDIOAR_CR_DIV124 ); + } + + /* Configure the CSR Clock Range */ + ( heth->Instance )->MACMDIOAR = ( uint32_t ) tmpreg; + } + +/** + * @brief Set the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + uint32_t filterconfig; + + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + filterconfig = ( ( uint32_t ) pFilterConfig->PromiscuousMode | + ( ( uint32_t ) pFilterConfig->HashUnicast << 1 ) | + ( ( uint32_t ) pFilterConfig->HashMulticast << 2 ) | + ( ( uint32_t ) pFilterConfig->DestAddrInverseFiltering << 3 ) | + ( ( uint32_t ) pFilterConfig->PassAllMulticast << 4 ) | + ( ( uint32_t ) ( ( pFilterConfig->BroadcastFilter == DISABLE ) ? 1U : 0U ) << 5 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrInverseFiltering << 8 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrFiltering << 9 ) | + ( ( uint32_t ) pFilterConfig->HachOrPerfectFilter << 10 ) | + ( ( uint32_t ) pFilterConfig->ReceiveAllMode << 31 ) | + pFilterConfig->ControlPacketsFilter ); + + MODIFY_REG( heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig ); + + return HAL_OK; + } + +/** + * @brief Get the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( const ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + pFilterConfig->PromiscuousMode = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PR ) ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashUnicast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HUC ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashMulticast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HMC ) >> 2 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->DestAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACPFR, + ETH_MACPFR_DAIF ) >> 3 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->PassAllMulticast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PM ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->BroadcastFilter = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_DBF ) >> 5 ) == 0U ) ? ENABLE : DISABLE; + pFilterConfig->ControlPacketsFilter = READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PCF ); + pFilterConfig->SrcAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACPFR, + ETH_MACPFR_SAIF ) >> 8 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->SrcAddrFiltering = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_SAF ) >> 9 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HachOrPerfectFilter = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HPF ) >> 10 ) > 0U ) + ? ENABLE : DISABLE; + pFilterConfig->ReceiveAllMode = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_RA ) >> 31 ) > 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Set the source MAC Address to be matched. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param AddrNbr: The MAC address to configure + * This parameter must be a value of the following: + * ETH_MAC_ADDRESS1 + * ETH_MAC_ADDRESS2 + * ETH_MAC_ADDRESS3 + * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ) + { + uint32_t macaddrlr; + uint32_t macaddrhr; + + if( pMACAddr == NULL ) + { + return HAL_ERROR; + } + + /* Get mac addr high reg offset */ + macaddrhr = ( ( uint32_t ) &( heth->Instance->MACA0HR ) + AddrNbr ); + /* Get mac addr low reg offset */ + macaddrlr = ( ( uint32_t ) &( heth->Instance->MACA0LR ) + AddrNbr ); + + /* Set MAC addr bits 32 to 47 */ + ( *( __IO uint32_t * ) macaddrhr ) = ( ( ( uint32_t ) ( pMACAddr[ 5 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 4 ] ); + /* Set MAC addr bits 0 to 31 */ + ( *( __IO uint32_t * ) macaddrlr ) = ( ( ( uint32_t ) ( pMACAddr[ 3 ] ) << 24 ) | ( ( uint32_t ) ( pMACAddr[ 2 ] ) << 16 ) | + ( ( uint32_t ) ( pMACAddr[ 1 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 0 ] ); + + /* Enable address and set source address bit */ + ( *( __IO uint32_t * ) macaddrhr ) |= ( ETH_MACAHR_SA | ETH_MACAHR_AE ); + + return HAL_OK; + } + +/** + * @brief Set the ETH Hash Table Value. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pHashTable: pointer to a table of two 32 bit values, that contains + * the 64 bits of the hash table. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ) + { + if( pHashTable == NULL ) + { + return HAL_ERROR; + } + + heth->Instance->MACHT0R = pHashTable[ 0 ]; + heth->Instance->MACHT1R = pHashTable[ 1 ]; + + return HAL_OK; + } + +/** + * @brief Set the VLAN Identifier for Rx packets + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ComparisonBits: 12 or 16 bit comparison mode + * must be a value of @ref ETH_VLAN_Tag_Comparison + * @param VLANIdentifier: VLAN Identifier value + * @retval None + */ + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ) + { + if( ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT ) + { + MODIFY_REG( heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier ); + CLEAR_BIT( heth->Instance->MACVTR, ETH_MACVTR_ETV ); + } + else + { + MODIFY_REG( heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier ); + SET_BIT( heth->Instance->MACVTR, ETH_MACVTR_ETV ); + } + } + +/** + * @brief Enters the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure + * that contains the Power Down configuration + * @retval None. + */ + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ) + { + uint32_t powerdownconfig; + + powerdownconfig = ( ( ( uint32_t ) pPowerDownConfig->MagicPacket << 1 ) | + ( ( uint32_t ) pPowerDownConfig->WakeUpPacket << 2 ) | + ( ( uint32_t ) pPowerDownConfig->GlobalUnicast << 9 ) | + ( ( uint32_t ) pPowerDownConfig->WakeUpForward << 10 ) | + ETH_MACPCSR_PWRDWN ); + + /* Enable PMT interrupt */ + __HAL_ETH_MAC_ENABLE_IT( heth, ETH_MACIER_PMTIE ); + + MODIFY_REG( heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig ); + } + +/** + * @brief Exits from the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ) + { + /* clear wake up sources */ + CLEAR_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | + ETH_MACPCSR_RWKPFE ); + + if( READ_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN ) != ( uint32_t ) RESET ) + { + /* Exit power down mode */ + CLEAR_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN ); + } + + /* Disable PMT interrupt */ + __HAL_ETH_MAC_DISABLE_IT( heth, ETH_MACIER_PMTIE ); + } + +/** + * @brief Set the WakeUp filter. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilter: pointer to filter registers values + * @param Count: number of filter registers, must be from 1 to 8. + * @retval None. + */ + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ) + { + uint32_t regindex; + + if( pFilter == NULL ) + { + return HAL_ERROR; + } + + /* Reset Filter Pointer */ + SET_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST ); + + /* Wake up packet filter config */ + for( regindex = 0; regindex < Count; regindex++ ) + { + /* Write filter regs */ + WRITE_REG( heth->Instance->MACRWKPFR, pFilter[ regindex ] ); + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions - * @brief ETH State and Errors functions - * -@verbatim - ============================================================================== - ##### Peripheral State and Errors functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to return the State of - ETH communication process, return Peripheral Errors occurred during communication - process - - -@endverbatim - * @{ - */ - -/** - * @brief Returns the ETH state. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL state - */ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth) -{ - return heth->gState; -} - -/** - * @brief Returns the ETH error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH Error Code - */ -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth) -{ - return heth->ErrorCode; -} - -/** - * @brief Returns the ETH DMA error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH DMA Error Code - */ -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth) -{ - return heth->DMAErrorCode; -} - -/** - * @brief Returns the ETH MAC error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC Error Code - */ -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth) -{ - return heth->MACErrorCode; -} - -/** - * @brief Returns the ETH MAC WakeUp event source - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC WakeUp event source - */ -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth) -{ - return heth->MACWakeUpEvent; -} - -/** - * @} - */ - -/** - * @} - */ + * @brief ETH State and Errors functions + * + * @verbatim + * ============================================================================== + ##### Peripheral State and Errors functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to return the State of + #####ETH communication process, return Peripheral Errors occurred during communication + #####process + ##### + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Returns the ETH state. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL state + */ + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ) + { + return heth->gState; + } + +/** + * @brief Returns the ETH error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH Error Code + */ + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ) + { + return heth->ErrorCode; + } + +/** + * @brief Returns the ETH DMA error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH DMA Error Code + */ + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ) + { + return heth->DMAErrorCode; + } + +/** + * @brief Returns the ETH MAC error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC Error Code + */ + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ) + { + return heth->MACErrorCode; + } + +/** + * @brief Returns the ETH MAC WakeUp event source + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event source + */ + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ) + { + return heth->MACWakeUpEvent; + } + +/** + * @} + */ + +/** + * @} + */ /** @addtogroup ETH_Private_Functions ETH Private Functions - * @{ - */ - -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf) -{ - uint32_t macregval; - - /*------------------------ MACCR Configuration --------------------*/ - macregval = (macconf->InterPacketGapVal | - macconf->SourceAddrControl | - ((uint32_t)macconf->ChecksumOffload << 27) | - ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) | - ((uint32_t)macconf->Support2KPacket << 22) | - ((uint32_t)macconf->CRCStripTypePacket << 21) | - ((uint32_t)macconf->AutomaticPadCRCStrip << 20) | - ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) | - ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) | - ((uint32_t)macconf->JumboPacket << 16) | - macconf->Speed | - macconf->DuplexMode | - ((uint32_t)macconf->LoopbackMode << 12) | - ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) | - ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) | - ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) | - ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) | - macconf->BackOffLimit | - ((uint32_t)macconf->DeferralCheck << 4) | - macconf->PreambleLength); - - /* Write to MACCR */ - MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval); - - /*------------------------ MACECR Configuration --------------------*/ - macregval = ((macconf->ExtendedInterPacketGapVal << 25) | - ((uint32_t)macconf->ExtendedInterPacketGap << 24) | - ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) | - ((uint32_t)macconf->SlowProtocolDetect << 17) | - ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) | - macconf->GiantPacketSizeLimit); - - /* Write to MACECR */ - MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval); - - /*------------------------ MACWTR Configuration --------------------*/ - macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) | - macconf->WatchdogTimeout); - - /* Write to MACWTR */ - MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval); - - /*------------------------ MACTFCR Configuration --------------------*/ - macregval = (((uint32_t)macconf->TransmitFlowControl << 1) | - macconf->PauseLowThreshold | - ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) | - (macconf->PauseTime << 16)); - - /* Write to MACTFCR */ - MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval); - - /*------------------------ MACRFCR Configuration --------------------*/ - macregval = ((uint32_t)macconf->ReceiveFlowControl | - ((uint32_t)macconf->UnicastPausePacketDetect << 1)); - - /* Write to MACRFCR */ - MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval); - - /*------------------------ MTLTQOMR Configuration --------------------*/ - /* Write to MTLTQOMR */ - MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode); - - /*------------------------ MTLRQOMR Configuration --------------------*/ - macregval = (macconf->ReceiveQueueMode | - ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) | - ((uint32_t)macconf->ForwardRxErrorPacket << 4) | - ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3)); - - /* Write to MTLRQOMR */ - MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval); -} - -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf) -{ - uint32_t dmaregval; - - /*------------------------ DMAMR Configuration --------------------*/ - MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration); - - /*------------------------ DMASBMR Configuration --------------------*/ - dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) | - dmaconf->BurstMode | - ((uint32_t)dmaconf->RebuildINCRxBurst << 15)); - - MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval); - - /*------------------------ DMACCR Configuration --------------------*/ - dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) | - dmaconf->MaximumSegmentSize); - MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval); - - /*------------------------ DMACTCR Configuration --------------------*/ - dmaregval = (dmaconf->TxDMABurstLength | - ((uint32_t)dmaconf->SecondPacketOperate << 4) | - ((uint32_t)dmaconf->TCPSegmentation << 12)); - - MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval); - - /*------------------------ DMACRCR Configuration --------------------*/ - dmaregval = (((uint32_t)dmaconf->FlushRxPacket << 31) | - dmaconf->RxDMABurstLength); - - /* Write to DMACRCR */ - MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval); -} - -/** - * @brief Configures Ethernet MAC and DMA with default parameters. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth) -{ - ETH_MACConfigTypeDef macDefaultConf; - ETH_DMAConfigTypeDef dmaDefaultConf; - - /*--------------- ETHERNET MAC registers default Configuration --------------*/ - macDefaultConf.AutomaticPadCRCStrip = ENABLE; - macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; - macDefaultConf.CarrierSenseBeforeTransmit = DISABLE; - macDefaultConf.CarrierSenseDuringTransmit = DISABLE; - macDefaultConf.ChecksumOffload = ENABLE; - macDefaultConf.CRCCheckingRxPackets = ENABLE; - macDefaultConf.CRCStripTypePacket = ENABLE; - macDefaultConf.DeferralCheck = DISABLE; - macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE; - macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; - macDefaultConf.ExtendedInterPacketGap = DISABLE; - macDefaultConf.ExtendedInterPacketGapVal = 0x0U; - macDefaultConf.ForwardRxErrorPacket = DISABLE; - macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE; - macDefaultConf.GiantPacketSizeLimit = 0x618U; - macDefaultConf.GiantPacketSizeLimitControl = DISABLE; - macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT; - macDefaultConf.Jabber = ENABLE; - macDefaultConf.JumboPacket = DISABLE; - macDefaultConf.LoopbackMode = DISABLE; - macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4; - macDefaultConf.PauseTime = 0x0U; - macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7; - macDefaultConf.ProgrammableWatchdog = DISABLE; - macDefaultConf.ReceiveFlowControl = DISABLE; - macDefaultConf.ReceiveOwn = ENABLE; - macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD; - macDefaultConf.RetryTransmission = ENABLE; - macDefaultConf.SlowProtocolDetect = DISABLE; - macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0; - macDefaultConf.Speed = ETH_SPEED_100M; - macDefaultConf.Support2KPacket = DISABLE; - macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD; - macDefaultConf.TransmitFlowControl = DISABLE; - macDefaultConf.UnicastPausePacketDetect = DISABLE; - macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE; - macDefaultConf.Watchdog = ENABLE; - macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB; - macDefaultConf.ZeroQuantaPause = ENABLE; - - /* MAC default configuration */ - ETH_SetMACConfig(heth, &macDefaultConf); - - /*--------------- ETHERNET DMA registers default Configuration --------------*/ - dmaDefaultConf.AddressAlignedBeats = ENABLE; - dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; - dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1; - dmaDefaultConf.FlushRxPacket = DISABLE; - dmaDefaultConf.PBLx8Mode = DISABLE; - dmaDefaultConf.RebuildINCRxBurst = DISABLE; - dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.SecondPacketOperate = DISABLE; - dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.TCPSegmentation = DISABLE; - dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT; - - /* DMA default configuration */ - ETH_SetDMAConfig(heth, &dmaDefaultConf); -} - -/** - * @brief Initializes the DMA Tx descriptors. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmatxdesc; - uint32_t i; - - /* Fill each DMATxDesc descriptor with the right values */ - for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++) - { - dmatxdesc = heth->Init.TxDesc + i; - - WRITE_REG(dmatxdesc->DESC0, 0x0U); - WRITE_REG(dmatxdesc->DESC1, 0x0U); - WRITE_REG(dmatxdesc->DESC2, 0x0U); - WRITE_REG(dmatxdesc->DESC3, 0x0U); - - WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc); - - } - - heth->TxDescList.CurTxDesc = 0; - - /* Set Transmit Descriptor Ring Length */ - WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U)); - - /* Set Transmit Descriptor List Address */ - WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc); - - /* Set Transmit Descriptor Tail pointer */ - WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc); -} - -/** - * @brief Initializes the DMA Rx descriptors in chain mode. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t i; - - for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) - { - dmarxdesc = heth->Init.RxDesc + i; - - WRITE_REG(dmarxdesc->DESC0, 0x0U); - WRITE_REG(dmarxdesc->DESC1, 0x0U); - WRITE_REG(dmarxdesc->DESC2, 0x0U); - WRITE_REG(dmarxdesc->DESC3, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr0, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr1, 0x0U); - - /* Set Rx descritors addresses */ - WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc); - - } - - WRITE_REG(heth->RxDescList.RxDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxDescCnt, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U); - WRITE_REG(heth->RxDescList.ItMode, 0U); - - /* Set Receive Descriptor Ring Length */ - WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U))); - - /* Set Receive Descriptor List Address */ - WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc); - - /* Set Receive Descriptor Tail pointer Address */ - WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U)))); -} - -/** - * @brief Prepare Tx DMA descriptor before transmission. - * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Tx packet configuration - * @param ItMode: Enable or disable Tx EOT interrept - * @retval Status - */ -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, - uint32_t ItMode) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - uint32_t firstdescidx = dmatxdesclist->CurTxDesc; - uint32_t idx; - uint32_t descnbr = 0; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer; - uint32_t bd_count = 0; - uint32_t primask_bit; - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - return HAL_ETH_ERROR_BUSY; - } - - /***************************************************************************/ - /***************** Context descriptor configuration (Optional) **********/ - /***************************************************************************/ - /* If VLAN tag is enabled for this packet */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) - { - /* Set vlan tag value */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag); - /* Set vlan tag valid bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV); - /* Set the descriptor as the vlan input source */ - SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI); - - /* if inner VLAN is enabled */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET) - { - /* Set inner vlan tag value */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16)); - /* Set inner vlan tag valid bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV); - - /* Set Vlan Tag control */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl); - - /* Set the descriptor as the inner vlan input source */ - SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI); - /* Enable double VLAN processing */ - SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP); - } - } - - /* if tcp segmentation is enabled for this packet */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) - { - /* Set MSS value */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize); - /* Set MSS valid bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV); - } - - if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) - || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)) - { - /* Set as context descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT); - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Set own bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN); - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - descnbr += 1U; - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) - { - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx]; - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Clear own bit */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN); - - return HAL_ETH_ERROR_BUSY; - } - } - - /***************************************************************************/ - /***************** Normal descriptors configuration *****************/ - /***************************************************************************/ - - descnbr += 1U; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); - - if (txbuffer->next != NULL) - { - txbuffer = txbuffer->next; - /* Set buffer 2 address */ - WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); - } - else - { - WRITE_REG(dmatxdesc->DESC1, 0x0U); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) - { - /* Set TCP Header length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19)); - /* Set TCP payload length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); - /* Set TCP Segmentation Enabled bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE); - } - else - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET) - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl); - } - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) - { - /* Set Vlan Tag control */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl); - } - - /* Mark it as First Descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); - /* Mark it as NORMAL descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* set OWN bit of FIRST descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); - - /* If source address insertion/replacement is enabled for this packet */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET) - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl); - } - - /* only if the packet is split into more than one descriptors > 1 */ - while (txbuffer->next != NULL) - { - /* Clear the LD bit of previous descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* Clear the FD bit of new Descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - descidx = firstdescidx; - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* clear previous desc own bit */ - for (idx = 0; idx < descnbr; idx ++) - { - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); - - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - } - - return HAL_ETH_ERROR_BUSY; - } - - descnbr += 1U; - - /* Get the next Tx buffer in the list */ - txbuffer = txbuffer->next; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); - - if (txbuffer->next != NULL) - { - /* Get the next Tx buffer in the list */ - txbuffer = txbuffer->next; - /* Set buffer 2 address */ - WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); - } - else - { - WRITE_REG(dmatxdesc->DESC1, 0x0U); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) - { - /* Set TCP payload length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); - /* Set TCP Segmentation Enabled bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE); - } - else - { - /* Set the packet length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) - { - /* Checksum Insertion Control */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); - } - } - - bd_count += 1U; - - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Set Own bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); - /* Mark it as NORMAL descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); - } - - if (ItMode != ((uint32_t)RESET)) - { - /* Set Interrupt on completion bit */ - SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); - } - else - { - /* Clear Interrupt on completion bit */ - CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); - } - - /* Mark it as LAST descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); - /* Save the current packet address to expose it to the application */ - dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress; - - dmatxdesclist->CurTxDesc = descidx; - - /* Enter critical section */ - primask_bit = __get_PRIMASK(); - __set_PRIMASK(1); - - dmatxdesclist->BuffersInUse += bd_count + 1U; - - /* Exit critical section: restore previous priority mask */ - __set_PRIMASK(primask_bit); - - /* Return function status */ - return HAL_ETH_ERROR_NONE; -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth) -{ - /* Init the ETH Callback settings */ - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ - heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ - heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ - heth->EEECallback = HAL_ETH_EEECallback; /* Legacy weak EEECallback */ - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ -#ifdef HAL_ETH_USE_PTP - heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ -#endif /* HAL_ETH_USE_PTP */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* ETH */ + * @{ + */ + + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + const ETH_MACConfigTypeDef * macconf ) + { + uint32_t macregval; + + /*------------------------ MACCR Configuration --------------------*/ + macregval = ( macconf->InterPacketGapVal | + macconf->SourceAddrControl | + ( ( uint32_t ) macconf->ChecksumOffload << 27 ) | + ( ( uint32_t ) macconf->GiantPacketSizeLimitControl << 23 ) | + ( ( uint32_t ) macconf->Support2KPacket << 22 ) | + ( ( uint32_t ) macconf->CRCStripTypePacket << 21 ) | + ( ( uint32_t ) macconf->AutomaticPadCRCStrip << 20 ) | + ( ( uint32_t ) ( ( macconf->Watchdog == DISABLE ) ? 1U : 0U ) << 19 ) | + ( ( uint32_t ) ( ( macconf->Jabber == DISABLE ) ? 1U : 0U ) << 17 ) | + ( ( uint32_t ) macconf->JumboPacket << 16 ) | + macconf->Speed | + macconf->DuplexMode | + ( ( uint32_t ) macconf->LoopbackMode << 12 ) | + ( ( uint32_t ) macconf->CarrierSenseBeforeTransmit << 11 ) | + ( ( uint32_t ) ( ( macconf->ReceiveOwn == DISABLE ) ? 1U : 0U ) << 10 ) | + ( ( uint32_t ) macconf->CarrierSenseDuringTransmit << 9 ) | + ( ( uint32_t ) ( ( macconf->RetryTransmission == DISABLE ) ? 1U : 0U ) << 8 ) | + macconf->BackOffLimit | + ( ( uint32_t ) macconf->DeferralCheck << 4 ) | + macconf->PreambleLength ); + + /* Write to MACCR */ + MODIFY_REG( heth->Instance->MACCR, ETH_MACCR_MASK, macregval ); + + /*------------------------ MACECR Configuration --------------------*/ + macregval = ( ( macconf->ExtendedInterPacketGapVal << 25 ) | + ( ( uint32_t ) macconf->ExtendedInterPacketGap << 24 ) | + ( ( uint32_t ) macconf->UnicastSlowProtocolPacketDetect << 18 ) | + ( ( uint32_t ) macconf->SlowProtocolDetect << 17 ) | + ( ( uint32_t ) ( ( macconf->CRCCheckingRxPackets == DISABLE ) ? 1U : 0U ) << 16 ) | + macconf->GiantPacketSizeLimit ); + + /* Write to MACECR */ + MODIFY_REG( heth->Instance->MACECR, ETH_MACECR_MASK, macregval ); + + /*------------------------ MACWTR Configuration --------------------*/ + macregval = ( ( ( uint32_t ) macconf->ProgrammableWatchdog << 8 ) | + macconf->WatchdogTimeout ); + + /* Write to MACWTR */ + MODIFY_REG( heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval ); + + /*------------------------ MACTFCR Configuration --------------------*/ + macregval = ( ( ( uint32_t ) macconf->TransmitFlowControl << 1 ) | + macconf->PauseLowThreshold | + ( ( uint32_t ) ( ( macconf->ZeroQuantaPause == DISABLE ) ? 1U : 0U ) << 7 ) | + ( macconf->PauseTime << 16 ) ); + + /* Write to MACTFCR */ + MODIFY_REG( heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval ); + + /*------------------------ MACRFCR Configuration --------------------*/ + macregval = ( ( uint32_t ) macconf->ReceiveFlowControl | + ( ( uint32_t ) macconf->UnicastPausePacketDetect << 1 ) ); + + /* Write to MACRFCR */ + MODIFY_REG( heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval ); + + /*------------------------ MTLTQOMR Configuration --------------------*/ + /* Write to MTLTQOMR */ + MODIFY_REG( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode ); + + /*------------------------ MTLRQOMR Configuration --------------------*/ + macregval = ( macconf->ReceiveQueueMode | + ( ( uint32_t ) ( ( macconf->DropTCPIPChecksumErrorPacket == DISABLE ) ? 1U : 0U ) << 6 ) | + ( ( uint32_t ) macconf->ForwardRxErrorPacket << 4 ) | + ( ( uint32_t ) macconf->ForwardRxUndersizedGoodPacket << 3 ) ); + + /* Write to MTLRQOMR */ + MODIFY_REG( heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval ); + } + + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + const ETH_DMAConfigTypeDef * dmaconf ) + { + uint32_t dmaregval; + + /*------------------------ DMAMR Configuration --------------------*/ + MODIFY_REG( heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration ); + + /*------------------------ DMASBMR Configuration --------------------*/ + dmaregval = ( ( ( uint32_t ) dmaconf->AddressAlignedBeats << 12 ) | + dmaconf->BurstMode | + ( ( uint32_t ) dmaconf->RebuildINCRxBurst << 15 ) ); + + MODIFY_REG( heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval ); + + /*------------------------ DMACCR Configuration --------------------*/ + dmaregval = ( ( ( uint32_t ) dmaconf->PBLx8Mode << 16 ) | + dmaconf->MaximumSegmentSize ); + MODIFY_REG( heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval ); + + /*------------------------ DMACTCR Configuration --------------------*/ + dmaregval = ( dmaconf->TxDMABurstLength | + ( ( uint32_t ) dmaconf->SecondPacketOperate << 4 ) | + ( ( uint32_t ) dmaconf->TCPSegmentation << 12 ) ); + + MODIFY_REG( heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval ); + + /*------------------------ DMACRCR Configuration --------------------*/ + dmaregval = ( ( ( uint32_t ) dmaconf->FlushRxPacket << 31 ) | + dmaconf->RxDMABurstLength ); + + /* Write to DMACRCR */ + MODIFY_REG( heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval ); + } + +/** + * @brief Configures Ethernet MAC and DMA with default parameters. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ) + { + ETH_MACConfigTypeDef macDefaultConf; + ETH_DMAConfigTypeDef dmaDefaultConf; + + /*--------------- ETHERNET MAC registers default Configuration --------------*/ + macDefaultConf.AutomaticPadCRCStrip = ENABLE; + macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; + macDefaultConf.CarrierSenseBeforeTransmit = DISABLE; + macDefaultConf.CarrierSenseDuringTransmit = DISABLE; + macDefaultConf.ChecksumOffload = ENABLE; + macDefaultConf.CRCCheckingRxPackets = ENABLE; + macDefaultConf.CRCStripTypePacket = ENABLE; + macDefaultConf.DeferralCheck = DISABLE; + macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE; + macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; + macDefaultConf.ExtendedInterPacketGap = DISABLE; + macDefaultConf.ExtendedInterPacketGapVal = 0x0U; + macDefaultConf.ForwardRxErrorPacket = DISABLE; + macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE; + macDefaultConf.GiantPacketSizeLimit = 0x618U; + macDefaultConf.GiantPacketSizeLimitControl = DISABLE; + macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT; + macDefaultConf.Jabber = ENABLE; + macDefaultConf.JumboPacket = DISABLE; + macDefaultConf.LoopbackMode = DISABLE; + macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4; + macDefaultConf.PauseTime = 0x0U; + macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7; + macDefaultConf.ProgrammableWatchdog = DISABLE; + macDefaultConf.ReceiveFlowControl = DISABLE; + macDefaultConf.ReceiveOwn = ENABLE; + macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD; + macDefaultConf.RetryTransmission = ENABLE; + macDefaultConf.SlowProtocolDetect = DISABLE; + macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0; + macDefaultConf.Speed = ETH_SPEED_100M; + macDefaultConf.Support2KPacket = DISABLE; + macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD; + macDefaultConf.TransmitFlowControl = DISABLE; + macDefaultConf.UnicastPausePacketDetect = DISABLE; + macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE; + macDefaultConf.Watchdog = ENABLE; + macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB; + macDefaultConf.ZeroQuantaPause = ENABLE; + + /* MAC default configuration */ + ETH_SetMACConfig( heth, &macDefaultConf ); + + /*--------------- ETHERNET DMA registers default Configuration --------------*/ + dmaDefaultConf.AddressAlignedBeats = ENABLE; + dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; + dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1; + dmaDefaultConf.FlushRxPacket = DISABLE; + dmaDefaultConf.PBLx8Mode = DISABLE; + dmaDefaultConf.RebuildINCRxBurst = DISABLE; + dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.SecondPacketOperate = DISABLE; + dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.TCPSegmentation = DISABLE; + dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT; + + /* DMA default configuration */ + ETH_SetDMAConfig( heth, &dmaDefaultConf ); + } + +/** + * @brief Initializes the DMA Tx descriptors. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmatxdesc; + uint32_t i; + + /* Fill each DMATxDesc descriptor with the right values */ + for( i = 0; i < ( uint32_t ) ETH_TX_DESC_CNT; i++ ) + { + dmatxdesc = heth->Init.TxDesc + i; + + WRITE_REG( dmatxdesc->DESC0, 0x0U ); + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + WRITE_REG( dmatxdesc->DESC2, 0x0U ); + WRITE_REG( dmatxdesc->DESC3, 0x0U ); + + WRITE_REG( heth->TxDescList.TxDesc[ i ], ( uint32_t ) dmatxdesc ); + } + + heth->TxDescList.CurTxDesc = 0; + + /* Set Transmit Descriptor Ring Length */ + WRITE_REG( heth->Instance->DMACTDRLR, ( ETH_TX_DESC_CNT - 1U ) ); + + /* Set Transmit Descriptor List Address */ + WRITE_REG( heth->Instance->DMACTDLAR, ( uint32_t ) heth->Init.TxDesc ); + + /* Set Transmit Descriptor Tail pointer */ + WRITE_REG( heth->Instance->DMACTDTPR, ( uint32_t ) heth->Init.TxDesc ); + } + +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmarxdesc; + uint32_t i; + + for( i = 0; i < ( uint32_t ) ETH_RX_DESC_CNT; i++ ) + { + dmarxdesc = heth->Init.RxDesc + i; + + WRITE_REG( dmarxdesc->DESC0, 0x0U ); + WRITE_REG( dmarxdesc->DESC1, 0x0U ); + WRITE_REG( dmarxdesc->DESC2, 0x0U ); + WRITE_REG( dmarxdesc->DESC3, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr0, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr1, 0x0U ); + + /* Set Rx descritors addresses */ + WRITE_REG( heth->RxDescList.RxDesc[ i ], ( uint32_t ) dmarxdesc ); + } + + WRITE_REG( heth->RxDescList.RxDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxDescCnt, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescCnt, 0U ); + WRITE_REG( heth->RxDescList.ItMode, 0U ); + + /* Set Receive Descriptor Ring Length */ + WRITE_REG( heth->Instance->DMACRDRLR, ( ( uint32_t ) ( ETH_RX_DESC_CNT - 1U ) ) ); + + /* Set Receive Descriptor List Address */ + WRITE_REG( heth->Instance->DMACRDLAR, ( uint32_t ) heth->Init.RxDesc ); + + /* Set Receive Descriptor Tail pointer Address */ + WRITE_REG( heth->Instance->DMACRDTPR, ( ( uint32_t ) ( heth->Init.RxDesc + ( uint32_t ) ( ETH_RX_DESC_CNT - 1U ) ) ) ); + } + +/** + * @brief Prepare Tx DMA descriptor before transmission. + * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Tx packet configuration + * @param ItMode: Enable or disable Tx EOT interrept + * @retval Status + */ + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + const ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t ItMode ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + uint32_t firstdescidx = dmatxdesclist->CurTxDesc; + uint32_t idx; + uint32_t descnbr = 0; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + ETH_BufferTypeDef * txbuffer = pTxConfig->TxBuffer; + uint32_t bd_count = 0; + uint32_t primask_bit; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN ) == ETH_DMATXNDESCWBF_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + return HAL_ETH_ERROR_BUSY; + } + + /***************************************************************************/ + /***************** Context descriptor configuration (Optional) **********/ + /***************************************************************************/ + /* If VLAN tag is enabled for this packet */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != ( uint32_t ) RESET ) + { + /* Set vlan tag value */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag ); + /* Set vlan tag valid bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV ); + /* Set the descriptor as the vlan input source */ + SET_BIT( heth->Instance->MACVIR, ETH_MACVIR_VLTI ); + + /* if inner VLAN is enabled */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG ) != ( uint32_t ) RESET ) + { + /* Set inner vlan tag value */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, ( pTxConfig->InnerVlanTag << 16 ) ); + /* Set inner vlan tag valid bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV ); + + /* Set Vlan Tag control */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl ); + + /* Set the descriptor as the inner vlan input source */ + SET_BIT( heth->Instance->MACIVIR, ETH_MACIVIR_VLTI ); + /* Enable double VLAN processing */ + SET_BIT( heth->Instance->MACVTR, ETH_MACVTR_EDVLP ); + } + } + + /* if tcp segmentation is enabled for this packet */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) + { + /* Set MSS value */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize ); + /* Set MSS valid bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV ); + } + + if( ( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != ( uint32_t ) RESET ) || + ( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) ) + { + /* Set as context descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT ); + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set own bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_OWN ); + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + descnbr += 1U; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( READ_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN ) == ETH_DMATXNDESCWBF_OWN ) + { + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ firstdescidx ]; + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Clear own bit */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_OWN ); + + return HAL_ETH_ERROR_BUSY; + } + } + + /***************************************************************************/ + /***************** Normal descriptors configuration *****************/ + /***************************************************************************/ + + descnbr += 1U; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC0, ( uint32_t ) txbuffer->buffer ); + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len ); + + if( txbuffer->next != NULL ) + { + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG( dmatxdesc->DESC1, ( uint32_t ) txbuffer->buffer ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, ( txbuffer->len << 16 ) ); + } + else + { + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) + { + /* Set TCP Header length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, ( pTxConfig->TCPHeaderLen << 19 ) ); + /* Set TCP payload length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen ); + /* Set TCP Segmentation Enabled bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE ); + } + else + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length ); + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM ) != ( uint32_t ) RESET ) + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD ) != ( uint32_t ) RESET ) + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl ); + } + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != ( uint32_t ) RESET ) + { + /* Set Vlan Tag control */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl ); + } + + /* Mark it as First Descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD ); + /* Mark it as NORMAL descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT ); + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* set OWN bit of FIRST descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ); + + /* If source address insertion/replacement is enabled for this packet */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC ) != ( uint32_t ) RESET ) + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl ); + } + + /* only if the packet is split into more than one descriptors > 1 */ + while( txbuffer->next != NULL ) + { + /* Clear the LD bit of previous descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD ); + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* Clear the FD bit of new Descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD ); + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ) == ETH_DMATXNDESCRF_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + descidx = firstdescidx; + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* clear previous desc own bit */ + for( idx = 0; idx < descnbr; idx++ ) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ); + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + } + + return HAL_ETH_ERROR_BUSY; + } + + descnbr += 1U; + + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC0, ( uint32_t ) txbuffer->buffer ); + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len ); + + if( txbuffer->next != NULL ) + { + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG( dmatxdesc->DESC1, ( uint32_t ) txbuffer->buffer ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, ( txbuffer->len << 16 ) ); + } + else + { + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) + { + /* Set TCP payload length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen ); + /* Set TCP Segmentation Enabled bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE ); + } + else + { + /* Set the packet length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length ); + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM ) != ( uint32_t ) RESET ) + { + /* Checksum Insertion Control */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl ); + } + } + + bd_count += 1U; + + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set Own bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ); + /* Mark it as NORMAL descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT ); + } + + if( ItMode != ( ( uint32_t ) RESET ) ) + { + /* Set Interrupt on completion bit */ + SET_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC ); + } + else + { + /* Clear Interrupt on completion bit */ + CLEAR_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC ); + } + + /* Mark it as LAST descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD ); + /* Save the current packet address to expose it to the application */ + dmatxdesclist->PacketAddress[ descidx ] = dmatxdesclist->CurrentPacketAddress; + + dmatxdesclist->CurTxDesc = descidx; + + /* Enter critical section */ + primask_bit = __get_PRIMASK(); + __set_PRIMASK( 1 ); + + dmatxdesclist->BuffersInUse += bd_count + 1U; + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK( primask_bit ); + + /* Return function status */ + return HAL_ETH_ERROR_NONE; + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ) + { + /* Init the ETH Callback settings */ + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ + heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ + heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ + heth->EEECallback = HAL_ETH_EEECallback; /* Legacy weak EEECallback */ + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ + #ifdef HAL_ETH_USE_PTP + heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ + #endif /* HAL_ETH_USE_PTP */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + + #endif /* ETH */ #endif /* HAL_ETH_MODULE_ENABLED */ /** - * @} - */ + * @} + */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.h b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.h index c32b34c6ac..376486aa14 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.h +++ b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth.h @@ -1,1823 +1,1927 @@ /** - ****************************************************************************** - * @file stm32h5xx_hal_eth.h - * @author MCD Application Team - * @brief Header file of ETH HAL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h5xx_hal_eth.h + * @author MCD Application Team + * @brief Header file of ETH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32H5xx_HAL_ETH_H -#define STM32H5xx_HAL_ETH_H + #define STM32H5xx_HAL_ETH_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32h5xx_hal_def.h" + #include "stm32h5xx_hal_def.h" -#if defined(ETH) + #if defined( ETH ) /** @addtogroup STM32H5xx_HAL_Driver - * @{ - */ + * @{ + */ /** @addtogroup ETH - * @{ - */ + * @{ + */ /* Exported types ------------------------------------------------------------*/ -#ifndef ETH_TX_DESC_CNT -#define ETH_TX_DESC_CNT 4U -#endif /* ETH_TX_DESC_CNT */ + #ifndef ETH_TX_DESC_CNT + #define ETH_TX_DESC_CNT 4U + #endif /* ETH_TX_DESC_CNT */ -#ifndef ETH_RX_DESC_CNT -#define ETH_RX_DESC_CNT 4U -#endif /* ETH_RX_DESC_CNT */ + #ifndef ETH_RX_DESC_CNT + #define ETH_RX_DESC_CNT 4U + #endif /* ETH_RX_DESC_CNT */ -#ifndef ETH_SWRESET_TIMEOUT -#define ETH_SWRESET_TIMEOUT 500U -#endif /* ETH_SWRESET_TIMEOUT */ + #ifndef ETH_SWRESET_TIMEOUT + #define ETH_SWRESET_TIMEOUT 500U + #endif /* ETH_SWRESET_TIMEOUT */ -#ifndef ETH_MDIO_BUS_TIMEOUT -#define ETH_MDIO_BUS_TIMEOUT 1000U -#endif /* ETH_MDIO_BUS_TIMEOUT */ + #ifndef ETH_MDIO_BUS_TIMEOUT + #define ETH_MDIO_BUS_TIMEOUT 1000U + #endif /* ETH_MDIO_BUS_TIMEOUT */ -#ifndef ETH_MAC_US_TICK -#define ETH_MAC_US_TICK 1000000U -#endif /* ETH_MAC_US_TICK */ + #ifndef ETH_MAC_US_TICK + #define ETH_MAC_US_TICK 1000000U + #endif /* ETH_MAC_US_TICK */ /*********************** Descriptors struct def section ************************/ + /** @defgroup ETH_Exported_Types ETH Exported Types - * @{ - */ + * @{ + */ /** - * @brief ETH DMA Descriptor structure definition - */ -typedef struct -{ - __IO uint32_t DESC0; - __IO uint32_t DESC1; - __IO uint32_t DESC2; - __IO uint32_t DESC3; - uint32_t BackupAddr0; /* used to store rx buffer 1 address */ - uint32_t BackupAddr1; /* used to store rx buffer 2 address */ -} ETH_DMADescTypeDef; + * @brief ETH DMA Descriptor structure definition + */ + typedef struct + { + __IO uint32_t DESC0; + __IO uint32_t DESC1; + __IO uint32_t DESC2; + __IO uint32_t DESC3; + uint32_t BackupAddr0; /* used to store rx buffer 1 address */ + uint32_t BackupAddr1; /* used to store rx buffer 2 address */ + } ETH_DMADescTypeDef; + /** - * - */ + * + */ /** - * @brief ETH Buffers List structure definition - */ -typedef struct __ETH_BufferTypeDef -{ - uint8_t *buffer; /*gState = HAL_ETH_STATE_RESET; \ - (__HANDLE__)->MspInitCallback = NULL; \ - (__HANDLE__)->MspDeInitCallback = NULL; \ - } while(0) -#else -#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) do{ \ - (__HANDLE__)->gState = HAL_ETH_STATE_RESET; \ - } while(0) -#endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @brief Enables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * enabled @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACIER |= (__INTERRUPT__)) - -/** - * @brief Disables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * disabled. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACIER &= ~(__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT source enabled or disabled. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The ETH DMA IT Source enabled or disabled - */ -#define __HAL_ETH_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ - (((__HANDLE__)->Instance->DMACIER & (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The state of ETH DMA IT (SET or RESET) - */ -#define __HAL_ETH_DMA_GET_IT(__HANDLE__, __INTERRUPT__) \ - (((__HANDLE__)->Instance->DMACSR & (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Clears the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACSR = (__INTERRUPT__)) - -/** - * @brief Checks whether the specified ETHERNET DMA flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMACSR &( __FLAG__)) == ( __FLAG__)) - -/** - * @brief Clears the specified ETHERNET DMA flag. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMACSR = ( __FLAG__)) - -/** - * @brief Enables the specified ETHERNET MAC interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be - * enabled @ref ETH_MAC_Interrupts - * @retval None - */ - -#define __HAL_ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIER |= (__INTERRUPT__)) - -/** - * @brief Disables the specified ETHERNET MAC interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be - * enabled @ref ETH_MAC_Interrupts - * @retval None - */ -#define __HAL_ETH_MAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIER &= ~(__INTERRUPT__)) - -/** - * @brief Checks whether the specified ETHERNET MAC flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts - * @retval The state of ETH MAC IT (SET or RESET). - */ -#define __HAL_ETH_MAC_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->MACISR &\ - ( __INTERRUPT__)) == ( __INTERRUPT__)) - -/*!< External interrupt line 46 Connected to the ETH wakeup EXTI Line */ -#define ETH_WAKEUP_EXTI_LINE 0x00004000U /* !< 46 - 32 = 14 */ +/** @defgroup ETH_State_Codes ETH States + * @{ + */ + #define HAL_ETH_STATE_RESET 0x00000000U /*!< Peripheral not yet Initialized or disabled */ + #define HAL_ETH_STATE_READY 0x00000010U /*!< Peripheral Communication started */ + #define HAL_ETH_STATE_BUSY 0x00000023U /*!< an internal process is ongoing */ + #define HAL_ETH_STATE_STARTED 0x00000023U /*!< an internal process is started */ + #define HAL_ETH_STATE_ERROR 0x000000E0U /*!< Error State */ /** - * @brief Enable the ETH WAKEUP Exti Line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT(__EXTI_LINE__) (EXTI->IMR2 |= (__EXTI_LINE__)) + * @} + */ -/** - * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval EXTI ETH WAKEUP Line Status. - */ -#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->RPR2 & (__EXTI_LINE__)) +/** @defgroup ETH_PTP_Config_Status ETH PTP Config Status + * @{ + */ + #define HAL_ETH_PTP_NOT_CONFIGURED 0x00000000U /*!< ETH PTP Configuration not done */ + #define HAL_ETH_PTP_CONFIGURED 0x00000001U /*!< ETH PTP Configuration done */ /** - * @brief Clear the ETH WAKEUP Exti flag. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->RPR2 = (__EXTI_LINE__)) + * @} + */ /** - * @brief enable rising edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE(__EXTI_LINE__) (EXTI->FTSR2 &= ~(__EXTI_LINE__)); \ - (EXTI->RTSR2 |= (__EXTI_LINE__)) + * @} + */ -/** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR2 &= ~(__EXTI_LINE__));\ - (EXTI->FTSR2 |= (__EXTI_LINE__)) +/* Exported macro ------------------------------------------------------------*/ -/** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR2 |= (__EXTI_LINE__));\ - (EXTI->FTSR2 |= (__EXTI_LINE__)) +/** @defgroup ETH_Exported_Macros ETH Exported Macros + * @{ + */ -/** - * @brief Generates a Software interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER2 |= (__EXTI_LINE__)) -#define __HAL_ETH_GET_PTP_CONTROL(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->MACTSCR) & \ - (__FLAG__)) == (__FLAG__)) ? SET : RESET) -#define __HAL_ETH_SET_PTP_CONTROL(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->MACTSCR |= (__FLAG__)) +/** @brief Reset ETH handle state + * @param __HANDLE__: specifies the ETH handle. + * @retval None + */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + ( __HANDLE__ )->MspInitCallback = NULL; \ + ( __HANDLE__ )->MspDeInitCallback = NULL; \ + } while( 0 ) + #else + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + } while( 0 ) + #endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @brief Enables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * enabled @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_ENABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMACIER |= ( __INTERRUPT__ ) ) + +/** + * @brief Disables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * disabled. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_DISABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMACIER &= ~( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT source enabled or disabled. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The ETH DMA IT Source enabled or disabled + */ + #define __HAL_ETH_DMA_GET_IT_SOURCE( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMACIER & ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The state of ETH DMA IT (SET or RESET) + */ + #define __HAL_ETH_DMA_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMACSR & ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Clears the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_CLEAR_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMACSR = ( __INTERRUPT__ ) ) + +/** + * @brief Checks whether the specified ETHERNET DMA flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_GET_FLAG( __HANDLE__, __FLAG__ ) ( ( ( __HANDLE__ )->Instance->DMACSR & ( __FLAG__ ) ) == ( __FLAG__ ) ) + +/** + * @brief Clears the specified ETHERNET DMA flag. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_CLEAR_FLAG( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->DMACSR = ( __FLAG__ ) ) + +/** + * @brief Enables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ + + #define __HAL_ETH_MAC_ENABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->MACIER |= ( __INTERRUPT__ ) ) + +/** + * @brief Disables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ + #define __HAL_ETH_MAC_DISABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->MACIER &= ~( __INTERRUPT__ ) ) + +/** + * @brief Checks whether the specified ETHERNET MAC flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts + * @retval The state of ETH MAC IT (SET or RESET). + */ + #define __HAL_ETH_MAC_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->MACISR & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) -/** - * @} - */ +/*!< External interrupt line 46 Connected to the ETH wakeup EXTI Line */ + #define ETH_WAKEUP_EXTI_LINE 0x00004000U/* !< 46 - 32 = 14 */ + +/** + * @brief Enable the ETH WAKEUP Exti Line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT( __EXTI_LINE__ ) ( EXTI->IMR2 |= ( __EXTI_LINE__ ) ) + +/** + * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval EXTI ETH WAKEUP Line Status. + */ + #define __HAL_ETH_WAKEUP_EXTI_GET_FLAG( __EXTI_LINE__ ) ( EXTI->RPR2 & ( __EXTI_LINE__ ) ) + +/** + * @brief Clear the ETH WAKEUP Exti flag. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( __EXTI_LINE__ ) ( EXTI->RPR2 = ( __EXTI_LINE__ ) ) + +/** + * @brief enable rising edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->FTSR2 &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->RTSR2 |= ( __EXTI_LINE__ ) ) + +/** + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR2 &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR2 |= ( __EXTI_LINE__ ) ) + +/** + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR2 |= ( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR2 |= ( __EXTI_LINE__ ) ) + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT( __EXTI_LINE__ ) ( EXTI->SWIER2 |= ( __EXTI_LINE__ ) ) + #define __HAL_ETH_GET_PTP_CONTROL( __HANDLE__, __FLAG__ ) \ + ( ( ( ( ( __HANDLE__ )->Instance->MACTSCR ) & \ + ( __FLAG__ ) ) == ( __FLAG__ ) ) ? SET : RESET ) + #define __HAL_ETH_SET_PTP_CONTROL( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->MACTSCR |= ( __FLAG__ ) ) + +/** + * @} + */ /* Include ETH HAL Extension module */ -#include "stm32h5xx_hal_eth_ex.h" + #include "stm32h5xx_hal_eth_ex.h" /* Exported functions --------------------------------------------------------*/ /** @addtogroup ETH_Exported_Functions - * @{ - */ + * @{ + */ /** @addtogroup ETH_Exported_Functions_Group1 - * @{ - */ + * @{ + */ /* Initialization and de initialization functions **********************************/ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ); /* Callbacks Register/UnRegister functions ***********************************/ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group2 - * @{ - */ + * @{ + */ /* IO operation functions *******************************************************/ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth); - -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff); -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode); -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth); - -#ifdef HAL_ETH_USE_PTP -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset); -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth); -#endif /* HAL_ETH_USE_PTP */ - -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout); -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig); - -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue); -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue); - -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth); -void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth); -void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxAllocateCallback(uint8_t **buff); -void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length); -void HAL_ETH_TxFreeCallback(uint32_t *buff); -void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp); -/** - * @} - */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ); + + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ); + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( const ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ); + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ); + + #ifdef HAL_ETH_USE_PTP + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ); + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ); + #endif /* HAL_ETH_USE_PTP */ + + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t Timeout ); + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig ); + + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ); + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ); + + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ); + void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_EEECallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxAllocateCallback( uint8_t ** buff ); + void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ); + void HAL_ETH_TxFreeCallback( uint32_t * buff ); + void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ); + +/** + * @} + */ /** @addtogroup ETH_Exported_Functions_Group3 - * @{ - */ + * @{ + */ /* Peripheral Control functions **********************************************/ /* MAC & DMA Configuration APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_GetMACConfig( const ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( const ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ); /* MAC VLAN Processing APIs ************************************************/ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, - uint32_t VLANIdentifier); + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ); /* MAC L2 Packet Filtering APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable); -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr); + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( const ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ); + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ); /* MAC Power Down APIs *****************************************************/ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, - const ETH_PowerDownConfigTypeDef *pPowerDownConfig); -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count); + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ); + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ); /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group4 - * @{ - */ + * @{ + */ /* Peripheral State functions **************************************************/ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth); + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ); + /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* STM32H5xx_HAL_ETH_H */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.c b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.c index e4fa9d76df..cfd682debe 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.c +++ b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.c @@ -1,660 +1,681 @@ /** - ****************************************************************************** - * @file stm32h5xx_hal_eth_ex.c - * @author MCD Application Team - * @brief ETH HAL Extended module driver. - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h5xx_hal_eth_ex.c + * @author MCD Application Team + * @brief ETH HAL Extended module driver. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32h5xx_hal.h" /** @addtogroup STM32H5xx_HAL_Driver - * @{ - */ + * @{ + */ #ifdef HAL_ETH_MODULE_ENABLED -#if defined(ETH) + #if defined( ETH ) /** @defgroup ETHEx ETHEx - * @brief ETH HAL Extended module driver - * @{ - */ + * @brief ETH HAL Extended module driver + * @{ + */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ + /** @defgroup ETHEx_Private_Constants ETHEx Private Constants - * @{ - */ -#define ETH_MACL4CR_MASK (ETH_MACL3L4CR_L4PEN | ETH_MACL3L4CR_L4SPM | \ - ETH_MACL3L4CR_L4SPIM | ETH_MACL3L4CR_L4DPM | \ - ETH_MACL3L4CR_L4DPIM) - -#define ETH_MACL3CR_MASK (ETH_MACL3L4CR_L3PEN | ETH_MACL3L4CR_L3SAM | \ - ETH_MACL3L4CR_L3SAIM | ETH_MACL3L4CR_L3DAM | \ - ETH_MACL3L4CR_L3DAIM | ETH_MACL3L4CR_L3HSBM | \ - ETH_MACL3L4CR_L3HDBM) - -#define ETH_MACRXVLAN_MASK (ETH_MACVTR_EIVLRXS | ETH_MACVTR_EIVLS | \ - ETH_MACVTR_ERIVLT | ETH_MACVTR_EDVLP | \ - ETH_MACVTR_VTHM | ETH_MACVTR_EVLRXS | \ - ETH_MACVTR_EVLS | ETH_MACVTR_DOVLTC | \ - ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL | \ - ETH_MACVTR_VTIM | ETH_MACVTR_ETV) - -#define ETH_MACTXVLAN_MASK (ETH_MACVIR_VLTI | ETH_MACVIR_CSVL | \ - ETH_MACVIR_VLP | ETH_MACVIR_VLC) - -#define ETH_MAC_L4_SRSP_MASK 0x0000FFFFU -#define ETH_MAC_L4_DSTP_MASK 0xFFFF0000U + * @{ + */ + #define ETH_MACL4CR_MASK \ + ( ETH_MACL3L4CR_L4PEN | ETH_MACL3L4CR_L4SPM | \ + ETH_MACL3L4CR_L4SPIM | ETH_MACL3L4CR_L4DPM | \ + ETH_MACL3L4CR_L4DPIM ) + + #define ETH_MACL3CR_MASK \ + ( ETH_MACL3L4CR_L3PEN | ETH_MACL3L4CR_L3SAM | \ + ETH_MACL3L4CR_L3SAIM | ETH_MACL3L4CR_L3DAM | \ + ETH_MACL3L4CR_L3DAIM | ETH_MACL3L4CR_L3HSBM | \ + ETH_MACL3L4CR_L3HDBM ) + + #define ETH_MACRXVLAN_MASK \ + ( ETH_MACVTR_EIVLRXS | ETH_MACVTR_EIVLS | \ + ETH_MACVTR_ERIVLT | ETH_MACVTR_EDVLP | \ + ETH_MACVTR_VTHM | ETH_MACVTR_EVLRXS | \ + ETH_MACVTR_EVLS | ETH_MACVTR_DOVLTC | \ + ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL | \ + ETH_MACVTR_VTIM | ETH_MACVTR_ETV ) + + #define ETH_MACTXVLAN_MASK \ + ( ETH_MACVIR_VLTI | ETH_MACVIR_CSVL | \ + ETH_MACVIR_VLP | ETH_MACVIR_VLC ) + + #define ETH_MAC_L4_SRSP_MASK 0x0000FFFFU + #define ETH_MAC_L4_DSTP_MASK 0xFFFF0000U + /** - * @} - */ + * @} + */ /* Private macros ------------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Exported functions ---------------------------------------------------------*/ + /** @defgroup ETHEx_Exported_Functions ETH Extended Exported Functions - * @{ - */ + * @{ + */ /** @defgroup ETHEx_Exported_Functions_Group1 Extended features functions - * @brief Extended features functions - * -@verbatim - =============================================================================== - ##### Extended features functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Configure ARP offload module - (+) Configure L3 and L4 filters - (+) Configure Extended VLAN features - (+) Configure Energy Efficient Ethernet module - -@endverbatim - * @{ - */ + * @brief Extended features functions + * + * @verbatim + * =============================================================================== + ##### Extended features functions ##### + #####=============================================================================== + #####[..] This section provides functions allowing to: + #####(+) Configure ARP offload module + #####(+) Configure L3 and L4 filters + #####(+) Configure Extended VLAN features + #####(+) Configure Energy Efficient Ethernet module + ##### + #####@endverbatim + * @{ + */ /** - * @brief Enables ARP Offload. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ + * @brief Enables ARP Offload. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ -void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth) -{ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_ARP); -} + void HAL_ETHEx_EnableARPOffload( ETH_HandleTypeDef * heth ) + { + SET_BIT( heth->Instance->MACCR, ETH_MACCR_ARP ); + } /** - * @brief Disables ARP Offload. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth) -{ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_ARP); -} + * @brief Disables ARP Offload. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETHEx_DisableARPOffload( ETH_HandleTypeDef * heth ) + { + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_ARP ); + } /** - * @brief Set the ARP Match IP address - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param IpAddress: IP Address to be matched for incoming ARP requests - * @retval None - */ -void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress) -{ - WRITE_REG(heth->Instance->MACARPAR, IpAddress); -} + * @brief Set the ARP Match IP address + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param IpAddress: IP Address to be matched for incoming ARP requests + * @retval None + */ + void HAL_ETHEx_SetARPAddressMatch( ETH_HandleTypeDef * heth, + uint32_t IpAddress ) + { + WRITE_REG( heth->Instance->MACARPAR, IpAddress ); + } /** - * @brief Configures the L4 Filter, this function allow to: - * set the layer 4 protocol to be matched (TCP or UDP) - * enable/disable L4 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L4 filter to configured, this parameter must be one of the following - * ETH_L4_FILTER_0 - * ETH_L4_FILTER_1 - * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure - * that contains L4 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L4FilterConfigTypeDef *pL4FilterConfig) -{ - if (pL4FilterConfig == NULL) - { - return HAL_ERROR; - } - - if (Filter == ETH_L4_FILTER_0) - { - /* Write configuration to MACL3L4C0R register */ - MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol | - pL4FilterConfig->SrcPortFilterMatch | - pL4FilterConfig->DestPortFilterMatch)); - - /* Write configuration to MACL4A0R register */ - WRITE_REG(heth->Instance->MACL4A0R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16))); - - } - else /* Filter == ETH_L4_FILTER_1 */ - { - /* Write configuration to MACL3L4C1R register */ - MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol | - pL4FilterConfig->SrcPortFilterMatch | - pL4FilterConfig->DestPortFilterMatch)); - - /* Write configuration to MACL4A1R register */ - WRITE_REG(heth->Instance->MACL4A1R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16))); - } - - /* Enable L4 filter */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); - - return HAL_OK; -} + * @brief Configures the L4 Filter, this function allow to: + * set the layer 4 protocol to be matched (TCP or UDP) + * enable/disable L4 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L4 filter to configured, this parameter must be one of the following + * ETH_L4_FILTER_0 + * ETH_L4_FILTER_1 + * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure + * that contains L4 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L4FilterConfigTypeDef * pL4FilterConfig ) + { + if( pL4FilterConfig == NULL ) + { + return HAL_ERROR; + } + + if( Filter == ETH_L4_FILTER_0 ) + { + /* Write configuration to MACL3L4C0R register */ + MODIFY_REG( heth->Instance->MACL3L4C0R, ETH_MACL4CR_MASK, ( pL4FilterConfig->Protocol | + pL4FilterConfig->SrcPortFilterMatch | + pL4FilterConfig->DestPortFilterMatch ) ); + + /* Write configuration to MACL4A0R register */ + WRITE_REG( heth->Instance->MACL4A0R, ( pL4FilterConfig->SourcePort | ( pL4FilterConfig->DestinationPort << 16 ) ) ); + } + else /* Filter == ETH_L4_FILTER_1 */ + { + /* Write configuration to MACL3L4C1R register */ + MODIFY_REG( heth->Instance->MACL3L4C1R, ETH_MACL4CR_MASK, ( pL4FilterConfig->Protocol | + pL4FilterConfig->SrcPortFilterMatch | + pL4FilterConfig->DestPortFilterMatch ) ); + + /* Write configuration to MACL4A1R register */ + WRITE_REG( heth->Instance->MACL4A1R, ( pL4FilterConfig->SourcePort | ( pL4FilterConfig->DestinationPort << 16 ) ) ); + } + + /* Enable L4 filter */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + + return HAL_OK; + } /** - * @brief Configures the L4 Filter, this function allow to: - * set the layer 4 protocol to be matched (TCP or UDP) - * enable/disable L4 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L4 filter to configured, this parameter must be one of the following - * ETH_L4_FILTER_0 - * ETH_L4_FILTER_1 - * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure - * that contains L4 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L4FilterConfigTypeDef *pL4FilterConfig) -{ - if (pL4FilterConfig == NULL) - { - return HAL_ERROR; - } - - if (Filter == ETH_L4_FILTER_0) - { - /* Get configuration from MACL3L4C0R register */ - pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C0R, ETH_MACL3L4CR_L4PEN); - pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R, - (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM)); - pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R, - (ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM)); - - /* Get configuration from MACL4A0R register */ - pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_DSTP_MASK) >> 16); - pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_SRSP_MASK); - } - else /* Filter == ETH_L4_FILTER_1 */ - { - /* Get configuration from MACL3L4C1R register */ - pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C1R, ETH_MACL3L4CR_L4PEN); - pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R, - (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM)); - pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R, - (ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM)); - - /* Get configuration from MACL4A1R register */ - pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_DSTP_MASK) >> 16); - pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_SRSP_MASK); - } - - return HAL_OK; -} + * @brief Configures the L4 Filter, this function allow to: + * set the layer 4 protocol to be matched (TCP or UDP) + * enable/disable L4 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L4 filter to configured, this parameter must be one of the following + * ETH_L4_FILTER_0 + * ETH_L4_FILTER_1 + * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure + * that contains L4 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L4FilterConfigTypeDef * pL4FilterConfig ) + { + if( pL4FilterConfig == NULL ) + { + return HAL_ERROR; + } + + if( Filter == ETH_L4_FILTER_0 ) + { + /* Get configuration from MACL3L4C0R register */ + pL4FilterConfig->Protocol = READ_BIT( heth->Instance->MACL3L4C0R, ETH_MACL3L4CR_L4PEN ); + pL4FilterConfig->DestPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C0R, + ( ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM ) ); + pL4FilterConfig->SrcPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C0R, + ( ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM ) ); + + /* Get configuration from MACL4A0R register */ + pL4FilterConfig->DestinationPort = ( READ_BIT( heth->Instance->MACL4A0R, ETH_MAC_L4_DSTP_MASK ) >> 16 ); + pL4FilterConfig->SourcePort = READ_BIT( heth->Instance->MACL4A0R, ETH_MAC_L4_SRSP_MASK ); + } + else /* Filter == ETH_L4_FILTER_1 */ + { + /* Get configuration from MACL3L4C1R register */ + pL4FilterConfig->Protocol = READ_BIT( heth->Instance->MACL3L4C1R, ETH_MACL3L4CR_L4PEN ); + pL4FilterConfig->DestPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C1R, + ( ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM ) ); + pL4FilterConfig->SrcPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C1R, + ( ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM ) ); + + /* Get configuration from MACL4A1R register */ + pL4FilterConfig->DestinationPort = ( READ_BIT( heth->Instance->MACL4A1R, ETH_MAC_L4_DSTP_MASK ) >> 16 ); + pL4FilterConfig->SourcePort = READ_BIT( heth->Instance->MACL4A1R, ETH_MAC_L4_SRSP_MASK ); + } + + return HAL_OK; + } /** - * @brief Configures the L3 Filter, this function allow to: - * set the layer 3 protocol to be matched (IPv4 or IPv6) - * enable/disable L3 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L3 filter to configured, this parameter must be one of the following - * ETH_L3_FILTER_0 - * ETH_L3_FILTER_1 - * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure - * that contains L3 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L3FilterConfigTypeDef *pL3FilterConfig) -{ - if (pL3FilterConfig == NULL) - { - return HAL_ERROR; - } - - if (Filter == ETH_L3_FILTER_0) - { - /* Write configuration to MACL3L4C0R register */ - MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol | - pL3FilterConfig->SrcAddrFilterMatch | - pL3FilterConfig->DestAddrFilterMatch | - (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) | - (pL3FilterConfig->DestAddrHigherBitsMatch << 11))); - } - else /* Filter == ETH_L3_FILTER_1 */ - { - /* Write configuration to MACL3L4C1R register */ - MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol | - pL3FilterConfig->SrcAddrFilterMatch | - pL3FilterConfig->DestAddrFilterMatch | - (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) | - (pL3FilterConfig->DestAddrHigherBitsMatch << 11))); - } - - if (Filter == ETH_L3_FILTER_0) - { - /* Check if IPv6 protocol is selected */ - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - /* Set the IPv6 address match */ - /* Set Bits[31:0] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip6Addr[0]); - /* Set Bits[63:32] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip6Addr[1]); - /* update Bits[95:64] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A2R0R, pL3FilterConfig->Ip6Addr[2]); - /* update Bits[127:96] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A3R0R, pL3FilterConfig->Ip6Addr[3]); - } - else /* IPv4 protocol is selected */ - { - /* Set the IPv4 source address match */ - WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip4SrcAddr); - /* Set the IPv4 destination address match */ - WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip4DestAddr); - } - } - else /* Filter == ETH_L3_FILTER_1 */ - { - /* Check if IPv6 protocol is selected */ - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - /* Set the IPv6 address match */ - /* Set Bits[31:0] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip6Addr[0]); - /* Set Bits[63:32] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[1]); - /* update Bits[95:64] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[2]); - /* update Bits[127:96] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[3]); - } - else /* IPv4 protocol is selected */ - { - /* Set the IPv4 source address match */ - WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4SrcAddr); - /* Set the IPv4 destination address match */ - WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4DestAddr); - - } - } - - /* Enable L3 filter */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); - - return HAL_OK; -} + * @brief Configures the L3 Filter, this function allow to: + * set the layer 3 protocol to be matched (IPv4 or IPv6) + * enable/disable L3 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L3 filter to configured, this parameter must be one of the following + * ETH_L3_FILTER_0 + * ETH_L3_FILTER_1 + * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure + * that contains L3 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L3FilterConfigTypeDef * pL3FilterConfig ) + { + if( pL3FilterConfig == NULL ) + { + return HAL_ERROR; + } + + if( Filter == ETH_L3_FILTER_0 ) + { + /* Write configuration to MACL3L4C0R register */ + MODIFY_REG( heth->Instance->MACL3L4C0R, ETH_MACL3CR_MASK, ( pL3FilterConfig->Protocol | + pL3FilterConfig->SrcAddrFilterMatch | + pL3FilterConfig->DestAddrFilterMatch | + ( pL3FilterConfig->SrcAddrHigherBitsMatch << 6 ) | + ( pL3FilterConfig->DestAddrHigherBitsMatch << 11 ) ) ); + } + else /* Filter == ETH_L3_FILTER_1 */ + { + /* Write configuration to MACL3L4C1R register */ + MODIFY_REG( heth->Instance->MACL3L4C1R, ETH_MACL3CR_MASK, ( pL3FilterConfig->Protocol | + pL3FilterConfig->SrcAddrFilterMatch | + pL3FilterConfig->DestAddrFilterMatch | + ( pL3FilterConfig->SrcAddrHigherBitsMatch << 6 ) | + ( pL3FilterConfig->DestAddrHigherBitsMatch << 11 ) ) ); + } + + if( Filter == ETH_L3_FILTER_0 ) + { + /* Check if IPv6 protocol is selected */ + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + /* Set the IPv6 address match */ + /* Set Bits[31:0] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip6Addr[ 0 ] ); + /* Set Bits[63:32] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip6Addr[ 1 ] ); + /* update Bits[95:64] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A2R0R, pL3FilterConfig->Ip6Addr[ 2 ] ); + /* update Bits[127:96] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A3R0R, pL3FilterConfig->Ip6Addr[ 3 ] ); + } + else /* IPv4 protocol is selected */ + { + /* Set the IPv4 source address match */ + WRITE_REG( heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip4SrcAddr ); + /* Set the IPv4 destination address match */ + WRITE_REG( heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip4DestAddr ); + } + } + else /* Filter == ETH_L3_FILTER_1 */ + { + /* Check if IPv6 protocol is selected */ + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + /* Set the IPv6 address match */ + /* Set Bits[31:0] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip6Addr[ 0 ] ); + /* Set Bits[63:32] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[ 1 ] ); + /* update Bits[95:64] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[ 2 ] ); + /* update Bits[127:96] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[ 3 ] ); + } + else /* IPv4 protocol is selected */ + { + /* Set the IPv4 source address match */ + WRITE_REG( heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4SrcAddr ); + /* Set the IPv4 destination address match */ + WRITE_REG( heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4DestAddr ); + } + } + + /* Enable L3 filter */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + + return HAL_OK; + } /** - * @brief Configures the L3 Filter, this function allow to: - * set the layer 3 protocol to be matched (IPv4 or IPv6) - * enable/disable L3 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L3 filter to configured, this parameter must be one of the following - * ETH_L3_FILTER_0 - * ETH_L3_FILTER_1 - * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure - * that will contain the L3 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L3FilterConfigTypeDef *pL3FilterConfig) -{ - if (pL3FilterConfig == NULL) - { - return HAL_ERROR; - } - pL3FilterConfig->Protocol = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - ETH_MACL3L4CR_L3PEN); - pL3FilterConfig->SrcAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - (ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM)); - pL3FilterConfig->DestAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - (ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM)); - pL3FilterConfig->SrcAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - ETH_MACL3L4CR_L3HSBM) >> 6); - pL3FilterConfig->DestAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - ETH_MACL3L4CR_L3HDBM) >> 11); - - if (Filter == ETH_L3_FILTER_0) - { - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A0R0R); - WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A1R0R); - WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A2R0R); - WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A3R0R); - } - else - { - WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R0R); - WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R0R); - } - } - else /* ETH_L3_FILTER_1 */ - { - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A0R1R); - WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A1R1R); - WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A2R1R); - WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A3R1R); - } - else - { - WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R1R); - WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R1R); - } - } - - return HAL_OK; -} + * @brief Configures the L3 Filter, this function allow to: + * set the layer 3 protocol to be matched (IPv4 or IPv6) + * enable/disable L3 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L3 filter to configured, this parameter must be one of the following + * ETH_L3_FILTER_0 + * ETH_L3_FILTER_1 + * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure + * that will contain the L3 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L3FilterConfigTypeDef * pL3FilterConfig ) + { + if( pL3FilterConfig == NULL ) + { + return HAL_ERROR; + } + + pL3FilterConfig->Protocol = READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ETH_MACL3L4CR_L3PEN ); + pL3FilterConfig->SrcAddrFilterMatch = READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ( ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM ) ); + pL3FilterConfig->DestAddrFilterMatch = READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ( ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM ) ); + pL3FilterConfig->SrcAddrHigherBitsMatch = ( READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ETH_MACL3L4CR_L3HSBM ) >> 6 ); + pL3FilterConfig->DestAddrHigherBitsMatch = ( READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ETH_MACL3L4CR_L3HDBM ) >> 11 ); + + if( Filter == ETH_L3_FILTER_0 ) + { + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + WRITE_REG( pL3FilterConfig->Ip6Addr[ 0 ], heth->Instance->MACL3A0R0R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 1 ], heth->Instance->MACL3A1R0R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 2 ], heth->Instance->MACL3A2R0R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 3 ], heth->Instance->MACL3A3R0R ); + } + else + { + WRITE_REG( pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R0R ); + WRITE_REG( pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R0R ); + } + } + else /* ETH_L3_FILTER_1 */ + { + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + WRITE_REG( pL3FilterConfig->Ip6Addr[ 0 ], heth->Instance->MACL3A0R1R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 1 ], heth->Instance->MACL3A1R1R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 2 ], heth->Instance->MACL3A2R1R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 3 ], heth->Instance->MACL3A3R1R ); + } + else + { + WRITE_REG( pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R1R ); + WRITE_REG( pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R1R ); + } + } + + return HAL_OK; + } /** - * @brief Enables L3 and L4 filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth) -{ - /* Enable L3/L4 filter */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); -} + * @brief Enables L3 and L4 filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_EnableL3L4Filtering( ETH_HandleTypeDef * heth ) + { + /* Enable L3/L4 filter */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + } /** - * @brief Disables L3 and L4 filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth) -{ - /* Disable L3/L4 filter */ - CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); -} + * @brief Disables L3 and L4 filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_DisableL3L4Filtering( ETH_HandleTypeDef * heth ) + { + /* Disable L3/L4 filter */ + CLEAR_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + } /** - * @brief Get the VLAN Configuration for Receive Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure - * that will contain the VLAN filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig) -{ - if (pVlanConfig == NULL) - { - return HAL_ERROR; - } - - pVlanConfig->InnerVLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_EIVLRXS) >> 31) == 0U) ? DISABLE : ENABLE; - pVlanConfig->StripInnerVLANTag = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EIVLS); - pVlanConfig->InnerVLANTag = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_ERIVLT) >> 27) == 0U) ? DISABLE : ENABLE; - pVlanConfig->DoubleVLANProcessing = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_EDVLP) >> 26) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagHashTableMatch = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_VTHM) >> 25) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_EVLRXS) >> 24) == 0U) ? DISABLE : ENABLE; - pVlanConfig->StripVLANTag = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EVLS); - pVlanConfig->VLANTypeCheck = READ_BIT(heth->Instance->MACVTR, - (ETH_MACVTR_DOVLTC | ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL)); - pVlanConfig->VLANTagInverceMatch = ((READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_VTIM) >> 17) == 0U) - ? DISABLE : ENABLE; - - return HAL_OK; -} + * @brief Get the VLAN Configuration for Receive Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure + * that will contain the VLAN filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig( const ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ) + { + if( pVlanConfig == NULL ) + { + return HAL_ERROR; + } + + pVlanConfig->InnerVLANTagInStatus = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_EIVLRXS ) >> 31 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->StripInnerVLANTag = READ_BIT( heth->Instance->MACVTR, ETH_MACVTR_EIVLS ); + pVlanConfig->InnerVLANTag = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_ERIVLT ) >> 27 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->DoubleVLANProcessing = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_EDVLP ) >> 26 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagHashTableMatch = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_VTHM ) >> 25 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagInStatus = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_EVLRXS ) >> 24 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->StripVLANTag = READ_BIT( heth->Instance->MACVTR, ETH_MACVTR_EVLS ); + pVlanConfig->VLANTypeCheck = READ_BIT( heth->Instance->MACVTR, + ( ETH_MACVTR_DOVLTC | ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL ) ); + pVlanConfig->VLANTagInverceMatch = ( ( READ_BIT( heth->Instance->MACVTR, ETH_MACVTR_VTIM ) >> 17 ) == 0U ) + ? DISABLE : ENABLE; + + return HAL_OK; + } /** - * @brief Set the VLAN Configuration for Receive Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure - * that contains VLAN filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig) -{ - if (pVlanConfig == NULL) - { - return HAL_ERROR; - } - - /* Write config to MACVTR */ - MODIFY_REG(heth->Instance->MACVTR, ETH_MACRXVLAN_MASK, (((uint32_t)pVlanConfig->InnerVLANTagInStatus << 31) | - pVlanConfig->StripInnerVLANTag | - ((uint32_t)pVlanConfig->InnerVLANTag << 27) | - ((uint32_t)pVlanConfig->DoubleVLANProcessing << 26) | - ((uint32_t)pVlanConfig->VLANTagHashTableMatch << 25) | - ((uint32_t)pVlanConfig->VLANTagInStatus << 24) | - pVlanConfig->StripVLANTag | - pVlanConfig->VLANTypeCheck | - ((uint32_t)pVlanConfig->VLANTagInverceMatch << 17))); - - return HAL_OK; -} + * @brief Set the VLAN Configuration for Receive Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure + * that contains VLAN filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig( ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ) + { + if( pVlanConfig == NULL ) + { + return HAL_ERROR; + } + + /* Write config to MACVTR */ + MODIFY_REG( heth->Instance->MACVTR, ETH_MACRXVLAN_MASK, ( ( ( uint32_t ) pVlanConfig->InnerVLANTagInStatus << 31 ) | + pVlanConfig->StripInnerVLANTag | + ( ( uint32_t ) pVlanConfig->InnerVLANTag << 27 ) | + ( ( uint32_t ) pVlanConfig->DoubleVLANProcessing << 26 ) | + ( ( uint32_t ) pVlanConfig->VLANTagHashTableMatch << 25 ) | + ( ( uint32_t ) pVlanConfig->VLANTagInStatus << 24 ) | + pVlanConfig->StripVLANTag | + pVlanConfig->VLANTypeCheck | + ( ( uint32_t ) pVlanConfig->VLANTagInverceMatch << 17 ) ) ); + + return HAL_OK; + } /** - * @brief Set the VLAN Hash Table - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANHashTable: VLAN hash table 16 bit value - * @retval None - */ -void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable) -{ - MODIFY_REG(heth->Instance->MACVHTR, ETH_MACVHTR_VLHT, VLANHashTable); -} + * @brief Set the VLAN Hash Table + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANHashTable: VLAN hash table 16 bit value + * @retval None + */ + void HAL_ETHEx_SetVLANHashTable( ETH_HandleTypeDef * heth, + uint32_t VLANHashTable ) + { + MODIFY_REG( heth->Instance->MACVHTR, ETH_MACVHTR_VLHT, VLANHashTable ); + } /** - * @brief Get the VLAN Configuration for Transmit Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANTag: Selects the vlan tag, this parameter must be one of the following - * ETH_OUTER_TX_VLANTAG - * ETH_INNER_TX_VLANTAG - * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure - * that will contain the Tx VLAN filter configuration. - * @retval HAL Status. - */ -HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef *heth, uint32_t VLANTag, - ETH_TxVLANConfigTypeDef *pVlanConfig) -{ - if (pVlanConfig == NULL) - { - return HAL_ERROR; - } - - if (VLANTag == ETH_INNER_TX_VLANTAG) - { - pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE; - pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACIVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC)); - } - else - { - pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE; - pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC)); - } - - return HAL_OK;; -} + * @brief Get the VLAN Configuration for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure + * that will contain the Tx VLAN filter configuration. + * @retval HAL Status. + */ + HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig( const ETH_HandleTypeDef * heth, + uint32_t VLANTag, + ETH_TxVLANConfigTypeDef * pVlanConfig ) + { + if( pVlanConfig == NULL ) + { + return HAL_ERROR; + } + + if( VLANTag == ETH_INNER_TX_VLANTAG ) + { + pVlanConfig->SourceTxDesc = ( ( READ_BIT( heth->Instance->MACIVIR, ETH_MACVIR_VLTI ) >> 20 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->SVLANType = ( ( READ_BIT( heth->Instance->MACIVIR, ETH_MACVIR_CSVL ) >> 19 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagControl = READ_BIT( heth->Instance->MACIVIR, ( ETH_MACVIR_VLP | ETH_MACVIR_VLC ) ); + } + else + { + pVlanConfig->SourceTxDesc = ( ( READ_BIT( heth->Instance->MACVIR, ETH_MACVIR_VLTI ) >> 20 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->SVLANType = ( ( READ_BIT( heth->Instance->MACVIR, ETH_MACVIR_CSVL ) >> 19 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagControl = READ_BIT( heth->Instance->MACVIR, ( ETH_MACVIR_VLP | ETH_MACVIR_VLC ) ); + } + + return HAL_OK; + } /** - * @brief Set the VLAN Configuration for Transmit Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANTag: Selects the vlan tag, this parameter must be one of the following - * ETH_OUTER_TX_VLANTAG - * ETH_INNER_TX_VLANTAG - * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure - * that contains Tx VLAN filter configuration. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, - const ETH_TxVLANConfigTypeDef *pVlanConfig) -{ - if (VLANTag == ETH_INNER_TX_VLANTAG) - { - MODIFY_REG(heth->Instance->MACIVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) | - ((uint32_t)pVlanConfig->SVLANType << 19) | - pVlanConfig->VLANTagControl)); - /* Enable Double VLAN processing */ - SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP); - } - else - { - MODIFY_REG(heth->Instance->MACVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) | - ((uint32_t)pVlanConfig->SVLANType << 19) | - pVlanConfig->VLANTagControl)); - } - - return HAL_OK; -} + * @brief Set the VLAN Configuration for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure + * that contains Tx VLAN filter configuration. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + const ETH_TxVLANConfigTypeDef * pVlanConfig ) + { + if( VLANTag == ETH_INNER_TX_VLANTAG ) + { + MODIFY_REG( heth->Instance->MACIVIR, ETH_MACTXVLAN_MASK, ( ( ( uint32_t ) pVlanConfig->SourceTxDesc << 20 ) | + ( ( uint32_t ) pVlanConfig->SVLANType << 19 ) | + pVlanConfig->VLANTagControl ) ); + /* Enable Double VLAN processing */ + SET_BIT( heth->Instance->MACVTR, ETH_MACVTR_EDVLP ); + } + else + { + MODIFY_REG( heth->Instance->MACVIR, ETH_MACTXVLAN_MASK, ( ( ( uint32_t ) pVlanConfig->SourceTxDesc << 20 ) | + ( ( uint32_t ) pVlanConfig->SVLANType << 19 ) | + pVlanConfig->VLANTagControl ) ); + } + + return HAL_OK; + } /** - * @brief Set the VLAN Tag Identifier for Transmit Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANTag: Selects the vlan tag, this parameter must be one of the following - * ETH_OUTER_TX_VLANTAG - * ETH_INNER_TX_VLANTAG - * @param VLANIdentifier: VLAN Identifier 16 bit value - * @retval None - */ -void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier) -{ - if (VLANTag == ETH_INNER_TX_VLANTAG) - { - MODIFY_REG(heth->Instance->MACIVIR, ETH_MACVIR_VLT, VLANIdentifier); - } - else - { - MODIFY_REG(heth->Instance->MACVIR, ETH_MACVIR_VLT, VLANIdentifier); - } -} + * @brief Set the VLAN Tag Identifier for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param VLANIdentifier: VLAN Identifier 16 bit value + * @retval None + */ + void HAL_ETHEx_SetTxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + uint32_t VLANIdentifier ) + { + if( VLANTag == ETH_INNER_TX_VLANTAG ) + { + MODIFY_REG( heth->Instance->MACIVIR, ETH_MACVIR_VLT, VLANIdentifier ); + } + else + { + MODIFY_REG( heth->Instance->MACVIR, ETH_MACVIR_VLT, VLANIdentifier ); + } + } /** - * @brief Enables the VLAN Tag Filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth) -{ - /* Enable VLAN processing */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE); -} + * @brief Enables the VLAN Tag Filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_EnableVLANProcessing( ETH_HandleTypeDef * heth ) + { + /* Enable VLAN processing */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_VTFE ); + } /** - * @brief Disables the VLAN Tag Filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth) -{ - /* Disable VLAN processing */ - CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE); -} + * @brief Disables the VLAN Tag Filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_DisableVLANProcessing( ETH_HandleTypeDef * heth ) + { + /* Disable VLAN processing */ + CLEAR_BIT( heth->Instance->MACPFR, ETH_MACPFR_VTFE ); + } /** - * @brief Enters the Low Power Idle (LPI) mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param TxAutomate: Enable/Disable automate enter/exit LPI mode. - * @param TxClockStop: Enable/Disable Tx clock stop in LPI mode. - * @retval None - */ -void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, FunctionalState TxClockStop) -{ - /* Enable LPI Interrupts */ - __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_LPIIE); - - /* Write to LPI Control register: Enter low power mode */ - MODIFY_REG(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE), - (((uint32_t)TxAutomate << 19) | - ((uint32_t)TxClockStop << 21) | - ETH_MACLCSR_LPIEN)); -} + * @brief Enters the Low Power Idle (LPI) mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param TxAutomate: Enable/Disable automate enter/exit LPI mode. + * @param TxClockStop: Enable/Disable Tx clock stop in LPI mode. + * @retval None + */ + void HAL_ETHEx_EnterLPIMode( ETH_HandleTypeDef * heth, + FunctionalState TxAutomate, + FunctionalState TxClockStop ) + { + /* Enable LPI Interrupts */ + __HAL_ETH_MAC_ENABLE_IT( heth, ETH_MACIER_LPIIE ); + + /* Write to LPI Control register: Enter low power mode */ + MODIFY_REG( heth->Instance->MACLCSR, ( ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE ), + ( ( ( uint32_t ) TxAutomate << 19 ) | + ( ( uint32_t ) TxClockStop << 21 ) | + ETH_MACLCSR_LPIEN ) ); + } /** - * @brief Exits the Low Power Idle (LPI) mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth) -{ - /* Clear the LPI Config and exit low power mode */ - CLEAR_BIT(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE)); - - /* Enable LPI Interrupts */ - __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_LPIIE); -} + * @brief Exits the Low Power Idle (LPI) mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETHEx_ExitLPIMode( ETH_HandleTypeDef * heth ) + { + /* Clear the LPI Config and exit low power mode */ + CLEAR_BIT( heth->Instance->MACLCSR, ( ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE ) ); + + /* Enable LPI Interrupts */ + __HAL_ETH_MAC_DISABLE_IT( heth, ETH_MACIER_LPIIE ); + } /** - * @brief Returns the ETH MAC LPI event - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC WakeUp event - */ -uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth) -{ - return heth->MACLPIEvent; -} + * @brief Returns the ETH MAC LPI event + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event + */ + uint32_t HAL_ETHEx_GetMACLPIEvent( const ETH_HandleTypeDef * heth ) + { + return heth->MACLPIEvent; + } /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ #endif /* HAL_ETH_MODULE_ENABLED */ + /** - * @} - */ + * @} + */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.h b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.h index 397ec092fc..97337cfed5 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.h +++ b/source/portable/NetworkInterface/STM32/Drivers/H5/stm32h5xx_hal_eth_ex.h @@ -1,366 +1,400 @@ /** - ****************************************************************************** - * @file stm32h5xx_hal_eth_ex.h - * @author MCD Application Team - * @brief Header file of ETH HAL Extended module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h5xx_hal_eth_ex.h + * @author MCD Application Team + * @brief Header file of ETH HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32H5xx_HAL_ETH_EX_H -#define STM32H5xx_HAL_ETH_EX_H + #define STM32H5xx_HAL_ETH_EX_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#if defined(ETH) + #if defined( ETH ) /* Includes ------------------------------------------------------------------*/ -#include "stm32h5xx_hal_def.h" + #include "stm32h5xx_hal_def.h" /** @addtogroup STM32H5xx_HAL_Driver - * @{ - */ + * @{ + */ /** @addtogroup ETHEx - * @{ - */ + * @{ + */ /* Exported types ------------------------------------------------------------*/ + /** @defgroup ETHEx_Exported_Types ETHEx Exported Types - * @{ - */ + * @{ + */ /** - * @brief ETH RX VLAN structure definition - */ -typedef struct -{ - FunctionalState InnerVLANTagInStatus; /*!< Enables or disables Inner VLAN Tag in Rx Status */ + * @brief ETH RX VLAN structure definition + */ + typedef struct + { + FunctionalState InnerVLANTagInStatus; /*!< Enables or disables Inner VLAN Tag in Rx Status */ + + uint32_t StripInnerVLANTag; /*!< Sets the Inner VLAN Tag Stripping on Receive + * This parameter can be a value of + * @ref ETHEx_Rx_Inner_VLAN_Tag_Stripping */ - uint32_t StripInnerVLANTag; /*!< Sets the Inner VLAN Tag Stripping on Receive - This parameter can be a value of - @ref ETHEx_Rx_Inner_VLAN_Tag_Stripping */ + FunctionalState InnerVLANTag; /*!< Enables or disables Inner VLAN Tag */ - FunctionalState InnerVLANTag; /*!< Enables or disables Inner VLAN Tag */ + FunctionalState DoubleVLANProcessing; /*!< Enable or Disable double VLAN processing */ - FunctionalState DoubleVLANProcessing; /*!< Enable or Disable double VLAN processing */ + FunctionalState VLANTagHashTableMatch; /*!< Enable or Disable VLAN Tag Hash Table Match */ - FunctionalState VLANTagHashTableMatch; /*!< Enable or Disable VLAN Tag Hash Table Match */ + FunctionalState VLANTagInStatus; /*!< Enable or Disable VLAN Tag in Rx status */ - FunctionalState VLANTagInStatus; /*!< Enable or Disable VLAN Tag in Rx status */ + uint32_t StripVLANTag; /*!< Set the VLAN Tag Stripping on Receive + * This parameter can be a value of @ref ETHEx_Rx_VLAN_Tag_Stripping */ - uint32_t StripVLANTag; /*!< Set the VLAN Tag Stripping on Receive - This parameter can be a value of @ref ETHEx_Rx_VLAN_Tag_Stripping */ + uint32_t VLANTypeCheck; /*!< Enable or Disable VLAN Type Check + * This parameter can be a value of @ref ETHEx_VLAN_Type_Check */ - uint32_t VLANTypeCheck; /*!< Enable or Disable VLAN Type Check - This parameter can be a value of @ref ETHEx_VLAN_Type_Check */ + FunctionalState VLANTagInverceMatch; /*!< Enable or disable VLAN Tag Inverse Match */ + } ETH_RxVLANConfigTypeDef; - FunctionalState VLANTagInverceMatch; /*!< Enable or disable VLAN Tag Inverse Match */ -} ETH_RxVLANConfigTypeDef; /** - * - */ + * + */ /** - * @brief ETH TX VLAN structure definition - */ -typedef struct -{ - FunctionalState SourceTxDesc; /*!< Enable or Disable VLAN tag source from DMA tx descriptors */ + * @brief ETH TX VLAN structure definition + */ + typedef struct + { + FunctionalState SourceTxDesc; /*!< Enable or Disable VLAN tag source from DMA tx descriptors */ + + FunctionalState SVLANType; /*!< Enable or Disable insertion of SVLAN type */ - FunctionalState SVLANType; /*!< Enable or Disable insertion of SVLAN type */ + uint32_t VLANTagControl; /*!< Sets the VLAN tag control in tx packets + * This parameter can be a value of @ref ETHEx_VLAN_Tag_Control */ + } ETH_TxVLANConfigTypeDef; - uint32_t VLANTagControl; /*!< Sets the VLAN tag control in tx packets - This parameter can be a value of @ref ETHEx_VLAN_Tag_Control */ -} ETH_TxVLANConfigTypeDef; /** - * - */ + * + */ /** - * @brief ETH L3 filter structure definition - */ -typedef struct -{ - uint32_t Protocol; /*!< Sets the L3 filter protocol to IPv4 or IPv6 - This parameter can be a value of @ref ETHEx_L3_Protocol */ + * @brief ETH L3 filter structure definition + */ + typedef struct + { + uint32_t Protocol; /*!< Sets the L3 filter protocol to IPv4 or IPv6 + * This parameter can be a value of @ref ETHEx_L3_Protocol */ - uint32_t SrcAddrFilterMatch; /*!< Sets the L3 filter source address match - This parameter can be a value of @ref ETHEx_L3_Source_Match */ + uint32_t SrcAddrFilterMatch; /*!< Sets the L3 filter source address match + * This parameter can be a value of @ref ETHEx_L3_Source_Match */ - uint32_t DestAddrFilterMatch; /*!< Sets the L3 filter destination address match - This parameter can be a value of @ref ETHEx_L3_Destination_Match */ + uint32_t DestAddrFilterMatch; /*!< Sets the L3 filter destination address match + * This parameter can be a value of @ref ETHEx_L3_Destination_Match */ - uint32_t SrcAddrHigherBitsMatch; /*!< Sets the L3 filter source address higher bits match - This parameter can be a value from 0 to 31 */ + uint32_t SrcAddrHigherBitsMatch; /*!< Sets the L3 filter source address higher bits match + * This parameter can be a value from 0 to 31 */ - uint32_t DestAddrHigherBitsMatch; /*!< Sets the L3 filter destination address higher bits match - This parameter can be a value from 0 to 31 */ + uint32_t DestAddrHigherBitsMatch; /*!< Sets the L3 filter destination address higher bits match + * This parameter can be a value from 0 to 31 */ - uint32_t Ip4SrcAddr; /*!< Sets the L3 filter IPv4 source address if IPv4 protocol is used - This parameter can be a value from 0x0 to 0xFFFFFFFF */ + uint32_t Ip4SrcAddr; /*!< Sets the L3 filter IPv4 source address if IPv4 protocol is used + * This parameter can be a value from 0x0 to 0xFFFFFFFF */ - uint32_t Ip4DestAddr; /*!< Sets the L3 filter IPv4 destination address if IPv4 protocol is used - This parameter can be a value from 0 to 0xFFFFFFFF */ + uint32_t Ip4DestAddr; /*!< Sets the L3 filter IPv4 destination address if IPv4 protocol is used + * This parameter can be a value from 0 to 0xFFFFFFFF */ + + uint32_t Ip6Addr[ 4 ]; /*!< Sets the L3 filter IPv6 address if IPv6 protocol is used + * This parameter must be a table of 4 words (4* 32 bits) */ + } ETH_L3FilterConfigTypeDef; - uint32_t Ip6Addr[4]; /*!< Sets the L3 filter IPv6 address if IPv6 protocol is used - This parameter must be a table of 4 words (4* 32 bits) */ -} ETH_L3FilterConfigTypeDef; /** - * - */ + * + */ /** - * @brief ETH L4 filter structure definition - */ -typedef struct -{ - uint32_t Protocol; /*!< Sets the L4 filter protocol to TCP or UDP - This parameter can be a value of @ref ETHEx_L4_Protocol */ + * @brief ETH L4 filter structure definition + */ + typedef struct + { + uint32_t Protocol; /*!< Sets the L4 filter protocol to TCP or UDP + * This parameter can be a value of @ref ETHEx_L4_Protocol */ + + uint32_t SrcPortFilterMatch; /*!< Sets the L4 filter source port match + * This parameter can be a value of @ref ETHEx_L4_Source_Match */ - uint32_t SrcPortFilterMatch; /*!< Sets the L4 filter source port match - This parameter can be a value of @ref ETHEx_L4_Source_Match */ + uint32_t DestPortFilterMatch; /*!< Sets the L4 filter destination port match + * This parameter can be a value of @ref ETHEx_L4_Destination_Match */ - uint32_t DestPortFilterMatch; /*!< Sets the L4 filter destination port match - This parameter can be a value of @ref ETHEx_L4_Destination_Match */ + uint32_t SourcePort; /*!< Sets the L4 filter source port + * This parameter must be a value from 0x0 to 0xFFFF */ - uint32_t SourcePort; /*!< Sets the L4 filter source port - This parameter must be a value from 0x0 to 0xFFFF */ + uint32_t DestinationPort; /*!< Sets the L4 filter destination port + * This parameter must be a value from 0x0 to 0xFFFF */ + } ETH_L4FilterConfigTypeDef; - uint32_t DestinationPort; /*!< Sets the L4 filter destination port - This parameter must be a value from 0x0 to 0xFFFF */ -} ETH_L4FilterConfigTypeDef; /** - * - */ + * + */ /** - * @} - */ + * @} + */ /* Exported constants --------------------------------------------------------*/ + /** @defgroup ETHEx_Exported_Constants ETHEx Exported Constants - * @{ - */ + * @{ + */ /** @defgroup ETHEx_LPI_Event ETHEx LPI Event - * @{ - */ -#define ETH_TX_LPI_ENTRY ETH_MACLCSR_TLPIEN -#define ETH_TX_LPI_EXIT ETH_MACLCSR_TLPIEX -#define ETH_RX_LPI_ENTRY ETH_MACLCSR_RLPIEN -#define ETH_RX_LPI_EXIT ETH_MACLCSR_RLPIEX + * @{ + */ + #define ETH_TX_LPI_ENTRY ETH_MACLCSR_TLPIEN + #define ETH_TX_LPI_EXIT ETH_MACLCSR_TLPIEX + #define ETH_RX_LPI_ENTRY ETH_MACLCSR_RLPIEN + #define ETH_RX_LPI_EXIT ETH_MACLCSR_RLPIEX + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Filter ETHEx L3 Filter - * @{ - */ -#define ETH_L3_FILTER_0 0x00000000U -#define ETH_L3_FILTER_1 0x0000000CU + * @{ + */ + #define ETH_L3_FILTER_0 0x00000000U + #define ETH_L3_FILTER_1 0x0000000CU + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Filter ETHEx L4 Filter - * @{ - */ -#define ETH_L4_FILTER_0 0x00000000U -#define ETH_L4_FILTER_1 0x0000000CU + * @{ + */ + #define ETH_L4_FILTER_0 0x00000000U + #define ETH_L4_FILTER_1 0x0000000CU + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Protocol ETHEx L3 Protocol - * @{ - */ -#define ETH_L3_IPV6_MATCH ETH_MACL3L4CR_L3PEN -#define ETH_L3_IPV4_MATCH 0x00000000U + * @{ + */ + #define ETH_L3_IPV6_MATCH ETH_MACL3L4CR_L3PEN + #define ETH_L3_IPV4_MATCH 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Source_Match ETHEx L3 Source Match - * @{ - */ -#define ETH_L3_SRC_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3SAM -#define ETH_L3_SRC_ADDR_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM) -#define ETH_L3_SRC_ADDR_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L3_SRC_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3SAM + #define ETH_L3_SRC_ADDR_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM ) + #define ETH_L3_SRC_ADDR_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Destination_Match ETHEx L3 Destination Match - * @{ - */ -#define ETH_L3_DEST_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3DAM -#define ETH_L3_DEST_ADDR_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM) -#define ETH_L3_DEST_ADDR_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L3_DEST_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3DAM + #define ETH_L3_DEST_ADDR_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM ) + #define ETH_L3_DEST_ADDR_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Protocol ETHEx L4 Protocol - * @{ - */ -#define ETH_L4_UDP_MATCH ETH_MACL3L4CR_L4PEN -#define ETH_L4_TCP_MATCH 0x00000000U + * @{ + */ + #define ETH_L4_UDP_MATCH ETH_MACL3L4CR_L4PEN + #define ETH_L4_TCP_MATCH 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Source_Match ETHEx L4 Source Match - * @{ - */ -#define ETH_L4_SRC_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4SPM -#define ETH_L4_SRC_PORT_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L4SPM |ETH_MACL3L4CR_L4SPIM) -#define ETH_L4_SRC_PORT_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L4_SRC_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4SPM + #define ETH_L4_SRC_PORT_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM ) + #define ETH_L4_SRC_PORT_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Destination_Match ETHEx L4 Destination Match - * @{ - */ -#define ETH_L4_DEST_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4DPM -#define ETH_L4_DEST_PORT_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM) -#define ETH_L4_DEST_PORT_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L4_DEST_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4DPM + #define ETH_L4_DEST_PORT_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM ) + #define ETH_L4_DEST_PORT_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_Rx_Inner_VLAN_Tag_Stripping ETHEx Rx Inner VLAN Tag Stripping - * @{ - */ -#define ETH_INNERVLANTAGRXSTRIPPING_NONE ETH_MACVTR_EIVLS_DONOTSTRIP -#define ETH_INNERVLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EIVLS_STRIPIFPASS -#define ETH_INNERVLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EIVLS_STRIPIFFAILS -#define ETH_INNERVLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EIVLS_ALWAYSSTRIP + * @{ + */ + #define ETH_INNERVLANTAGRXSTRIPPING_NONE ETH_MACVTR_EIVLS_DONOTSTRIP + #define ETH_INNERVLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EIVLS_STRIPIFPASS + #define ETH_INNERVLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EIVLS_STRIPIFFAILS + #define ETH_INNERVLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EIVLS_ALWAYSSTRIP + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_Rx_VLAN_Tag_Stripping ETHEx Rx VLAN Tag Stripping - * @{ - */ -#define ETH_VLANTAGRXSTRIPPING_NONE ETH_MACVTR_EVLS_DONOTSTRIP -#define ETH_VLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EVLS_STRIPIFPASS -#define ETH_VLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EVLS_STRIPIFFAILS -#define ETH_VLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EVLS_ALWAYSSTRIP + * @{ + */ + #define ETH_VLANTAGRXSTRIPPING_NONE ETH_MACVTR_EVLS_DONOTSTRIP + #define ETH_VLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EVLS_STRIPIFPASS + #define ETH_VLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EVLS_STRIPIFFAILS + #define ETH_VLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EVLS_ALWAYSSTRIP + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_VLAN_Type_Check ETHEx VLAN Type Check - * @{ - */ -#define ETH_VLANTYPECHECK_DISABLE ETH_MACVTR_DOVLTC -#define ETH_VLANTYPECHECK_SVLAN (ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL) -#define ETH_VLANTYPECHECK_CVLAN 0x00000000U + * @{ + */ + #define ETH_VLANTYPECHECK_DISABLE ETH_MACVTR_DOVLTC + #define ETH_VLANTYPECHECK_SVLAN ( ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL ) + #define ETH_VLANTYPECHECK_CVLAN 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_VLAN_Tag_Control ETHEx_VLAN_Tag_Control - * @{ - */ -#define ETH_VLANTAGCONTROL_NONE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_NOVLANTAG) -#define ETH_VLANTAGCONTROL_DELETE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGDELETE) -#define ETH_VLANTAGCONTROL_INSERT (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGINSERT) -#define ETH_VLANTAGCONTROL_REPLACE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGREPLACE) + * @{ + */ + #define ETH_VLANTAGCONTROL_NONE ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_NOVLANTAG ) + #define ETH_VLANTAGCONTROL_DELETE ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGDELETE ) + #define ETH_VLANTAGCONTROL_INSERT ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGINSERT ) + #define ETH_VLANTAGCONTROL_REPLACE ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGREPLACE ) + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_Tx_VLAN_Tag ETHEx Tx VLAN Tag - * @{ - */ -#define ETH_INNER_TX_VLANTAG 0x00000001U -#define ETH_OUTER_TX_VLANTAG 0x00000000U + * @{ + */ + #define ETH_INNER_TX_VLANTAG 0x00000001U + #define ETH_OUTER_TX_VLANTAG 0x00000000U + /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /* Exported functions --------------------------------------------------------*/ + /** @addtogroup ETHEx_Exported_Functions - * @{ - */ + * @{ + */ /** @addtogroup ETHEx_Exported_Functions_Group1 - * @{ - */ + * @{ + */ /* MAC ARP Offloading APIs ***************************************************/ -void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth); -void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth); -void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress); + void HAL_ETHEx_EnableARPOffload( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_DisableARPOffload( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_SetARPAddressMatch( ETH_HandleTypeDef * heth, + uint32_t IpAddress ); /* MAC L3 L4 Filtering APIs ***************************************************/ -void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth); -void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L3FilterConfigTypeDef *pL3FilterConfig); -HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L4FilterConfigTypeDef *pL4FilterConfig); -HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L3FilterConfigTypeDef *pL3FilterConfig); -HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L4FilterConfigTypeDef *pL4FilterConfig); + void HAL_ETHEx_EnableL3L4Filtering( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_DisableL3L4Filtering( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L3FilterConfigTypeDef * pL3FilterConfig ); + HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L4FilterConfigTypeDef * pL4FilterConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L3FilterConfigTypeDef * pL3FilterConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L4FilterConfigTypeDef * pL4FilterConfig ); /* MAC VLAN Processing APIs ************************************************/ -void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth); -void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig); -HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig); -void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable); -HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef *heth, uint32_t VLANTag, - ETH_TxVLANConfigTypeDef *pVlanConfig); -HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, - const ETH_TxVLANConfigTypeDef *pVlanConfig); -void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier); + void HAL_ETHEx_EnableVLANProcessing( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_DisableVLANProcessing( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig( const ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig( ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ); + void HAL_ETHEx_SetVLANHashTable( ETH_HandleTypeDef * heth, + uint32_t VLANHashTable ); + HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig( const ETH_HandleTypeDef * heth, + uint32_t VLANTag, + ETH_TxVLANConfigTypeDef * pVlanConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + const ETH_TxVLANConfigTypeDef * pVlanConfig ); + void HAL_ETHEx_SetTxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + uint32_t VLANIdentifier ); /* Energy Efficient Ethernet APIs *********************************************/ -void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, - FunctionalState TxClockStop); -void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth); -uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth); + void HAL_ETHEx_EnterLPIMode( ETH_HandleTypeDef * heth, + FunctionalState TxAutomate, + FunctionalState TxClockStop ); + void HAL_ETHEx_ExitLPIMode( ETH_HandleTypeDef * heth ); + uint32_t HAL_ETHEx_GetMACLPIEvent( const ETH_HandleTypeDef * heth ); /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* STM32H5xx_HAL_ETH_EX_H */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.c b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.c index 2536a73b12..a6682eb57e 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.c +++ b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.c @@ -1,3379 +1,3452 @@ /** - ****************************************************************************** - * @file stm32h7xx_hal_eth.c - * @author MCD Application Team - * @brief ETH HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Ethernet (ETH) peripheral: - * + Initialization and deinitialization functions - * + IO operation functions - * + Peripheral Control functions - * + Peripheral State and Errors functions - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - The ETH HAL driver can be used as follows: - - (#)Declare a ETH_HandleTypeDef handle structure, for example: - ETH_HandleTypeDef heth; - - (#)Fill parameters of Init structure in heth handle - - (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) - - (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: - (##) Enable the Ethernet interface clock using - (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() - (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() - (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() - - (##) Initialize the related GPIO clocks - (##) Configure Ethernet pinout - (##) Configure Ethernet NVIC interrupt (in Interrupt mode) - - (#) Ethernet data reception is asynchronous, so call the following API - to start the listening mode: - (##) HAL_ETH_Start(): - This API starts the MAC and DMA transmission and reception process, - without enabling end of transfer interrupts, in this mode user - has to poll for data reception by calling HAL_ETH_ReadData() - (##) HAL_ETH_Start_IT(): - This API starts the MAC and DMA transmission and reception process, - end of transfer interrupts are enabled in this mode, - HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received - - (#) When data is received user can call the following API to get received data: - (##) HAL_ETH_ReadData(): Read a received packet - - (#) For transmission path, two APIs are available: - (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode - (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, - HAL_ETH_TxCpltCallback() will be executed when end of transfer occur - - (#) Communication with an external PHY device: - (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY - (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register - - (#) Configure the Ethernet MAC after ETH peripheral initialization - (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef - (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef - - (#) Configure the Ethernet DMA after ETH peripheral initialization - (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef - (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef - - (#) Configure the Ethernet PTP after ETH peripheral initialization - (##) Define HAL_ETH_USE_PTP to use PTP APIs. - (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef - (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers - (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers - (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission - (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp - (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp - - -@- The ARP offload feature is not supported in this driver. - - -@- The PTP offload feature is not supported in this driver. - - *** Callback registration *** - ============================================= - - The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 - allows the user to configure dynamically the driver callbacks. - Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. - - Function HAL_ETH_RegisterCallback() allows to register following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - This function takes as parameters the HAL peripheral handle, the Callback ID - and a pointer to the user callback function. - - For specific callbacks RxAllocateCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated register callbacks: - respectively HAL_ETH_RegisterTxPtpCallback(). - - Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default - weak function. - HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, - and the Callback ID. - This function allows to reset following callbacks: - (+) TxCpltCallback : Tx Complete Callback. - (+) RxCpltCallback : Rx Complete Callback. - (+) ErrorCallback : Error Callback. - (+) PMTCallback : Power Management Callback - (+) EEECallback : EEE Callback. - (+) WakeUpCallback : Wake UP Callback - (+) MspInitCallback : MspInit Callback. - (+) MspDeInitCallback: MspDeInit Callback. - - For specific callbacks RxAllocateCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxAllocateCallback(). - - For specific callbacks RxLinkCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterRxLinkCallback(). - - For specific callbacks TxFreeCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxFreeCallback(). - - For specific callbacks TxPtpCallback use dedicated unregister callbacks: - respectively HAL_ETH_UnRegisterTxPtpCallback(). - - By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET - all callbacks are set to the corresponding weak functions: - examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). - Exception done for MspInit and MspDeInit functions that are - reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when - these callbacks are null (not registered beforehand). - if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit - keep and use the user MspInit/MspDeInit callbacks (registered beforehand) - - Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. - Exception done MspInit/MspDeInit that can be registered/unregistered - in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, - thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. - In that case first register the MspInit/MspDeInit user callbacks - using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit - or HAL_ETH_Init function. - - When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or - not defined, the callback registration feature is not available and all callbacks - are set to the corresponding weak functions. - - @endverbatim - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h7xx_hal_eth.c + * @author MCD Application Team + * @brief ETH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Ethernet (ETH) peripheral: + * + Initialization and deinitialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @verbatim + * ============================================================================== + ##### How to use this driver ##### + #####============================================================================== + #####[..] + #####The ETH HAL driver can be used as follows: + ##### + #####(#)Declare a ETH_HandleTypeDef handle structure, for example: + ##### ETH_HandleTypeDef heth; + ##### + #####(#)Fill parameters of Init structure in heth handle + ##### + #####(#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) + ##### + #####(#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: + ##### (##) Enable the Ethernet interface clock using + ##### (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() + ##### (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() + ##### + ##### (##) Initialize the related GPIO clocks + ##### (##) Configure Ethernet pinout + ##### (##) Configure Ethernet NVIC interrupt (in Interrupt mode) + ##### + #####(#) Ethernet data reception is asynchronous, so call the following API + ##### to start the listening mode: + ##### (##) HAL_ETH_Start(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### without enabling end of transfer interrupts, in this mode user + ##### has to poll for data reception by calling HAL_ETH_ReadData() + ##### (##) HAL_ETH_Start_IT(): + ##### This API starts the MAC and DMA transmission and reception process, + ##### end of transfer interrupts are enabled in this mode, + ##### HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received + ##### + #####(#) When data is received user can call the following API to get received data: + ##### (##) HAL_ETH_ReadData(): Read a received packet + ##### + #####(#) For transmission path, two APIs are available: + ##### (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode + ##### (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, + ##### HAL_ETH_TxCpltCallback() will be executed when end of transfer occur + ##### + #####(#) Communication with an external PHY device: + ##### (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY + ##### (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register + ##### + #####(#) Configure the Ethernet MAC after ETH peripheral initialization + ##### (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef + ##### (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef + ##### + #####(#) Configure the Ethernet DMA after ETH peripheral initialization + ##### (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef + ##### (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef + ##### + #####(#) Configure the Ethernet PTP after ETH peripheral initialization + ##### (##) Define HAL_ETH_USE_PTP to use PTP APIs. + ##### (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef + ##### (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers + ##### (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission + ##### (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp + ##### (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp + ##### + #####-@- The ARP offload feature is not supported in this driver. + ##### + #####-@- The PTP offload feature is not supported in this driver. + ##### + *** Callback registration *** + ***============================================= + *** + ***The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 + ***allows the user to configure dynamically the driver callbacks. + ***Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. + *** + ***Function HAL_ETH_RegisterCallback() allows to register following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***This function takes as parameters the HAL peripheral handle, the Callback ID + ***and a pointer to the user callback function. + *** + ***For specific callbacks RxAllocateCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated register callbacks: + ***respectively HAL_ETH_RegisterTxPtpCallback(). + *** + ***Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default + ***weak function. + ***HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, + ***and the Callback ID. + ***This function allows to reset following callbacks: + ***(+) TxCpltCallback : Tx Complete Callback. + ***(+) RxCpltCallback : Rx Complete Callback. + ***(+) ErrorCallback : Error Callback. + ***(+) PMTCallback : Power Management Callback + ***(+) EEECallback : EEE Callback. + ***(+) WakeUpCallback : Wake UP Callback + ***(+) MspInitCallback : MspInit Callback. + ***(+) MspDeInitCallback: MspDeInit Callback. + *** + ***For specific callbacks RxAllocateCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxAllocateCallback(). + *** + ***For specific callbacks RxLinkCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterRxLinkCallback(). + *** + ***For specific callbacks TxFreeCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxFreeCallback(). + *** + ***For specific callbacks TxPtpCallback use dedicated unregister callbacks: + ***respectively HAL_ETH_UnRegisterTxPtpCallback(). + *** + ***By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET + ***all callbacks are set to the corresponding weak functions: + ***examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). + ***Exception done for MspInit and MspDeInit functions that are + ***reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when + ***these callbacks are null (not registered beforehand). + ***if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit + ***keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + *** + ***Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. + ***Exception done MspInit/MspDeInit that can be registered/unregistered + ***in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, + ***thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + ***In that case first register the MspInit/MspDeInit user callbacks + ***using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit + ***or HAL_ETH_Init function. + *** + ***When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or + ***not defined, the callback registration feature is not available and all callbacks + ***are set to the corresponding weak functions. + *** + ***@endverbatim + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32h7xx_hal.h" /** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ + * @{ + */ #ifdef HAL_ETH_MODULE_ENABLED -#if defined(ETH) + #if defined( ETH ) /** @defgroup ETH ETH - * @brief ETH HAL module driver - * @{ - */ + * @brief ETH HAL module driver + * @{ + */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ + /** @addtogroup ETH_Private_Constants ETH Private Constants - * @{ - */ -#define ETH_MACCR_MASK 0xFFFB7F7CU -#define ETH_MACECR_MASK 0x3F077FFFU -#define ETH_MACPFR_MASK 0x800007FFU -#define ETH_MACWTR_MASK 0x0000010FU -#define ETH_MACTFCR_MASK 0xFFFF00F2U -#define ETH_MACRFCR_MASK 0x00000003U -#define ETH_MTLTQOMR_MASK 0x00000072U -#define ETH_MTLRQOMR_MASK 0x0000007BU - -#define ETH_DMAMR_MASK 0x00007802U -#define ETH_DMASBMR_MASK 0x0000D001U -#define ETH_DMACCR_MASK 0x00013FFFU -#define ETH_DMACTCR_MASK 0x003F1010U -#define ETH_DMACRCR_MASK 0x803F0000U -#define ETH_MACPCSR_MASK (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \ - ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \ - ETH_MACPCSR_RWKPFE) + * @{ + */ + #define ETH_MACCR_MASK 0xFFFB7F7CU + #define ETH_MACECR_MASK 0x3F077FFFU + #define ETH_MACPFR_MASK 0x800007FFU + #define ETH_MACWTR_MASK 0x0000010FU + #define ETH_MACTFCR_MASK 0xFFFF00F2U + #define ETH_MACRFCR_MASK 0x00000003U + #define ETH_MTLTQOMR_MASK 0x00000072U + #define ETH_MTLRQOMR_MASK 0x0000007BU + + #define ETH_DMAMR_MASK 0x00007802U + #define ETH_DMASBMR_MASK 0x0000D001U + #define ETH_DMACCR_MASK 0x00013FFFU + #define ETH_DMACTCR_MASK 0x003F1010U + #define ETH_DMACRCR_MASK 0x803F0000U + #define ETH_MACPCSR_MASK \ + ( ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \ + ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \ + ETH_MACPCSR_RWKPFE ) /* Timeout values */ -#define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \ - ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\ - ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE)) + #define ETH_DMARXNDESCWBF_ERRORS_MASK \ + ( ( uint32_t ) ( ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \ + ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT | \ + ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE ) ) + + #define ETH_MACTSCR_MASK 0x0087FF2FU -#define ETH_MACTSCR_MASK 0x0087FF2FU + #define ETH_MACSTSUR_VALUE 0xFFFFFFFFU + #define ETH_MACSTNUR_VALUE 0xBB9ACA00U + #define ETH_SEGMENT_SIZE_DEFAULT 0x218U -#define ETH_MACSTSUR_VALUE 0xFFFFFFFFU -#define ETH_MACSTNUR_VALUE 0xBB9ACA00U -#define ETH_SEGMENT_SIZE_DEFAULT 0x218U /** - * @} - */ + * @} + */ /* Private macros ------------------------------------------------------------*/ + /** @defgroup ETH_Private_Macros ETH Private Macros - * @{ - */ + * @{ + */ /* Helper macros for TX descriptor handling */ -#define INCR_TX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\ - } while (0) + #define INCR_TX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_TX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_TX_DESC_CNT ); } \ + } while( 0 ) /* Helper macros for RX descriptor handling */ -#define INCR_RX_DESC_INDEX(inx, offset) do {\ - (inx) += (offset);\ - if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\ - (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\ - } while (0) -/** - * @} - */ + #define INCR_RX_DESC_INDEX( inx, offset ) \ + do { \ + ( inx ) += ( offset ); \ + if( ( inx ) >= ( uint32_t ) ETH_RX_DESC_CNT ) { \ + ( inx ) = ( ( inx ) - ( uint32_t ) ETH_RX_DESC_CNT ); } \ + } while( 0 ) + +/** + * @} + */ /* Private function prototypes -----------------------------------------------*/ + /** @defgroup ETH_Private_Functions ETH Private Functions - * @{ - */ -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf); -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf); -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth); -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth); -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth); -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, - uint32_t ItMode); -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ -/** - * @} - */ + * @{ + */ + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + const ETH_MACConfigTypeDef * macconf ); + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + const ETH_DMAConfigTypeDef * dmaconf ); + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ); + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ); + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ); + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + const ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t ItMode ); + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /* Exported functions ---------------------------------------------------------*/ + /** @defgroup ETH_Exported_Functions ETH Exported Functions - * @{ - */ + * @{ + */ /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions - * @brief Initialization and Configuration functions - * -@verbatim -=============================================================================== - ##### Initialization and Configuration functions ##### - =============================================================================== - [..] This subsection provides a set of functions allowing to initialize and - deinitialize the ETH peripheral: - - (+) User must Implement HAL_ETH_MspInit() function in which he configures - all related peripherals resources (CLOCK, GPIO and NVIC ). - - (+) Call the function HAL_ETH_Init() to configure the selected device with - the selected configuration: - (++) MAC address - (++) Media interface (MII or RMII) - (++) Rx DMA Descriptors Tab - (++) Tx DMA Descriptors Tab - (++) Length of Rx Buffers - - (+) Call the function HAL_ETH_DeInit() to restore the default configuration - of the selected ETH peripheral. - -@endverbatim - * @{ - */ - -/** - * @brief Initialize the Ethernet peripheral registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) -{ - uint32_t tickstart; - - if (heth == NULL) - { - return HAL_ERROR; - } - if (heth->gState == HAL_ETH_STATE_RESET) - { - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - ETH_InitCallbacksToDefault(heth); - - if (heth->MspInitCallback == NULL) - { - heth->MspInitCallback = HAL_ETH_MspInit; - } - - /* Init the low level hardware */ - heth->MspInitCallback(heth); -#else - /* Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - } - - __HAL_RCC_SYSCFG_CLK_ENABLE(); - - if (heth->Init.MediaInterface == HAL_ETH_MII_MODE) - { - HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII); - } - else - { - HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII); - } - - /* Dummy read to sync with ETH */ - (void)SYSCFG->PMCR; - - /* Ethernet Software reset */ - /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ - /* After reset all the registers holds their respective reset values */ - SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Wait for software reset */ - while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)) - { - /* Set Error Code */ - heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; - /* Set State as Error */ - heth->gState = HAL_ETH_STATE_ERROR; - /* Return Error */ - return HAL_ERROR; - } - } - - /*------------------ MDIO CSR Clock Range Configuration --------------------*/ - HAL_ETH_SetMDIOClockRange(heth); - - /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/ - WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U)); - - /*------------------ MAC, MTL and DMA default Configuration ----------------*/ - ETH_MACDMAConfig(heth); - - /* SET DSL to 64 bit */ - MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT); - - /* Set Receive Buffers Length (must be a multiple of 4) */ - if ((heth->Init.RxBuffLen % 0x4U) != 0x0U) - { - /* Set Error Code */ - heth->ErrorCode = HAL_ETH_ERROR_PARAM; - /* Set State as Error */ - heth->gState = HAL_ETH_STATE_ERROR; - /* Return Error */ - return HAL_ERROR; - } - else - { - MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1)); - } - - /*------------------ DMA Tx Descriptors Configuration ----------------------*/ - ETH_DMATxDescListInit(heth); - - /*------------------ DMA Rx Descriptors Configuration ----------------------*/ - ETH_DMARxDescListInit(heth); - - /*--------------------- ETHERNET MAC Address Configuration ------------------*/ - /* Set MAC addr bits 32 to 47 */ - heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]); - /* Set MAC addr bits 0 to 31 */ - heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) | - ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]); - - /* Disable Rx MMC Interrupts */ - SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \ - ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM); - - /* Disable Tx MMC Interrupts */ - SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \ - ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM); - - heth->ErrorCode = HAL_ETH_ERROR_NONE; - heth->gState = HAL_ETH_STATE_READY; - - return HAL_OK; -} - -/** - * @brief DeInitializes the ETH peripheral. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) -{ - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - - if (heth->MspDeInitCallback == NULL) - { - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - } - /* DeInit the low level hardware */ - heth->MspDeInitCallback(heth); -#else - - /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ - HAL_ETH_MspDeInit(heth); - -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - - /* Set ETH HAL state to Disabled */ - heth->gState = HAL_ETH_STATE_RESET; - - /* 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 - * @retval None - */ -__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspInit could be implemented in the user file - */ -} - -/** - * @brief DeInitializes ETH MSP. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_MspDeInit could be implemented in the user file - */ -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -/** - * @brief Register a User ETH Callback - * To be used instead of the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be registered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @param pCallback pointer to the Callback function - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = pCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = pCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = pCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = pCallback; - break; - - case HAL_ETH_EEE_CB_ID : - heth->EEECallback = pCallback; - break; - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = pCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = pCallback; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} - -/** - * @brief Unregister an ETH Callback - * ETH callback is redirected to the weak predefined callback - * @param heth eth handle - * @param CallbackID ID of the callback to be unregistered - * This parameter can be one of the following values: - * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID - * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID - * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID - * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID - * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID - * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID - * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID - * @retval status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (heth->gState == HAL_ETH_STATE_READY) - { - switch (CallbackID) - { - case HAL_ETH_TX_COMPLETE_CB_ID : - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; - break; - - case HAL_ETH_RX_COMPLETE_CB_ID : - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; - break; - - case HAL_ETH_ERROR_CB_ID : - heth->ErrorCallback = HAL_ETH_ErrorCallback; - break; - - case HAL_ETH_PMT_CB_ID : - heth->PMTCallback = HAL_ETH_PMTCallback; - break; - - case HAL_ETH_EEE_CB_ID : - heth->EEECallback = HAL_ETH_EEECallback; - break; - - case HAL_ETH_WAKEUP_CB_ID : - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; - break; - - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (heth->gState == HAL_ETH_STATE_RESET) - { - switch (CallbackID) - { - case HAL_ETH_MSPINIT_CB_ID : - heth->MspInitCallback = HAL_ETH_MspInit; - break; - - case HAL_ETH_MSPDEINIT_CB_ID : - heth->MspDeInitCallback = HAL_ETH_MspDeInit; - break; - - default : - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ + * @brief Initialization and Configuration functions + * + * @verbatim + * =============================================================================== + ##### Initialization and Configuration functions ##### + #####=============================================================================== + #####[..] This subsection provides a set of functions allowing to initialize and + ##### deinitialize the ETH peripheral: + ##### + #####(+) User must Implement HAL_ETH_MspInit() function in which he configures + ##### all related peripherals resources (CLOCK, GPIO and NVIC ). + ##### + #####(+) Call the function HAL_ETH_Init() to configure the selected device with + ##### the selected configuration: + ##### (++) MAC address + ##### (++) Media interface (MII or RMII) + ##### (++) Rx DMA Descriptors Tab + ##### (++) Tx DMA Descriptors Tab + ##### (++) Length of Rx Buffers + ##### + #####(+) Call the function HAL_ETH_DeInit() to restore the default configuration + ##### of the selected ETH peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Initialize the Ethernet peripheral registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ) + { + uint32_t tickstart; + + if( heth == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_RESET ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + ETH_InitCallbacksToDefault( heth ); + + if( heth->MspInitCallback == NULL ) + { + heth->MspInitCallback = HAL_ETH_MspInit; + } + + /* Init the low level hardware */ + heth->MspInitCallback( heth ); + #else + /* Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + } + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + if( heth->Init.MediaInterface == HAL_ETH_MII_MODE ) + { + HAL_SYSCFG_ETHInterfaceSelect( SYSCFG_ETH_MII ); + } + else + { + HAL_SYSCFG_ETHInterfaceSelect( SYSCFG_ETH_RMII ); + } + + /* Dummy read to sync with ETH */ + ( void ) SYSCFG->PMCR; + + /* Ethernet Software reset */ + /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ + /* After reset all the registers holds their respective reset values */ + SET_BIT( heth->Instance->DMAMR, ETH_DMAMR_SWR ); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for software reset */ + while( READ_BIT( heth->Instance->DMAMR, ETH_DMAMR_SWR ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_SWRESET_TIMEOUT ) ) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + } + + /*------------------ MDIO CSR Clock Range Configuration --------------------*/ + HAL_ETH_SetMDIOClockRange( heth ); + + /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/ + WRITE_REG( heth->Instance->MAC1USTCR, ( ( ( uint32_t ) HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK ) - 1U ) ); + + /*------------------ MAC, MTL and DMA default Configuration ----------------*/ + ETH_MACDMAConfig( heth ); + + /* SET DSL to 64 bit */ + MODIFY_REG( heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT ); + + /* Set Receive Buffers Length (must be a multiple of 4) */ + if( ( heth->Init.RxBuffLen % 0x4U ) != 0x0U ) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_PARAM; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + else + { + MODIFY_REG( heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ( ( heth->Init.RxBuffLen ) << 1 ) ); + } + + /*------------------ DMA Tx Descriptors Configuration ----------------------*/ + ETH_DMATxDescListInit( heth ); + + /*------------------ DMA Rx Descriptors Configuration ----------------------*/ + ETH_DMARxDescListInit( heth ); + + /*--------------------- ETHERNET MAC Address Configuration ------------------*/ + /* Set MAC addr bits 32 to 47 */ + heth->Instance->MACA0HR = ( ( ( uint32_t ) ( heth->Init.MACAddr[ 5 ] ) << 8 ) | ( uint32_t ) heth->Init.MACAddr[ 4 ] ); + /* Set MAC addr bits 0 to 31 */ + heth->Instance->MACA0LR = ( ( ( uint32_t ) ( heth->Init.MACAddr[ 3 ] ) << 24 ) | ( ( uint32_t ) ( heth->Init.MACAddr[ 2 ] ) << 16 ) | + ( ( uint32_t ) ( heth->Init.MACAddr[ 1 ] ) << 8 ) | ( uint32_t ) heth->Init.MACAddr[ 0 ] ); + + /* Disable Rx MMC Interrupts */ + SET_BIT( heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \ + ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM ); + + /* Disable Tx MMC Interrupts */ + SET_BIT( heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \ + ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM ); + + heth->ErrorCode = HAL_ETH_ERROR_NONE; + heth->gState = HAL_ETH_STATE_READY; + + return HAL_OK; + } + +/** + * @brief DeInitializes the ETH peripheral. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + if( heth->MspDeInitCallback == NULL ) + { + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + } + + /* DeInit the low level hardware */ + heth->MspDeInitCallback( heth ); + #else + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspDeInit( heth ); + #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + + /* Set ETH HAL state to Disabled */ + heth->gState = HAL_ETH_STATE_RESET; + + /* 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 + * @retval None + */ + __weak void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspInit could be implemented in the user file + */ + } + +/** + * @brief DeInitializes ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_MspDeInit could be implemented in the user file + */ + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + +/** + * @brief Register a User ETH Callback + * To be used instead of the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( pCallback == NULL ) + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = pCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = pCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = pCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = pCallback; + break; + + case HAL_ETH_EEE_CB_ID: + heth->EEECallback = pCallback; + break; + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = pCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + +/** + * @brief Unregister an ETH Callback + * ETH callback is redirected to the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ) + { + HAL_StatusTypeDef status = HAL_OK; + + if( heth->gState == HAL_ETH_STATE_READY ) + { + switch( CallbackID ) + { + case HAL_ETH_TX_COMPLETE_CB_ID: + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID: + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; + break; + + case HAL_ETH_ERROR_CB_ID: + heth->ErrorCallback = HAL_ETH_ErrorCallback; + break; + + case HAL_ETH_PMT_CB_ID: + heth->PMTCallback = HAL_ETH_PMTCallback; + break; + + case HAL_ETH_EEE_CB_ID: + heth->EEECallback = HAL_ETH_EEECallback; + break; + + case HAL_ETH_WAKEUP_CB_ID: + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if( heth->gState == HAL_ETH_STATE_RESET ) + { + switch( CallbackID ) + { + case HAL_ETH_MSPINIT_CB_ID: + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID: + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default: + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group2 IO operation functions - * @brief ETH Transmit and Receive functions - * -@verbatim - ============================================================================== - ##### IO operation functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to manage the ETH - data transfer. - -@endverbatim - * @{ - */ - -/** - * @brief Enables Ethernet MAC and DMA reception and transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) -{ - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Clear Tx and Rx process stopped flags */ - heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); - - heth->gState = HAL_ETH_STATE_STARTED; - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) -{ - if (heth->gState == HAL_ETH_STATE_READY) - { - heth->gState = HAL_ETH_STATE_BUSY; - - /* save IT mode to ETH Handle */ - heth->RxDescList.ItMode = 1U; - - /* Set number of descriptors to build */ - heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; - - /* Build all descriptors */ - ETH_UpdateDescriptor(heth); - - /* Enable the DMA transmission */ - SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Enable the DMA reception */ - SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Clear Tx and Rx process stopped flags */ - heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Enable the MAC transmission */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Enable the MAC reception */ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Enable ETH DMA interrupts: - - Tx complete interrupt - - Rx complete interrupt - - Fatal bus interrupt - */ - __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | - ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE)); - - heth->gState = HAL_ETH_STATE_STARTED; - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) -{ - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t descindex; - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Set the ETH peripheral state to BUSY */ - heth->gState = HAL_ETH_STATE_BUSY; - - /* Disable interrupts: - - Tx complete interrupt - - Rx complete interrupt - - Fatal bus interrupt - */ - __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | - ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE)); - - /* Disable the DMA transmission */ - CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); - - /* Disable the DMA reception */ - CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); - - /* Disable the MAC reception */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); - - /* Set the Flush Transmit FIFO bit */ - SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); - - /* Disable the MAC transmission */ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); - - /* Clear IOC bit to all Rx descriptors */ - for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++) - { - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; - CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC); - } - - heth->RxDescList.ItMode = 0U; - - heth->gState = HAL_ETH_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in polling mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @param Timeout: timeout value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout) -{ - uint32_t tickstart; - ETH_DMADescTypeDef *dmatxdesc; - - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE) - { - /* Set the ETH error code */ - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc]; - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); - - tickstart = HAL_GetTick(); - - /* Wait for data to be transmitted or timeout occurred */ - while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET) - { - if ((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - heth->DMAErrorCode = heth->Instance->DMACSR; - /* Return function status */ - return HAL_ERROR; - } - - /* Check for the Timeout */ - if (Timeout != HAL_MAX_DELAY) - { - if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + * @brief ETH Transmit and Receive functions + * + * @verbatim + * ============================================================================== + ##### IO operation functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to manage the ETH + #####data transfer. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Enables Ethernet MAC and DMA reception and transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ) + { + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->DMACSR |= ( ETH_DMACSR_TPS | ETH_DMACSR_RPS ); + + heth->gState = HAL_ETH_STATE_STARTED; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ) + { + if( heth->gState == HAL_ETH_STATE_READY ) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* save IT mode to ETH Handle */ + heth->RxDescList.ItMode = 1U; + + /* Set number of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor( heth ); + + /* Enable the DMA transmission */ + SET_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Enable the DMA reception */ + SET_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->DMACSR |= ( ETH_DMACSR_TPS | ETH_DMACSR_RPS ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Enable the MAC transmission */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Enable the MAC reception */ + SET_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Enable ETH DMA interrupts: + * - Tx complete interrupt + * - Rx complete interrupt + * - Fatal bus interrupt + */ + __HAL_ETH_DMA_ENABLE_IT( heth, ( ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | + ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE ) ); + + heth->gState = HAL_ETH_STATE_STARTED; + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ) + { + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmarxdesc; + uint32_t descindex; + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable interrupts: + * - Tx complete interrupt + * - Rx complete interrupt + * - Fatal bus interrupt + */ + __HAL_ETH_DMA_DISABLE_IT( heth, ( ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | + ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE ) ); + + /* Disable the DMA transmission */ + CLEAR_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_ST ); + + /* Disable the DMA reception */ + CLEAR_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_SR ); + + /* Disable the MAC reception */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE ); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ ); + + /* Disable the MAC transmission */ + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_TE ); + + /* Clear IOC bit to all Rx descriptors */ + for( descindex = 0; descindex < ( uint32_t ) ETH_RX_DESC_CNT; descindex++ ) + { + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descindex ]; + CLEAR_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC ); + } + + heth->RxDescList.ItMode = 0U; + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Sends an Ethernet Packet in polling mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @param Timeout: timeout value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t Timeout ) + { + uint32_t tickstart; + ETH_DMADescTypeDef * dmatxdesc; + + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 0 ) != HAL_ETH_ERROR_NONE ) + { + /* Set the ETH error code */ + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + dmatxdesc = ( ETH_DMADescTypeDef * ) ( &heth->TxDescList )->TxDesc[ heth->TxDescList.CurTxDesc ]; + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG( heth->Instance->DMACTDTPR, ( uint32_t ) ( heth->TxDescList.TxDesc[ heth->TxDescList.CurTxDesc ] ) ); + + tickstart = HAL_GetTick(); + + /* Wait for data to be transmitted or timeout occurred */ + while( ( dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN ) != ( uint32_t ) RESET ) + { + if( ( heth->Instance->DMACSR & ETH_DMACSR_FBE ) != ( uint32_t ) RESET ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + heth->DMAErrorCode = heth->Instance->DMACSR; + /* Return function status */ + return HAL_ERROR; + } + + /* Check for the Timeout */ + if( Timeout != HAL_MAX_DELAY ) + { + if( ( ( HAL_GetTick() - tickstart ) > Timeout ) || ( Timeout == 0U ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; + /* Clear TX descriptor so that we can proceed */ + dmatxdesc->DESC3 = ( ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD ); + return HAL_ERROR; + } + } + } + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Sends an Ethernet Packet in interrupt mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig ) + { + if( pTxConfig == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_STARTED ) + { + /* Save the packet pointer to release. */ + heth->TxDescList.CurrentPacketAddress = ( uint32_t * ) pTxConfig->pData; + + /* Config DMA Tx descriptor by Tx Packet info */ + if( ETH_Prepare_Tx_Descriptors( heth, pTxConfig, 1 ) != HAL_ETH_ERROR_NONE ) + { + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX( heth->TxDescList.CurTxDesc, 1U ); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG( heth->Instance->DMACTDTPR, ( uint32_t ) ( heth->TxDescList.TxDesc[ heth->TxDescList.CurTxDesc ] ) ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Read a received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pAppBuff: Pointer to an application buffer to receive the packet. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ) + { + uint32_t descidx; + ETH_DMADescTypeDef * dmarxdesc; + uint32_t desccnt = 0U; + uint32_t desccntmax; + uint32_t bufflength; + uint8_t rxdataready = 0U; + + if( pAppBuff == NULL ) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if( heth->gState != HAL_ETH_STATE_STARTED ) + { + return HAL_ERROR; + } + + descidx = heth->RxDescList.RxDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; + + /* Check if descriptor is not owned by DMA */ + while( ( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN ) == ( uint32_t ) RESET ) && ( desccnt < desccntmax ) && + ( rxdataready == 0U ) ) + { + if( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT ) != ( uint32_t ) RESET ) + { + /* Get timestamp high */ + heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1; + /* Get timestamp low */ + heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC0; + } + + if( ( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD ) != ( uint32_t ) RESET ) || ( heth->RxDescList.pRxStart != NULL ) ) + { + /* Check if first descriptor */ + if( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD ) != ( uint32_t ) RESET ) + { + heth->RxDescList.RxDescCnt = 0; + heth->RxDescList.RxDataLength = 0; + } + + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + bufflength = READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL ) - heth->RxDescList.RxDataLength; + + /* Check if last descriptor */ + if( READ_BIT( dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD ) != ( uint32_t ) RESET ) + { + /* Save Last descriptor index */ + heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3; + + /* Packet ready */ + rxdataready = 1; + } + + /* Link data */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Link callback*/ + heth->rxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, bufflength ); + #else + /* Link callback */ + HAL_ETH_RxLinkCallback( &heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + ( uint8_t * ) dmarxdesc->BackupAddr0, ( uint16_t ) bufflength ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->RxDescList.RxDescCnt++; + heth->RxDescList.RxDataLength += bufflength; + + /* Clear buffer pointer */ + dmarxdesc->BackupAddr0 = 0; + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccnt++; + } + + heth->RxDescList.RxBuildDescCnt += desccnt; + + if( ( heth->RxDescList.RxBuildDescCnt ) != 0U ) + { + /* Update Descriptors */ + ETH_UpdateDescriptor( heth ); + } + + heth->RxDescList.RxDescIdx = descidx; + + if( rxdataready == 1U ) + { + /* Return received packet */ + *pAppBuff = heth->RxDescList.pRxStart; + /* Reset first element */ + heth->RxDescList.pRxStart = NULL; + + return HAL_OK; + } + + /* Packet not ready */ + return HAL_ERROR; + } + +/** + * @brief This function gives back Rx Desc of the last received Packet + * to the DMA, so ETH DMA will be able to use these descriptors + * to receive next Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_UpdateDescriptor( ETH_HandleTypeDef * heth ) + { + uint32_t descidx; + uint32_t tailidx; + uint32_t desccount; + ETH_DMADescTypeDef * dmarxdesc; + uint8_t * buff = NULL; + uint8_t allocStatus = 1U; + + descidx = heth->RxDescList.RxBuildDescIdx; + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount = heth->RxDescList.RxBuildDescCnt; + + while( ( desccount > 0U ) && ( allocStatus != 0U ) ) + { + /* Check if a buffer's attached the descriptor */ + if( READ_REG( dmarxdesc->BackupAddr0 ) == 0U ) + { + /* Get a new buffer. */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Allocate callback*/ + heth->rxAllocateCallback( &buff ); + #else + /* Allocate callback */ + HAL_ETH_RxAllocateCallback( &buff ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + if( buff == NULL ) + { + allocStatus = 0U; + } + else + { + WRITE_REG( dmarxdesc->BackupAddr0, ( uint32_t ) buff ); + WRITE_REG( dmarxdesc->DESC0, ( uint32_t ) buff ); + } + } + + if( allocStatus != 0U ) + { + if( heth->RxDescList.ItMode != 0U ) + { + WRITE_REG( dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC ); + } + else + { + WRITE_REG( dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V ); + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmarxdesc = ( ETH_DMADescTypeDef * ) heth->RxDescList.RxDesc[ descidx ]; + desccount--; + } + } + + if( heth->RxDescList.RxBuildDescCnt != desccount ) + { + /* Set the tail pointer index */ + tailidx = ( descidx + 1U ) % ETH_RX_DESC_CNT; + + /* DMB instruction to avoid race condition */ + __DMB(); + + /* Set the Tail pointer address */ + WRITE_REG( heth->Instance->DMACRDTPR, ( ( uint32_t ) ( heth->Init.RxDesc + ( tailidx ) ) ) ); + + heth->RxDescList.RxBuildDescIdx = descidx; + heth->RxDescList.RxBuildDescCnt = desccount; + } + } + +/** + * @brief Register the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxAllocateCallback: pointer to function to alloc buffer + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ) { - heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; - /* Clear TX descriptor so that we can proceed */ - dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD); - return HAL_ERROR; + if( rxAllocateCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to allocate buffer */ + heth->rxAllocateCallback = rxAllocateCallback; + + return HAL_OK; } - } - } - - /* Return function status */ - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Sends an Ethernet Packet in interrupt mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Hold the configuration of packet to be transmitted - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig) -{ - if (pTxConfig == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_STARTED) - { - /* Save the packet pointer to release. */ - heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData; - - /* Config DMA Tx descriptor by Tx Packet info */ - if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE) - { - heth->ErrorCode |= HAL_ETH_ERROR_BUSY; - return HAL_ERROR; - } - - /* Ensure completion of descriptor preparation before transmission start */ - __DSB(); - - /* Incr current tx desc index */ - INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); - - /* Start transmission */ - /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ - WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); - - return HAL_OK; - - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Read a received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pAppBuff: Pointer to an application buffer to receive the packet. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff) -{ - uint32_t descidx; - ETH_DMADescTypeDef *dmarxdesc; - uint32_t desccnt = 0U; - uint32_t desccntmax; - uint32_t bufflength; - uint8_t rxdataready = 0U; - - if (pAppBuff == NULL) - { - heth->ErrorCode |= HAL_ETH_ERROR_PARAM; - return HAL_ERROR; - } - - if (heth->gState != HAL_ETH_STATE_STARTED) - { - return HAL_ERROR; - } - - descidx = heth->RxDescList.RxDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; - - /* Check if descriptor is not owned by DMA */ - while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax) - && (rxdataready == 0U)) - { - if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET) - { - /* Get timestamp high */ - heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1; - /* Get timestamp low */ - heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC0; - } - if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL)) - { - /* Check if first descriptor */ - if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) - { - heth->RxDescList.RxDescCnt = 0; - heth->RxDescList.RxDataLength = 0; - } - - /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ - bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength; - - /* Check if last descriptor */ - if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET) - { - /* Save Last descriptor index */ - heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3; - - /* Packet ready */ - rxdataready = 1; - } - - /* Link data */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Link callback*/ - heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, bufflength); -#else - /* Link callback */ - HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, - (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - heth->RxDescList.RxDescCnt++; - heth->RxDescList.RxDataLength += bufflength; - - /* Clear buffer pointer */ - dmarxdesc->BackupAddr0 = 0; - } - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccnt++; - } - - heth->RxDescList.RxBuildDescCnt += desccnt; - if ((heth->RxDescList.RxBuildDescCnt) != 0U) - { - /* Update Descriptors */ - ETH_UpdateDescriptor(heth); - } - - heth->RxDescList.RxDescIdx = descidx; - - if (rxdataready == 1U) - { - /* Return received packet */ - *pAppBuff = heth->RxDescList.pRxStart; - /* Reset first element */ - heth->RxDescList.pRxStart = NULL; - - return HAL_OK; - } - - /* Packet not ready */ - return HAL_ERROR; -} - -/** - * @brief This function gives back Rx Desc of the last received Packet - * to the DMA, so ETH DMA will be able to use these descriptors - * to receive next Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth) -{ - uint32_t descidx; - uint32_t tailidx; - uint32_t desccount; - ETH_DMADescTypeDef *dmarxdesc; - uint8_t *buff = NULL; - uint8_t allocStatus = 1U; - - descidx = heth->RxDescList.RxBuildDescIdx; - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount = heth->RxDescList.RxBuildDescCnt; - - while ((desccount > 0U) && (allocStatus != 0U)) - { - /* Check if a buffer's attached the descriptor */ - if (READ_REG(dmarxdesc->BackupAddr0) == 0U) - { - /* Get a new buffer. */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Allocate callback*/ - heth->rxAllocateCallback(&buff); -#else - /* Allocate callback */ - HAL_ETH_RxAllocateCallback(&buff); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - if (buff == NULL) - { - allocStatus = 0U; - } - else - { - WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff); - WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff); - } - } - - if (allocStatus != 0U) - { - - if (heth->RxDescList.ItMode != 0U) - { - WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC); - } - else - { - WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V); - } - - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; - desccount--; - } - } - - if (heth->RxDescList.RxBuildDescCnt != desccount) - { - /* Set the tail pointer index */ - tailidx = (descidx + 1U) % ETH_RX_DESC_CNT; - - /* DMB instruction to avoid race condition */ - __DMB(); - - /* Set the Tail pointer address */ - WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (tailidx)))); - - heth->RxDescList.RxBuildDescIdx = descidx; - heth->RxDescList.RxBuildDescCnt = desccount; - } -} - -/** - * @brief Register the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxAllocateCallback: pointer to function to alloc buffer - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback) -{ - if (rxAllocateCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to allocate buffer */ - heth->rxAllocateCallback = rxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx alloc callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; - - return HAL_OK; -} - -/** - * @brief Rx Allocate callback. - * @param buff: pointer to allocated buffer - * @retval None - */ -__weak void HAL_ETH_RxAllocateCallback(uint8_t **buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxAllocateCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Link callback. - * @param pStart: pointer to packet start - * @param pEnd: pointer to packet end - * @param buff: pointer to received data - * @param Length: received data length - * @retval None - */ -__weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(pStart); - UNUSED(pEnd); - UNUSED(buff); - UNUSED(Length); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxLinkCallback could be implemented in the user file - */ -} - -/** - * @brief Set the Rx link data function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param rxLinkCallback: pointer to function to link data - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback) -{ - if (rxLinkCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to link data */ - heth->rxLinkCallback = rxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Rx link callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; - - return HAL_OK; -} - -/** - * @brief Get the error state of the last received packet. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pErrorCode: pointer to uint32_t to hold the error code - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode) -{ - /* Get error bits. */ - *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK); - - return HAL_OK; -} - -/** - * @brief Set the Tx free function. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txFreeCallback: pointer to function to release the packet - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback) -{ - if (txFreeCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - - /* Set function to free transmmitted packet */ - heth->txFreeCallback = txFreeCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx free callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; - - return HAL_OK; -} - -/** - * @brief Tx Free callback. - * @param buff: pointer to buffer to free - * @retval None - */ -__weak void HAL_ETH_TxFreeCallback(uint32_t *buff) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxFreeCallback could be implemented in the user file - */ -} - -/** - * @brief Release transmitted Tx packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t numOfBuf = dmatxdesclist->BuffersInUse; - uint32_t idx = dmatxdesclist->releaseIndex; - uint8_t pktTxStatus = 1U; - uint8_t pktInUse; -#ifdef HAL_ETH_USE_PTP - ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp; -#endif /* HAL_ETH_USE_PTP */ - - /* Loop through buffers in use. */ - while ((numOfBuf != 0U) && (pktTxStatus != 0U)) - { - pktInUse = 1U; - numOfBuf--; - /* If no packet, just examine the next packet. */ - if (dmatxdesclist->PacketAddress[idx] == NULL) - { - /* No packet in use, skip to next. */ - INCR_TX_DESC_INDEX(idx, 1U); - pktInUse = 0U; - } - - if (pktInUse != 0U) - { - /* Determine if the packet has been transmitted. */ - if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U) - { -#ifdef HAL_ETH_USE_PTP - - /* Disable Ptp transmission */ - CLEAR_BIT(heth->Init.TxDesc[idx].DESC3, (0x40000000U)); - - if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_LD) - && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_TTSS)) + +/** + * @brief Unregister the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ) { - /* Get timestamp low */ - timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1; + /* Set function to allocate buffer */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; + + return HAL_OK; } - else + +/** + * @brief Rx Allocate callback. + * @param buff: pointer to allocated buffer + * @retval None + */ + __weak void HAL_ETH_RxAllocateCallback( uint8_t ** buff ) { - timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX; + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxAllocateCallback could be implemented in the user file + */ } -#endif /* HAL_ETH_USE_PTP */ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered callbacks*/ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX) +/** + * @brief Rx Link callback. + * @param pStart: pointer to packet start + * @param pEnd: pointer to packet end + * @param buff: pointer to received data + * @param Length: received data length + * @retval None + */ + __weak void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ) { - heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); + /* Prevent unused argument(s) compilation warning */ + UNUSED( pStart ); + UNUSED( pEnd ); + UNUSED( buff ); + UNUSED( Length ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxLinkCallback could be implemented in the user file + */ } -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]); -#else - /* Call callbacks */ -#ifdef HAL_ETH_USE_PTP - /* Handle Ptp */ - if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX) + +/** + * @brief Set the Rx link data function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxLinkCallback: pointer to function to link data + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ) { - HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); + if( rxLinkCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to link data */ + heth->rxLinkCallback = rxLinkCallback; + + return HAL_OK; } -#endif /* HAL_ETH_USE_PTP */ - /* Release the packet. */ - HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - /* Clear the entry in the in-use array. */ - dmatxdesclist->PacketAddress[idx] = NULL; - - /* Update the transmit relesae index and number of buffers in use. */ - INCR_TX_DESC_INDEX(idx, 1U); - dmatxdesclist->BuffersInUse = numOfBuf; - dmatxdesclist->releaseIndex = idx; - } - else - { - /* Get out of the loop! */ - pktTxStatus = 0U; - } - } - } - return HAL_OK; -} - -#ifdef HAL_ETH_USE_PTP -/** - * @brief Set the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - uint32_t tmpTSCR; - ETH_TimeTypeDef time; - - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - - tmpTSCR = ptpconfig->Timestamp | - ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) | - ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) | - ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) | - ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) | - ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) | - ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) | - ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) | - ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) | - ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) | - ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) | - ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) | - ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) | - ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos); - - /* Write to MACTSCR */ - MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR); - - /* Enable Timestamp */ - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA); - WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc); - WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend); - - /* Enable Timestamp */ - if (ptpconfig->TimestampAddendUpdate == ENABLE) - { - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG); - while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0) - { - - } - } - - /* Ptp Init */ - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT); - - /* Set PTP Configuration done */ - heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED; - - /* Set Seconds */ - time.Seconds = heth->Instance->MACSTSR; - /* Set NanoSeconds */ - time.NanoSeconds = heth->Instance->MACSTNR; - - HAL_ETH_PTP_SetTime(heth, &time); - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Get the Ethernet PTP configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains - * the configuration information for PTP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) -{ - if (ptpconfig == NULL) - { - return HAL_ERROR; - } - ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA); - ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U) - ? ENABLE : DISABLE; - ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE; - ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR, - ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U) - ? ENABLE : DISABLE; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param time: pointer to a ETH_TimeTypeDef structure that contains - * time to set - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Set Seconds */ - heth->Instance->MACSTSUR = time->Seconds; - - /* Set NanoSeconds */ - heth->Instance->MACSTNUR = time->NanoSeconds; - - /* the system time is updated */ - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param time: pointer to a ETH_TimeTypeDef structure that contains - * time to get - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get Seconds */ - time->Seconds = heth->Instance->MACSTSR; - /* Get NanoSeconds */ - time->NanoSeconds = heth->Instance->MACSTNR; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Update time for the Ethernet PTP registers. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains - * the time update information - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE) - { - /* Set Seconds update */ - heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U; - - if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR) - { - /* Set nanoSeconds update */ - heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds; - } - else - { - /* Set nanoSeconds update */ - heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U; - } - } - else - { - /* Set Seconds update */ - heth->Instance->MACSTSUR = timeoffset->Seconds; - /* Set nanoSeconds update */ - heth->Instance->MACSTNUR = timeoffset->NanoSeconds; - } - - SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Insert Timestamp in transmission. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Enable Time Stamp transmission */ - SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get transmission timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * transmission timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t idx = dmatxdesclist->releaseIndex; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx]; - - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = dmatxdesc->DESC0; - /* Get timestamp high */ - timestamp->TimeStampHigh = dmatxdesc->DESC1; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Get receive timestamp. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains - * receive timestamp - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) -{ - if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED) - { - /* Get timestamp low */ - timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; - /* Get timestamp high */ - timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Register the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param txPtpCallback: Function to handle Ptp transmission - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback) -{ - if (txPtpCallback == NULL) - { - /* No buffer to save */ - return HAL_ERROR; - } - /* Set Function to handle Tx Ptp */ - heth->txPtpCallback = txPtpCallback; - - return HAL_OK; -} - -/** - * @brief Unregister the Tx Ptp callback. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth) -{ - /* Set function to allocate buffer */ - heth->txPtpCallback = HAL_ETH_TxPtpCallback; - - return HAL_OK; -} - -/** - * @brief Tx Ptp callback. - * @param buff: pointer to application buffer - * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains - * transmission timestamp - * @retval None - */ -__weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(buff); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxPtpCallback could be implemented in the user file - */ -} -#endif /* HAL_ETH_USE_PTP */ - -/** - * @brief This function handles ETH interrupt request. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) -{ - uint32_t mac_flag = READ_REG(heth->Instance->MACISR); - uint32_t dma_flag = READ_REG(heth->Instance->DMACSR); - uint32_t dma_itsource = READ_REG(heth->Instance->DMACIER); - uint32_t exti_d1_flag = READ_REG(EXTI_D1->PR3); -#if defined(DUAL_CORE) - uint32_t exti_d2_flag = READ_REG(EXTI_D2->PR3); -#endif /* DUAL_CORE */ - - /* Packet received */ - if (((dma_flag & ETH_DMACSR_RI) != 0U) && ((dma_itsource & ETH_DMACIER_RIE) != 0U)) - { - /* Clear the Eth DMA Rx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Receive complete callback*/ - heth->RxCpltCallback(heth); -#else - /* Receive complete callback */ - HAL_ETH_RxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* Packet transmitted */ - if (((dma_flag & ETH_DMACSR_TI) != 0U) && ((dma_itsource & ETH_DMACIER_TIE) != 0U)) - { - /* Clear the Eth DMA Tx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /*Call registered Transmit complete callback*/ - heth->TxCpltCallback(heth); -#else - /* Transfer complete callback */ - HAL_ETH_TxCpltCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* ETH DMA Error */ - if (((dma_flag & ETH_DMACSR_AIS) != 0U) && ((dma_itsource & ETH_DMACIER_AIE) != 0U)) - { - heth->ErrorCode |= HAL_ETH_ERROR_DMA; - /* if fatal bus error occurred */ - if ((dma_flag & ETH_DMACSR_FBE) != 0U) - { - /* Get DMA error code */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS)); - - /* Disable all interrupts */ - __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE); - - /* Set HAL state to ERROR */ - heth->gState = HAL_ETH_STATE_ERROR; - } - else - { - /* Get DMA error status */ - heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | - ETH_DMACSR_RBU | ETH_DMACSR_AIS)); - - /* Clear the interrupt summary flag */ - __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | - ETH_DMACSR_RBU | ETH_DMACSR_AIS)); - } -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered Error callback*/ - heth->ErrorCallback(heth); -#else - /* Ethernet DMA Error callback */ - HAL_ETH_ErrorCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - - /* ETH MAC Error IT */ - if (((mac_flag & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \ - ((mac_flag & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE)) - { - heth->ErrorCode |= HAL_ETH_ERROR_MAC; - - /* Get MAC Rx Tx status and clear Status register pending bit */ - heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR); - - heth->gState = HAL_ETH_STATE_ERROR; - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered Error callback*/ - heth->ErrorCallback(heth); -#else - /* Ethernet Error callback */ - HAL_ETH_ErrorCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - heth->MACErrorCode = (uint32_t)(0x0U); - } - - /* ETH PMT IT */ - if ((mac_flag & ETH_MAC_PMT_IT) != 0U) - { - /* Get MAC Wake-up source and clear the status register pending bit */ - heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD)); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered PMT callback*/ - heth->PMTCallback(heth); -#else - /* Ethernet PMT callback */ - HAL_ETH_PMTCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - heth->MACWakeUpEvent = (uint32_t)(0x0U); - } - - /* ETH EEE IT */ - if ((mac_flag & ETH_MAC_LPI_IT) != 0U) - { - /* Get MAC LPI interrupt source and clear the status register pending bit */ - heth->MACLPIEvent = READ_BIT(heth->Instance->MACLCSR, 0x0000000FU); - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered EEE callback*/ - heth->EEECallback(heth); -#else - /* Ethernet EEE callback */ - HAL_ETH_EEECallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - heth->MACLPIEvent = (uint32_t)(0x0U); - } - -#if defined(DUAL_CORE) - if (HAL_GetCurrentCPUID() == CM7_CPUID) - { - /* check ETH WAKEUP exti flag */ - if ((exti_d1_flag & ETH_WAKEUP_EXTI_LINE) != 0U) - { - /* Clear ETH WAKEUP Exti pending bit */ - __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered WakeUp callback*/ - heth->WakeUpCallback(heth); -#else - /* ETH WAKEUP callback */ - HAL_ETH_WakeUpCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - } - else - { - /* check ETH WAKEUP exti flag */ - if ((exti_d2_flag & ETH_WAKEUP_EXTI_LINE) != 0U) - { - /* Clear ETH WAKEUP Exti pending bit */ - __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered WakeUp callback*/ - heth->WakeUpCallback(heth); -#else - /* ETH WAKEUP callback */ - HAL_ETH_WakeUpCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } - } -#else /* DUAL_CORE not defined */ - /* check ETH WAKEUP exti flag */ - if ((exti_d1_flag & ETH_WAKEUP_EXTI_LINE) != 0U) - { - /* Clear ETH WAKEUP Exti pending bit */ - __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered WakeUp callback*/ - heth->WakeUpCallback(heth); -#else - /* ETH WAKEUP callback */ - HAL_ETH_WakeUpCallback(heth); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - } -#endif /* DUAL_CORE */ -} - -/** - * @brief Tx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_TxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Rx Transfer completed callbacks. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_RxCpltCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet transfer error callbacks - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_ErrorCallback could be implemented in the user file - */ -} - -/** - * @brief Ethernet Power Management module IT callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_PMTCallback could be implemented in the user file - */ -} - -/** - * @brief Energy Efficient Etherent IT callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_EEECallback could be implemented in the user file - */ -} - -/** - * @brief ETH WAKEUP interrupt callback - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -__weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(heth); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_ETH_WakeUpCallback could be implemented in the user file - */ -} - -/** - * @brief Read a PHY register - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param pRegValue: parameter to hold read value - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue) -{ - uint32_t tickstart; - uint32_t tmpreg; - - /* Check for the Busy flag */ - if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) - { - return HAL_ERROR; - } - - /* Get the MACMDIOAR value */ - WRITE_REG(tmpreg, heth->Instance->MACMDIOAR); - - /* Prepare the MDIO Address Register value - - Set the PHY device address - - Set the PHY register address - - Set the read mode - - Set the MII Busy bit */ - - MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD); - SET_BIT(tmpreg, ETH_MACMDIOAR_MB); - - /* Write the result value into the MDII Address register */ - WRITE_REG(heth->Instance->MACMDIOAR, tmpreg); - - tickstart = HAL_GetTick(); - - /* Wait for the Busy flag */ - while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) - { - return HAL_ERROR; - } - } - - /* Get MACMIIDR value */ - WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR); - - return HAL_OK; -} - -/** - * @brief Writes to a PHY register. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYAddr: PHY port address, must be a value from 0 to 31 - * @param PHYReg: PHY register address, must be a value from 0 to 31 - * @param RegValue: the value to write - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue) -{ - uint32_t tickstart; - uint32_t tmpreg; - - /* Check for the Busy flag */ - if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) - { - return HAL_ERROR; - } - - /* Get the MACMDIOAR value */ - WRITE_REG(tmpreg, heth->Instance->MACMDIOAR); - - /* Prepare the MDIO Address Register value - - Set the PHY device address - - Set the PHY register address - - Set the write mode - - Set the MII Busy bit */ - - MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16)); - MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR); - SET_BIT(tmpreg, ETH_MACMDIOAR_MB); - - /* Give the value to the MII data register */ - WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue); - - /* Write the result value into the MII Address register */ - WRITE_REG(ETH->MACMDIOAR, tmpreg); - - tickstart = HAL_GetTick(); - - /* Wait for the Busy flag */ - while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) - { - if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) - { - return HAL_ERROR; - } - } - - return HAL_OK; -} - -/** - * @} - */ + +/** + * @brief Unregister the Rx link callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; + + return HAL_OK; + } + +/** + * @brief Get the error state of the last received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pErrorCode: pointer to uint32_t to hold the error code + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( const ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ) + { + /* Get error bits. */ + *pErrorCode = READ_BIT( heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK ); + + return HAL_OK; + } + +/** + * @brief Set the Tx free function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txFreeCallback: pointer to function to release the packet + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ) + { + if( txFreeCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to free transmmitted packet */ + heth->txFreeCallback = txFreeCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx free callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; + + return HAL_OK; + } + +/** + * @brief Tx Free callback. + * @param buff: pointer to buffer to free + * @retval None + */ + __weak void HAL_ETH_TxFreeCallback( uint32_t * buff ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxFreeCallback could be implemented in the user file + */ + } + +/** + * @brief Release transmitted Tx packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t numOfBuf = dmatxdesclist->BuffersInUse; + uint32_t idx = dmatxdesclist->releaseIndex; + uint8_t pktTxStatus = 1U; + uint8_t pktInUse; + + #ifdef HAL_ETH_USE_PTP + ETH_TimeStampTypeDef * timestamp = &heth->TxTimestamp; + #endif /* HAL_ETH_USE_PTP */ + + /* Loop through buffers in use. */ + while( ( numOfBuf != 0U ) && ( pktTxStatus != 0U ) ) + { + pktInUse = 1U; + numOfBuf--; + + /* If no packet, just examine the next packet. */ + if( dmatxdesclist->PacketAddress[ idx ] == NULL ) + { + /* No packet in use, skip to next. */ + INCR_TX_DESC_INDEX( idx, 1U ); + pktInUse = 0U; + } + + if( pktInUse != 0U ) + { + /* Determine if the packet has been transmitted. */ + if( ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXNDESCRF_OWN ) == 0U ) + { + #ifdef HAL_ETH_USE_PTP + /* Disable Ptp transmission */ + CLEAR_BIT( heth->Init.TxDesc[ idx ].DESC3, ( 0x40000000U ) ); + + if( ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXNDESCWBF_LD ) && + ( heth->Init.TxDesc[ idx ].DESC3 & ETH_DMATXNDESCWBF_TTSS ) ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->Init.TxDesc[ idx ].DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->Init.TxDesc[ idx ].DESC1; + } + else + { + timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX; + } + #endif /* HAL_ETH_USE_PTP */ + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered callbacks*/ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + if( ( timestamp->TimeStampHigh != UINT32_MAX ) && ( timestamp->TimeStampLow != UINT32_MAX ) ) + { + heth->txPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + } + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + heth->txFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #else /* if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) */ + /* Call callbacks */ + #ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + if( ( timestamp->TimeStampHigh != UINT32_MAX ) && ( timestamp->TimeStampLow != UINT32_MAX ) ) + { + HAL_ETH_TxPtpCallback( dmatxdesclist->PacketAddress[ idx ], timestamp ); + } + #endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + HAL_ETH_TxFreeCallback( dmatxdesclist->PacketAddress[ idx ] ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + /* Clear the entry in the in-use array. */ + dmatxdesclist->PacketAddress[ idx ] = NULL; + + /* Update the transmit relesae index and number of buffers in use. */ + INCR_TX_DESC_INDEX( idx, 1U ); + dmatxdesclist->BuffersInUse = numOfBuf; + dmatxdesclist->releaseIndex = idx; + } + else + { + /* Get out of the loop! */ + pktTxStatus = 0U; + } + } + } + + return HAL_OK; + } + + #ifdef HAL_ETH_USE_PTP + +/** + * @brief Set the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + uint32_t tmpTSCR; + ETH_TimeTypeDef time; + + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + tmpTSCR = ptpconfig->Timestamp | + ( ( uint32_t ) ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos ) | + ( ( uint32_t ) ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos ); + + /* Write to MACTSCR */ + MODIFY_REG( heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR ); + + /* Enable Timestamp */ + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSENA ); + WRITE_REG( heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc ); + WRITE_REG( heth->Instance->MACTSAR, ptpconfig->TimestampAddend ); + + /* Enable Timestamp */ + if( ptpconfig->TimestampAddendUpdate == ENABLE ) + { + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG ); + + while( ( heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG ) != 0 ) + { + } + } + + /* Ptp Init */ + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT ); + + /* Set PTP Configuration done */ + heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED; + + /* Set Seconds */ + time.Seconds = heth->Instance->MACSTSR; + /* Set NanoSeconds */ + time.NanoSeconds = heth->Instance->MACSTNR; + + HAL_ETH_PTP_SetTime( heth, &time ); + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Get the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ) + { + if( ptpconfig == NULL ) + { + return HAL_ERROR; + } + + ptpconfig->Timestamp = READ_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSENA ); + ptpconfig->TimestampUpdate = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSCFUPDT ) >> ETH_MACTSCR_TSUPDT_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampAll = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSENALL ) >> ETH_MACTSCR_TSENALL_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampRolloverMode = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSCTRLSSR ) >> ETH_MACTSCR_TSCTRLSSR_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampV2 = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSVER2ENA ) >> ETH_MACTSCR_TSVER2ENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEthernet = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPENA ) >> ETH_MACTSCR_TSIPENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv6 = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPV6ENA ) >> ETH_MACTSCR_TSIPV6ENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv4 = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPV4ENA ) >> ETH_MACTSCR_TSIPV4ENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampEvent = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSEVNTENA ) >> ETH_MACTSCR_TSEVNTENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampMaster = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSMSTRENA ) >> ETH_MACTSCR_TSMSTRENA_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampSnapshots = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_SNAPTYPSEL ) >> ETH_MACTSCR_SNAPTYPSEL_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampFilter = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TSENMACADDR ) >> ETH_MACTSCR_TSENMACADDR_Pos ) > 0U ) + ? ENABLE : DISABLE; + ptpconfig->TimestampChecksumCorrection = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_CSC ) >> ETH_MACTSCR_CSC_Pos ) > 0U ) ? ENABLE : DISABLE; + ptpconfig->TimestampStatusMode = ( ( READ_BIT( heth->Instance->MACTSCR, + ETH_MACTSCR_TXTSSTSM ) >> ETH_MACTSCR_TXTSSTSM_Pos ) > 0U ) + ? ENABLE : DISABLE; + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to set + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Set Seconds */ + heth->Instance->MACSTSUR = time->Seconds; + + /* Set NanoSeconds */ + heth->Instance->MACSTNUR = time->NanoSeconds; + + /* the system time is updated */ + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param time: pointer to a ETH_TimeTypeDef structure that contains + * time to get + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get Seconds */ + time->Seconds = heth->Instance->MACSTSR; + /* Get NanoSeconds */ + time->NanoSeconds = heth->Instance->MACSTNR; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Update time for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains + * the time update information + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + if( ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE ) + { + /* Set Seconds update */ + heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U; + + if( READ_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR ) == ETH_MACTSCR_TSCTRLSSR ) + { + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds; + } + else + { + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U; + } + } + else + { + /* Set Seconds update */ + heth->Instance->MACSTSUR = timeoffset->Seconds; + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = timeoffset->NanoSeconds; + } + + SET_BIT( heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Insert Timestamp in transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Enable Time Stamp transmission */ + SET_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE ); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get transmission timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * transmission timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t idx = dmatxdesclist->releaseIndex; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ idx ]; + + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = dmatxdesc->DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = dmatxdesc->DESC1; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Get receive timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * receive timestamp + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ) + { + if( heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED ) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } + } + +/** + * @brief Register the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txPtpCallback: Function to handle Ptp transmission + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ) + { + if( txPtpCallback == NULL ) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set Function to handle Tx Ptp */ + heth->txPtpCallback = txPtpCallback; + + return HAL_OK; + } + +/** + * @brief Unregister the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ) + { + /* Set function to allocate buffer */ + heth->txPtpCallback = HAL_ETH_TxPtpCallback; + + return HAL_OK; + } + +/** + * @brief Tx Ptp callback. + * @param buff: pointer to application buffer + * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains + * transmission timestamp + * @retval None + */ + __weak void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( buff ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxPtpCallback could be implemented in the user file + */ + } + #endif /* HAL_ETH_USE_PTP */ + +/** + * @brief This function handles ETH interrupt request. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ) + { + uint32_t mac_flag = READ_REG( heth->Instance->MACISR ); + uint32_t dma_flag = READ_REG( heth->Instance->DMACSR ); + uint32_t dma_itsource = READ_REG( heth->Instance->DMACIER ); + uint32_t exti_d1_flag = READ_REG( EXTI_D1->PR3 ); + + #if defined( DUAL_CORE ) + uint32_t exti_d2_flag = READ_REG( EXTI_D2->PR3 ); + #endif /* DUAL_CORE */ + + /* Packet received */ + if( ( ( dma_flag & ETH_DMACSR_RI ) != 0U ) && ( ( dma_itsource & ETH_DMACIER_RIE ) != 0U ) ) + { + /* Clear the Eth DMA Rx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMACSR_RI | ETH_DMACSR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Receive complete callback*/ + heth->RxCpltCallback( heth ); + #else + /* Receive complete callback */ + HAL_ETH_RxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* Packet transmitted */ + if( ( ( dma_flag & ETH_DMACSR_TI ) != 0U ) && ( ( dma_itsource & ETH_DMACIER_TIE ) != 0U ) ) + { + /* Clear the Eth DMA Tx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT( heth, ETH_DMACSR_TI | ETH_DMACSR_NIS ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /*Call registered Transmit complete callback*/ + heth->TxCpltCallback( heth ); + #else + /* Transfer complete callback */ + HAL_ETH_TxCpltCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* ETH DMA Error */ + if( ( ( dma_flag & ETH_DMACSR_AIS ) != 0U ) && ( ( dma_itsource & ETH_DMACIER_AIE ) != 0U ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + + /* if fatal bus error occurred */ + if( ( dma_flag & ETH_DMACSR_FBE ) != 0U ) + { + /* Get DMA error code */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMACSR, ( ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS ) ); + + /* Disable all interrupts */ + __HAL_ETH_DMA_DISABLE_IT( heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE ); + + /* Set HAL state to ERROR */ + heth->gState = HAL_ETH_STATE_ERROR; + } + else + { + /* Get DMA error status */ + heth->DMAErrorCode = READ_BIT( heth->Instance->DMACSR, ( ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | + ETH_DMACSR_RBU | ETH_DMACSR_AIS ) ); + + /* Clear the interrupt summary flag */ + __HAL_ETH_DMA_CLEAR_IT( heth, ( ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | + ETH_DMACSR_RBU | ETH_DMACSR_AIS ) ); + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered Error callback*/ + heth->ErrorCallback( heth ); + #else + /* Ethernet DMA Error callback */ + HAL_ETH_ErrorCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + + /* ETH MAC Error IT */ + if( ( ( mac_flag & ETH_MACIER_RXSTSIE ) == ETH_MACIER_RXSTSIE ) || \ + ( ( mac_flag & ETH_MACIER_TXSTSIE ) == ETH_MACIER_TXSTSIE ) ) + { + heth->ErrorCode |= HAL_ETH_ERROR_MAC; + + /* Get MAC Rx Tx status and clear Status register pending bit */ + heth->MACErrorCode = READ_REG( heth->Instance->MACRXTXSR ); + + heth->gState = HAL_ETH_STATE_ERROR; + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered Error callback*/ + heth->ErrorCallback( heth ); + #else + /* Ethernet Error callback */ + HAL_ETH_ErrorCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->MACErrorCode = ( uint32_t ) ( 0x0U ); + } + + /* ETH PMT IT */ + if( ( mac_flag & ETH_MAC_PMT_IT ) != 0U ) + { + /* Get MAC Wake-up source and clear the status register pending bit */ + heth->MACWakeUpEvent = READ_BIT( heth->Instance->MACPCSR, ( ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD ) ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered PMT callback*/ + heth->PMTCallback( heth ); + #else + /* Ethernet PMT callback */ + HAL_ETH_PMTCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACWakeUpEvent = ( uint32_t ) ( 0x0U ); + } + + /* ETH EEE IT */ + if( ( mac_flag & ETH_MAC_LPI_IT ) != 0U ) + { + /* Get MAC LPI interrupt source and clear the status register pending bit */ + heth->MACLPIEvent = READ_BIT( heth->Instance->MACLCSR, 0x0000000FU ); + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered EEE callback*/ + heth->EEECallback( heth ); + #else + /* Ethernet EEE callback */ + HAL_ETH_EEECallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACLPIEvent = ( uint32_t ) ( 0x0U ); + } + + #if defined( DUAL_CORE ) + if( HAL_GetCurrentCPUID() == CM7_CPUID ) + { + /* check ETH WAKEUP exti flag */ + if( ( exti_d1_flag & ETH_WAKEUP_EXTI_LINE ) != 0U ) + { + /* Clear ETH WAKEUP Exti pending bit */ + __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( ETH_WAKEUP_EXTI_LINE ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered WakeUp callback*/ + heth->WakeUpCallback( heth ); + #else + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + else + { + /* check ETH WAKEUP exti flag */ + if( ( exti_d2_flag & ETH_WAKEUP_EXTI_LINE ) != 0U ) + { + /* Clear ETH WAKEUP Exti pending bit */ + __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG( ETH_WAKEUP_EXTI_LINE ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered WakeUp callback*/ + heth->WakeUpCallback( heth ); + #else + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + #else /* DUAL_CORE not defined */ + /* check ETH WAKEUP exti flag */ + if( ( exti_d1_flag & ETH_WAKEUP_EXTI_LINE ) != 0U ) + { + /* Clear ETH WAKEUP Exti pending bit */ + __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( ETH_WAKEUP_EXTI_LINE ); + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + /* Call registered WakeUp callback*/ + heth->WakeUpCallback( heth ); + #else + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback( heth ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + #endif /* DUAL_CORE */ + } + +/** + * @brief Tx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_TxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Rx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_RxCpltCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet transfer error callbacks + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_ErrorCallback could be implemented in the user file + */ + } + +/** + * @brief Ethernet Power Management module IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_PMTCallback could be implemented in the user file + */ + } + +/** + * @brief Energy Efficient Etherent IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_EEECallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_EEECallback could be implemented in the user file + */ + } + +/** + * @brief ETH WAKEUP interrupt callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + __weak void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ) + { + /* Prevent unused argument(s) compilation warning */ + UNUSED( heth ); + + /* NOTE : This function Should not be modified, when the callback is needed, + * the HAL_ETH_WakeUpCallback could be implemented in the user file + */ + } + +/** + * @brief Read a PHY register + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param pRegValue: parameter to hold read value + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ) + { + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) != ( uint32_t ) RESET ) + { + return HAL_ERROR; + } + + /* Get the MACMDIOAR value */ + WRITE_REG( tmpreg, heth->Instance->MACMDIOAR ); + + /* Prepare the MDIO Address Register value + * - Set the PHY device address + * - Set the PHY register address + * - Set the read mode + * - Set the MII Busy bit */ + + MODIFY_REG( tmpreg, ETH_MACMDIOAR_PA, ( PHYAddr << 21 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_RDA, ( PHYReg << 16 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD ); + SET_BIT( tmpreg, ETH_MACMDIOAR_MB ); + + /* Write the result value into the MDII Address register */ + WRITE_REG( heth->Instance->MACMDIOAR, tmpreg ); + + tickstart = HAL_GetTick(); + + /* Wait for the Busy flag */ + while( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT ) ) + { + return HAL_ERROR; + } + } + + /* Get MACMIIDR value */ + WRITE_REG( *pRegValue, ( uint16_t ) heth->Instance->MACMDIODR ); + + return HAL_OK; + } + +/** + * @brief Writes to a PHY register. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param RegValue: the value to write + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ) + { + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) != ( uint32_t ) RESET ) + { + return HAL_ERROR; + } + + /* Get the MACMDIOAR value */ + WRITE_REG( tmpreg, heth->Instance->MACMDIOAR ); + + /* Prepare the MDIO Address Register value + * - Set the PHY device address + * - Set the PHY register address + * - Set the write mode + * - Set the MII Busy bit */ + + MODIFY_REG( tmpreg, ETH_MACMDIOAR_PA, ( PHYAddr << 21 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_RDA, ( PHYReg << 16 ) ); + MODIFY_REG( tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR ); + SET_BIT( tmpreg, ETH_MACMDIOAR_MB ); + + /* Give the value to the MII data register */ + WRITE_REG( ETH->MACMDIODR, ( uint16_t ) RegValue ); + + /* Write the result value into the MII Address register */ + WRITE_REG( ETH->MACMDIOAR, tmpreg ); + + tickstart = HAL_GetTick(); + + /* Wait for the Busy flag */ + while( READ_BIT( heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB ) > 0U ) + { + if( ( ( HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT ) ) + { + return HAL_ERROR; + } + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions - * @brief ETH control functions - * -@verbatim - ============================================================================== - ##### Peripheral Control functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to control the ETH - peripheral. - -@endverbatim - * @{ - */ -/** - * @brief Get the configuration of the MAC and MTL subsystems. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold - * the configuration of the MAC. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - /* Get MAC parameters */ - macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN); - macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE; - macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL); - macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE; - macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U) - ? ENABLE : DISABLE; - macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE; - macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR, - ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE; - macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE; - macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM); - macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES); - macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE; - macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE; - macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE; - macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE; - macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE; - macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE; - macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR, - ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE; - macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG); - macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE; - macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC); - - macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL); - macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE; - macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE; - macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR, - ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE; - macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U) - ? ENABLE : DISABLE; - macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25; - - macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE; - macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO); - - macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE; - macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE; - macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT); - macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16); - macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE; - macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U) - ? ENABLE : DISABLE; - - macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF)); - - macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF)); - macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR, - ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE; - macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE; - macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, - ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Get the configuration of the DMA. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE; - dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB); - dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE; - - dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA)); - - dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE; - dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS); - - dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE; - dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL); - - dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE; - dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE; - dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL); - - return HAL_OK; -} - -/** - * @brief Set the MAC configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains - * the configuration of the MAC. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) -{ - if (macconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetMACConfig(heth, macconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Set the ETH DMA configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold - * the configuration of the ETH DMA. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) -{ - if (dmaconf == NULL) - { - return HAL_ERROR; - } - - if (heth->gState == HAL_ETH_STATE_READY) - { - ETH_SetDMAConfig(heth, dmaconf); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} - -/** - * @brief Configures the Clock range of ETH MDIO interface. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth) -{ - uint32_t hclk; - uint32_t tmpreg; - - /* Get the ETHERNET MACMDIOAR value */ - tmpreg = (heth->Instance)->MACMDIOAR; - - /* Clear CSR Clock Range bits */ - tmpreg &= ~ETH_MACMDIOAR_CR; - - /* Get hclk frequency value */ - hclk = HAL_RCC_GetHCLKFreq(); - - /* Set CR bits depending on hclk value */ - if (hclk < 35000000U) - { - /* CSR Clock Range between 0-35 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16; - } - else if (hclk < 60000000U) - { - /* CSR Clock Range between 35-60 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26; - } - else if (hclk < 100000000U) - { - /* CSR Clock Range between 60-100 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42; - } - else if (hclk < 150000000U) - { - /* CSR Clock Range between 100-150 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62; - } - else if (hclk < 250000000U) - { - /* CSR Clock Range between 150-250 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102; - } - else /* (hclk >= 250000000U) */ - { - /* CSR Clock >= 250 MHz */ - tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV124); - } - - /* Configure the CSR Clock Range */ - (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg; -} - -/** - * @brief Set the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - uint32_t filterconfig; - - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode | - ((uint32_t)pFilterConfig->HashUnicast << 1) | - ((uint32_t)pFilterConfig->HashMulticast << 2) | - ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) | - ((uint32_t)pFilterConfig->PassAllMulticast << 4) | - ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) | - ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) | - ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) | - ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) | - ((uint32_t)pFilterConfig->ReceiveAllMode << 31) | - pFilterConfig->ControlPacketsFilter); - - MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig); - - return HAL_OK; -} - -/** - * @brief Get the ETH MAC (L2) Filters configuration. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold - * the configuration of the ETH MAC filters. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig) -{ - if (pFilterConfig == NULL) - { - return HAL_ERROR; - } - - pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE; - pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, - ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE; - pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE; - pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE; - pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF); - pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, - ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE; - pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE; - pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U) - ? ENABLE : DISABLE; - pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE; - - return HAL_OK; -} - -/** - * @brief Set the source MAC Address to be matched. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param AddrNbr: The MAC address to configure - * This parameter must be a value of the following: - * ETH_MAC_ADDRESS1 - * ETH_MAC_ADDRESS2 - * ETH_MAC_ADDRESS3 - * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr) -{ - uint32_t macaddrlr; - uint32_t macaddrhr; - - if (pMACAddr == NULL) - { - return HAL_ERROR; - } - - /* Get mac addr high reg offset */ - macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr); - /* Get mac addr low reg offset */ - macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr); - - /* Set MAC addr bits 32 to 47 */ - (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]); - /* Set MAC addr bits 0 to 31 */ - (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) | - ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]); - - /* Enable address and set source address bit */ - (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE); - - return HAL_OK; -} - -/** - * @brief Set the ETH Hash Table Value. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pHashTable: pointer to a table of two 32 bit values, that contains - * the 64 bits of the hash table. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable) -{ - if (pHashTable == NULL) - { - return HAL_ERROR; - } - - heth->Instance->MACHT0R = pHashTable[0]; - heth->Instance->MACHT1R = pHashTable[1]; - - return HAL_OK; -} - -/** - * @brief Set the VLAN Identifier for Rx packets - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param ComparisonBits: 12 or 16 bit comparison mode - must be a value of @ref ETH_VLAN_Tag_Comparison - * @param VLANIdentifier: VLAN Identifier value - * @retval None - */ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier) -{ - if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) - { - MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier); - CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV); - } - else - { - MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier); - SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV); - } -} - -/** - * @brief Enters the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure - * that contains the Power Down configuration - * @retval None. - */ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig) -{ - uint32_t powerdownconfig; - - powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) | - ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) | - ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) | - ((uint32_t)pPowerDownConfig->WakeUpForward << 10) | - ETH_MACPCSR_PWRDWN); - - /* Enable PMT interrupt */ - __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE); - - MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig); -} - -/** - * @brief Exits from the Power down mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth) -{ - /* clear wake up sources */ - CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | - ETH_MACPCSR_RWKPFE); - - if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET) - { - /* Exit power down mode */ - CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN); - } - - /* Disable PMT interrupt */ - __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE); -} - -/** - * @brief Set the WakeUp filter. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pFilter: pointer to filter registers values - * @param Count: number of filter registers, must be from 1 to 8. - * @retval None. - */ -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count) -{ - uint32_t regindex; - - if (pFilter == NULL) - { - return HAL_ERROR; - } - - /* Reset Filter Pointer */ - SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST); - - /* Wake up packet filter config */ - for (regindex = 0; regindex < Count; regindex++) - { - /* Write filter regs */ - WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]); - } - - return HAL_OK; -} - -/** - * @} - */ + * @brief ETH control functions + * + * @verbatim + * ============================================================================== + ##### Peripheral Control functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to control the ETH + #####peripheral. + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Get the configuration of the MAC and MTL subsystems. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold + * the configuration of the MAC. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetMACConfig( const ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + /* Get MAC parameters */ + macconf->PreambleLength = READ_BIT( heth->Instance->MACCR, ETH_MACCR_PRELEN ); + macconf->DeferralCheck = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DC ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + macconf->BackOffLimit = READ_BIT( heth->Instance->MACCR, ETH_MACCR_BL ); + macconf->RetryTransmission = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DR ) >> 8 ) == 0U ) ? ENABLE : DISABLE; + macconf->CarrierSenseDuringTransmit = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DCRS ) >> 9 ) > 0U ) + ? ENABLE : DISABLE; + macconf->ReceiveOwn = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_DO ) >> 10 ) == 0U ) ? ENABLE : DISABLE; + macconf->CarrierSenseBeforeTransmit = ( ( READ_BIT( heth->Instance->MACCR, + ETH_MACCR_ECRSFD ) >> 11 ) > 0U ) ? ENABLE : DISABLE; + macconf->LoopbackMode = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_LM ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + macconf->DuplexMode = READ_BIT( heth->Instance->MACCR, ETH_MACCR_DM ); + macconf->Speed = READ_BIT( heth->Instance->MACCR, ETH_MACCR_FES ); + macconf->JumboPacket = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_JE ) >> 16 ) > 0U ) ? ENABLE : DISABLE; + macconf->Jabber = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_JD ) >> 17 ) == 0U ) ? ENABLE : DISABLE; + macconf->Watchdog = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_WD ) >> 19 ) == 0U ) ? ENABLE : DISABLE; + macconf->AutomaticPadCRCStrip = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_ACS ) >> 20 ) > 0U ) ? ENABLE : DISABLE; + macconf->CRCStripTypePacket = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_CST ) >> 21 ) > 0U ) ? ENABLE : DISABLE; + macconf->Support2KPacket = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_S2KP ) >> 22 ) > 0U ) ? ENABLE : DISABLE; + macconf->GiantPacketSizeLimitControl = ( ( READ_BIT( heth->Instance->MACCR, + ETH_MACCR_GPSLCE ) >> 23 ) > 0U ) ? ENABLE : DISABLE; + macconf->InterPacketGapVal = READ_BIT( heth->Instance->MACCR, ETH_MACCR_IPG ); + macconf->ChecksumOffload = ( ( READ_BIT( heth->Instance->MACCR, ETH_MACCR_IPC ) >> 27 ) > 0U ) ? ENABLE : DISABLE; + macconf->SourceAddrControl = READ_BIT( heth->Instance->MACCR, ETH_MACCR_SARC ); + + macconf->GiantPacketSizeLimit = READ_BIT( heth->Instance->MACECR, ETH_MACECR_GPSL ); + macconf->CRCCheckingRxPackets = ( ( READ_BIT( heth->Instance->MACECR, ETH_MACECR_DCRCC ) >> 16 ) == 0U ) ? ENABLE : DISABLE; + macconf->SlowProtocolDetect = ( ( READ_BIT( heth->Instance->MACECR, ETH_MACECR_SPEN ) >> 17 ) > 0U ) ? ENABLE : DISABLE; + macconf->UnicastSlowProtocolPacketDetect = ( ( READ_BIT( heth->Instance->MACECR, + ETH_MACECR_USP ) >> 18 ) > 0U ) ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGap = ( ( READ_BIT( heth->Instance->MACECR, ETH_MACECR_EIPGEN ) >> 24 ) > 0U ) + ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGapVal = READ_BIT( heth->Instance->MACECR, ETH_MACECR_EIPG ) >> 25; + + macconf->ProgrammableWatchdog = ( ( READ_BIT( heth->Instance->MACWTR, ETH_MACWTR_PWE ) >> 8 ) > 0U ) ? ENABLE : DISABLE; + macconf->WatchdogTimeout = READ_BIT( heth->Instance->MACWTR, ETH_MACWTR_WTO ); + + macconf->TransmitFlowControl = ( ( READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_TFE ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + macconf->ZeroQuantaPause = ( ( READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ ) >> 7 ) == 0U ) ? ENABLE : DISABLE; + macconf->PauseLowThreshold = READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_PLT ); + macconf->PauseTime = ( READ_BIT( heth->Instance->MACTFCR, ETH_MACTFCR_PT ) >> 16 ); + macconf->ReceiveFlowControl = ( READ_BIT( heth->Instance->MACRFCR, ETH_MACRFCR_RFE ) > 0U ) ? ENABLE : DISABLE; + macconf->UnicastPausePacketDetect = ( ( READ_BIT( heth->Instance->MACRFCR, ETH_MACRFCR_UP ) >> 1 ) > 0U ) + ? ENABLE : DISABLE; + + macconf->TransmitQueueMode = READ_BIT( heth->Instance->MTLTQOMR, ( ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF ) ); + + macconf->ReceiveQueueMode = READ_BIT( heth->Instance->MTLRQOMR, ( ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF ) ); + macconf->ForwardRxUndersizedGoodPacket = ( ( READ_BIT( heth->Instance->MTLRQOMR, + ETH_MTLRQOMR_FUP ) >> 3 ) > 0U ) ? ENABLE : DISABLE; + macconf->ForwardRxErrorPacket = ( ( READ_BIT( heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + macconf->DropTCPIPChecksumErrorPacket = ( ( READ_BIT( heth->Instance->MTLRQOMR, + ETH_MTLRQOMR_DISTCPEF ) >> 6 ) == 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Get the configuration of the DMA. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( const ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + dmaconf->AddressAlignedBeats = ( ( READ_BIT( heth->Instance->DMASBMR, ETH_DMASBMR_AAL ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->BurstMode = READ_BIT( heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB ); + dmaconf->RebuildINCRxBurst = ( ( READ_BIT( heth->Instance->DMASBMR, ETH_DMASBMR_RB ) >> 15 ) > 0U ) ? ENABLE : DISABLE; + + dmaconf->DMAArbitration = READ_BIT( heth->Instance->DMAMR, ( ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA ) ); + + dmaconf->PBLx8Mode = ( ( READ_BIT( heth->Instance->DMACCR, ETH_DMACCR_8PBL ) >> 16 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->MaximumSegmentSize = READ_BIT( heth->Instance->DMACCR, ETH_DMACCR_MSS ); + + dmaconf->FlushRxPacket = ( ( READ_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_RPF ) >> 31 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->RxDMABurstLength = READ_BIT( heth->Instance->DMACRCR, ETH_DMACRCR_RPBL ); + + dmaconf->SecondPacketOperate = ( ( READ_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_OSP ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->TCPSegmentation = ( ( READ_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_TSE ) >> 12 ) > 0U ) ? ENABLE : DISABLE; + dmaconf->TxDMABurstLength = READ_BIT( heth->Instance->DMACTCR, ETH_DMACTCR_TPBL ); + + return HAL_OK; + } + +/** + * @brief Set the MAC configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains + * the configuration of the MAC. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ) + { + if( macconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetMACConfig( heth, macconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Set the ETH DMA configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ) + { + if( dmaconf == NULL ) + { + return HAL_ERROR; + } + + if( heth->gState == HAL_ETH_STATE_READY ) + { + ETH_SetDMAConfig( heth, dmaconf ); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } + } + +/** + * @brief Configures the Clock range of ETH MDIO interface. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ) + { + uint32_t hclk; + uint32_t tmpreg; + + /* Get the ETHERNET MACMDIOAR value */ + tmpreg = ( heth->Instance )->MACMDIOAR; + + /* Clear CSR Clock Range bits */ + tmpreg &= ~ETH_MACMDIOAR_CR; + + /* Get hclk frequency value */ + hclk = HAL_RCC_GetHCLKFreq(); + + /* Set CR bits depending on hclk value */ + if( hclk < 35000000U ) + { + /* CSR Clock Range between 0-35 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV16; + } + else if( hclk < 60000000U ) + { + /* CSR Clock Range between 35-60 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV26; + } + else if( hclk < 100000000U ) + { + /* CSR Clock Range between 60-100 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV42; + } + else if( hclk < 150000000U ) + { + /* CSR Clock Range between 100-150 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV62; + } + else if( hclk < 250000000U ) + { + /* CSR Clock Range between 150-250 MHz */ + tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV102; + } + else /* (hclk >= 250000000U) */ + { + /* CSR Clock >= 250 MHz */ + tmpreg |= ( uint32_t ) ( ETH_MACMDIOAR_CR_DIV124 ); + } + + /* Configure the CSR Clock Range */ + ( heth->Instance )->MACMDIOAR = ( uint32_t ) tmpreg; + } + +/** + * @brief Set the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + uint32_t filterconfig; + + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + filterconfig = ( ( uint32_t ) pFilterConfig->PromiscuousMode | + ( ( uint32_t ) pFilterConfig->HashUnicast << 1 ) | + ( ( uint32_t ) pFilterConfig->HashMulticast << 2 ) | + ( ( uint32_t ) pFilterConfig->DestAddrInverseFiltering << 3 ) | + ( ( uint32_t ) pFilterConfig->PassAllMulticast << 4 ) | + ( ( uint32_t ) ( ( pFilterConfig->BroadcastFilter == DISABLE ) ? 1U : 0U ) << 5 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrInverseFiltering << 8 ) | + ( ( uint32_t ) pFilterConfig->SrcAddrFiltering << 9 ) | + ( ( uint32_t ) pFilterConfig->HachOrPerfectFilter << 10 ) | + ( ( uint32_t ) pFilterConfig->ReceiveAllMode << 31 ) | + pFilterConfig->ControlPacketsFilter ); + + MODIFY_REG( heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig ); + + return HAL_OK; + } + +/** + * @brief Get the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold + * the configuration of the ETH MAC filters. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( const ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ) + { + if( pFilterConfig == NULL ) + { + return HAL_ERROR; + } + + pFilterConfig->PromiscuousMode = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PR ) ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashUnicast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HUC ) >> 1 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HashMulticast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HMC ) >> 2 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->DestAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACPFR, + ETH_MACPFR_DAIF ) >> 3 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->PassAllMulticast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PM ) >> 4 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->BroadcastFilter = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_DBF ) >> 5 ) == 0U ) ? ENABLE : DISABLE; + pFilterConfig->ControlPacketsFilter = READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PCF ); + pFilterConfig->SrcAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACPFR, + ETH_MACPFR_SAIF ) >> 8 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->SrcAddrFiltering = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_SAF ) >> 9 ) > 0U ) ? ENABLE : DISABLE; + pFilterConfig->HachOrPerfectFilter = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HPF ) >> 10 ) > 0U ) + ? ENABLE : DISABLE; + pFilterConfig->ReceiveAllMode = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_RA ) >> 31 ) > 0U ) ? ENABLE : DISABLE; + + return HAL_OK; + } + +/** + * @brief Set the source MAC Address to be matched. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param AddrNbr: The MAC address to configure + * This parameter must be a value of the following: + * ETH_MAC_ADDRESS1 + * ETH_MAC_ADDRESS2 + * ETH_MAC_ADDRESS3 + * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ) + { + uint32_t macaddrlr; + uint32_t macaddrhr; + + if( pMACAddr == NULL ) + { + return HAL_ERROR; + } + + /* Get mac addr high reg offset */ + macaddrhr = ( ( uint32_t ) &( heth->Instance->MACA0HR ) + AddrNbr ); + /* Get mac addr low reg offset */ + macaddrlr = ( ( uint32_t ) &( heth->Instance->MACA0LR ) + AddrNbr ); + + /* Set MAC addr bits 32 to 47 */ + ( *( __IO uint32_t * ) macaddrhr ) = ( ( ( uint32_t ) ( pMACAddr[ 5 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 4 ] ); + /* Set MAC addr bits 0 to 31 */ + ( *( __IO uint32_t * ) macaddrlr ) = ( ( ( uint32_t ) ( pMACAddr[ 3 ] ) << 24 ) | ( ( uint32_t ) ( pMACAddr[ 2 ] ) << 16 ) | + ( ( uint32_t ) ( pMACAddr[ 1 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 0 ] ); + + /* Enable address and set source address bit */ + ( *( __IO uint32_t * ) macaddrhr ) |= ( ETH_MACAHR_SA | ETH_MACAHR_AE ); + + return HAL_OK; + } + +/** + * @brief Set the ETH Hash Table Value. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pHashTable: pointer to a table of two 32 bit values, that contains + * the 64 bits of the hash table. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ) + { + if( pHashTable == NULL ) + { + return HAL_ERROR; + } + + heth->Instance->MACHT0R = pHashTable[ 0 ]; + heth->Instance->MACHT1R = pHashTable[ 1 ]; + + return HAL_OK; + } + +/** + * @brief Set the VLAN Identifier for Rx packets + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ComparisonBits: 12 or 16 bit comparison mode + * must be a value of @ref ETH_VLAN_Tag_Comparison + * @param VLANIdentifier: VLAN Identifier value + * @retval None + */ + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ) + { + if( ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT ) + { + MODIFY_REG( heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier ); + CLEAR_BIT( heth->Instance->MACVTR, ETH_MACVTR_ETV ); + } + else + { + MODIFY_REG( heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier ); + SET_BIT( heth->Instance->MACVTR, ETH_MACVTR_ETV ); + } + } + +/** + * @brief Enters the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure + * that contains the Power Down configuration + * @retval None. + */ + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ) + { + uint32_t powerdownconfig; + + powerdownconfig = ( ( ( uint32_t ) pPowerDownConfig->MagicPacket << 1 ) | + ( ( uint32_t ) pPowerDownConfig->WakeUpPacket << 2 ) | + ( ( uint32_t ) pPowerDownConfig->GlobalUnicast << 9 ) | + ( ( uint32_t ) pPowerDownConfig->WakeUpForward << 10 ) | + ETH_MACPCSR_PWRDWN ); + + /* Enable PMT interrupt */ + __HAL_ETH_MAC_ENABLE_IT( heth, ETH_MACIER_PMTIE ); + + MODIFY_REG( heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig ); + } + +/** + * @brief Exits from the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ) + { + /* clear wake up sources */ + CLEAR_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | + ETH_MACPCSR_RWKPFE ); + + if( READ_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN ) != ( uint32_t ) RESET ) + { + /* Exit power down mode */ + CLEAR_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN ); + } + + /* Disable PMT interrupt */ + __HAL_ETH_MAC_DISABLE_IT( heth, ETH_MACIER_PMTIE ); + } + +/** + * @brief Set the WakeUp filter. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilter: pointer to filter registers values + * @param Count: number of filter registers, must be from 1 to 8. + * @retval None. + */ + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ) + { + uint32_t regindex; + + if( pFilter == NULL ) + { + return HAL_ERROR; + } + + /* Reset Filter Pointer */ + SET_BIT( heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST ); + + /* Wake up packet filter config */ + for( regindex = 0; regindex < Count; regindex++ ) + { + /* Write filter regs */ + WRITE_REG( heth->Instance->MACRWKPFR, pFilter[ regindex ] ); + } + + return HAL_OK; + } + +/** + * @} + */ /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions - * @brief ETH State and Errors functions - * -@verbatim - ============================================================================== - ##### Peripheral State and Errors functions ##### - ============================================================================== - [..] - This subsection provides a set of functions allowing to return the State of - ETH communication process, return Peripheral Errors occurred during communication - process - - -@endverbatim - * @{ - */ - -/** - * @brief Returns the ETH state. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL state - */ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth) -{ - return heth->gState; -} - -/** - * @brief Returns the ETH error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH Error Code - */ -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth) -{ - return heth->ErrorCode; -} - -/** - * @brief Returns the ETH DMA error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH DMA Error Code - */ -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth) -{ - return heth->DMAErrorCode; -} - -/** - * @brief Returns the ETH MAC error code - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC Error Code - */ -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth) -{ - return heth->MACErrorCode; -} - -/** - * @brief Returns the ETH MAC WakeUp event source - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC WakeUp event source - */ -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth) -{ - return heth->MACWakeUpEvent; -} - -/** - * @} - */ - -/** - * @} - */ + * @brief ETH State and Errors functions + * + * @verbatim + * ============================================================================== + ##### Peripheral State and Errors functions ##### + #####============================================================================== + #####[..] + #####This subsection provides a set of functions allowing to return the State of + #####ETH communication process, return Peripheral Errors occurred during communication + #####process + ##### + ##### + #####@endverbatim + * @{ + */ + +/** + * @brief Returns the ETH state. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL state + */ + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ) + { + return heth->gState; + } + +/** + * @brief Returns the ETH error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH Error Code + */ + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ) + { + return heth->ErrorCode; + } + +/** + * @brief Returns the ETH DMA error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH DMA Error Code + */ + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ) + { + return heth->DMAErrorCode; + } + +/** + * @brief Returns the ETH MAC error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC Error Code + */ + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ) + { + return heth->MACErrorCode; + } + +/** + * @brief Returns the ETH MAC WakeUp event source + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event source + */ + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ) + { + return heth->MACWakeUpEvent; + } + +/** + * @} + */ + +/** + * @} + */ /** @addtogroup ETH_Private_Functions ETH Private Functions - * @{ - */ - -static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf) -{ - uint32_t macregval; - - /*------------------------ MACCR Configuration --------------------*/ - macregval = (macconf->InterPacketGapVal | - macconf->SourceAddrControl | - ((uint32_t)macconf->ChecksumOffload << 27) | - ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) | - ((uint32_t)macconf->Support2KPacket << 22) | - ((uint32_t)macconf->CRCStripTypePacket << 21) | - ((uint32_t)macconf->AutomaticPadCRCStrip << 20) | - ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) | - ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) | - ((uint32_t)macconf->JumboPacket << 16) | - macconf->Speed | - macconf->DuplexMode | - ((uint32_t)macconf->LoopbackMode << 12) | - ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) | - ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) | - ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) | - ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) | - macconf->BackOffLimit | - ((uint32_t)macconf->DeferralCheck << 4) | - macconf->PreambleLength); - - /* Write to MACCR */ - MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval); - - /*------------------------ MACECR Configuration --------------------*/ - macregval = ((macconf->ExtendedInterPacketGapVal << 25) | - ((uint32_t)macconf->ExtendedInterPacketGap << 24) | - ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) | - ((uint32_t)macconf->SlowProtocolDetect << 17) | - ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) | - macconf->GiantPacketSizeLimit); - - /* Write to MACECR */ - MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval); - - /*------------------------ MACWTR Configuration --------------------*/ - macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) | - macconf->WatchdogTimeout); - - /* Write to MACWTR */ - MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval); - - /*------------------------ MACTFCR Configuration --------------------*/ - macregval = (((uint32_t)macconf->TransmitFlowControl << 1) | - macconf->PauseLowThreshold | - ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) | - (macconf->PauseTime << 16)); - - /* Write to MACTFCR */ - MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval); - - /*------------------------ MACRFCR Configuration --------------------*/ - macregval = ((uint32_t)macconf->ReceiveFlowControl | - ((uint32_t)macconf->UnicastPausePacketDetect << 1)); - - /* Write to MACRFCR */ - MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval); - - /*------------------------ MTLTQOMR Configuration --------------------*/ - /* Write to MTLTQOMR */ - MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode); - - /*------------------------ MTLRQOMR Configuration --------------------*/ - macregval = (macconf->ReceiveQueueMode | - ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) | - ((uint32_t)macconf->ForwardRxErrorPacket << 4) | - ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3)); - - /* Write to MTLRQOMR */ - MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval); -} - -static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf) -{ - uint32_t dmaregval; - - /*------------------------ DMAMR Configuration --------------------*/ - MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration); - - /*------------------------ DMASBMR Configuration --------------------*/ - dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) | - dmaconf->BurstMode | - ((uint32_t)dmaconf->RebuildINCRxBurst << 15)); - - MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval); - - /*------------------------ DMACCR Configuration --------------------*/ - dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) | - dmaconf->MaximumSegmentSize); - MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval); - - /*------------------------ DMACTCR Configuration --------------------*/ - dmaregval = (dmaconf->TxDMABurstLength | - ((uint32_t)dmaconf->SecondPacketOperate << 4) | - ((uint32_t)dmaconf->TCPSegmentation << 12)); - - MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval); - - /*------------------------ DMACRCR Configuration --------------------*/ - dmaregval = (((uint32_t)dmaconf->FlushRxPacket << 31) | - dmaconf->RxDMABurstLength); - - /* Write to DMACRCR */ - MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval); -} - -/** - * @brief Configures Ethernet MAC and DMA with default parameters. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status - */ -static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth) -{ - ETH_MACConfigTypeDef macDefaultConf; - ETH_DMAConfigTypeDef dmaDefaultConf; - - /*--------------- ETHERNET MAC registers default Configuration --------------*/ - macDefaultConf.AutomaticPadCRCStrip = ENABLE; - macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; - macDefaultConf.CarrierSenseBeforeTransmit = DISABLE; - macDefaultConf.CarrierSenseDuringTransmit = DISABLE; - macDefaultConf.ChecksumOffload = ENABLE; - macDefaultConf.CRCCheckingRxPackets = ENABLE; - macDefaultConf.CRCStripTypePacket = ENABLE; - macDefaultConf.DeferralCheck = DISABLE; - macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE; - macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; - macDefaultConf.ExtendedInterPacketGap = DISABLE; - macDefaultConf.ExtendedInterPacketGapVal = 0x0U; - macDefaultConf.ForwardRxErrorPacket = DISABLE; - macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE; - macDefaultConf.GiantPacketSizeLimit = 0x618U; - macDefaultConf.GiantPacketSizeLimitControl = DISABLE; - macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT; - macDefaultConf.Jabber = ENABLE; - macDefaultConf.JumboPacket = DISABLE; - macDefaultConf.LoopbackMode = DISABLE; - macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4; - macDefaultConf.PauseTime = 0x0U; - macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7; - macDefaultConf.ProgrammableWatchdog = DISABLE; - macDefaultConf.ReceiveFlowControl = DISABLE; - macDefaultConf.ReceiveOwn = ENABLE; - macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD; - macDefaultConf.RetryTransmission = ENABLE; - macDefaultConf.SlowProtocolDetect = DISABLE; - macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0; - macDefaultConf.Speed = ETH_SPEED_100M; - macDefaultConf.Support2KPacket = DISABLE; - macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD; - macDefaultConf.TransmitFlowControl = DISABLE; - macDefaultConf.UnicastPausePacketDetect = DISABLE; - macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE; - macDefaultConf.Watchdog = ENABLE; - macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB; - macDefaultConf.ZeroQuantaPause = ENABLE; - - /* MAC default configuration */ - ETH_SetMACConfig(heth, &macDefaultConf); - - /*--------------- ETHERNET DMA registers default Configuration --------------*/ - dmaDefaultConf.AddressAlignedBeats = ENABLE; - dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; - dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1; - dmaDefaultConf.FlushRxPacket = DISABLE; - dmaDefaultConf.PBLx8Mode = DISABLE; - dmaDefaultConf.RebuildINCRxBurst = DISABLE; - dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.SecondPacketOperate = DISABLE; - dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; - dmaDefaultConf.TCPSegmentation = DISABLE; - dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT; - - /* DMA default configuration */ - ETH_SetDMAConfig(heth, &dmaDefaultConf); -} - -/** - * @brief Initializes the DMA Tx descriptors. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmatxdesc; - uint32_t i; - - /* Fill each DMATxDesc descriptor with the right values */ - for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++) - { - dmatxdesc = heth->Init.TxDesc + i; - - WRITE_REG(dmatxdesc->DESC0, 0x0U); - WRITE_REG(dmatxdesc->DESC1, 0x0U); - WRITE_REG(dmatxdesc->DESC2, 0x0U); - WRITE_REG(dmatxdesc->DESC3, 0x0U); - - WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc); - - } - - heth->TxDescList.CurTxDesc = 0; - - /* Set Transmit Descriptor Ring Length */ - WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U)); - - /* Set Transmit Descriptor List Address */ - WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc); - - /* Set Transmit Descriptor Tail pointer */ - WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc); -} - -/** - * @brief Initializes the DMA Rx descriptors in chain mode. - * called by HAL_ETH_Init() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) -{ - ETH_DMADescTypeDef *dmarxdesc; - uint32_t i; - - for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) - { - dmarxdesc = heth->Init.RxDesc + i; - - WRITE_REG(dmarxdesc->DESC0, 0x0U); - WRITE_REG(dmarxdesc->DESC1, 0x0U); - WRITE_REG(dmarxdesc->DESC2, 0x0U); - WRITE_REG(dmarxdesc->DESC3, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr0, 0x0U); - WRITE_REG(dmarxdesc->BackupAddr1, 0x0U); - - /* Set Rx descritors addresses */ - WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc); - - } - - WRITE_REG(heth->RxDescList.RxDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxDescCnt, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U); - WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U); - WRITE_REG(heth->RxDescList.ItMode, 0U); - - /* Set Receive Descriptor Ring Length */ - WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U))); - - /* Set Receive Descriptor List Address */ - WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc); - - /* Set Receive Descriptor Tail pointer Address */ - WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U)))); -} - -/** - * @brief Prepare Tx DMA descriptor before transmission. - * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pTxConfig: Tx packet configuration - * @param ItMode: Enable or disable Tx EOT interrept - * @retval Status - */ -static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig, - uint32_t ItMode) -{ - ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; - uint32_t descidx = dmatxdesclist->CurTxDesc; - uint32_t firstdescidx = dmatxdesclist->CurTxDesc; - uint32_t idx; - uint32_t descnbr = 0; - ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer; - uint32_t bd_count = 0; - uint32_t primask_bit; - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - return HAL_ETH_ERROR_BUSY; - } - - /***************************************************************************/ - /***************** Context descriptor configuration (Optional) **********/ - /***************************************************************************/ - /* If VLAN tag is enabled for this packet */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) - { - /* Set vlan tag value */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag); - /* Set vlan tag valid bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV); - /* Set the descriptor as the vlan input source */ - SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI); - - /* if inner VLAN is enabled */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET) - { - /* Set inner vlan tag value */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16)); - /* Set inner vlan tag valid bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV); - - /* Set Vlan Tag control */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl); - - /* Set the descriptor as the inner vlan input source */ - SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI); - /* Enable double VLAN processing */ - SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP); - } - } - - /* if tcp segmentation is enabled for this packet */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) - { - /* Set MSS value */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize); - /* Set MSS valid bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV); - } - - if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) - || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)) - { - /* Set as context descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT); - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Set own bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN); - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - descnbr += 1U; - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) - { - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx]; - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Clear own bit */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN); - - return HAL_ETH_ERROR_BUSY; - } - } - - /***************************************************************************/ - /***************** Normal descriptors configuration *****************/ - /***************************************************************************/ - - descnbr += 1U; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); - - if (txbuffer->next != NULL) - { - txbuffer = txbuffer->next; - /* Set buffer 2 address */ - WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); - } - else - { - WRITE_REG(dmatxdesc->DESC1, 0x0U); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) - { - /* Set TCP Header length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19)); - /* Set TCP payload length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); - /* Set TCP Segmentation Enabled bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE); - } - else - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET) - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl); - } - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) - { - /* Set Vlan Tag control */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl); - } - - /* Mark it as First Descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); - /* Mark it as NORMAL descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* set OWN bit of FIRST descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); - - /* If source address insertion/replacement is enabled for this packet */ - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET) - { - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl); - } - - /* only if the packet is split into more than one descriptors > 1 */ - while (txbuffer->next != NULL) - { - /* Clear the LD bit of previous descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* Clear the FD bit of new Descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); - - /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN) - || (dmatxdesclist->PacketAddress[descidx] != NULL)) - { - descidx = firstdescidx; - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - - /* clear previous desc own bit */ - for (idx = 0; idx < descnbr; idx ++) - { - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); - - /* Increment current tx descriptor index */ - INCR_TX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - } - - return HAL_ETH_ERROR_BUSY; - } - - descnbr += 1U; - - /* Get the next Tx buffer in the list */ - txbuffer = txbuffer->next; - - /* Set header or buffer 1 address */ - WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); - /* Set header or buffer 1 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); - - if (txbuffer->next != NULL) - { - /* Get the next Tx buffer in the list */ - txbuffer = txbuffer->next; - /* Set buffer 2 address */ - WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); - } - else - { - WRITE_REG(dmatxdesc->DESC1, 0x0U); - /* Set buffer 2 Length */ - MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); - } - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) - { - /* Set TCP payload length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); - /* Set TCP Segmentation Enabled bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE); - } - else - { - /* Set the packet length */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); - - if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) - { - /* Checksum Insertion Control */ - MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); - } - } - - bd_count += 1U; - - /* Ensure rest of descriptor is written to RAM before the OWN bit */ - __DMB(); - /* Set Own bit */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); - /* Mark it as NORMAL descriptor */ - CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); - } - - if (ItMode != ((uint32_t)RESET)) - { - /* Set Interrupt on completion bit */ - SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); - } - else - { - /* Clear Interrupt on completion bit */ - CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); - } - - /* Mark it as LAST descriptor */ - SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); - /* Save the current packet address to expose it to the application */ - dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress; - - dmatxdesclist->CurTxDesc = descidx; - - /* Enter critical section */ - primask_bit = __get_PRIMASK(); - __set_PRIMASK(1); - - dmatxdesclist->BuffersInUse += bd_count + 1U; - - /* Exit critical section: restore previous priority mask */ - __set_PRIMASK(primask_bit); - - /* Return function status */ - return HAL_ETH_ERROR_NONE; -} - -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth) -{ - /* Init the ETH Callback settings */ - heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ - heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ - heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ - heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ - heth->EEECallback = HAL_ETH_EEECallback; /* Legacy weak EEECallback */ - heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ - heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ - heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ -#ifdef HAL_ETH_USE_PTP - heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ -#endif /* HAL_ETH_USE_PTP */ - heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ -} -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* ETH */ + * @{ + */ + + static void ETH_SetMACConfig( ETH_HandleTypeDef * heth, + const ETH_MACConfigTypeDef * macconf ) + { + uint32_t macregval; + + /*------------------------ MACCR Configuration --------------------*/ + macregval = ( macconf->InterPacketGapVal | + macconf->SourceAddrControl | + ( ( uint32_t ) macconf->ChecksumOffload << 27 ) | + ( ( uint32_t ) macconf->GiantPacketSizeLimitControl << 23 ) | + ( ( uint32_t ) macconf->Support2KPacket << 22 ) | + ( ( uint32_t ) macconf->CRCStripTypePacket << 21 ) | + ( ( uint32_t ) macconf->AutomaticPadCRCStrip << 20 ) | + ( ( uint32_t ) ( ( macconf->Watchdog == DISABLE ) ? 1U : 0U ) << 19 ) | + ( ( uint32_t ) ( ( macconf->Jabber == DISABLE ) ? 1U : 0U ) << 17 ) | + ( ( uint32_t ) macconf->JumboPacket << 16 ) | + macconf->Speed | + macconf->DuplexMode | + ( ( uint32_t ) macconf->LoopbackMode << 12 ) | + ( ( uint32_t ) macconf->CarrierSenseBeforeTransmit << 11 ) | + ( ( uint32_t ) ( ( macconf->ReceiveOwn == DISABLE ) ? 1U : 0U ) << 10 ) | + ( ( uint32_t ) macconf->CarrierSenseDuringTransmit << 9 ) | + ( ( uint32_t ) ( ( macconf->RetryTransmission == DISABLE ) ? 1U : 0U ) << 8 ) | + macconf->BackOffLimit | + ( ( uint32_t ) macconf->DeferralCheck << 4 ) | + macconf->PreambleLength ); + + /* Write to MACCR */ + MODIFY_REG( heth->Instance->MACCR, ETH_MACCR_MASK, macregval ); + + /*------------------------ MACECR Configuration --------------------*/ + macregval = ( ( macconf->ExtendedInterPacketGapVal << 25 ) | + ( ( uint32_t ) macconf->ExtendedInterPacketGap << 24 ) | + ( ( uint32_t ) macconf->UnicastSlowProtocolPacketDetect << 18 ) | + ( ( uint32_t ) macconf->SlowProtocolDetect << 17 ) | + ( ( uint32_t ) ( ( macconf->CRCCheckingRxPackets == DISABLE ) ? 1U : 0U ) << 16 ) | + macconf->GiantPacketSizeLimit ); + + /* Write to MACECR */ + MODIFY_REG( heth->Instance->MACECR, ETH_MACECR_MASK, macregval ); + + /*------------------------ MACWTR Configuration --------------------*/ + macregval = ( ( ( uint32_t ) macconf->ProgrammableWatchdog << 8 ) | + macconf->WatchdogTimeout ); + + /* Write to MACWTR */ + MODIFY_REG( heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval ); + + /*------------------------ MACTFCR Configuration --------------------*/ + macregval = ( ( ( uint32_t ) macconf->TransmitFlowControl << 1 ) | + macconf->PauseLowThreshold | + ( ( uint32_t ) ( ( macconf->ZeroQuantaPause == DISABLE ) ? 1U : 0U ) << 7 ) | + ( macconf->PauseTime << 16 ) ); + + /* Write to MACTFCR */ + MODIFY_REG( heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval ); + + /*------------------------ MACRFCR Configuration --------------------*/ + macregval = ( ( uint32_t ) macconf->ReceiveFlowControl | + ( ( uint32_t ) macconf->UnicastPausePacketDetect << 1 ) ); + + /* Write to MACRFCR */ + MODIFY_REG( heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval ); + + /*------------------------ MTLTQOMR Configuration --------------------*/ + /* Write to MTLTQOMR */ + MODIFY_REG( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode ); + + /*------------------------ MTLRQOMR Configuration --------------------*/ + macregval = ( macconf->ReceiveQueueMode | + ( ( uint32_t ) ( ( macconf->DropTCPIPChecksumErrorPacket == DISABLE ) ? 1U : 0U ) << 6 ) | + ( ( uint32_t ) macconf->ForwardRxErrorPacket << 4 ) | + ( ( uint32_t ) macconf->ForwardRxUndersizedGoodPacket << 3 ) ); + + /* Write to MTLRQOMR */ + MODIFY_REG( heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval ); + } + + static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + const ETH_DMAConfigTypeDef * dmaconf ) + { + uint32_t dmaregval; + + /*------------------------ DMAMR Configuration --------------------*/ + MODIFY_REG( heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration ); + + /*------------------------ DMASBMR Configuration --------------------*/ + dmaregval = ( ( ( uint32_t ) dmaconf->AddressAlignedBeats << 12 ) | + dmaconf->BurstMode | + ( ( uint32_t ) dmaconf->RebuildINCRxBurst << 15 ) ); + + MODIFY_REG( heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval ); + + /*------------------------ DMACCR Configuration --------------------*/ + dmaregval = ( ( ( uint32_t ) dmaconf->PBLx8Mode << 16 ) | + dmaconf->MaximumSegmentSize ); + MODIFY_REG( heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval ); + + /*------------------------ DMACTCR Configuration --------------------*/ + dmaregval = ( dmaconf->TxDMABurstLength | + ( ( uint32_t ) dmaconf->SecondPacketOperate << 4 ) | + ( ( uint32_t ) dmaconf->TCPSegmentation << 12 ) ); + + MODIFY_REG( heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval ); + + /*------------------------ DMACRCR Configuration --------------------*/ + dmaregval = ( ( ( uint32_t ) dmaconf->FlushRxPacket << 31 ) | + dmaconf->RxDMABurstLength ); + + /* Write to DMACRCR */ + MODIFY_REG( heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval ); + } + +/** + * @brief Configures Ethernet MAC and DMA with default parameters. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ + static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth ) + { + ETH_MACConfigTypeDef macDefaultConf; + ETH_DMAConfigTypeDef dmaDefaultConf; + + /*--------------- ETHERNET MAC registers default Configuration --------------*/ + macDefaultConf.AutomaticPadCRCStrip = ENABLE; + macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; + macDefaultConf.CarrierSenseBeforeTransmit = DISABLE; + macDefaultConf.CarrierSenseDuringTransmit = DISABLE; + macDefaultConf.ChecksumOffload = ENABLE; + macDefaultConf.CRCCheckingRxPackets = ENABLE; + macDefaultConf.CRCStripTypePacket = ENABLE; + macDefaultConf.DeferralCheck = DISABLE; + macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE; + macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; + macDefaultConf.ExtendedInterPacketGap = DISABLE; + macDefaultConf.ExtendedInterPacketGapVal = 0x0U; + macDefaultConf.ForwardRxErrorPacket = DISABLE; + macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE; + macDefaultConf.GiantPacketSizeLimit = 0x618U; + macDefaultConf.GiantPacketSizeLimitControl = DISABLE; + macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT; + macDefaultConf.Jabber = ENABLE; + macDefaultConf.JumboPacket = DISABLE; + macDefaultConf.LoopbackMode = DISABLE; + macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4; + macDefaultConf.PauseTime = 0x0U; + macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7; + macDefaultConf.ProgrammableWatchdog = DISABLE; + macDefaultConf.ReceiveFlowControl = DISABLE; + macDefaultConf.ReceiveOwn = ENABLE; + macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD; + macDefaultConf.RetryTransmission = ENABLE; + macDefaultConf.SlowProtocolDetect = DISABLE; + macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0; + macDefaultConf.Speed = ETH_SPEED_100M; + macDefaultConf.Support2KPacket = DISABLE; + macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD; + macDefaultConf.TransmitFlowControl = DISABLE; + macDefaultConf.UnicastPausePacketDetect = DISABLE; + macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE; + macDefaultConf.Watchdog = ENABLE; + macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB; + macDefaultConf.ZeroQuantaPause = ENABLE; + + /* MAC default configuration */ + ETH_SetMACConfig( heth, &macDefaultConf ); + + /*--------------- ETHERNET DMA registers default Configuration --------------*/ + dmaDefaultConf.AddressAlignedBeats = ENABLE; + dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; + dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1; + dmaDefaultConf.FlushRxPacket = DISABLE; + dmaDefaultConf.PBLx8Mode = DISABLE; + dmaDefaultConf.RebuildINCRxBurst = DISABLE; + dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.SecondPacketOperate = DISABLE; + dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.TCPSegmentation = DISABLE; + dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT; + + /* DMA default configuration */ + ETH_SetDMAConfig( heth, &dmaDefaultConf ); + } + +/** + * @brief Initializes the DMA Tx descriptors. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmatxdesc; + uint32_t i; + + /* Fill each DMATxDesc descriptor with the right values */ + for( i = 0; i < ( uint32_t ) ETH_TX_DESC_CNT; i++ ) + { + dmatxdesc = heth->Init.TxDesc + i; + + WRITE_REG( dmatxdesc->DESC0, 0x0U ); + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + WRITE_REG( dmatxdesc->DESC2, 0x0U ); + WRITE_REG( dmatxdesc->DESC3, 0x0U ); + + WRITE_REG( heth->TxDescList.TxDesc[ i ], ( uint32_t ) dmatxdesc ); + } + + heth->TxDescList.CurTxDesc = 0; + + /* Set Transmit Descriptor Ring Length */ + WRITE_REG( heth->Instance->DMACTDRLR, ( ETH_TX_DESC_CNT - 1U ) ); + + /* Set Transmit Descriptor List Address */ + WRITE_REG( heth->Instance->DMACTDLAR, ( uint32_t ) heth->Init.TxDesc ); + + /* Set Transmit Descriptor Tail pointer */ + WRITE_REG( heth->Instance->DMACTDTPR, ( uint32_t ) heth->Init.TxDesc ); + } + +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth ) + { + ETH_DMADescTypeDef * dmarxdesc; + uint32_t i; + + for( i = 0; i < ( uint32_t ) ETH_RX_DESC_CNT; i++ ) + { + dmarxdesc = heth->Init.RxDesc + i; + + WRITE_REG( dmarxdesc->DESC0, 0x0U ); + WRITE_REG( dmarxdesc->DESC1, 0x0U ); + WRITE_REG( dmarxdesc->DESC2, 0x0U ); + WRITE_REG( dmarxdesc->DESC3, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr0, 0x0U ); + WRITE_REG( dmarxdesc->BackupAddr1, 0x0U ); + + /* Set Rx descritors addresses */ + WRITE_REG( heth->RxDescList.RxDesc[ i ], ( uint32_t ) dmarxdesc ); + } + + WRITE_REG( heth->RxDescList.RxDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxDescCnt, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescIdx, 0U ); + WRITE_REG( heth->RxDescList.RxBuildDescCnt, 0U ); + WRITE_REG( heth->RxDescList.ItMode, 0U ); + + /* Set Receive Descriptor Ring Length */ + WRITE_REG( heth->Instance->DMACRDRLR, ( ( uint32_t ) ( ETH_RX_DESC_CNT - 1U ) ) ); + + /* Set Receive Descriptor List Address */ + WRITE_REG( heth->Instance->DMACRDLAR, ( uint32_t ) heth->Init.RxDesc ); + + /* Set Receive Descriptor Tail pointer Address */ + WRITE_REG( heth->Instance->DMACRDTPR, ( ( uint32_t ) ( heth->Init.RxDesc + ( uint32_t ) ( ETH_RX_DESC_CNT - 1U ) ) ) ); + } + +/** + * @brief Prepare Tx DMA descriptor before transmission. + * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Tx packet configuration + * @param ItMode: Enable or disable Tx EOT interrept + * @retval Status + */ + static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth, + const ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t ItMode ) + { + ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + uint32_t firstdescidx = dmatxdesclist->CurTxDesc; + uint32_t idx; + uint32_t descnbr = 0; + ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + ETH_BufferTypeDef * txbuffer = pTxConfig->TxBuffer; + uint32_t bd_count = 0; + uint32_t primask_bit; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN ) == ETH_DMATXNDESCWBF_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + return HAL_ETH_ERROR_BUSY; + } + + /***************************************************************************/ + /***************** Context descriptor configuration (Optional) **********/ + /***************************************************************************/ + /* If VLAN tag is enabled for this packet */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != ( uint32_t ) RESET ) + { + /* Set vlan tag value */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag ); + /* Set vlan tag valid bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV ); + /* Set the descriptor as the vlan input source */ + SET_BIT( heth->Instance->MACVIR, ETH_MACVIR_VLTI ); + + /* if inner VLAN is enabled */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG ) != ( uint32_t ) RESET ) + { + /* Set inner vlan tag value */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, ( pTxConfig->InnerVlanTag << 16 ) ); + /* Set inner vlan tag valid bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV ); + + /* Set Vlan Tag control */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl ); + + /* Set the descriptor as the inner vlan input source */ + SET_BIT( heth->Instance->MACIVIR, ETH_MACIVIR_VLTI ); + /* Enable double VLAN processing */ + SET_BIT( heth->Instance->MACVTR, ETH_MACVTR_EDVLP ); + } + } + + /* if tcp segmentation is enabled for this packet */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) + { + /* Set MSS value */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize ); + /* Set MSS valid bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV ); + } + + if( ( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != ( uint32_t ) RESET ) || + ( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) ) + { + /* Set as context descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT ); + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set own bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_OWN ); + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + descnbr += 1U; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( READ_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN ) == ETH_DMATXNDESCWBF_OWN ) + { + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ firstdescidx ]; + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Clear own bit */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXCDESC_OWN ); + + return HAL_ETH_ERROR_BUSY; + } + } + + /***************************************************************************/ + /***************** Normal descriptors configuration *****************/ + /***************************************************************************/ + + descnbr += 1U; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC0, ( uint32_t ) txbuffer->buffer ); + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len ); + + if( txbuffer->next != NULL ) + { + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG( dmatxdesc->DESC1, ( uint32_t ) txbuffer->buffer ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, ( txbuffer->len << 16 ) ); + } + else + { + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) + { + /* Set TCP Header length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, ( pTxConfig->TCPHeaderLen << 19 ) ); + /* Set TCP payload length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen ); + /* Set TCP Segmentation Enabled bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE ); + } + else + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length ); + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM ) != ( uint32_t ) RESET ) + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD ) != ( uint32_t ) RESET ) + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl ); + } + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG ) != ( uint32_t ) RESET ) + { + /* Set Vlan Tag control */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl ); + } + + /* Mark it as First Descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD ); + /* Mark it as NORMAL descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT ); + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* set OWN bit of FIRST descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ); + + /* If source address insertion/replacement is enabled for this packet */ + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC ) != ( uint32_t ) RESET ) + { + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl ); + } + + /* only if the packet is split into more than one descriptors > 1 */ + while( txbuffer->next != NULL ) + { + /* Clear the LD bit of previous descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD ); + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* Clear the FD bit of new Descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD ); + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if( ( READ_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ) == ETH_DMATXNDESCRF_OWN ) || + ( dmatxdesclist->PacketAddress[ descidx ] != NULL ) ) + { + descidx = firstdescidx; + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + + /* clear previous desc own bit */ + for( idx = 0; idx < descnbr; idx++ ) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ); + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX( descidx, 1U ); + /* Get current descriptor address */ + dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ descidx ]; + } + + return HAL_ETH_ERROR_BUSY; + } + + descnbr += 1U; + + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + + /* Set header or buffer 1 address */ + WRITE_REG( dmatxdesc->DESC0, ( uint32_t ) txbuffer->buffer ); + /* Set header or buffer 1 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len ); + + if( txbuffer->next != NULL ) + { + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG( dmatxdesc->DESC1, ( uint32_t ) txbuffer->buffer ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, ( txbuffer->len << 16 ) ); + } + else + { + WRITE_REG( dmatxdesc->DESC1, 0x0U ); + /* Set buffer 2 Length */ + MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U ); + } + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO ) != ( uint32_t ) RESET ) + { + /* Set TCP payload length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen ); + /* Set TCP Segmentation Enabled bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE ); + } + else + { + /* Set the packet length */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length ); + + if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM ) != ( uint32_t ) RESET ) + { + /* Checksum Insertion Control */ + MODIFY_REG( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl ); + } + } + + bd_count += 1U; + + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set Own bit */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN ); + /* Mark it as NORMAL descriptor */ + CLEAR_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT ); + } + + if( ItMode != ( ( uint32_t ) RESET ) ) + { + /* Set Interrupt on completion bit */ + SET_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC ); + } + else + { + /* Clear Interrupt on completion bit */ + CLEAR_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC ); + } + + /* Mark it as LAST descriptor */ + SET_BIT( dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD ); + /* Save the current packet address to expose it to the application */ + dmatxdesclist->PacketAddress[ descidx ] = dmatxdesclist->CurrentPacketAddress; + + dmatxdesclist->CurTxDesc = descidx; + + /* Enter critical section */ + primask_bit = __get_PRIMASK(); + __set_PRIMASK( 1 ); + + dmatxdesclist->BuffersInUse += bd_count + 1U; + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK( primask_bit ); + + /* Return function status */ + return HAL_ETH_ERROR_NONE; + } + + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth ) + { + /* Init the ETH Callback settings */ + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ + heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ + heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ + heth->EEECallback = HAL_ETH_EEECallback; /* Legacy weak EEECallback */ + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ + #ifdef HAL_ETH_USE_PTP + heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ + #endif /* HAL_ETH_USE_PTP */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ + } + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + + #endif /* ETH */ #endif /* HAL_ETH_MODULE_ENABLED */ /** - * @} - */ + * @} + */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.h b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.h index 726127ea68..eed010e395 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.h +++ b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth.h @@ -1,1849 +1,1954 @@ /** - ****************************************************************************** - * @file stm32h7xx_hal_eth.h - * @author MCD Application Team - * @brief Header file of ETH HAL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h7xx_hal_eth.h + * @author MCD Application Team + * @brief Header file of ETH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32H7xx_HAL_ETH_H -#define STM32H7xx_HAL_ETH_H + #define STM32H7xx_HAL_ETH_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32h7xx_hal_def.h" + #include "stm32h7xx_hal_def.h" -#if defined(ETH) + #if defined( ETH ) /** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ + * @{ + */ /** @addtogroup ETH - * @{ - */ + * @{ + */ /* Exported types ------------------------------------------------------------*/ -#ifndef ETH_TX_DESC_CNT -#define ETH_TX_DESC_CNT 4U -#endif /* ETH_TX_DESC_CNT */ + #ifndef ETH_TX_DESC_CNT + #define ETH_TX_DESC_CNT 4U + #endif /* ETH_TX_DESC_CNT */ -#ifndef ETH_RX_DESC_CNT -#define ETH_RX_DESC_CNT 4U -#endif /* ETH_RX_DESC_CNT */ + #ifndef ETH_RX_DESC_CNT + #define ETH_RX_DESC_CNT 4U + #endif /* ETH_RX_DESC_CNT */ -#ifndef ETH_SWRESET_TIMEOUT -#define ETH_SWRESET_TIMEOUT 500U -#endif /* ETH_SWRESET_TIMEOUT */ + #ifndef ETH_SWRESET_TIMEOUT + #define ETH_SWRESET_TIMEOUT 500U + #endif /* ETH_SWRESET_TIMEOUT */ -#ifndef ETH_MDIO_BUS_TIMEOUT -#define ETH_MDIO_BUS_TIMEOUT 1000U -#endif /* ETH_MDIO_BUS_TIMEOUT */ + #ifndef ETH_MDIO_BUS_TIMEOUT + #define ETH_MDIO_BUS_TIMEOUT 1000U + #endif /* ETH_MDIO_BUS_TIMEOUT */ -#ifndef ETH_MAC_US_TICK -#define ETH_MAC_US_TICK 1000000U -#endif /* ETH_MAC_US_TICK */ + #ifndef ETH_MAC_US_TICK + #define ETH_MAC_US_TICK 1000000U + #endif /* ETH_MAC_US_TICK */ /*********************** Descriptors struct def section ************************/ + /** @defgroup ETH_Exported_Types ETH Exported Types - * @{ - */ + * @{ + */ /** - * @brief ETH DMA Descriptor structure definition - */ -typedef struct -{ - __IO uint32_t DESC0; - __IO uint32_t DESC1; - __IO uint32_t DESC2; - __IO uint32_t DESC3; - uint32_t BackupAddr0; /* used to store rx buffer 1 address */ - uint32_t BackupAddr1; /* used to store rx buffer 2 address */ -} ETH_DMADescTypeDef; + * @brief ETH DMA Descriptor structure definition + */ + typedef struct + { + __IO uint32_t DESC0; + __IO uint32_t DESC1; + __IO uint32_t DESC2; + __IO uint32_t DESC3; + uint32_t BackupAddr0; /* used to store rx buffer 1 address */ + uint32_t BackupAddr1; /* used to store rx buffer 2 address */ + } ETH_DMADescTypeDef; + /** - * - */ + * + */ /** - * @brief ETH Buffers List structure definition - */ -typedef struct __ETH_BufferTypeDef -{ - uint8_t *buffer; /*gState = HAL_ETH_STATE_RESET; \ - (__HANDLE__)->MspInitCallback = NULL; \ - (__HANDLE__)->MspDeInitCallback = NULL; \ - } while(0) -#else -#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) do{ \ - (__HANDLE__)->gState = HAL_ETH_STATE_RESET; \ - } while(0) -#endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ - -/** - * @brief Enables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * enabled @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACIER |= (__INTERRUPT__)) - -/** - * @brief Disables the specified ETHERNET DMA interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be - * disabled. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACIER &= ~(__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT source enabled or disabled. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The ETH DMA IT Source enabled or disabled - */ -#define __HAL_ETH_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ - (((__HANDLE__)->Instance->DMACIER & (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Gets the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts - * @retval The state of ETH DMA IT (SET or RESET) - */ -#define __HAL_ETH_DMA_GET_IT(__HANDLE__, __INTERRUPT__) \ - (((__HANDLE__)->Instance->DMACSR & (__INTERRUPT__)) == (__INTERRUPT__)) - -/** - * @brief Clears the ETHERNET DMA IT pending bit. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts - * @retval None - */ -#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACSR = (__INTERRUPT__)) - -/** - * @brief Checks whether the specified ETHERNET DMA flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMACSR &( __FLAG__)) == ( __FLAG__)) - -/** - * @brief Clears the specified ETHERNET DMA flag. - * @param __HANDLE__: ETH Handle - * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags - * @retval The state of ETH DMA FLAG (SET or RESET). - */ -#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMACSR = ( __FLAG__)) - -/** - * @brief Enables the specified ETHERNET MAC interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be - * enabled @ref ETH_MAC_Interrupts - * @retval None - */ - -#define __HAL_ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIER |= (__INTERRUPT__)) - -/** - * @brief Disables the specified ETHERNET MAC interrupts. - * @param __HANDLE__ : ETH Handle - * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be - * enabled @ref ETH_MAC_Interrupts - * @retval None - */ -#define __HAL_ETH_MAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIER &= ~(__INTERRUPT__)) - -/** - * @brief Checks whether the specified ETHERNET MAC flag is set or not. - * @param __HANDLE__: ETH Handle - * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts - * @retval The state of ETH MAC IT (SET or RESET). - */ -#define __HAL_ETH_MAC_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->MACISR &\ - ( __INTERRUPT__)) == ( __INTERRUPT__)) + * @param __HANDLE__: specifies the ETH handle. + * @retval None + */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + ( __HANDLE__ )->MspInitCallback = NULL; \ + ( __HANDLE__ )->MspDeInitCallback = NULL; \ + } while( 0 ) + #else + #define __HAL_ETH_RESET_HANDLE_STATE( __HANDLE__ ) \ + do { \ + ( __HANDLE__ )->gState = HAL_ETH_STATE_RESET; \ + } while( 0 ) + #endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @brief Enables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * enabled @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_ENABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMACIER |= ( __INTERRUPT__ ) ) + +/** + * @brief Disables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * disabled. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_DISABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMACIER &= ~( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT source enabled or disabled. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The ETH DMA IT Source enabled or disabled + */ + #define __HAL_ETH_DMA_GET_IT_SOURCE( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMACIER & ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Gets the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The state of ETH DMA IT (SET or RESET) + */ + #define __HAL_ETH_DMA_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->DMACSR & ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) + +/** + * @brief Clears the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts + * @retval None + */ + #define __HAL_ETH_DMA_CLEAR_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->DMACSR = ( __INTERRUPT__ ) ) + +/** + * @brief Checks whether the specified ETHERNET DMA flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_GET_FLAG( __HANDLE__, __FLAG__ ) ( ( ( __HANDLE__ )->Instance->DMACSR & ( __FLAG__ ) ) == ( __FLAG__ ) ) + +/** + * @brief Clears the specified ETHERNET DMA flag. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ + #define __HAL_ETH_DMA_CLEAR_FLAG( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->DMACSR = ( __FLAG__ ) ) + +/** + * @brief Enables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ + + #define __HAL_ETH_MAC_ENABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->MACIER |= ( __INTERRUPT__ ) ) + +/** + * @brief Disables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ + #define __HAL_ETH_MAC_DISABLE_IT( __HANDLE__, __INTERRUPT__ ) ( ( __HANDLE__ )->Instance->MACIER &= ~( __INTERRUPT__ ) ) + +/** + * @brief Checks whether the specified ETHERNET MAC flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts + * @retval The state of ETH MAC IT (SET or RESET). + */ + #define __HAL_ETH_MAC_GET_IT( __HANDLE__, __INTERRUPT__ ) \ + ( ( ( __HANDLE__ )->Instance->MACISR & \ + ( __INTERRUPT__ ) ) == ( __INTERRUPT__ ) ) /*!< External interrupt line 86 Connected to the ETH wakeup EXTI Line */ -#define ETH_WAKEUP_EXTI_LINE 0x00400000U /* !< 86 - 64 = 22 */ + #define ETH_WAKEUP_EXTI_LINE 0x00400000U/* !< 86 - 64 = 22 */ /** - * @brief Enable the ETH WAKEUP Exti Line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT(__EXTI_LINE__) (EXTI_D1->IMR3 |= (__EXTI_LINE__)) + * @brief Enable the ETH WAKEUP Exti Line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT( __EXTI_LINE__ ) ( EXTI_D1->IMR3 |= ( __EXTI_LINE__ ) ) /** - * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval EXTI ETH WAKEUP Line Status. - */ -#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI_D1->PR3 & (__EXTI_LINE__)) + * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval EXTI ETH WAKEUP Line Status. + */ + #define __HAL_ETH_WAKEUP_EXTI_GET_FLAG( __EXTI_LINE__ ) ( EXTI_D1->PR3 & ( __EXTI_LINE__ ) ) /** - * @brief Clear the ETH WAKEUP Exti flag. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI_D1->PR3 = (__EXTI_LINE__)) + * @brief Clear the ETH WAKEUP Exti flag. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG( __EXTI_LINE__ ) ( EXTI_D1->PR3 = ( __EXTI_LINE__ ) ) + + #if defined( DUAL_CORE ) -#if defined(DUAL_CORE) /** - * @brief Enable the ETH WAKEUP Exti Line by Core2. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTID2_ENABLE_IT(__EXTI_LINE__) (EXTI_D2->IMR3 |= (__EXTI_LINE__)) + * @brief Enable the ETH WAKEUP Exti Line by Core2. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTID2_ENABLE_IT( __EXTI_LINE__ ) ( EXTI_D2->IMR3 |= ( __EXTI_LINE__ ) ) /** - * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval EXTI ETH WAKEUP Line Status. - */ -#define __HAL_ETH_WAKEUP_EXTID2_GET_FLAG(__EXTI_LINE__) (EXTI_D2->PR3 & (__EXTI_LINE__)) + * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval EXTI ETH WAKEUP Line Status. + */ + #define __HAL_ETH_WAKEUP_EXTID2_GET_FLAG( __EXTI_LINE__ ) ( EXTI_D2->PR3 & ( __EXTI_LINE__ ) ) /** - * @brief Clear the ETH WAKEUP Exti flag. - * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None. - */ -#define __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG(__EXTI_LINE__) (EXTI_D2->PR3 = (__EXTI_LINE__)) -#endif /* DUAL_CORE */ + * @brief Clear the ETH WAKEUP Exti flag. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ + #define __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG( __EXTI_LINE__ ) ( EXTI_D2->PR3 = ( __EXTI_LINE__ ) ) + #endif /* DUAL_CORE */ /** - * @brief enable rising edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE(__EXTI_LINE__) (EXTI->FTSR3 &= ~(__EXTI_LINE__)); \ - (EXTI->RTSR3 |= (__EXTI_LINE__)) + * @brief enable rising edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->FTSR3 &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->RTSR3 |= ( __EXTI_LINE__ ) ) /** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR3 &= ~(__EXTI_LINE__));\ - (EXTI->FTSR3 |= (__EXTI_LINE__)) + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR3 &= ~( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR3 |= ( __EXTI_LINE__ ) ) /** - * @brief enable falling edge interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR3 |= (__EXTI_LINE__));\ - (EXTI->FTSR3 |= (__EXTI_LINE__)) + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE( __EXTI_LINE__ ) \ + ( EXTI->RTSR3 |= ( __EXTI_LINE__ ) ); \ + ( EXTI->FTSR3 |= ( __EXTI_LINE__ ) ) /** - * @brief Generates a Software interrupt on selected EXTI line. - * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. - * @arg ETH_WAKEUP_EXTI_LINE - * @retval None - */ -#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER3 |= (__EXTI_LINE__)) -#define __HAL_ETH_GET_PTP_CONTROL(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->MACTSCR) & \ - (__FLAG__)) == (__FLAG__)) ? SET : RESET) -#define __HAL_ETH_SET_PTP_CONTROL(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->MACTSCR |= (__FLAG__)) + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ + #define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT( __EXTI_LINE__ ) ( EXTI->SWIER3 |= ( __EXTI_LINE__ ) ) + #define __HAL_ETH_GET_PTP_CONTROL( __HANDLE__, __FLAG__ ) \ + ( ( ( ( ( __HANDLE__ )->Instance->MACTSCR ) & \ + ( __FLAG__ ) ) == ( __FLAG__ ) ) ? SET : RESET ) + #define __HAL_ETH_SET_PTP_CONTROL( __HANDLE__, __FLAG__ ) ( ( __HANDLE__ )->Instance->MACTSCR |= ( __FLAG__ ) ) /** - * @} - */ + * @} + */ /* Include ETH HAL Extension module */ -#include "stm32h7xx_hal_eth_ex.h" + #include "stm32h7xx_hal_eth_ex.h" /* Exported functions --------------------------------------------------------*/ /** @addtogroup ETH_Exported_Functions - * @{ - */ + * @{ + */ /** @addtogroup ETH_Exported_Functions_Group1 - * @{ - */ + * @{ + */ /* Initialization and de initialization functions **********************************/ -HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspInit(ETH_HandleTypeDef *heth); -void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ); + void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ); /* Callbacks Register/UnRegister functions ***********************************/ -#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) -HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, - pETH_CallbackTypeDef pCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID); -#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 ) + HAL_StatusTypeDef HAL_ETH_RegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterCallback( ETH_HandleTypeDef * heth, + HAL_ETH_CallbackIDTypeDef CallbackID ); + #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group2 - * @{ - */ + * @{ + */ /* IO operation functions *******************************************************/ -HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth); - -HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff); -HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, - pETH_rxAllocateCallbackTypeDef rxAllocateCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode); -HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth); - -#ifdef HAL_ETH_USE_PTP -HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); -HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); -HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, - ETH_TimeTypeDef *timeoffset); -HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); -HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback); -HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth); -#endif /* HAL_ETH_USE_PTP */ - -HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout); -HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig); - -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t RegValue); -HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, - uint32_t *pRegValue); - -void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth); -void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth); -void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth); -void HAL_ETH_RxAllocateCallback(uint8_t **buff); -void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length); -void HAL_ETH_TxFreeCallback(uint32_t *buff); -void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp); -/** - * @} - */ + HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Start_IT( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_Stop_IT( ETH_HandleTypeDef * heth ); + + HAL_StatusTypeDef HAL_ETH_ReadData( ETH_HandleTypeDef * heth, + void ** pAppBuff ); + HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback( ETH_HandleTypeDef * heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback( ETH_HandleTypeDef * heth, + pETH_rxLinkCallbackTypeDef rxLinkCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode( const ETH_HandleTypeDef * heth, + uint32_t * pErrorCode ); + HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback( ETH_HandleTypeDef * heth, + pETH_txFreeCallbackTypeDef txFreeCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket( ETH_HandleTypeDef * heth ); + + #ifdef HAL_ETH_USE_PTP + HAL_StatusTypeDef HAL_ETH_PTP_SetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_GetConfig( ETH_HandleTypeDef * heth, + ETH_PTP_ConfigTypeDef * ptpconfig ); + HAL_StatusTypeDef HAL_ETH_PTP_SetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTime( ETH_HandleTypeDef * heth, + ETH_TimeTypeDef * time ); + HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset( ETH_HandleTypeDef * heth, + ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef * timeoffset ); + HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp( ETH_HandleTypeDef * heth, + ETH_TimeStampTypeDef * timestamp ); + HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback( ETH_HandleTypeDef * heth, + pETH_txPtpCallbackTypeDef txPtpCallback ); + HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback( ETH_HandleTypeDef * heth ); + #endif /* HAL_ETH_USE_PTP */ + + HAL_StatusTypeDef HAL_ETH_Transmit( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig, + uint32_t Timeout ); + HAL_StatusTypeDef HAL_ETH_Transmit_IT( ETH_HandleTypeDef * heth, + ETH_TxPacketConfigTypeDef * pTxConfig ); + + HAL_StatusTypeDef HAL_ETH_WritePHYRegister( const ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t RegValue ); + HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, + uint32_t PHYAddr, + uint32_t PHYReg, + uint32_t * pRegValue ); + + void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ); + void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_PMTCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_EEECallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_WakeUpCallback( ETH_HandleTypeDef * heth ); + void HAL_ETH_RxAllocateCallback( uint8_t ** buff ); + void HAL_ETH_RxLinkCallback( void ** pStart, + void ** pEnd, + uint8_t * buff, + uint16_t Length ); + void HAL_ETH_TxFreeCallback( uint32_t * buff ); + void HAL_ETH_TxPtpCallback( uint32_t * buff, + ETH_TimeStampTypeDef * timestamp ); + +/** + * @} + */ /** @addtogroup ETH_Exported_Functions_Group3 - * @{ - */ + * @{ + */ /* Peripheral Control functions **********************************************/ /* MAC & DMA Configuration APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); -HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); -void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth); + HAL_StatusTypeDef HAL_ETH_GetMACConfig( const ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_GetDMAConfig( const ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + HAL_StatusTypeDef HAL_ETH_SetMACConfig( ETH_HandleTypeDef * heth, + ETH_MACConfigTypeDef * macconf ); + HAL_StatusTypeDef HAL_ETH_SetDMAConfig( ETH_HandleTypeDef * heth, + ETH_DMAConfigTypeDef * dmaconf ); + void HAL_ETH_SetMDIOClockRange( ETH_HandleTypeDef * heth ); /* MAC VLAN Processing APIs ************************************************/ -void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, - uint32_t VLANIdentifier); + void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t ComparisonBits, + uint32_t VLANIdentifier ); /* MAC L2 Packet Filtering APIs **********************************************/ -HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig); -HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable); -HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, - const uint8_t *pMACAddr); + HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( const ETH_HandleTypeDef * heth, + ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth, + const ETH_MACFilterConfigTypeDef * pFilterConfig ); + HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth, + uint32_t * pHashTable ); + HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( const ETH_HandleTypeDef * heth, + uint32_t AddrNbr, + const uint8_t * pMACAddr ); /* MAC Power Down APIs *****************************************************/ -void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, - const ETH_PowerDownConfigTypeDef *pPowerDownConfig); -void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count); + void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth, + const ETH_PowerDownConfigTypeDef * pPowerDownConfig ); + void HAL_ETH_ExitPowerDownMode( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter( ETH_HandleTypeDef * heth, + uint32_t * pFilter, + uint32_t Count ); /** - * @} - */ + * @} + */ /** @addtogroup ETH_Exported_Functions_Group4 - * @{ - */ + * @{ + */ /* Peripheral State functions **************************************************/ -HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth); -uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth); + HAL_ETH_StateTypeDef HAL_ETH_GetState( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetDMAError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACError( const ETH_HandleTypeDef * heth ); + uint32_t HAL_ETH_GetMACWakeUpSource( const ETH_HandleTypeDef * heth ); + /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* STM32H7xx_HAL_ETH_H */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.c b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.c index feb0cfd629..394396796b 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.c +++ b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.c @@ -1,660 +1,681 @@ /** - ****************************************************************************** - * @file stm32h7xx_hal_eth_ex.c - * @author MCD Application Team - * @brief ETH HAL Extended module driver. - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h7xx_hal_eth_ex.c + * @author MCD Application Team + * @brief ETH HAL Extended module driver. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32h7xx_hal.h" /** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ + * @{ + */ #ifdef HAL_ETH_MODULE_ENABLED -#if defined(ETH) + #if defined( ETH ) /** @defgroup ETHEx ETHEx - * @brief ETH HAL Extended module driver - * @{ - */ + * @brief ETH HAL Extended module driver + * @{ + */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ + /** @defgroup ETHEx_Private_Constants ETHEx Private Constants - * @{ - */ -#define ETH_MACL4CR_MASK (ETH_MACL3L4CR_L4PEN | ETH_MACL3L4CR_L4SPM | \ - ETH_MACL3L4CR_L4SPIM | ETH_MACL3L4CR_L4DPM | \ - ETH_MACL3L4CR_L4DPIM) - -#define ETH_MACL3CR_MASK (ETH_MACL3L4CR_L3PEN | ETH_MACL3L4CR_L3SAM | \ - ETH_MACL3L4CR_L3SAIM | ETH_MACL3L4CR_L3DAM | \ - ETH_MACL3L4CR_L3DAIM | ETH_MACL3L4CR_L3HSBM | \ - ETH_MACL3L4CR_L3HDBM) - -#define ETH_MACRXVLAN_MASK (ETH_MACVTR_EIVLRXS | ETH_MACVTR_EIVLS | \ - ETH_MACVTR_ERIVLT | ETH_MACVTR_EDVLP | \ - ETH_MACVTR_VTHM | ETH_MACVTR_EVLRXS | \ - ETH_MACVTR_EVLS | ETH_MACVTR_DOVLTC | \ - ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL | \ - ETH_MACVTR_VTIM | ETH_MACVTR_ETV) - -#define ETH_MACTXVLAN_MASK (ETH_MACVIR_VLTI | ETH_MACVIR_CSVL | \ - ETH_MACVIR_VLP | ETH_MACVIR_VLC) - -#define ETH_MAC_L4_SRSP_MASK 0x0000FFFFU -#define ETH_MAC_L4_DSTP_MASK 0xFFFF0000U + * @{ + */ + #define ETH_MACL4CR_MASK \ + ( ETH_MACL3L4CR_L4PEN | ETH_MACL3L4CR_L4SPM | \ + ETH_MACL3L4CR_L4SPIM | ETH_MACL3L4CR_L4DPM | \ + ETH_MACL3L4CR_L4DPIM ) + + #define ETH_MACL3CR_MASK \ + ( ETH_MACL3L4CR_L3PEN | ETH_MACL3L4CR_L3SAM | \ + ETH_MACL3L4CR_L3SAIM | ETH_MACL3L4CR_L3DAM | \ + ETH_MACL3L4CR_L3DAIM | ETH_MACL3L4CR_L3HSBM | \ + ETH_MACL3L4CR_L3HDBM ) + + #define ETH_MACRXVLAN_MASK \ + ( ETH_MACVTR_EIVLRXS | ETH_MACVTR_EIVLS | \ + ETH_MACVTR_ERIVLT | ETH_MACVTR_EDVLP | \ + ETH_MACVTR_VTHM | ETH_MACVTR_EVLRXS | \ + ETH_MACVTR_EVLS | ETH_MACVTR_DOVLTC | \ + ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL | \ + ETH_MACVTR_VTIM | ETH_MACVTR_ETV ) + + #define ETH_MACTXVLAN_MASK \ + ( ETH_MACVIR_VLTI | ETH_MACVIR_CSVL | \ + ETH_MACVIR_VLP | ETH_MACVIR_VLC ) + + #define ETH_MAC_L4_SRSP_MASK 0x0000FFFFU + #define ETH_MAC_L4_DSTP_MASK 0xFFFF0000U + /** - * @} - */ + * @} + */ /* Private macros ------------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Exported functions ---------------------------------------------------------*/ + /** @defgroup ETHEx_Exported_Functions ETH Extended Exported Functions - * @{ - */ + * @{ + */ /** @defgroup ETHEx_Exported_Functions_Group1 Extended features functions - * @brief Extended features functions - * -@verbatim - =============================================================================== - ##### Extended features functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Configure ARP offload module - (+) Configure L3 and L4 filters - (+) Configure Extended VLAN features - (+) Configure Energy Efficient Ethernet module - -@endverbatim - * @{ - */ + * @brief Extended features functions + * + * @verbatim + * =============================================================================== + ##### Extended features functions ##### + #####=============================================================================== + #####[..] This section provides functions allowing to: + #####(+) Configure ARP offload module + #####(+) Configure L3 and L4 filters + #####(+) Configure Extended VLAN features + #####(+) Configure Energy Efficient Ethernet module + ##### + #####@endverbatim + * @{ + */ /** - * @brief Enables ARP Offload. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ + * @brief Enables ARP Offload. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ -void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth) -{ - SET_BIT(heth->Instance->MACCR, ETH_MACCR_ARP); -} + void HAL_ETHEx_EnableARPOffload( ETH_HandleTypeDef * heth ) + { + SET_BIT( heth->Instance->MACCR, ETH_MACCR_ARP ); + } /** - * @brief Disables ARP Offload. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth) -{ - CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_ARP); -} + * @brief Disables ARP Offload. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETHEx_DisableARPOffload( ETH_HandleTypeDef * heth ) + { + CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_ARP ); + } /** - * @brief Set the ARP Match IP address - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param IpAddress: IP Address to be matched for incoming ARP requests - * @retval None - */ -void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress) -{ - WRITE_REG(heth->Instance->MACARPAR, IpAddress); -} + * @brief Set the ARP Match IP address + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param IpAddress: IP Address to be matched for incoming ARP requests + * @retval None + */ + void HAL_ETHEx_SetARPAddressMatch( ETH_HandleTypeDef * heth, + uint32_t IpAddress ) + { + WRITE_REG( heth->Instance->MACARPAR, IpAddress ); + } /** - * @brief Configures the L4 Filter, this function allow to: - * set the layer 4 protocol to be matched (TCP or UDP) - * enable/disable L4 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L4 filter to configured, this parameter must be one of the following - * ETH_L4_FILTER_0 - * ETH_L4_FILTER_1 - * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure - * that contains L4 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L4FilterConfigTypeDef *pL4FilterConfig) -{ - if (pL4FilterConfig == NULL) - { - return HAL_ERROR; - } - - if (Filter == ETH_L4_FILTER_0) - { - /* Write configuration to MACL3L4C0R register */ - MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol | - pL4FilterConfig->SrcPortFilterMatch | - pL4FilterConfig->DestPortFilterMatch)); - - /* Write configuration to MACL4A0R register */ - WRITE_REG(heth->Instance->MACL4A0R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16))); - - } - else /* Filter == ETH_L4_FILTER_1 */ - { - /* Write configuration to MACL3L4C1R register */ - MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol | - pL4FilterConfig->SrcPortFilterMatch | - pL4FilterConfig->DestPortFilterMatch)); - - /* Write configuration to MACL4A1R register */ - WRITE_REG(heth->Instance->MACL4A1R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16))); - } - - /* Enable L4 filter */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); - - return HAL_OK; -} + * @brief Configures the L4 Filter, this function allow to: + * set the layer 4 protocol to be matched (TCP or UDP) + * enable/disable L4 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L4 filter to configured, this parameter must be one of the following + * ETH_L4_FILTER_0 + * ETH_L4_FILTER_1 + * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure + * that contains L4 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L4FilterConfigTypeDef * pL4FilterConfig ) + { + if( pL4FilterConfig == NULL ) + { + return HAL_ERROR; + } + + if( Filter == ETH_L4_FILTER_0 ) + { + /* Write configuration to MACL3L4C0R register */ + MODIFY_REG( heth->Instance->MACL3L4C0R, ETH_MACL4CR_MASK, ( pL4FilterConfig->Protocol | + pL4FilterConfig->SrcPortFilterMatch | + pL4FilterConfig->DestPortFilterMatch ) ); + + /* Write configuration to MACL4A0R register */ + WRITE_REG( heth->Instance->MACL4A0R, ( pL4FilterConfig->SourcePort | ( pL4FilterConfig->DestinationPort << 16 ) ) ); + } + else /* Filter == ETH_L4_FILTER_1 */ + { + /* Write configuration to MACL3L4C1R register */ + MODIFY_REG( heth->Instance->MACL3L4C1R, ETH_MACL4CR_MASK, ( pL4FilterConfig->Protocol | + pL4FilterConfig->SrcPortFilterMatch | + pL4FilterConfig->DestPortFilterMatch ) ); + + /* Write configuration to MACL4A1R register */ + WRITE_REG( heth->Instance->MACL4A1R, ( pL4FilterConfig->SourcePort | ( pL4FilterConfig->DestinationPort << 16 ) ) ); + } + + /* Enable L4 filter */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + + return HAL_OK; + } /** - * @brief Configures the L4 Filter, this function allow to: - * set the layer 4 protocol to be matched (TCP or UDP) - * enable/disable L4 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L4 filter to configured, this parameter must be one of the following - * ETH_L4_FILTER_0 - * ETH_L4_FILTER_1 - * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure - * that contains L4 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L4FilterConfigTypeDef *pL4FilterConfig) -{ - if (pL4FilterConfig == NULL) - { - return HAL_ERROR; - } - - if (Filter == ETH_L4_FILTER_0) - { - /* Get configuration from MACL3L4C0R register */ - pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C0R, ETH_MACL3L4CR_L4PEN); - pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R, - (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM)); - pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R, - (ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM)); - - /* Get configuration from MACL4A0R register */ - pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_DSTP_MASK) >> 16); - pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_SRSP_MASK); - } - else /* Filter == ETH_L4_FILTER_1 */ - { - /* Get configuration from MACL3L4C1R register */ - pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C1R, ETH_MACL3L4CR_L4PEN); - pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R, - (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM)); - pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R, - (ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM)); - - /* Get configuration from MACL4A1R register */ - pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_DSTP_MASK) >> 16); - pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_SRSP_MASK); - } - - return HAL_OK; -} + * @brief Configures the L4 Filter, this function allow to: + * set the layer 4 protocol to be matched (TCP or UDP) + * enable/disable L4 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L4 filter to configured, this parameter must be one of the following + * ETH_L4_FILTER_0 + * ETH_L4_FILTER_1 + * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure + * that contains L4 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L4FilterConfigTypeDef * pL4FilterConfig ) + { + if( pL4FilterConfig == NULL ) + { + return HAL_ERROR; + } + + if( Filter == ETH_L4_FILTER_0 ) + { + /* Get configuration from MACL3L4C0R register */ + pL4FilterConfig->Protocol = READ_BIT( heth->Instance->MACL3L4C0R, ETH_MACL3L4CR_L4PEN ); + pL4FilterConfig->DestPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C0R, + ( ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM ) ); + pL4FilterConfig->SrcPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C0R, + ( ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM ) ); + + /* Get configuration from MACL4A0R register */ + pL4FilterConfig->DestinationPort = ( READ_BIT( heth->Instance->MACL4A0R, ETH_MAC_L4_DSTP_MASK ) >> 16 ); + pL4FilterConfig->SourcePort = READ_BIT( heth->Instance->MACL4A0R, ETH_MAC_L4_SRSP_MASK ); + } + else /* Filter == ETH_L4_FILTER_1 */ + { + /* Get configuration from MACL3L4C1R register */ + pL4FilterConfig->Protocol = READ_BIT( heth->Instance->MACL3L4C1R, ETH_MACL3L4CR_L4PEN ); + pL4FilterConfig->DestPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C1R, + ( ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM ) ); + pL4FilterConfig->SrcPortFilterMatch = READ_BIT( heth->Instance->MACL3L4C1R, + ( ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM ) ); + + /* Get configuration from MACL4A1R register */ + pL4FilterConfig->DestinationPort = ( READ_BIT( heth->Instance->MACL4A1R, ETH_MAC_L4_DSTP_MASK ) >> 16 ); + pL4FilterConfig->SourcePort = READ_BIT( heth->Instance->MACL4A1R, ETH_MAC_L4_SRSP_MASK ); + } + + return HAL_OK; + } /** - * @brief Configures the L3 Filter, this function allow to: - * set the layer 3 protocol to be matched (IPv4 or IPv6) - * enable/disable L3 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L3 filter to configured, this parameter must be one of the following - * ETH_L3_FILTER_0 - * ETH_L3_FILTER_1 - * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure - * that contains L3 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L3FilterConfigTypeDef *pL3FilterConfig) -{ - if (pL3FilterConfig == NULL) - { - return HAL_ERROR; - } - - if (Filter == ETH_L3_FILTER_0) - { - /* Write configuration to MACL3L4C0R register */ - MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol | - pL3FilterConfig->SrcAddrFilterMatch | - pL3FilterConfig->DestAddrFilterMatch | - (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) | - (pL3FilterConfig->DestAddrHigherBitsMatch << 11))); - } - else /* Filter == ETH_L3_FILTER_1 */ - { - /* Write configuration to MACL3L4C1R register */ - MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol | - pL3FilterConfig->SrcAddrFilterMatch | - pL3FilterConfig->DestAddrFilterMatch | - (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) | - (pL3FilterConfig->DestAddrHigherBitsMatch << 11))); - } - - if (Filter == ETH_L3_FILTER_0) - { - /* Check if IPv6 protocol is selected */ - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - /* Set the IPv6 address match */ - /* Set Bits[31:0] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip6Addr[0]); - /* Set Bits[63:32] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip6Addr[1]); - /* update Bits[95:64] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A2R0R, pL3FilterConfig->Ip6Addr[2]); - /* update Bits[127:96] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A3R0R, pL3FilterConfig->Ip6Addr[3]); - } - else /* IPv4 protocol is selected */ - { - /* Set the IPv4 source address match */ - WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip4SrcAddr); - /* Set the IPv4 destination address match */ - WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip4DestAddr); - } - } - else /* Filter == ETH_L3_FILTER_1 */ - { - /* Check if IPv6 protocol is selected */ - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - /* Set the IPv6 address match */ - /* Set Bits[31:0] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip6Addr[0]); - /* Set Bits[63:32] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[1]); - /* update Bits[95:64] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[2]); - /* update Bits[127:96] of 128-bit IP addr */ - WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[3]); - } - else /* IPv4 protocol is selected */ - { - /* Set the IPv4 source address match */ - WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4SrcAddr); - /* Set the IPv4 destination address match */ - WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4DestAddr); - - } - } - - /* Enable L3 filter */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); - - return HAL_OK; -} + * @brief Configures the L3 Filter, this function allow to: + * set the layer 3 protocol to be matched (IPv4 or IPv6) + * enable/disable L3 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L3 filter to configured, this parameter must be one of the following + * ETH_L3_FILTER_0 + * ETH_L3_FILTER_1 + * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure + * that contains L3 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L3FilterConfigTypeDef * pL3FilterConfig ) + { + if( pL3FilterConfig == NULL ) + { + return HAL_ERROR; + } + + if( Filter == ETH_L3_FILTER_0 ) + { + /* Write configuration to MACL3L4C0R register */ + MODIFY_REG( heth->Instance->MACL3L4C0R, ETH_MACL3CR_MASK, ( pL3FilterConfig->Protocol | + pL3FilterConfig->SrcAddrFilterMatch | + pL3FilterConfig->DestAddrFilterMatch | + ( pL3FilterConfig->SrcAddrHigherBitsMatch << 6 ) | + ( pL3FilterConfig->DestAddrHigherBitsMatch << 11 ) ) ); + } + else /* Filter == ETH_L3_FILTER_1 */ + { + /* Write configuration to MACL3L4C1R register */ + MODIFY_REG( heth->Instance->MACL3L4C1R, ETH_MACL3CR_MASK, ( pL3FilterConfig->Protocol | + pL3FilterConfig->SrcAddrFilterMatch | + pL3FilterConfig->DestAddrFilterMatch | + ( pL3FilterConfig->SrcAddrHigherBitsMatch << 6 ) | + ( pL3FilterConfig->DestAddrHigherBitsMatch << 11 ) ) ); + } + + if( Filter == ETH_L3_FILTER_0 ) + { + /* Check if IPv6 protocol is selected */ + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + /* Set the IPv6 address match */ + /* Set Bits[31:0] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip6Addr[ 0 ] ); + /* Set Bits[63:32] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip6Addr[ 1 ] ); + /* update Bits[95:64] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A2R0R, pL3FilterConfig->Ip6Addr[ 2 ] ); + /* update Bits[127:96] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A3R0R, pL3FilterConfig->Ip6Addr[ 3 ] ); + } + else /* IPv4 protocol is selected */ + { + /* Set the IPv4 source address match */ + WRITE_REG( heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip4SrcAddr ); + /* Set the IPv4 destination address match */ + WRITE_REG( heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip4DestAddr ); + } + } + else /* Filter == ETH_L3_FILTER_1 */ + { + /* Check if IPv6 protocol is selected */ + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + /* Set the IPv6 address match */ + /* Set Bits[31:0] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip6Addr[ 0 ] ); + /* Set Bits[63:32] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[ 1 ] ); + /* update Bits[95:64] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[ 2 ] ); + /* update Bits[127:96] of 128-bit IP addr */ + WRITE_REG( heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[ 3 ] ); + } + else /* IPv4 protocol is selected */ + { + /* Set the IPv4 source address match */ + WRITE_REG( heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4SrcAddr ); + /* Set the IPv4 destination address match */ + WRITE_REG( heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4DestAddr ); + } + } + + /* Enable L3 filter */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + + return HAL_OK; + } /** - * @brief Configures the L3 Filter, this function allow to: - * set the layer 3 protocol to be matched (IPv4 or IPv6) - * enable/disable L3 source/destination port perfect/inverse match. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Filter: L3 filter to configured, this parameter must be one of the following - * ETH_L3_FILTER_0 - * ETH_L3_FILTER_1 - * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure - * that will contain the L3 filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L3FilterConfigTypeDef *pL3FilterConfig) -{ - if (pL3FilterConfig == NULL) - { - return HAL_ERROR; - } - pL3FilterConfig->Protocol = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - ETH_MACL3L4CR_L3PEN); - pL3FilterConfig->SrcAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - (ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM)); - pL3FilterConfig->DestAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - (ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM)); - pL3FilterConfig->SrcAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - ETH_MACL3L4CR_L3HSBM) >> 6); - pL3FilterConfig->DestAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), - ETH_MACL3L4CR_L3HDBM) >> 11); - - if (Filter == ETH_L3_FILTER_0) - { - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A0R0R); - WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A1R0R); - WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A2R0R); - WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A3R0R); - } - else - { - WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R0R); - WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R0R); - } - } - else /* ETH_L3_FILTER_1 */ - { - if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) - { - WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A0R1R); - WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A1R1R); - WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A2R1R); - WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A3R1R); - } - else - { - WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R1R); - WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R1R); - } - } - - return HAL_OK; -} + * @brief Configures the L3 Filter, this function allow to: + * set the layer 3 protocol to be matched (IPv4 or IPv6) + * enable/disable L3 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L3 filter to configured, this parameter must be one of the following + * ETH_L3_FILTER_0 + * ETH_L3_FILTER_1 + * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure + * that will contain the L3 filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L3FilterConfigTypeDef * pL3FilterConfig ) + { + if( pL3FilterConfig == NULL ) + { + return HAL_ERROR; + } + + pL3FilterConfig->Protocol = READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ETH_MACL3L4CR_L3PEN ); + pL3FilterConfig->SrcAddrFilterMatch = READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ( ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM ) ); + pL3FilterConfig->DestAddrFilterMatch = READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ( ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM ) ); + pL3FilterConfig->SrcAddrHigherBitsMatch = ( READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ETH_MACL3L4CR_L3HSBM ) >> 6 ); + pL3FilterConfig->DestAddrHigherBitsMatch = ( READ_BIT( *( ( __IO uint32_t * ) ( &( heth->Instance->MACL3L4C0R ) + Filter ) ), + ETH_MACL3L4CR_L3HDBM ) >> 11 ); + + if( Filter == ETH_L3_FILTER_0 ) + { + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + WRITE_REG( pL3FilterConfig->Ip6Addr[ 0 ], heth->Instance->MACL3A0R0R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 1 ], heth->Instance->MACL3A1R0R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 2 ], heth->Instance->MACL3A2R0R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 3 ], heth->Instance->MACL3A3R0R ); + } + else + { + WRITE_REG( pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R0R ); + WRITE_REG( pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R0R ); + } + } + else /* ETH_L3_FILTER_1 */ + { + if( pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH ) + { + WRITE_REG( pL3FilterConfig->Ip6Addr[ 0 ], heth->Instance->MACL3A0R1R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 1 ], heth->Instance->MACL3A1R1R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 2 ], heth->Instance->MACL3A2R1R ); + WRITE_REG( pL3FilterConfig->Ip6Addr[ 3 ], heth->Instance->MACL3A3R1R ); + } + else + { + WRITE_REG( pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R1R ); + WRITE_REG( pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R1R ); + } + } + + return HAL_OK; + } /** - * @brief Enables L3 and L4 filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth) -{ - /* Enable L3/L4 filter */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); -} + * @brief Enables L3 and L4 filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_EnableL3L4Filtering( ETH_HandleTypeDef * heth ) + { + /* Enable L3/L4 filter */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + } /** - * @brief Disables L3 and L4 filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth) -{ - /* Disable L3/L4 filter */ - CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); -} + * @brief Disables L3 and L4 filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_DisableL3L4Filtering( ETH_HandleTypeDef * heth ) + { + /* Disable L3/L4 filter */ + CLEAR_BIT( heth->Instance->MACPFR, ETH_MACPFR_IPFE ); + } /** - * @brief Get the VLAN Configuration for Receive Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure - * that will contain the VLAN filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig) -{ - if (pVlanConfig == NULL) - { - return HAL_ERROR; - } - - pVlanConfig->InnerVLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_EIVLRXS) >> 31) == 0U) ? DISABLE : ENABLE; - pVlanConfig->StripInnerVLANTag = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EIVLS); - pVlanConfig->InnerVLANTag = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_ERIVLT) >> 27) == 0U) ? DISABLE : ENABLE; - pVlanConfig->DoubleVLANProcessing = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_EDVLP) >> 26) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagHashTableMatch = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_VTHM) >> 25) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR, - ETH_MACVTR_EVLRXS) >> 24) == 0U) ? DISABLE : ENABLE; - pVlanConfig->StripVLANTag = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EVLS); - pVlanConfig->VLANTypeCheck = READ_BIT(heth->Instance->MACVTR, - (ETH_MACVTR_DOVLTC | ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL)); - pVlanConfig->VLANTagInverceMatch = ((READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_VTIM) >> 17) == 0U) - ? DISABLE : ENABLE; - - return HAL_OK; -} + * @brief Get the VLAN Configuration for Receive Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure + * that will contain the VLAN filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig( const ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ) + { + if( pVlanConfig == NULL ) + { + return HAL_ERROR; + } + + pVlanConfig->InnerVLANTagInStatus = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_EIVLRXS ) >> 31 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->StripInnerVLANTag = READ_BIT( heth->Instance->MACVTR, ETH_MACVTR_EIVLS ); + pVlanConfig->InnerVLANTag = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_ERIVLT ) >> 27 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->DoubleVLANProcessing = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_EDVLP ) >> 26 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagHashTableMatch = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_VTHM ) >> 25 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagInStatus = ( ( READ_BIT( heth->Instance->MACVTR, + ETH_MACVTR_EVLRXS ) >> 24 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->StripVLANTag = READ_BIT( heth->Instance->MACVTR, ETH_MACVTR_EVLS ); + pVlanConfig->VLANTypeCheck = READ_BIT( heth->Instance->MACVTR, + ( ETH_MACVTR_DOVLTC | ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL ) ); + pVlanConfig->VLANTagInverceMatch = ( ( READ_BIT( heth->Instance->MACVTR, ETH_MACVTR_VTIM ) >> 17 ) == 0U ) + ? DISABLE : ENABLE; + + return HAL_OK; + } /** - * @brief Set the VLAN Configuration for Receive Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure - * that contains VLAN filter configuration. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig) -{ - if (pVlanConfig == NULL) - { - return HAL_ERROR; - } - - /* Write config to MACVTR */ - MODIFY_REG(heth->Instance->MACVTR, ETH_MACRXVLAN_MASK, (((uint32_t)pVlanConfig->InnerVLANTagInStatus << 31) | - pVlanConfig->StripInnerVLANTag | - ((uint32_t)pVlanConfig->InnerVLANTag << 27) | - ((uint32_t)pVlanConfig->DoubleVLANProcessing << 26) | - ((uint32_t)pVlanConfig->VLANTagHashTableMatch << 25) | - ((uint32_t)pVlanConfig->VLANTagInStatus << 24) | - pVlanConfig->StripVLANTag | - pVlanConfig->VLANTypeCheck | - ((uint32_t)pVlanConfig->VLANTagInverceMatch << 17))); - - return HAL_OK; -} + * @brief Set the VLAN Configuration for Receive Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure + * that contains VLAN filter configuration. + * @retval HAL status + */ + HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig( ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ) + { + if( pVlanConfig == NULL ) + { + return HAL_ERROR; + } + + /* Write config to MACVTR */ + MODIFY_REG( heth->Instance->MACVTR, ETH_MACRXVLAN_MASK, ( ( ( uint32_t ) pVlanConfig->InnerVLANTagInStatus << 31 ) | + pVlanConfig->StripInnerVLANTag | + ( ( uint32_t ) pVlanConfig->InnerVLANTag << 27 ) | + ( ( uint32_t ) pVlanConfig->DoubleVLANProcessing << 26 ) | + ( ( uint32_t ) pVlanConfig->VLANTagHashTableMatch << 25 ) | + ( ( uint32_t ) pVlanConfig->VLANTagInStatus << 24 ) | + pVlanConfig->StripVLANTag | + pVlanConfig->VLANTypeCheck | + ( ( uint32_t ) pVlanConfig->VLANTagInverceMatch << 17 ) ) ); + + return HAL_OK; + } /** - * @brief Set the VLAN Hash Table - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANHashTable: VLAN hash table 16 bit value - * @retval None - */ -void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable) -{ - MODIFY_REG(heth->Instance->MACVHTR, ETH_MACVHTR_VLHT, VLANHashTable); -} + * @brief Set the VLAN Hash Table + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANHashTable: VLAN hash table 16 bit value + * @retval None + */ + void HAL_ETHEx_SetVLANHashTable( ETH_HandleTypeDef * heth, + uint32_t VLANHashTable ) + { + MODIFY_REG( heth->Instance->MACVHTR, ETH_MACVHTR_VLHT, VLANHashTable ); + } /** - * @brief Get the VLAN Configuration for Transmit Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANTag: Selects the vlan tag, this parameter must be one of the following - * ETH_OUTER_TX_VLANTAG - * ETH_INNER_TX_VLANTAG - * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure - * that will contain the Tx VLAN filter configuration. - * @retval HAL Status. - */ -HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef *heth, uint32_t VLANTag, - ETH_TxVLANConfigTypeDef *pVlanConfig) -{ - if (pVlanConfig == NULL) - { - return HAL_ERROR; - } - - if (VLANTag == ETH_INNER_TX_VLANTAG) - { - pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE; - pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACIVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC)); - } - else - { - pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE; - pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE; - pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC)); - } - - return HAL_OK;; -} + * @brief Get the VLAN Configuration for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure + * that will contain the Tx VLAN filter configuration. + * @retval HAL Status. + */ + HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig( const ETH_HandleTypeDef * heth, + uint32_t VLANTag, + ETH_TxVLANConfigTypeDef * pVlanConfig ) + { + if( pVlanConfig == NULL ) + { + return HAL_ERROR; + } + + if( VLANTag == ETH_INNER_TX_VLANTAG ) + { + pVlanConfig->SourceTxDesc = ( ( READ_BIT( heth->Instance->MACIVIR, ETH_MACVIR_VLTI ) >> 20 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->SVLANType = ( ( READ_BIT( heth->Instance->MACIVIR, ETH_MACVIR_CSVL ) >> 19 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagControl = READ_BIT( heth->Instance->MACIVIR, ( ETH_MACVIR_VLP | ETH_MACVIR_VLC ) ); + } + else + { + pVlanConfig->SourceTxDesc = ( ( READ_BIT( heth->Instance->MACVIR, ETH_MACVIR_VLTI ) >> 20 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->SVLANType = ( ( READ_BIT( heth->Instance->MACVIR, ETH_MACVIR_CSVL ) >> 19 ) == 0U ) ? DISABLE : ENABLE; + pVlanConfig->VLANTagControl = READ_BIT( heth->Instance->MACVIR, ( ETH_MACVIR_VLP | ETH_MACVIR_VLC ) ); + } + + return HAL_OK; + } /** - * @brief Set the VLAN Configuration for Transmit Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANTag: Selects the vlan tag, this parameter must be one of the following - * ETH_OUTER_TX_VLANTAG - * ETH_INNER_TX_VLANTAG - * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure - * that contains Tx VLAN filter configuration. - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, - const ETH_TxVLANConfigTypeDef *pVlanConfig) -{ - if (VLANTag == ETH_INNER_TX_VLANTAG) - { - MODIFY_REG(heth->Instance->MACIVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) | - ((uint32_t)pVlanConfig->SVLANType << 19) | - pVlanConfig->VLANTagControl)); - /* Enable Double VLAN processing */ - SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP); - } - else - { - MODIFY_REG(heth->Instance->MACVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) | - ((uint32_t)pVlanConfig->SVLANType << 19) | - pVlanConfig->VLANTagControl)); - } - - return HAL_OK; -} + * @brief Set the VLAN Configuration for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure + * that contains Tx VLAN filter configuration. + * @retval HAL Status + */ + HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + const ETH_TxVLANConfigTypeDef * pVlanConfig ) + { + if( VLANTag == ETH_INNER_TX_VLANTAG ) + { + MODIFY_REG( heth->Instance->MACIVIR, ETH_MACTXVLAN_MASK, ( ( ( uint32_t ) pVlanConfig->SourceTxDesc << 20 ) | + ( ( uint32_t ) pVlanConfig->SVLANType << 19 ) | + pVlanConfig->VLANTagControl ) ); + /* Enable Double VLAN processing */ + SET_BIT( heth->Instance->MACVTR, ETH_MACVTR_EDVLP ); + } + else + { + MODIFY_REG( heth->Instance->MACVIR, ETH_MACTXVLAN_MASK, ( ( ( uint32_t ) pVlanConfig->SourceTxDesc << 20 ) | + ( ( uint32_t ) pVlanConfig->SVLANType << 19 ) | + pVlanConfig->VLANTagControl ) ); + } + + return HAL_OK; + } /** - * @brief Set the VLAN Tag Identifier for Transmit Packets. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param VLANTag: Selects the vlan tag, this parameter must be one of the following - * ETH_OUTER_TX_VLANTAG - * ETH_INNER_TX_VLANTAG - * @param VLANIdentifier: VLAN Identifier 16 bit value - * @retval None - */ -void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier) -{ - if (VLANTag == ETH_INNER_TX_VLANTAG) - { - MODIFY_REG(heth->Instance->MACIVIR, ETH_MACVIR_VLT, VLANIdentifier); - } - else - { - MODIFY_REG(heth->Instance->MACVIR, ETH_MACVIR_VLT, VLANIdentifier); - } -} + * @brief Set the VLAN Tag Identifier for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param VLANIdentifier: VLAN Identifier 16 bit value + * @retval None + */ + void HAL_ETHEx_SetTxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + uint32_t VLANIdentifier ) + { + if( VLANTag == ETH_INNER_TX_VLANTAG ) + { + MODIFY_REG( heth->Instance->MACIVIR, ETH_MACVIR_VLT, VLANIdentifier ); + } + else + { + MODIFY_REG( heth->Instance->MACVIR, ETH_MACVIR_VLT, VLANIdentifier ); + } + } /** - * @brief Enables the VLAN Tag Filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth) -{ - /* Enable VLAN processing */ - SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE); -} + * @brief Enables the VLAN Tag Filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_EnableVLANProcessing( ETH_HandleTypeDef * heth ) + { + /* Enable VLAN processing */ + SET_BIT( heth->Instance->MACPFR, ETH_MACPFR_VTFE ); + } /** - * @brief Disables the VLAN Tag Filtering process. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None. - */ -void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth) -{ - /* Disable VLAN processing */ - CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE); -} + * @brief Disables the VLAN Tag Filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ + void HAL_ETHEx_DisableVLANProcessing( ETH_HandleTypeDef * heth ) + { + /* Disable VLAN processing */ + CLEAR_BIT( heth->Instance->MACPFR, ETH_MACPFR_VTFE ); + } /** - * @brief Enters the Low Power Idle (LPI) mode - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param TxAutomate: Enable/Disable automate enter/exit LPI mode. - * @param TxClockStop: Enable/Disable Tx clock stop in LPI mode. - * @retval None - */ -void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, FunctionalState TxClockStop) -{ - /* Enable LPI Interrupts */ - __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_LPIIE); - - /* Write to LPI Control register: Enter low power mode */ - MODIFY_REG(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE), - (((uint32_t)TxAutomate << 19) | - ((uint32_t)TxClockStop << 21) | - ETH_MACLCSR_LPIEN)); -} + * @brief Enters the Low Power Idle (LPI) mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param TxAutomate: Enable/Disable automate enter/exit LPI mode. + * @param TxClockStop: Enable/Disable Tx clock stop in LPI mode. + * @retval None + */ + void HAL_ETHEx_EnterLPIMode( ETH_HandleTypeDef * heth, + FunctionalState TxAutomate, + FunctionalState TxClockStop ) + { + /* Enable LPI Interrupts */ + __HAL_ETH_MAC_ENABLE_IT( heth, ETH_MACIER_LPIIE ); + + /* Write to LPI Control register: Enter low power mode */ + MODIFY_REG( heth->Instance->MACLCSR, ( ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE ), + ( ( ( uint32_t ) TxAutomate << 19 ) | + ( ( uint32_t ) TxClockStop << 21 ) | + ETH_MACLCSR_LPIEN ) ); + } /** - * @brief Exits the Low Power Idle (LPI) mode. - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval None - */ -void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth) -{ - /* Clear the LPI Config and exit low power mode */ - CLEAR_BIT(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE)); - - /* Enable LPI Interrupts */ - __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_LPIIE); -} + * @brief Exits the Low Power Idle (LPI) mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + void HAL_ETHEx_ExitLPIMode( ETH_HandleTypeDef * heth ) + { + /* Clear the LPI Config and exit low power mode */ + CLEAR_BIT( heth->Instance->MACLCSR, ( ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE ) ); + + /* Enable LPI Interrupts */ + __HAL_ETH_MAC_DISABLE_IT( heth, ETH_MACIER_LPIIE ); + } /** - * @brief Returns the ETH MAC LPI event - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval ETH MAC WakeUp event - */ -uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth) -{ - return heth->MACLPIEvent; -} + * @brief Returns the ETH MAC LPI event + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event + */ + uint32_t HAL_ETHEx_GetMACLPIEvent( const ETH_HandleTypeDef * heth ) + { + return heth->MACLPIEvent; + } /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ #endif /* HAL_ETH_MODULE_ENABLED */ + /** - * @} - */ + * @} + */ diff --git a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.h b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.h index 4e229bc852..258cba3971 100644 --- a/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.h +++ b/source/portable/NetworkInterface/STM32/Drivers/H7/stm32h7xx_hal_eth_ex.h @@ -1,366 +1,400 @@ /** - ****************************************************************************** - * @file stm32h7xx_hal_eth_ex.h - * @author MCD Application Team - * @brief Header file of ETH HAL Extended module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * @file stm32h7xx_hal_eth_ex.h + * @author MCD Application Team + * @brief Header file of ETH HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32H7xx_HAL_ETH_EX_H -#define STM32H7xx_HAL_ETH_EX_H + #define STM32H7xx_HAL_ETH_EX_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#if defined(ETH) + #if defined( ETH ) /* Includes ------------------------------------------------------------------*/ -#include "stm32h7xx_hal_def.h" + #include "stm32h7xx_hal_def.h" /** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ + * @{ + */ /** @addtogroup ETHEx - * @{ - */ + * @{ + */ /* Exported types ------------------------------------------------------------*/ + /** @defgroup ETHEx_Exported_Types ETHEx Exported Types - * @{ - */ + * @{ + */ /** - * @brief ETH RX VLAN structure definition - */ -typedef struct -{ - FunctionalState InnerVLANTagInStatus; /*!< Enables or disables Inner VLAN Tag in Rx Status */ + * @brief ETH RX VLAN structure definition + */ + typedef struct + { + FunctionalState InnerVLANTagInStatus; /*!< Enables or disables Inner VLAN Tag in Rx Status */ + + uint32_t StripInnerVLANTag; /*!< Sets the Inner VLAN Tag Stripping on Receive + * This parameter can be a value of + * @ref ETHEx_Rx_Inner_VLAN_Tag_Stripping */ - uint32_t StripInnerVLANTag; /*!< Sets the Inner VLAN Tag Stripping on Receive - This parameter can be a value of - @ref ETHEx_Rx_Inner_VLAN_Tag_Stripping */ + FunctionalState InnerVLANTag; /*!< Enables or disables Inner VLAN Tag */ - FunctionalState InnerVLANTag; /*!< Enables or disables Inner VLAN Tag */ + FunctionalState DoubleVLANProcessing; /*!< Enable or Disable double VLAN processing */ - FunctionalState DoubleVLANProcessing; /*!< Enable or Disable double VLAN processing */ + FunctionalState VLANTagHashTableMatch; /*!< Enable or Disable VLAN Tag Hash Table Match */ - FunctionalState VLANTagHashTableMatch; /*!< Enable or Disable VLAN Tag Hash Table Match */ + FunctionalState VLANTagInStatus; /*!< Enable or Disable VLAN Tag in Rx status */ - FunctionalState VLANTagInStatus; /*!< Enable or Disable VLAN Tag in Rx status */ + uint32_t StripVLANTag; /*!< Set the VLAN Tag Stripping on Receive + * This parameter can be a value of @ref ETHEx_Rx_VLAN_Tag_Stripping */ - uint32_t StripVLANTag; /*!< Set the VLAN Tag Stripping on Receive - This parameter can be a value of @ref ETHEx_Rx_VLAN_Tag_Stripping */ + uint32_t VLANTypeCheck; /*!< Enable or Disable VLAN Type Check + * This parameter can be a value of @ref ETHEx_VLAN_Type_Check */ - uint32_t VLANTypeCheck; /*!< Enable or Disable VLAN Type Check - This parameter can be a value of @ref ETHEx_VLAN_Type_Check */ + FunctionalState VLANTagInverceMatch; /*!< Enable or disable VLAN Tag Inverse Match */ + } ETH_RxVLANConfigTypeDef; - FunctionalState VLANTagInverceMatch; /*!< Enable or disable VLAN Tag Inverse Match */ -} ETH_RxVLANConfigTypeDef; /** - * - */ + * + */ /** - * @brief ETH TX VLAN structure definition - */ -typedef struct -{ - FunctionalState SourceTxDesc; /*!< Enable or Disable VLAN tag source from DMA tx descriptors */ + * @brief ETH TX VLAN structure definition + */ + typedef struct + { + FunctionalState SourceTxDesc; /*!< Enable or Disable VLAN tag source from DMA tx descriptors */ + + FunctionalState SVLANType; /*!< Enable or Disable insertion of SVLAN type */ - FunctionalState SVLANType; /*!< Enable or Disable insertion of SVLAN type */ + uint32_t VLANTagControl; /*!< Sets the VLAN tag control in tx packets + * This parameter can be a value of @ref ETHEx_VLAN_Tag_Control */ + } ETH_TxVLANConfigTypeDef; - uint32_t VLANTagControl; /*!< Sets the VLAN tag control in tx packets - This parameter can be a value of @ref ETHEx_VLAN_Tag_Control */ -} ETH_TxVLANConfigTypeDef; /** - * - */ + * + */ /** - * @brief ETH L3 filter structure definition - */ -typedef struct -{ - uint32_t Protocol; /*!< Sets the L3 filter protocol to IPv4 or IPv6 - This parameter can be a value of @ref ETHEx_L3_Protocol */ + * @brief ETH L3 filter structure definition + */ + typedef struct + { + uint32_t Protocol; /*!< Sets the L3 filter protocol to IPv4 or IPv6 + * This parameter can be a value of @ref ETHEx_L3_Protocol */ - uint32_t SrcAddrFilterMatch; /*!< Sets the L3 filter source address match - This parameter can be a value of @ref ETHEx_L3_Source_Match */ + uint32_t SrcAddrFilterMatch; /*!< Sets the L3 filter source address match + * This parameter can be a value of @ref ETHEx_L3_Source_Match */ - uint32_t DestAddrFilterMatch; /*!< Sets the L3 filter destination address match - This parameter can be a value of @ref ETHEx_L3_Destination_Match */ + uint32_t DestAddrFilterMatch; /*!< Sets the L3 filter destination address match + * This parameter can be a value of @ref ETHEx_L3_Destination_Match */ - uint32_t SrcAddrHigherBitsMatch; /*!< Sets the L3 filter source address higher bits match - This parameter can be a value from 0 to 31 */ + uint32_t SrcAddrHigherBitsMatch; /*!< Sets the L3 filter source address higher bits match + * This parameter can be a value from 0 to 31 */ - uint32_t DestAddrHigherBitsMatch; /*!< Sets the L3 filter destination address higher bits match - This parameter can be a value from 0 to 31 */ + uint32_t DestAddrHigherBitsMatch; /*!< Sets the L3 filter destination address higher bits match + * This parameter can be a value from 0 to 31 */ - uint32_t Ip4SrcAddr; /*!< Sets the L3 filter IPv4 source address if IPv4 protocol is used - This parameter can be a value from 0x0 to 0xFFFFFFFF */ + uint32_t Ip4SrcAddr; /*!< Sets the L3 filter IPv4 source address if IPv4 protocol is used + * This parameter can be a value from 0x0 to 0xFFFFFFFF */ - uint32_t Ip4DestAddr; /*!< Sets the L3 filter IPv4 destination address if IPv4 protocol is used - This parameter can be a value from 0 to 0xFFFFFFFF */ + uint32_t Ip4DestAddr; /*!< Sets the L3 filter IPv4 destination address if IPv4 protocol is used + * This parameter can be a value from 0 to 0xFFFFFFFF */ + + uint32_t Ip6Addr[ 4 ]; /*!< Sets the L3 filter IPv6 address if IPv6 protocol is used + * This parameter must be a table of 4 words (4* 32 bits) */ + } ETH_L3FilterConfigTypeDef; - uint32_t Ip6Addr[4]; /*!< Sets the L3 filter IPv6 address if IPv6 protocol is used - This parameter must be a table of 4 words (4* 32 bits) */ -} ETH_L3FilterConfigTypeDef; /** - * - */ + * + */ /** - * @brief ETH L4 filter structure definition - */ -typedef struct -{ - uint32_t Protocol; /*!< Sets the L4 filter protocol to TCP or UDP - This parameter can be a value of @ref ETHEx_L4_Protocol */ + * @brief ETH L4 filter structure definition + */ + typedef struct + { + uint32_t Protocol; /*!< Sets the L4 filter protocol to TCP or UDP + * This parameter can be a value of @ref ETHEx_L4_Protocol */ + + uint32_t SrcPortFilterMatch; /*!< Sets the L4 filter source port match + * This parameter can be a value of @ref ETHEx_L4_Source_Match */ - uint32_t SrcPortFilterMatch; /*!< Sets the L4 filter source port match - This parameter can be a value of @ref ETHEx_L4_Source_Match */ + uint32_t DestPortFilterMatch; /*!< Sets the L4 filter destination port match + * This parameter can be a value of @ref ETHEx_L4_Destination_Match */ - uint32_t DestPortFilterMatch; /*!< Sets the L4 filter destination port match - This parameter can be a value of @ref ETHEx_L4_Destination_Match */ + uint32_t SourcePort; /*!< Sets the L4 filter source port + * This parameter must be a value from 0x0 to 0xFFFF */ - uint32_t SourcePort; /*!< Sets the L4 filter source port - This parameter must be a value from 0x0 to 0xFFFF */ + uint32_t DestinationPort; /*!< Sets the L4 filter destination port + * This parameter must be a value from 0x0 to 0xFFFF */ + } ETH_L4FilterConfigTypeDef; - uint32_t DestinationPort; /*!< Sets the L4 filter destination port - This parameter must be a value from 0x0 to 0xFFFF */ -} ETH_L4FilterConfigTypeDef; /** - * - */ + * + */ /** - * @} - */ + * @} + */ /* Exported constants --------------------------------------------------------*/ + /** @defgroup ETHEx_Exported_Constants ETHEx Exported Constants - * @{ - */ + * @{ + */ /** @defgroup ETHEx_LPI_Event ETHEx LPI Event - * @{ - */ -#define ETH_TX_LPI_ENTRY ETH_MACLCSR_TLPIEN -#define ETH_TX_LPI_EXIT ETH_MACLCSR_TLPIEX -#define ETH_RX_LPI_ENTRY ETH_MACLCSR_RLPIEN -#define ETH_RX_LPI_EXIT ETH_MACLCSR_RLPIEX + * @{ + */ + #define ETH_TX_LPI_ENTRY ETH_MACLCSR_TLPIEN + #define ETH_TX_LPI_EXIT ETH_MACLCSR_TLPIEX + #define ETH_RX_LPI_ENTRY ETH_MACLCSR_RLPIEN + #define ETH_RX_LPI_EXIT ETH_MACLCSR_RLPIEX + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Filter ETHEx L3 Filter - * @{ - */ -#define ETH_L3_FILTER_0 0x00000000U -#define ETH_L3_FILTER_1 0x0000000CU + * @{ + */ + #define ETH_L3_FILTER_0 0x00000000U + #define ETH_L3_FILTER_1 0x0000000CU + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Filter ETHEx L4 Filter - * @{ - */ -#define ETH_L4_FILTER_0 0x00000000U -#define ETH_L4_FILTER_1 0x0000000CU + * @{ + */ + #define ETH_L4_FILTER_0 0x00000000U + #define ETH_L4_FILTER_1 0x0000000CU + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Protocol ETHEx L3 Protocol - * @{ - */ -#define ETH_L3_IPV6_MATCH ETH_MACL3L4CR_L3PEN -#define ETH_L3_IPV4_MATCH 0x00000000U + * @{ + */ + #define ETH_L3_IPV6_MATCH ETH_MACL3L4CR_L3PEN + #define ETH_L3_IPV4_MATCH 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Source_Match ETHEx L3 Source Match - * @{ - */ -#define ETH_L3_SRC_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3SAM -#define ETH_L3_SRC_ADDR_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM) -#define ETH_L3_SRC_ADDR_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L3_SRC_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3SAM + #define ETH_L3_SRC_ADDR_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM ) + #define ETH_L3_SRC_ADDR_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L3_Destination_Match ETHEx L3 Destination Match - * @{ - */ -#define ETH_L3_DEST_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3DAM -#define ETH_L3_DEST_ADDR_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM) -#define ETH_L3_DEST_ADDR_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L3_DEST_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3DAM + #define ETH_L3_DEST_ADDR_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM ) + #define ETH_L3_DEST_ADDR_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Protocol ETHEx L4 Protocol - * @{ - */ -#define ETH_L4_UDP_MATCH ETH_MACL3L4CR_L4PEN -#define ETH_L4_TCP_MATCH 0x00000000U + * @{ + */ + #define ETH_L4_UDP_MATCH ETH_MACL3L4CR_L4PEN + #define ETH_L4_TCP_MATCH 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Source_Match ETHEx L4 Source Match - * @{ - */ -#define ETH_L4_SRC_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4SPM -#define ETH_L4_SRC_PORT_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L4SPM |ETH_MACL3L4CR_L4SPIM) -#define ETH_L4_SRC_PORT_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L4_SRC_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4SPM + #define ETH_L4_SRC_PORT_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM ) + #define ETH_L4_SRC_PORT_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_L4_Destination_Match ETHEx L4 Destination Match - * @{ - */ -#define ETH_L4_DEST_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4DPM -#define ETH_L4_DEST_PORT_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM) -#define ETH_L4_DEST_PORT_MATCH_DISABLE 0x00000000U + * @{ + */ + #define ETH_L4_DEST_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4DPM + #define ETH_L4_DEST_PORT_INVERSE_MATCH_ENABLE ( ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM ) + #define ETH_L4_DEST_PORT_MATCH_DISABLE 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_Rx_Inner_VLAN_Tag_Stripping ETHEx Rx Inner VLAN Tag Stripping - * @{ - */ -#define ETH_INNERVLANTAGRXSTRIPPING_NONE ETH_MACVTR_EIVLS_DONOTSTRIP -#define ETH_INNERVLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EIVLS_STRIPIFPASS -#define ETH_INNERVLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EIVLS_STRIPIFFAILS -#define ETH_INNERVLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EIVLS_ALWAYSSTRIP + * @{ + */ + #define ETH_INNERVLANTAGRXSTRIPPING_NONE ETH_MACVTR_EIVLS_DONOTSTRIP + #define ETH_INNERVLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EIVLS_STRIPIFPASS + #define ETH_INNERVLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EIVLS_STRIPIFFAILS + #define ETH_INNERVLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EIVLS_ALWAYSSTRIP + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_Rx_VLAN_Tag_Stripping ETHEx Rx VLAN Tag Stripping - * @{ - */ -#define ETH_VLANTAGRXSTRIPPING_NONE ETH_MACVTR_EVLS_DONOTSTRIP -#define ETH_VLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EVLS_STRIPIFPASS -#define ETH_VLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EVLS_STRIPIFFAILS -#define ETH_VLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EVLS_ALWAYSSTRIP + * @{ + */ + #define ETH_VLANTAGRXSTRIPPING_NONE ETH_MACVTR_EVLS_DONOTSTRIP + #define ETH_VLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EVLS_STRIPIFPASS + #define ETH_VLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EVLS_STRIPIFFAILS + #define ETH_VLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EVLS_ALWAYSSTRIP + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_VLAN_Type_Check ETHEx VLAN Type Check - * @{ - */ -#define ETH_VLANTYPECHECK_DISABLE ETH_MACVTR_DOVLTC -#define ETH_VLANTYPECHECK_SVLAN (ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL) -#define ETH_VLANTYPECHECK_CVLAN 0x00000000U + * @{ + */ + #define ETH_VLANTYPECHECK_DISABLE ETH_MACVTR_DOVLTC + #define ETH_VLANTYPECHECK_SVLAN ( ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL ) + #define ETH_VLANTYPECHECK_CVLAN 0x00000000U + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_VLAN_Tag_Control ETHEx_VLAN_Tag_Control - * @{ - */ -#define ETH_VLANTAGCONTROL_NONE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_NOVLANTAG) -#define ETH_VLANTAGCONTROL_DELETE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGDELETE) -#define ETH_VLANTAGCONTROL_INSERT (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGINSERT) -#define ETH_VLANTAGCONTROL_REPLACE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGREPLACE) + * @{ + */ + #define ETH_VLANTAGCONTROL_NONE ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_NOVLANTAG ) + #define ETH_VLANTAGCONTROL_DELETE ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGDELETE ) + #define ETH_VLANTAGCONTROL_INSERT ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGINSERT ) + #define ETH_VLANTAGCONTROL_REPLACE ( ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGREPLACE ) + /** - * @} - */ + * @} + */ /** @defgroup ETHEx_Tx_VLAN_Tag ETHEx Tx VLAN Tag - * @{ - */ -#define ETH_INNER_TX_VLANTAG 0x00000001U -#define ETH_OUTER_TX_VLANTAG 0x00000000U + * @{ + */ + #define ETH_INNER_TX_VLANTAG 0x00000001U + #define ETH_OUTER_TX_VLANTAG 0x00000000U + /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /* Exported functions --------------------------------------------------------*/ + /** @addtogroup ETHEx_Exported_Functions - * @{ - */ + * @{ + */ /** @addtogroup ETHEx_Exported_Functions_Group1 - * @{ - */ + * @{ + */ /* MAC ARP Offloading APIs ***************************************************/ -void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth); -void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth); -void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress); + void HAL_ETHEx_EnableARPOffload( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_DisableARPOffload( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_SetARPAddressMatch( ETH_HandleTypeDef * heth, + uint32_t IpAddress ); /* MAC L3 L4 Filtering APIs ***************************************************/ -void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth); -void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L3FilterConfigTypeDef *pL3FilterConfig); -HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter, - ETH_L4FilterConfigTypeDef *pL4FilterConfig); -HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L3FilterConfigTypeDef *pL3FilterConfig); -HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, - const ETH_L4FilterConfigTypeDef *pL4FilterConfig); + void HAL_ETHEx_EnableL3L4Filtering( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_DisableL3L4Filtering( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L3FilterConfigTypeDef * pL3FilterConfig ); + HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig( const ETH_HandleTypeDef * heth, + uint32_t Filter, + ETH_L4FilterConfigTypeDef * pL4FilterConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L3FilterConfigTypeDef * pL3FilterConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig( ETH_HandleTypeDef * heth, + uint32_t Filter, + const ETH_L4FilterConfigTypeDef * pL4FilterConfig ); /* MAC VLAN Processing APIs ************************************************/ -void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth); -void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig); -HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig); -void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable); -HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef *heth, uint32_t VLANTag, - ETH_TxVLANConfigTypeDef *pVlanConfig); -HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, - const ETH_TxVLANConfigTypeDef *pVlanConfig); -void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier); + void HAL_ETHEx_EnableVLANProcessing( ETH_HandleTypeDef * heth ); + void HAL_ETHEx_DisableVLANProcessing( ETH_HandleTypeDef * heth ); + HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig( const ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig( ETH_HandleTypeDef * heth, + ETH_RxVLANConfigTypeDef * pVlanConfig ); + void HAL_ETHEx_SetVLANHashTable( ETH_HandleTypeDef * heth, + uint32_t VLANHashTable ); + HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig( const ETH_HandleTypeDef * heth, + uint32_t VLANTag, + ETH_TxVLANConfigTypeDef * pVlanConfig ); + HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + const ETH_TxVLANConfigTypeDef * pVlanConfig ); + void HAL_ETHEx_SetTxVLANIdentifier( ETH_HandleTypeDef * heth, + uint32_t VLANTag, + uint32_t VLANIdentifier ); /* Energy Efficient Ethernet APIs *********************************************/ -void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, - FunctionalState TxClockStop); -void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth); -uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth); + void HAL_ETHEx_EnterLPIMode( ETH_HandleTypeDef * heth, + FunctionalState TxAutomate, + FunctionalState TxClockStop ); + void HAL_ETHEx_ExitLPIMode( ETH_HandleTypeDef * heth ); + uint32_t HAL_ETHEx_GetMACLPIEvent( const ETH_HandleTypeDef * heth ); /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ /** - * @} - */ + * @} + */ -#endif /* ETH */ + #endif /* ETH */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* STM32H7xx_HAL_ETH_EX_H */ diff --git a/source/portable/NetworkInterface/STM32/NetworkInterface.c b/source/portable/NetworkInterface/STM32/NetworkInterface.c index edc79b5f08..3c432f7a49 100644 --- a/source/portable/NetworkInterface/STM32/NetworkInterface.c +++ b/source/portable/NetworkInterface/STM32/NetworkInterface.c @@ -602,7 +602,7 @@ static BaseType_t prvNetworkInterfaceOutput( NetworkInterface_t * pxInterface, break; } - // ETH_TxPacketConfigTypeDef + /* ETH_TxPacketConfigTypeDef */ ETH_TxPacketConfig xTxConfig = { .CRCPadCtrl = ETH_CRC_PAD_INSERT, @@ -1178,8 +1178,8 @@ static void prvInitMacAddresses( ETH_HandleTypeDef * pxEthHandle, xL3FilterConfig.DestAddrFilterMatch = ETH_L3_DEST_ADDR_PERFECT_MATCH_ENABLE; xL3FilterConfig.SrcAddrHigherBitsMatch = 0x1FU; xL3FilterConfig.DestAddrHigherBitsMatch = 0x1FU; - xL3FilterConfig.Ip4SrcAddr = ipBROADCAST_IP_ADDRESS; - xL3FilterConfig.Ip4DestAddr = ipBROADCAST_IP_ADDRESS; + xL3FilterConfig.Ip4SrcAddr = FREERTOS_INADDR_BROADCAST; + xL3FilterConfig.Ip4DestAddr = FREERTOS_INADDR_BROADCAST; ( void ) HAL_ETHEx_SetL3FilterConfig( pxEthHandle, ETH_L3_FILTER_0, &xL3FilterConfig ); #endif /* if ipconfigIS_DISABLED( ipconfigUSE_IPv4 ) */ diff --git a/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json b/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json index 3301afb404..a7fde8a865 100644 --- a/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json +++ b/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json @@ -6,6 +6,7 @@ "--unwindset prvCacheLookup.0:7", "--unwindset FreeRTOS_FindEndPointOnIP_IPv4.0:3", "--unwindset FreeRTOS_InterfaceEndPointOnNetMask.0:3", + "--unwindset xIsIPv4Broadcast.0:3", "--unwindset eARPGetCacheEntry.0:3", "--unwindset FreeRTOS_FindGateWay.0:3", "--nondet-static" diff --git a/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c b/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c index add375d180..283f6fab1d 100644 --- a/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c +++ b/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c @@ -157,6 +157,7 @@ void harness() NetworkBufferDescriptor_t * const pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); uint8_t * pucEthernetBuffer = ( uint8_t * ) safeMalloc( ipTOTAL_ETHERNET_FRAME_SIZE + ipIP_TYPE_OFFSET ); EthernetHeader_t * pxHeader; + NetworkEndPoint_t xEndPoint; __CPROVER_assume( pxNetworkBuffer != NULL ); __CPROVER_assume( pucEthernetBuffer != NULL ); @@ -166,6 +167,19 @@ void harness() pxNetworkBuffer->pucEthernetBuffer = &( pucEthernetBuffer[ ipIP_TYPE_OFFSET ] ); __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + /* prvProcessIPPacket is guranteed to receive a network buffer that has a valid + * endpoint, hence no NULL checks are needed to be performed inside prvProcessIPPacket. + * See the check: + * + * if( ( pxNetworkBuffer->pxInterface == NULL ) || ( pxNetworkBuffer->pxEndPoint == NULL ) ) + * { + * break; + * } + * + * inside the prvProcessEthernetPacket before which prvProcessIPPacket is called. + */ + pxNetworkBuffer->pxEndPoint = &xEndPoint; + /* Minimum length of the pxNetworkBuffer->xDataLength is at least the size of the IPPacket_t. */ __CPROVER_assume( pxNetworkBuffer->xDataLength >= sizeof( IPPacket_t ) && pxNetworkBuffer->xDataLength <= ipTOTAL_ETHERNET_FRAME_SIZE ); diff --git a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c index c6b41eb1b6..8006c3145e 100644 --- a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c +++ b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c @@ -557,9 +557,9 @@ void test_eARPProcessPacket_Request_GratuitousARP( void ) /* Reset the private variable uxARPClashCounter. */ vResetARPClashCounter(); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); xIsIPv4Loopback_ExpectAndReturn( ulTargetIP, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); @@ -621,9 +621,9 @@ void test_eARPProcessPacket_Request_GratuitousARP_MACUnchanged( void ) /* Reset the private variable uxARPClashCounter. */ vResetARPClashCounter(); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); xIsIPv4Loopback_ExpectAndReturn( ulTargetIP, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); @@ -864,9 +864,9 @@ void test_eARPProcessPacket_Request_GratuitousARP_NonMatchingEndpoint( void ) /* Reset the private variable uxARPClashCounter. */ vResetARPClashCounter(); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); xIsIPv4Loopback_ExpectAndReturn( ulTargetIP, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) pxARPFrame; @@ -928,9 +928,9 @@ void test_eARPProcessPacket_Request_GratuitousARP_NonMatchingIP( void ) /* Reset the private variable uxARPClashCounter. */ vResetARPClashCounter(); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); xIsIPv4Loopback_ExpectAndReturn( ulTargetIP, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulTargetIP, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) pxARPFrame; @@ -2069,18 +2069,20 @@ void test_eARPGetCacheEntry_IPMatchesBroadcastAddr( void ) eResolutionLookupResult_t eResult; uint32_t ulSavedGatewayAddress; struct xNetworkEndPoint * pxEndPoint, xEndPoint; + struct xNetworkEndPoint * pxEndPoint2 = &xEndPoint; /* =================================================== */ ulIPAddress = FreeRTOS_ntohl( xNetworkAddressing.ulBroadcastAddress ); /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); - FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 1UL ); + xIsIPv4Broadcast_ReturnThruPtr_ppxEndPoint( &pxEndPoint2 ); + eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); TEST_ASSERT_EQUAL_MESSAGE( eResolutionCacheHit, eResult, "Test 3" ); - TEST_ASSERT_EQUAL( pxEndPoint, &xEndPoint ); + TEST_ASSERT_EQUAL( &xEndPoint, pxEndPoint ); TEST_ASSERT_EQUAL_MEMORY_MESSAGE( &xBroadcastMACAddress, &xMACAddress, sizeof( xMACAddress ), "Test 3" ); /* =================================================== */ } @@ -2092,14 +2094,16 @@ void test_eARPGetCacheEntry_IPMatchesBroadcastAddr_NullEndPointOnNetMask( void ) eResolutionLookupResult_t eResult; uint32_t ulSavedGatewayAddress; struct xNetworkEndPoint * pxEndPoint, xEndPoint; + struct xNetworkEndPoint * pxEndPoint2 = NULL; /* =================================================== */ ulIPAddress = FreeRTOS_ntohl( xNetworkAddressing.ulBroadcastAddress ); /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); - FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( NULL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 1UL ); + xIsIPv4Broadcast_ReturnThruPtr_ppxEndPoint( &pxEndPoint2 ); + eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); TEST_ASSERT_EQUAL( eResolutionCacheHit, eResult ); @@ -2117,7 +2121,6 @@ void test_eARPGetCacheEntry_MultiCastAddr( void ) /* =================================================== */ ulIPAddress = FreeRTOS_ntohl( xNetworkAddressing.ulBroadcastAddress ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 1UL ); vSetMultiCastIPv4MacAddress_Ignore(); @@ -2130,7 +2133,6 @@ void test_eARPGetCacheEntry_MultiCastAddr( void ) /* =================================================== */ xEndPoint.bits.bIPv6 = 1; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 1UL ); vSetMultiCastIPv4MacAddress_Ignore(); @@ -2152,14 +2154,15 @@ void test_eARPGetCacheEntry_IPMatchesOtherBroadcastAddr( void ) uint32_t ulSavedGatewayAddress; struct xNetworkInterface * xInterface; struct xNetworkEndPoint * pxEndPoint, xEndPoint; + struct xNetworkEndPoint * pxEndPoint2 = &xEndPoint; /* =================================================== */ - ulIPAddress = FreeRTOS_ntohl( ipBROADCAST_IP_ADDRESS ); + ulIPAddress = FreeRTOS_ntohl( FREERTOS_INADDR_BROADCAST ); /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); - FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( &xEndPoint ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 1UL ); + xIsIPv4Broadcast_ReturnThruPtr_ppxEndPoint( &pxEndPoint2 ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); TEST_ASSERT_EQUAL_MESSAGE( eResolutionCacheHit, eResult, "Test 3" ); TEST_ASSERT_EQUAL_MEMORY_MESSAGE( &xBroadcastMACAddress, &xMACAddress, sizeof( xMACAddress ), "Test 3" ); @@ -2186,9 +2189,9 @@ void test_eARPGetCacheEntry_MatchingInvalidEntry( void ) xARPCache[ 1 ].ucValid = pdFALSE; /* Not worried about what these functions do. */ xEndPoint.ipv4_settings.ulGatewayAddress = xNetworkAddressing.ulGatewayAddress; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( NULL ); FreeRTOS_FindGateWay_ExpectAnyArgsAndReturn( &xEndPoint ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); @@ -2216,9 +2219,9 @@ void test_eARPGetCacheEntry_MatchingValidEntry( void ) xARPCache[ 1 ].ucValid = pdTRUE; /* Not worried about what these functions do. */ xEndPoint.ipv4_settings.ulGatewayAddress = xNetworkAddressing.ulGatewayAddress; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( NULL ); FreeRTOS_FindGateWay_ExpectAnyArgsAndReturn( &xEndPoint ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); @@ -2249,9 +2252,9 @@ void test_eARPGetCacheEntry_GatewayAddressZero( void ) ulIPAddress = 0x4321; /* Not worried about what these functions do. */ xEndPoint.ipv4_settings.ulGatewayAddress = 0; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( NULL ); FreeRTOS_FindGateWay_ExpectAnyArgsAndReturn( NULL ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); @@ -2277,9 +2280,9 @@ void test_eARPGetCacheEntry_AddressNotOnLocalAddress( void ) pxNetworkEndPoints = &xEndPoint; /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( NULL ); FreeRTOS_FindGateWay_ExpectAnyArgsAndReturn( NULL ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); @@ -2316,9 +2319,9 @@ void test_eARPGetCacheEntry_NoCacheHit( void ) xEndPoint.ipv4_settings.ulIPAddress = 0x1234; pxNetworkEndPoints = &xEndPoint; /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( NULL ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); xNetworkAddressing.ulGatewayAddress = ulSavedGatewayAddress; @@ -2360,8 +2363,8 @@ void test_eARPGetCacheEntry_LoopbackAddress( void ) xEndPoint.ipv4_settings.ulIPAddress = 0x1234; pxNetworkEndPoints = &xEndPoint; /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 1UL ); + FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); TEST_ASSERT_EQUAL( eResolutionFailed, eResult ); TEST_ASSERT_NOT_EQUAL( pxEndPoint, &xEndPoint ); @@ -2403,8 +2406,8 @@ void test_eARPGetCacheEntry_LoopbackAddress_ValidLPEndpoint( void ) memcpy( xEndPoint.xMACAddress.ucBytes, xMACAddressExp.ucBytes, sizeof( MACAddress_t ) ); pxNetworkEndPoints = &xEndPoint; /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 1UL ); + FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( &xEndPoint ); eResult = eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); TEST_ASSERT_EQUAL( eResolutionCacheHit, eResult ); TEST_ASSERT_EQUAL( pxEndPoint, &xEndPoint ); @@ -2719,7 +2722,6 @@ void test_xARPWaitResolution_PrivateFunctionReturnsHit( void ) xEndPoint.bits.bIPv6 = pdFALSE_UNSIGNED; xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE ); /* Not worried about what these functions do. */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 1UL ); vSetMultiCastIPv4MacAddress_Ignore(); @@ -2756,11 +2758,11 @@ void test_xARPWaitResolution_GNWFailsNoTimeout( void ) xEndPoint.ipv4_settings.ulIPAddress = 0x00000034; /* Assertion on calling from IP-task */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE ); /* Not worried about what these functions do. */ xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( ( void * ) 1234 ); vTaskSetTimeOutState_Stub( vStoreTimeValue ); @@ -2771,9 +2773,9 @@ void test_xARPWaitResolution_GNWFailsNoTimeout( void ) FreeRTOS_FindEndPointOnNetMask_ExpectAndReturn( ulIPAddress, &xEndPoint ); pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL ); vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( ( void * ) 1234 ); xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE ); } @@ -2809,11 +2811,11 @@ void test_xARPWaitResolution( void ) xEndPoint.ipv4_settings.ulIPAddress = 0x00000034; /* Assertion on calling from IP-task */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE ); /* Not worried about what these functions do. */ xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( ( void * ) 1234 ); vTaskSetTimeOutState_Stub( vStoreTimeValue ); @@ -2824,9 +2826,9 @@ void test_xARPWaitResolution( void ) FreeRTOS_FindEndPointOnNetMask_ExpectAndReturn( ulIPAddress, &xEndPoint ); pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL ); vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( ( void * ) 1234 ); xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE ); } @@ -2834,9 +2836,9 @@ void test_xARPWaitResolution( void ) FreeRTOS_FindEndPointOnNetMask_ExpectAndReturn( ulIPAddress, &xEndPoint ); pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL ); vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( ( void * ) 1234 ); xTaskCheckForTimeOut_IgnoreAndReturn( pdTRUE ); @@ -2860,11 +2862,11 @@ void test_xARPWaitResolution( void ) xEndPoint.ipv4_settings.ulIPAddress = 0x00000034; /* Assertion on calling from IP-task */ - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsCallingFromIPTask_IgnoreAndReturn( pdFALSE ); /* Not worried about what these functions do. */ xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( ( void * ) 1234 ); vTaskSetTimeOutState_Stub( vStoreTimeValue ); @@ -2875,9 +2877,9 @@ void test_xARPWaitResolution( void ) FreeRTOS_FindEndPointOnNetMask_ExpectAndReturn( ulIPAddress, &xEndPoint ); pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL ); vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 0UL ); + xIsIPv4Broadcast_ExpectAnyArgsAndReturn( 0UL ); FreeRTOS_FindEndPointOnNetMask_ExpectAnyArgsAndReturn( ( void * ) 1234 ); xTaskCheckForTimeOut_IgnoreAndReturn( pdFALSE ); } @@ -2885,7 +2887,6 @@ void test_xARPWaitResolution( void ) FreeRTOS_FindEndPointOnNetMask_ExpectAndReturn( ulIPAddress, &xEndPoint ); pxGetNetworkBufferWithDescriptor_ExpectAndReturn( sizeof( ARPPacket_t ), 0, NULL ); vTaskDelay_Expect( pdMS_TO_TICKS( 250U ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); xIsIPv4Loopback_ExpectAndReturn( ulIPAddress, 0UL ); xIsIPv4Multicast_ExpectAndReturn( ulIPAddress, 1UL ); vSetMultiCastIPv4MacAddress_Ignore(); diff --git a/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c b/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c index dfe97e4038..3ae1718e9f 100644 --- a/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c +++ b/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c @@ -4695,7 +4695,7 @@ void test_vDHCPProcess_eWaitingAcknowledge_IncorrectDNSServerAddress2( void ) prvWriteDHCPOptionU32( &DHCPOption, dhcpIPv4_SUBNET_MASK_OPTION_CODE, ulSubnetMask ); prvWriteDHCPOptionU32( &DHCPOption, dhcpIPv4_GATEWAY_OPTION_CODE, ulGateway ); prvWriteDHCPOptionU32( &DHCPOption, dhcpIPv4_LEASE_TIME_OPTION_CODE, ulLeaseTime ); - prvWriteDHCPOptionU32( &DHCPOption, dhcpIPv4_DNS_SERVER_OPTIONS_CODE, ipBROADCAST_IP_ADDRESS ); + prvWriteDHCPOptionU32( &DHCPOption, dhcpIPv4_DNS_SERVER_OPTIONS_CODE, FREERTOS_INADDR_BROADCAST ); *DHCPOption++ = 0xFF; TEST_ASSERT_EQUAL( DHCPOption - DHCPMsg, xTotalLength ); diff --git a/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c b/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c index 69ef050dfe..c8a32c868a 100644 --- a/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c +++ b/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c @@ -1033,7 +1033,7 @@ void test_FreeRTOS_getaddrinfo_a_IPv4Random_BindFailWithDot( void ) xEndPoint[ 2 ].bits.bIPv6 = pdFALSE; xEndPoint[ 2 ].ipv4_settings.ucDNSIndex = 0; - xEndPoint[ 2 ].ipv4_settings.ulDNSServerAddresses[ 0 ] = ipBROADCAST_IP_ADDRESS; + xEndPoint[ 2 ].ipv4_settings.ulDNSServerAddresses[ 0 ] = FREERTOS_INADDR_BROADCAST; xEndPoint[ 3 ].bits.bIPv6 = pdFALSE; xEndPoint[ 3 ].ipv4_settings.ucDNSIndex = 0; diff --git a/test/unit-test/FreeRTOS_IPv4/FreeRTOS_IPv4_utest.c b/test/unit-test/FreeRTOS_IPv4/FreeRTOS_IPv4_utest.c index d571040a9b..ba9824f4f8 100644 --- a/test/unit-test/FreeRTOS_IPv4/FreeRTOS_IPv4_utest.c +++ b/test/unit-test/FreeRTOS_IPv4/FreeRTOS_IPv4_utest.c @@ -123,6 +123,141 @@ void test_xIsIPv4Multicast_IsMultiCast( void ) TEST_ASSERT_EQUAL( pdTRUE, xReturn ); } +/** + * @brief test_xIsIPv4Broadcast_BroadcastAddress + * To validate if xIsIPv4Broadcast() when given broadcast address. + */ +void test_xIsIPv4Broadcast_BroadcastAddress( void ) +{ + BaseType_t xIsBroadcast; + NetworkEndPoint_t xEndPoints[ 2 ]; /* IPv6->IPv4 */ + NetworkEndPoint_t * pxEndPoint = NULL; + + memset( &xEndPoints[ 0 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 0 ].bits.bIPv6 = pdTRUE; + memset( &xEndPoints[ 1 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 1 ].bits.bIPv6 = pdFALSE; + xEndPoints[ 1 ].ipv4_settings.ulIPAddress = FREERTOS_INADDR_BROADCAST; + + FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( &xEndPoints[ 0 ] ); + FreeRTOS_NextEndPoint_ExpectAndReturn( NULL, &xEndPoints[ 0 ], &xEndPoints[ 1 ] ); + + xIsBroadcast = xIsIPv4Broadcast( FREERTOS_INADDR_BROADCAST, &pxEndPoint ); + + TEST_ASSERT_EQUAL( pdTRUE, xIsBroadcast ); + TEST_ASSERT_EQUAL( &xEndPoints[ 1 ], pxEndPoint ); +} + +/** + * @brief test_xIsIPv4Broadcast_BroadcastAddressNoPtr + * To validate if xIsIPv4Broadcast() when given broadcast address but + * no input EP pointer. + */ +void test_xIsIPv4Broadcast_BroadcastAddressNoPtr( void ) +{ + BaseType_t xIsBroadcast; + NetworkEndPoint_t xEndPoints[ 2 ]; /* IPv6->IPv4 */ + + memset( &xEndPoints[ 0 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 0 ].bits.bIPv6 = pdTRUE; + memset( &xEndPoints[ 1 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 1 ].bits.bIPv6 = pdFALSE; + xEndPoints[ 1 ].ipv4_settings.ulIPAddress = FREERTOS_INADDR_BROADCAST; + + FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( &xEndPoints[ 0 ] ); + FreeRTOS_NextEndPoint_ExpectAndReturn( NULL, &xEndPoints[ 0 ], &xEndPoints[ 1 ] ); + + xIsBroadcast = xIsIPv4Broadcast( FREERTOS_INADDR_BROADCAST, NULL ); + + TEST_ASSERT_EQUAL( pdTRUE, xIsBroadcast ); +} + +/** + * @brief test_xIsIPv4Broadcast_BroadcastAddressNotFREERTOS_INADDR_BROADCAST + * To validate if + * test_xIsIPv4Broadcast_BroadcastAddressNotFREERTOS_INADDR_BROADCAST() + * when given broadcast address but not FREERTOS_INADDR_BROADCAST. + */ +void test_xIsIPv4Broadcast_BroadcastAddressNotFREERTOS_INADDR_BROADCAST( void ) +{ + BaseType_t xIsBroadcast; + NetworkEndPoint_t xEndPoints[ 2 ]; /* IPv6->IPv4 */ + NetworkEndPoint_t * pxEndPoint = NULL; + + memset( &xEndPoints[ 0 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 0 ].bits.bIPv6 = pdTRUE; + memset( &xEndPoints[ 1 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 1 ].bits.bIPv6 = pdFALSE; + xEndPoints[ 1 ].ipv4_settings.ulBroadcastAddress = 0xFFFF1234; + + FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( &xEndPoints[ 0 ] ); + FreeRTOS_NextEndPoint_ExpectAndReturn( NULL, &xEndPoints[ 0 ], &xEndPoints[ 1 ] ); + + xIsBroadcast = xIsIPv4Broadcast( 0xFFFF1234, &pxEndPoint ); + + TEST_ASSERT_EQUAL( pdTRUE, xIsBroadcast ); + TEST_ASSERT_EQUAL( &xEndPoints[ 1 ], pxEndPoint ); +} + +/** + * @brief test_xIsIPv4Broadcast_NotBroadcastAddress + * To validate if xIsIPv4Broadcast() when given not a broadcast address. + */ +void test_xIsIPv4Broadcast_NotBroadcastAddress( void ) +{ + BaseType_t xIsBroadcast; + NetworkEndPoint_t xEndPoints[ 2 ]; /* IPv6->IPv4 */ + NetworkEndPoint_t * pxEndPoint = NULL; + + memset( &xEndPoints[ 0 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 0 ].bits.bIPv6 = pdTRUE; + memset( &xEndPoints[ 1 ], 0, sizeof( NetworkEndPoint_t ) ); + xEndPoints[ 1 ].bits.bIPv6 = pdFALSE; + xEndPoints[ 1 ].ipv4_settings.ulIPAddress = FREERTOS_INADDR_BROADCAST; + + FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( &xEndPoints[ 0 ] ); + FreeRTOS_NextEndPoint_ExpectAndReturn( NULL, &xEndPoints[ 0 ], &xEndPoints[ 1 ] ); + FreeRTOS_NextEndPoint_ExpectAndReturn( NULL, &xEndPoints[ 1 ], NULL ); + + xIsBroadcast = xIsIPv4Broadcast( 0xABCD1235, &pxEndPoint ); + + TEST_ASSERT_EQUAL( pdFALSE, xIsBroadcast ); + TEST_ASSERT_EQUAL( NULL, pxEndPoint ); +} + +/** + * @brief test_xIsIPv4Broadcast_NoEndPoints + * To validate if xIsIPv4Broadcast() when no endpoints are there. + */ +void test_xIsIPv4Broadcast_NoEndPoints( void ) +{ + BaseType_t xIsBroadcast; + NetworkEndPoint_t * pxEndPoint = NULL; + + FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( NULL ); + + xIsBroadcast = xIsIPv4Broadcast( 0xABCD1235, &pxEndPoint ); + + TEST_ASSERT_EQUAL( pdFALSE, xIsBroadcast ); + TEST_ASSERT_EQUAL( NULL, pxEndPoint ); +} + +/** + * @brief test_xIsIPv4Broadcast_NoEndPointsNoPtr + * To validate if xIsIPv4Broadcast() when no endpoints are there + * and no pointer given. + */ +void test_xIsIPv4Broadcast_NoEndPointsNoPtr( void ) +{ + BaseType_t xIsBroadcast; + + FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( NULL ); + + xIsBroadcast = xIsIPv4Broadcast( 0xABCD1235, NULL ); + + TEST_ASSERT_EQUAL( pdFALSE, xIsBroadcast ); +} + /** * @brief test_prvAllowIPPacketIPv4_LessHeaderLength * To validate if prvAllowIPPacketIPv4() returns eReleaseBuffer when ucVersionHeaderLength @@ -252,7 +387,7 @@ void test_prvAllowIPPacketIPv4_NotMatchingIP( void ) pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -261,8 +396,6 @@ void test_prvAllowIPPacketIPv4_NotMatchingIP( void ) pxIPHeader->ucVersionHeaderLength = 0x45; pxIPHeader->ulDestinationIPAddress = pxEndpoint->ipv4_settings.ulIPAddress + 1; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -299,8 +432,6 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPMatch( void ) pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( pxEndpoint ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -327,7 +458,7 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPBrdCast( void ) pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = pxEndpoint; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -339,8 +470,6 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPBrdCast( void ) pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -366,7 +495,7 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPLLMNR( void ) memset( pxEndpoint, 0, sizeof( NetworkEndPoint_t ) ); pxNetworkBuffer = &xNetworkBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = pxEndpoint; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -379,8 +508,6 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPLLMNR( void ) pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -400,12 +527,13 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_NoLocalIP( void ) UBaseType_t uxHeaderLength = 0; uint8_t ucEthBuffer[ ipconfigTCP_MSS ]; IPHeader_t * pxIPHeader; + NetworkEndPoint_t xEndpoint; memset( ucEthBuffer, 0, ipconfigTCP_MSS ); pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -414,9 +542,6 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_NoLocalIP( void ) pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF; - - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -436,12 +561,13 @@ void test_prvAllowIPPacketIPv4_DestMACBrdCast_DestIPUnicast( void ) UBaseType_t uxHeaderLength = 0; uint8_t ucEthBuffer[ ipconfigTCP_MSS ]; IPHeader_t * pxIPHeader; + NetworkEndPoint_t xEndpoint; memset( ucEthBuffer, 0, ipconfigTCP_MSS ); pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -452,7 +578,45 @@ void test_prvAllowIPPacketIPv4_DestMACBrdCast_DestIPUnicast( void ) memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ + eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); + + TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); +} + +/** + * @brief test_prvAllowIPPacketIPv4_DestMACBrdCast_DestIPBroadcastAndIncorrectChkSum + * To validate if prvAllowIPPacketIPv4() when + * destination MAC address is broadcast address and the IP address is broadcast address. + * And the endpoint is up. + */ +void test_prvAllowIPPacketIPv4_DestMACBrdCast_DestIPBroadcastAndIncorrectChkSum( void ) +{ + eFrameProcessingResult_t eResult; + IPPacket_t * pxIPPacket; + NetworkBufferDescriptor_t * pxNetworkBuffer, xNetworkBuffer; + UBaseType_t uxHeaderLength = 0; + uint8_t ucEthBuffer[ ipconfigTCP_MSS ]; + IPHeader_t * pxIPHeader; + NetworkEndPoint_t xEndpoint; + + memset( ucEthBuffer, 0, ipconfigTCP_MSS ); + + pxNetworkBuffer = &xNetworkBuffer; + pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; + pxNetworkBuffer->pxEndPoint = &xEndpoint; + pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; + pxIPHeader = &( pxIPPacket->xIPHeader ); + + pxIPHeader->ucVersionHeaderLength = 0x45; + + pxIPHeader->ulDestinationIPAddress = 0xABCDFFFF; + xEndpoint.ipv4_settings.ulBroadcastAddress = 0xABCDFFFF; + + memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); + + FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL ); + + usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC - 1 ); eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); @@ -472,12 +636,13 @@ void test_prvAllowIPPacketIPv4_SrcMACBrdCast( void ) UBaseType_t uxHeaderLength = 0; uint8_t ucEthBuffer[ ipconfigTCP_MSS ]; IPHeader_t * pxIPHeader; + NetworkEndPoint_t xEndpoint; memset( ucEthBuffer, 0, ipconfigTCP_MSS ); pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -488,8 +653,6 @@ void test_prvAllowIPPacketIPv4_SrcMACBrdCast( void ) memcpy( pxIPPacket->xEthernetHeader.xSourceAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -509,12 +672,13 @@ void test_prvAllowIPPacketIPv4_SrcMACBrdCastDestMACBrdCast( void ) UBaseType_t uxHeaderLength = 0; uint8_t ucEthBuffer[ ipconfigTCP_MSS ]; IPHeader_t * pxIPHeader; + NetworkEndPoint_t xEndpoint; memset( ucEthBuffer, 0, ipconfigTCP_MSS ); pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -525,9 +689,6 @@ void test_prvAllowIPPacketIPv4_SrcMACBrdCastDestMACBrdCast( void ) memcpy( pxIPPacket->xEthernetHeader.xSourceAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) ); - - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -556,7 +717,7 @@ void test_prvAllowIPPacketIPv4_SrcIPAddrIsMulticast( void ) pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxEndpoint->ipv4_settings.ulIPAddress = 0xFFFFFFFF; @@ -569,8 +730,6 @@ void test_prvAllowIPPacketIPv4_SrcIPAddrIsMulticast( void ) pxIPHeader->ulSourceIPAddress = FreeRTOS_htonl( 0xE0000000 + 1 ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -596,7 +755,7 @@ void test_prvAllowIPPacketIPv4_IncorrectChecksum( void ) pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer ); pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -610,9 +769,6 @@ void test_prvAllowIPPacketIPv4_IncorrectChecksum( void ) pxIPHeader->ulSourceIPAddress = 0xC0C00101; - - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL ); usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC - 1 ); @@ -642,7 +798,7 @@ void test_prvAllowIPPacketIPv4_IncorrectProtocolChecksum( void ) pxNetworkBuffer = &xNetworkBuffer; pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer; - pxNetworkBuffer->pxEndPoint = NULL; + pxNetworkBuffer->pxEndPoint = &xEndpoint; pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; pxIPHeader = &( pxIPPacket->xIPHeader ); @@ -656,9 +812,6 @@ void test_prvAllowIPPacketIPv4_IncorrectProtocolChecksum( void ) pxIPHeader->ulSourceIPAddress = 0xC0C00101; - - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL ); usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC ); @@ -704,8 +857,6 @@ void test_prvAllowIPPacketIPv4_HappyPath( void ) pxIPHeader->ulSourceIPAddress = 0xC0C00101; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL ); usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC ); @@ -789,9 +940,6 @@ void test_prvAllowIPPacketIPv4_DestMacBroadcastIPNotBroadcast( void ) pxIPHeader->ulSourceIPAddress = 0xC0C00101; - - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( pxEndpoint ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -958,8 +1106,6 @@ void test_xBadIPv4Loopback_0_test( void ) memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xMACAddress.ucBytes, sizeof( MACAddress_t ) ); - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( pxEndpoint ); - FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL ); usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC ); diff --git a/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOS_IPv4_DiffConfig_utest.c b/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOS_IPv4_DiffConfig_utest.c index 412ba9d5fb..f8061c199d 100644 --- a/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOS_IPv4_DiffConfig_utest.c +++ b/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOS_IPv4_DiffConfig_utest.c @@ -106,8 +106,6 @@ void test_prvAllowIPPacketIPv4_BroadcastSourceIP( void ) pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -149,8 +147,6 @@ void test_prvAllowIPPacketIPv4_BufferLengthLessThanMinimum( void ) pxIPHeader->ulSourceIPAddress = 0xC0C00101; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -196,8 +192,6 @@ void test_prvAllowIPPacketIPv4_UDPCheckSumZero( void ) pxIPHeader->ulSourceIPAddress = 0xC0C00101; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eReleaseBuffer, eResult ); @@ -249,8 +243,6 @@ void test_prvAllowIPPacketIPv4_UDP_HappyPath( void ) pxProtPack->xUDPPacket.xUDPHeader.usChecksum = 0xFF12; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eProcessBuffer, eResult ); @@ -296,8 +288,6 @@ void test_prvAllowIPPacketIPv4_TCP_HappyPath( void ) pxIPHeader->ulSourceIPAddress = 0xC0C00101; - FreeRTOS_FindEndPointOnIP_IPv4_ExpectAnyArgsAndReturn( NULL ); /* From prvAllowIPPacketIPv4() */ - eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); TEST_ASSERT_EQUAL( eProcessBuffer, eResult );