diff options
Diffstat (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c')
-rw-r--r-- | bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c | 2023 |
1 files changed, 1194 insertions, 829 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c index 9d327f3593..526e83e140 100644 --- a/bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c +++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c @@ -10,6 +10,17 @@ * + 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 ##### @@ -39,18 +50,14 @@ (##) 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 availability by calling HAL_ETH_IsRxDataAvailable() + 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 (HAL_ETH_IsRxDataAvailable() returns 1 or Rx interrupt - occurred), user can call the following APIs to get received data: - (##) HAL_ETH_GetRxDataBuffer(): Get buffer address of received frame - (##) HAL_ETH_GetRxDataLength(): Get received frame length - (##) HAL_ETH_GetRxDataInfo(): Get received frame additional info, - please refer to ETH_RxPacketInfo typedef structure + (#) 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 @@ -69,20 +76,32 @@ (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef - -@- The PTP protocol offload APIs are not supported in this driver. + (#) 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 @ref HAL_ETH_RegisterCallback() to register an interrupt callback. + Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. - Function @ref HAL_ETH_RegisterCallback() allows to register following callbacks: + Function HAL_ETH_RegisterCallback() allows to register following callbacks: (+) TxCpltCallback : Tx Complete Callback. (+) RxCpltCallback : Rx Complete Callback. - (+) DMAErrorCallback : DMA Error Callback. - (+) MACErrorCallback : MAC Error Callback. + (+) ErrorCallback : Error Callback. (+) PMTCallback : Power Management Callback (+) EEECallback : EEE Callback. (+) WakeUpCallback : Wake UP Callback @@ -92,28 +111,51 @@ This function takes as parameters the HAL peripheral handle, the Callback ID and a pointer to the user callback function. - Use function @ref HAL_ETH_UnRegisterCallback() to reset a callback to the default + 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. - @ref HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, + 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. - (+) DMAErrorCallback : DMA Error Callback. - (+) MACErrorCallback : MAC Error 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 @ref HAL_ETH_TxCpltCallback(), @ref HAL_ETH_RxCpltCallback(). + 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/ @ref HAL_ETH_DeInit only when + 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/ @ref HAL_ETH_DeInit + 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. @@ -121,7 +163,7 @@ 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 @ref HAL_ETH_RegisterCallback() before calling @ref HAL_ETH_DeInit + 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 @@ -130,17 +172,6 @@ @endverbatim ****************************************************************************** - * @attention - * - * <h2><center>© Copyright (c) 2017 STMicroelectronics. - * All rights reserved.</center></h2> - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ @@ -164,33 +195,34 @@ /** @addtogroup ETH_Private_Constants ETH Private Constants * @{ */ -#define ETH_MACCR_MASK ((uint32_t)0xFFFB7F7CU) -#define ETH_MACECR_MASK ((uint32_t)0x3F077FFFU) -#define ETH_MACPFR_MASK ((uint32_t)0x800007FFU) -#define ETH_MACWTR_MASK ((uint32_t)0x0000010FU) -#define ETH_MACTFCR_MASK ((uint32_t)0xFFFF00F2U) -#define ETH_MACRFCR_MASK ((uint32_t)0x00000003U) -#define ETH_MTLTQOMR_MASK ((uint32_t)0x00000072U) -#define ETH_MTLRQOMR_MASK ((uint32_t)0x0000007BU) - -#define ETH_DMAMR_MASK ((uint32_t)0x00007802U) -#define ETH_DMASBMR_MASK ((uint32_t)0x0000D001U) -#define ETH_DMACCR_MASK ((uint32_t)0x00013FFFU) -#define ETH_DMACTCR_MASK ((uint32_t)0x003F1010U) -#define ETH_DMACRCR_MASK ((uint32_t)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_SWRESET_TIMEOUT ((uint32_t)500U) -#define ETH_MDIO_BUS_TIMEOUT ((uint32_t)1000U) - #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_MAC_US_TICK ((uint32_t)1000000U) +#define ETH_MACTSCR_MASK 0x0087FF2FU + +#define ETH_MACSTSUR_VALUE 0xFFFFFFFFU +#define ETH_MACSTNUR_VALUE 0xBB9ACA00U +#define ETH_SEGMENT_SIZE_DEFAULT 0x218U /** * @} */ @@ -202,17 +234,17 @@ */ /* 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) + (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) + (inx) += (offset);\ + if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\ + (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\ + } while (0) /** * @} */ @@ -221,13 +253,13 @@ * @ingroup RTEMSBSPsARMSTM32H7 * @{ */ -static void ETH_MAC_MDIO_ClkConfig(ETH_HandleTypeDef *heth); 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); #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth); @@ -264,9 +296,6 @@ static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth); (++) Tx DMA Descriptors Tab (++) Length of Rx Buffers - (+) Call the function HAL_ETH_DescAssignMemory() to assign data buffers - for each Rx DMA Descriptor - (+) Call the function HAL_ETH_DeInit() to restore the default configuration of the selected ETH peripheral. @@ -284,44 +313,35 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) { uint32_t tickstart; - if(heth == NULL) + 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) - if(heth->gState == HAL_ETH_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - heth->Lock = HAL_UNLOCKED; - ETH_InitCallbacksToDefault(heth); - if(heth->MspInitCallback == NULL) + if (heth->MspInitCallback == NULL) { heth->MspInitCallback = HAL_ETH_MspInit; } /* Init the low level hardware */ heth->MspInitCallback(heth); - } - #else - - /* Check the ETH peripheral state */ - if(heth->gState == HAL_ETH_STATE_RESET) - { /* Init the low level hardware : GPIO, CLOCK, NVIC. */ HAL_ETH_MspInit(heth); - } -#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ - heth->gState = HAL_ETH_STATE_BUSY; +#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + } __HAL_RCC_SYSCFG_CLK_ENABLE(); - if(heth->Init.MediaInterface == HAL_ETH_MII_MODE) + if (heth->Init.MediaInterface == HAL_ETH_MII_MODE) { HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII); } @@ -330,6 +350,9 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) 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 */ @@ -341,7 +364,7 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) /* Wait for software reset */ while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U) { - if(((HAL_GetTick() - tickstart ) > ETH_SWRESET_TIMEOUT)) + if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)) { /* Set Error Code */ heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; @@ -353,7 +376,7 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) } /*------------------ MDIO CSR Clock Range Configuration --------------------*/ - ETH_MAC_MDIO_ClkConfig(heth); + 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)); @@ -396,7 +419,6 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) heth->ErrorCode = HAL_ETH_ERROR_NONE; heth->gState = HAL_ETH_STATE_READY; - heth->RxState = HAL_ETH_STATE_READY; return HAL_OK; } @@ -414,7 +436,7 @@ HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - if(heth->MspDeInitCallback == NULL) + if (heth->MspDeInitCallback == NULL) { heth->MspDeInitCallback = HAL_ETH_MspDeInit; } @@ -428,7 +450,7 @@ HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ /* Set ETH HAL state to Disabled */ - heth->gState= HAL_ETH_STATE_RESET; + heth->gState = HAL_ETH_STATE_RESET; /* Return function status */ return HAL_OK; @@ -475,8 +497,7 @@ __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) * 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_DMA_ERROR_CB_ID DMA Error Callback ID - * @arg @ref HAL_ETH_MAC_ERROR_CB_ID MAC Error 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 @@ -485,86 +506,81 @@ __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) * @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 HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback) { HAL_StatusTypeDef status = HAL_OK; - if(pCallback == NULL) + if (pCallback == NULL) { /* Update the error code */ heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; return HAL_ERROR; } - /* Process locked */ - __HAL_LOCK(heth); - if(heth->gState == HAL_ETH_STATE_READY) + 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_DMA_ERROR_CB_ID : - heth->DMAErrorCallback = pCallback; - break; - - case HAL_ETH_MAC_ERROR_CB_ID : - heth->MACErrorCallback = 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; + 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) + 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; + 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 @@ -575,9 +591,6 @@ HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_Call status = HAL_ERROR; } - /* Release Lock */ - __HAL_UNLOCK(heth); - return status; } @@ -589,8 +602,7 @@ HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_Call * 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_DMA_ERROR_CB_ID DMA Error Callback ID - * @arg @ref HAL_ETH_MAC_ERROR_CB_ID MAC Error 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 @@ -602,75 +614,68 @@ HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_Ca { HAL_StatusTypeDef status = HAL_OK; - /* Process locked */ - __HAL_LOCK(heth); - - if(heth->gState == HAL_ETH_STATE_READY) + 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_DMA_ERROR_CB_ID : - heth->DMAErrorCallback = HAL_ETH_DMAErrorCallback; - break; - - case HAL_ETH_MAC_ERROR_CB_ID : - heth->MACErrorCallback = HAL_ETH_MACErrorCallback; - 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; + 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) + 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; + 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 @@ -681,58 +686,11 @@ HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_Ca status = HAL_ERROR; } - /* Release Lock */ - __HAL_UNLOCK(heth); - return status; } #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ /** - * @brief Assign memory buffers to a DMA Rx descriptor - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param Index : index of the DMA Rx descriptor - * this parameter can be a value from 0x0 to (ETH_RX_DESC_CNT -1) - * @param pBuffer1: address of buffer 1 - * @param pBuffer2: address of buffer 2 if available - * @retval HAL status - */ -HAL_StatusTypeDef HAL_ETH_DescAssignMemory(ETH_HandleTypeDef *heth, uint32_t Index, uint8_t *pBuffer1, uint8_t *pBuffer2) -{ - ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[Index]; - - if((pBuffer1 == NULL) || (Index >= (uint32_t)ETH_RX_DESC_CNT)) - { - /* Set Error Code */ - heth->ErrorCode = HAL_ETH_ERROR_PARAM; - /* Return Error */ - return HAL_ERROR; - } - - /* write buffer address to RDES0 */ - WRITE_REG(dmarxdesc->DESC0, (uint32_t)pBuffer1); - /* store buffer address */ - WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)pBuffer1); - /* set buffer address valid bit to RDES3 */ - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF1V); - - if(pBuffer2 != NULL) - { - /* write buffer 2 address to RDES1 */ - WRITE_REG(dmarxdesc->DESC2, (uint32_t)pBuffer2); - /* store buffer 2 address */ - WRITE_REG(dmarxdesc->BackupAddr1, (uint32_t)pBuffer2); - /* set buffer 2 address valid bit to RDES3 */ - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF2V); - } - /* set OWN bit to RDES3 */ - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN); - - return HAL_OK; -} - -/** * @} */ @@ -760,10 +718,16 @@ HAL_StatusTypeDef HAL_ETH_DescAssignMemory(ETH_HandleTypeDef *heth, uint32_t Ind */ HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) { - if(heth->gState == HAL_ETH_STATE_READY) + if (heth->gState == HAL_ETH_STATE_READY) { heth->gState = HAL_ETH_STATE_BUSY; + /* Set nombre 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); @@ -782,8 +746,7 @@ HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) /* Clear Tx and Rx process stopped flags */ heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); - heth->gState = HAL_ETH_STATE_READY; - heth->RxState = HAL_ETH_STATE_BUSY_RX; + heth->gState = HAL_ETH_STATE_STARTED; return HAL_OK; } @@ -801,23 +764,25 @@ HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) */ HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) { - uint32_t descindex = 0, counter; - ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; - - if(heth->gState == HAL_ETH_STATE_READY) + if (heth->gState == HAL_ETH_STATE_READY) { heth->gState = HAL_ETH_STATE_BUSY; - /* Set IOC bit to all Rx descriptors */ - for(counter= 0; counter < (uint32_t)ETH_RX_DESC_CNT; counter++) - { - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC); - INCR_RX_DESC_INDEX(descindex, 1U); - dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; - } - /* save IT mode to ETH Handle */ heth->RxDescList.ItMode = 1U; + /* 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); + + /* Set nombre 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); @@ -837,17 +802,15 @@ HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) /* Clear Tx and Rx process stopped flags */ heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); - heth->gState = HAL_ETH_STATE_READY; - heth->RxState = HAL_ETH_STATE_BUSY_RX; - /* 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_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE)); + heth->gState = HAL_ETH_STATE_STARTED; return HAL_OK; } else @@ -864,11 +827,10 @@ HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) */ HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) { - if(heth->gState != HAL_ETH_STATE_RESET) + if (heth->gState == HAL_ETH_STATE_STARTED) { - /* Set the ETH peripheral state to BUSY */ + /* 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); @@ -876,7 +838,7 @@ HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); /* Disable the MAC reception */ - CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE); + CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); /* Set the Flush Transmit FIFO bit */ SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); @@ -885,7 +847,6 @@ HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); heth->gState = HAL_ETH_STATE_READY; - heth->RxState = HAL_ETH_STATE_READY; /* Return function status */ return HAL_OK; @@ -904,18 +865,21 @@ HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) */ HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) { - ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[0]; - uint32_t index; + ETH_DMADescTypeDef *dmarxdesc; + uint32_t descindex; - if(heth->gState != HAL_ETH_STATE_RESET) + if (heth->gState == HAL_ETH_STATE_STARTED) { /* Set the ETH peripheral state to BUSY */ heth->gState = HAL_ETH_STATE_BUSY; - /* Disable intrrupts: + /* Disable interrupts: - Tx complete interrupt - - Rx complete interrupt */ - __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMA_NORMAL_IT | ETH_DMA_RX_IT | ETH_DMA_TX_IT)); + - 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); @@ -924,8 +888,7 @@ HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); /* Disable the MAC reception */ - CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE); - + CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); /* Set the Flush Transmit FIFO bit */ SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); @@ -933,15 +896,15 @@ HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); /* Clear IOC bit to all Rx descriptors */ - for(index = 0; index < (uint32_t)ETH_RX_DESC_CNT; index++) + 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; - heth->RxState = HAL_ETH_STATE_READY; /* Return function status */ return HAL_OK; @@ -963,15 +926,15 @@ HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout) { uint32_t tickstart; - const ETH_DMADescTypeDef *dmatxdesc; + ETH_DMADescTypeDef *dmatxdesc; - if(pTxConfig == NULL) + if (pTxConfig == NULL) { heth->ErrorCode |= HAL_ETH_ERROR_PARAM; return HAL_ERROR; } - if(heth->gState == HAL_ETH_STATE_READY) + 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) @@ -981,6 +944,9 @@ HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig * 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 */ @@ -992,34 +958,30 @@ HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig * tickstart = HAL_GetTick(); - /* Wait for data to be transmitted or timeout occured */ - while((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET) + /* 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) + if ((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET) { heth->ErrorCode |= HAL_ETH_ERROR_DMA; heth->DMAErrorCode = heth->Instance->DMACSR; - /* Set ETH HAL State to Ready */ - heth->gState = HAL_ETH_STATE_ERROR; /* Return function status */ return HAL_ERROR; } /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if(((HAL_GetTick() - tickstart ) > Timeout) || (Timeout == 0U)) + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) { heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; - heth->gState = HAL_ETH_STATE_READY; + /* Clear TX descriptor so that we can proceed */ + dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD); return HAL_ERROR; } } } - /* Set ETH HAL State to Ready */ - heth->gState = HAL_ETH_STATE_READY; - /* Return function status */ return HAL_OK; } @@ -1038,20 +1000,27 @@ HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig * */ HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig) { - if(pTxConfig == NULL) + if (pTxConfig == NULL) { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; return HAL_ERROR; } - if(heth->gState == HAL_ETH_STATE_READY) + 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; + 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); @@ -1069,400 +1038,802 @@ HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfi } /** - * @brief Checks for received Packets. + * @brief Read a received packet. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module - * @retval 1: A Packet is received - * 0: no Packet received + * @param pAppBuff: Pointer to an application buffer to receive the packet. + * @retval HAL status */ -uint8_t HAL_ETH_IsRxDataAvailable(ETH_HandleTypeDef *heth) +HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff) { - ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList; - uint32_t descidx = dmarxdesclist->CurRxDesc; - ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; - uint32_t descscancnt = 0; - uint32_t appdesccnt = 0, firstappdescidx = 0; + 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(dmarxdesclist->AppDescNbr != 0U) + if (heth->gState != HAL_ETH_STATE_STARTED) { - /* data already received by not yet processed*/ - return 0; + 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) && (descscancnt < (uint32_t)ETH_RX_DESC_CNT)) + while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax) + && (rxdataready == 0U)) { - descscancnt++; - - /* Check if last descriptor */ - if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET) + if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET) { - /* Increment the number of descriptors to be passed to the application */ - appdesccnt += 1U; - - if(appdesccnt == 1U) + /* 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) { - WRITE_REG(firstappdescidx, descidx); + heth->RxDescList.RxDescCnt = 0; + heth->RxDescList.RxDataLength = 0; } - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); + /* Check if last descriptor */ + bufflength = heth->Init.RxBuffLen; + if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET) + { + bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength; - /* Check for Context descriptor */ - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; + /* Save Last descriptor index */ + heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3; - if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) - { - if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET) - { - /* Increment the number of descriptors to be passed to the application */ - dmarxdesclist->AppContextDesc = 1; - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - } + /* Packet ready */ + rxdataready = 1; } - /* Fill information to Rx descriptors list */ - dmarxdesclist->CurRxDesc = descidx; - dmarxdesclist->FirstAppDesc = firstappdescidx; - dmarxdesclist->AppDescNbr = appdesccnt; - /* Return function status */ - return 1; - } - /* Check if first descriptor */ - else if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) - { - WRITE_REG(firstappdescidx, descidx); - /* Increment the number of descriptors to be passed to the application */ - appdesccnt = 1U; + /* 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; - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; + /* Clear buffer pointer */ + dmarxdesc->BackupAddr0 = 0; } - /* It should be an intermediate descriptor */ - else - { - /* Increment the number of descriptors to be passed to the application */ - appdesccnt += 1U; - /* Increment current rx descriptor index */ - INCR_RX_DESC_INDEX(descidx, 1U); - /* Get current descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; - } + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccnt++; } - /* Build Descriptors if an incomplete Packet is received */ - if(appdesccnt > 0U) + heth->RxDescList.RxBuildDescCnt += desccnt; + if ((heth->RxDescList.RxBuildDescCnt) != 0U) { - descidx = firstappdescidx; - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; + /* Update Descriptors */ + ETH_UpdateDescriptor(heth); + } - for(descscancnt = 0; descscancnt < appdesccnt; descscancnt++) - { - WRITE_REG(dmarxdesc->DESC0, dmarxdesc->BackupAddr0); - WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF1V); + heth->RxDescList.RxDescIdx = descidx; - if (READ_REG(dmarxdesc->BackupAddr1) != ((uint32_t)RESET)) + 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) +{ +#ifndef __rtems__ + 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) { - WRITE_REG(dmarxdesc->DESC2, dmarxdesc->BackupAddr1); - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF2V); + allocStatus = 0U; } + else + { + WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff); + WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff); + } + } - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN); + if (allocStatus != 0U) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); - if(dmarxdesclist->ItMode != ((uint32_t)RESET)) + if (heth->RxDescList.ItMode != 0U) { - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC); + 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 rx descriptor index */ + /* Increment current rx descriptor index */ INCR_RX_DESC_INDEX(descidx, 1U); - /* Get descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; + /* Get current descriptor address */ + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccount--; } } - /* Fill information to Rx descriptors list: No received Packet */ - dmarxdesclist->AppDescNbr = 0U; + if (heth->RxDescList.RxBuildDescCnt != desccount) + { + /* Set the Tail pointer address */ + WRITE_REG(heth->Instance->DMACRDTPR, 0); - return 0; + heth->RxDescList.RxBuildDescIdx = descidx; + heth->RxDescList.RxBuildDescCnt = desccount; + } +#endif /* ! __rtems__ */ } /** - * @brief This function gets the buffer address of last received Packet. - * @note Please insure to allocate the RxBuffer structure before calling this function - * how to use example: - * HAL_ETH_GetRxDataLength(heth, &Length); - * BuffersNbr = (Length / heth->Init.RxBuffLen) + 1; - * RxBuffer = (ETH_BufferTypeDef *)malloc(BuffersNbr * sizeof(ETH_BufferTypeDef)); - * HAL_ETH_GetRxDataBuffer(heth, RxBuffer); + * @brief Register the Rx alloc callback. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module - * @param RxBuffer: Pointer to a ETH_BufferTypeDef structure + * @param rxAllocateCallback: pointer to function to alloc buffer * @retval HAL status */ -HAL_StatusTypeDef HAL_ETH_GetRxDataBuffer(ETH_HandleTypeDef *heth, ETH_BufferTypeDef *RxBuffer) +HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback) { - ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList; - uint32_t descidx = dmarxdesclist->FirstAppDesc; - uint32_t index, accumulatedlen = 0, lastdesclen; - __IO const ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; - ETH_BufferTypeDef *rxbuff = RxBuffer; - - if(rxbuff == NULL) + if (rxAllocateCallback == NULL) { - heth->ErrorCode = HAL_ETH_ERROR_PARAM; + /* No buffer to save */ return HAL_ERROR; } - if(dmarxdesclist->AppDescNbr == 0U) + /* 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 pStart: 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) { - if(HAL_ETH_IsRxDataAvailable(heth) == 0U) - { - /* No data to be transferred to the application */ - return HAL_ERROR; - } - else - { - descidx = dmarxdesclist->FirstAppDesc; - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; - } + /* No buffer to save */ + return HAL_ERROR; } - /* Get intermediate descriptors buffers: in case of the Packet is splitted into multi descriptors */ - for(index = 0; index < (dmarxdesclist->AppDescNbr - 1U); index++) + /* 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_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) { - /* Get Address and length of the first buffer address */ - rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr0; - rxbuff->len = heth->Init.RxBuffLen; + /* 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; +} - /* Check if the second buffer address of this descriptor is valid */ - if(dmarxdesc->BackupAddr1 != 0U) +/** + * @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) { - /* Point to next buffer */ - rxbuff = (struct __ETH_BufferTypeDef *)rxbuff->next; - /* Get Address and length of the second buffer address */ - rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr1; - rxbuff->len = heth->Init.RxBuffLen; + /* No packet in use, skip to next. */ + idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U); + pktInUse = 0U; } - else + + if (pktInUse != 0U) { - /* Nothing to do here */ - } + /* 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)); - /* get total length until this descriptor */ - accumulatedlen = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL); + /* Get timestamp low */ + timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1; +#endif /* HAL_ETH_USE_PTP */ - /* Increment to next descriptor */ - INCR_RX_DESC_INDEX(descidx, 1U); - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; +#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 */ - /* Point to next buffer */ - rxbuff = (struct __ETH_BufferTypeDef *)rxbuff->next; - } + /* Clear the entry in the in-use array. */ + dmatxdesclist->PacketAddress[idx] = NULL; - /* last descriptor data length */ - lastdesclen = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - accumulatedlen; + /* 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; +} - /* Get Address of the first buffer address */ - rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr0; +#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; - /* data is in only one buffer */ - if(lastdesclen <= heth->Init.RxBuffLen) + if (ptpconfig == NULL) { - rxbuff->len = lastdesclen; + return HAL_ERROR; } - /* data is in two buffers */ - else if(dmarxdesc->BackupAddr1 != 0U) + + 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) { - /* Get the Length of the first buffer address */ - rxbuff->len = heth->Init.RxBuffLen; - /* Point to next buffer */ - rxbuff = (struct __ETH_BufferTypeDef *)rxbuff->next; - /* Get the Address the Length of the second buffer address */ - rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr1; - rxbuff->len = lastdesclen - (heth->Init.RxBuffLen); + SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG); + while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0) {} } - else /* Buffer 2 not valid*/ + + /* Enable Update mode */ + if (ptpconfig->TimestampUpdateMode == ENABLE) { - return HAL_ERROR; + SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCFUPDT); } + /* Initialize Time */ + time.Seconds = 0; + time.NanoSeconds = 0; + HAL_ETH_PTP_SetTime(heth, &time); + + /* Ptp Init */ + SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT); + + /* Set PTP Configuration done */ + heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED; + + /* Return function status */ return HAL_OK; } /** - * @brief This function gets the length of last received Packet. + * @brief Get the Ethernet PTP configuration. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module - * @param Length: parameter to hold Rx packet length - * @retval HAL Status + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status */ -HAL_StatusTypeDef HAL_ETH_GetRxDataLength(ETH_HandleTypeDef *heth, uint32_t *Length) +HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) { - ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList; - uint32_t descidx = dmarxdesclist->FirstAppDesc; - __IO const ETH_DMADescTypeDef *dmarxdesc; - - if(dmarxdesclist->AppDescNbr == 0U) + if (ptpconfig == NULL) { - if(HAL_ETH_IsRxDataAvailable(heth) == 0U) - { - /* No data to be transferred to the application */ - return HAL_ERROR; - } + 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; - /* Get index of last descriptor */ - INCR_RX_DESC_INDEX(descidx, (dmarxdesclist->AppDescNbr - 1U)); - /* Point to last descriptor */ - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; - - *Length = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL); - + /* Return function status */ return HAL_OK; } /** - * @brief Get the Rx data info (Packet type, VLAN tag, Filters status, ...) + * @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 RxPacketInfo: parameter to hold info of received buffer + * @param heth: pointer to a ETH_TimeTypeDef structure that contains + * time to set * @retval HAL status */ -HAL_StatusTypeDef HAL_ETH_GetRxDataInfo(ETH_HandleTypeDef *heth, ETH_RxPacketInfo *RxPacketInfo) +HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) { - ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList; - uint32_t descidx = dmarxdesclist->FirstAppDesc; - __IO const ETH_DMADescTypeDef *dmarxdesc; + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) + { + /* Set Seconds */ + heth->Instance->MACSTSUR = time->Seconds; - if(dmarxdesclist->AppDescNbr == 0U) + /* Set NanoSeconds */ + heth->Instance->MACSTNUR = time->NanoSeconds; + + /* Return function status */ + return HAL_OK; + } + else { - if(HAL_ETH_IsRxDataAvailable(heth) == 0U) - { - /* No data to be transferred to the application */ - return HAL_ERROR; - } + /* Return function status */ + return HAL_ERROR; } +} - /* Get index of last descriptor */ - INCR_RX_DESC_INDEX(descidx, ((dmarxdesclist->AppDescNbr) - 1U)); - /* Point to last descriptor */ - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx]; - - if((dmarxdesc->DESC3 & ETH_DMARXNDESCWBF_ES) != (uint32_t)RESET) +/** + * @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) { - RxPacketInfo->ErrorCode = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_ERRORS_MASK); + /* Get Seconds */ + time->Seconds = heth->Instance->MACSTSUR; + + /* Get NanoSeconds */ + time->NanoSeconds = heth->Instance->MACSTNUR; + + /* Return function status */ + return HAL_OK; } else { - if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_RS0V) != 0U) + /* 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->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U; - if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LT) == ETH_DMARXNDESCWBF_LT_DVLAN) + if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR) { - RxPacketInfo->VlanTag = READ_BIT(dmarxdesc->DESC0, ETH_DMARXNDESCWBF_OVT); - RxPacketInfo->InnerVlanTag = READ_BIT(dmarxdesc->DESC0, ETH_DMARXNDESCWBF_IVT) >> 16; + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds; } else { - RxPacketInfo->VlanTag = READ_BIT(dmarxdesc->DESC0, ETH_DMARXNDESCWBF_OVT); + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U; } } - - if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_RS1V) != 0U) + else { - /* Get Payload type */ - RxPacketInfo->PayloadType =READ_BIT( dmarxdesc->DESC1, ETH_DMARXNDESCWBF_PT); - /* Get Header type */ - RxPacketInfo->HeaderType = READ_BIT(dmarxdesc->DESC1, (ETH_DMARXNDESCWBF_IPV4 | ETH_DMARXNDESCWBF_IPV6)); - /* Get Checksum status */ - RxPacketInfo->Checksum = READ_BIT(dmarxdesc->DESC1, (ETH_DMARXNDESCWBF_IPCE | ETH_DMARXNDESCWBF_IPCB | ETH_DMARXNDESCWBF_IPHE)); + /* Set Seconds update */ + heth->Instance->MACSTSUR = timeoffset->Seconds; + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = timeoffset->NanoSeconds; } - if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_RS2V) != 0U) - { - RxPacketInfo->MacFilterStatus = READ_BIT(dmarxdesc->DESC2, (ETH_DMARXNDESCWBF_HF | ETH_DMARXNDESCWBF_DAF | ETH_DMARXNDESCWBF_SAF | ETH_DMARXNDESCWBF_VF)); - RxPacketInfo->L3FilterStatus = READ_BIT(dmarxdesc->DESC2, (ETH_DMARXNDESCWBF_L3FM | ETH_DMARXNDESCWBF_L3L4FM)); - RxPacketInfo->L4FilterStatus = READ_BIT(dmarxdesc->DESC2, (ETH_DMARXNDESCWBF_L4FM | ETH_DMARXNDESCWBF_L3L4FM)); - } + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; } - - /* Get the segment count */ - WRITE_REG(RxPacketInfo->SegmentCnt, dmarxdesclist->AppDescNbr); - - 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. -* It should be called after processing the received Packet. -* @param heth: pointer to a ETH_HandleTypeDef structure that contains -* the configuration information for ETHERNET module -* @retval HAL status. -*/ -HAL_StatusTypeDef HAL_ETH_BuildRxDescriptors(ETH_HandleTypeDef *heth) + * @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_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList; - uint32_t descindex = dmarxdesclist->FirstAppDesc; - __IO ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descindex]; - uint32_t totalappdescnbr = dmarxdesclist->AppDescNbr; - uint32_t descscan; + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; - if(dmarxdesclist->AppDescNbr == 0U) + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) { - /* No Rx descriptors to build */ - return HAL_ERROR; - } + /* Enable Time Stamp transmission */ + SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE); - if(dmarxdesclist->AppContextDesc != 0U) + /* Return function status */ + return HAL_OK; + } + else { - /* A context descriptor is available */ - totalappdescnbr += 1U; + /* Return function status */ + return HAL_ERROR; } +} - for(descscan =0; descscan < totalappdescnbr; descscan++) +/** + * @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) { - WRITE_REG(dmarxdesc->DESC0, dmarxdesc->BackupAddr0); - WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF1V); + /* Get timestamp low */ + timestamp->TimeStampLow = dmatxdesc->DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = dmatxdesc->DESC1; - if (READ_REG(dmarxdesc->BackupAddr1) != 0U) - { - WRITE_REG(dmarxdesc->DESC2, dmarxdesc->BackupAddr1); - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF2V); - } + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN); +/** + * @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; - if(dmarxdesclist->ItMode != 0U) - { - SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC); - } + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} - if(descscan < (dmarxdesclist->AppDescNbr - 1U)) - { - /* Increment rx descriptor index */ - INCR_RX_DESC_INDEX(descindex, 1U); - /* Get descriptor address */ - dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descindex]; - } +/** + * @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; - /* Set the Tail pointer address to the last rx descriptor hold by the app */ - WRITE_REG(heth->Instance->DMACRDTPR, (uint32_t)dmarxdesc); + return HAL_OK; +} - /* reset the Application desc number */ - WRITE_REG(dmarxdesclist->AppDescNbr, 0); +/** + * @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. @@ -1472,11 +1843,14 @@ HAL_StatusTypeDef HAL_ETH_BuildRxDescriptors(ETH_HandleTypeDef *heth) */ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) { + uint32_t macirqenable; /* Packet received */ if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_RI)) { - if(__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_RIE)) + if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_RIE)) { + /* 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*/ @@ -1485,39 +1859,36 @@ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) /* Receive complete callback */ HAL_ETH_RxCpltCallback(heth); #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - /* Clear the Eth DMA Rx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS); } } /* Packet transmitted */ if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_TI)) { - if(__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_TIE)) + if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_TIE)) { + /* 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); + /*Call registered Transmit complete callback*/ + heth->TxCpltCallback(heth); #else /* Transfer complete callback */ HAL_ETH_TxCpltCallback(heth); #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ - - /* Clear the Eth DMA Tx IT pending bits */ - __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS); } } /* ETH DMA Error */ - if(__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_AIS)) + if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_AIS)) { - if(__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_AIE)) + if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_AIE)) { heth->ErrorCode |= HAL_ETH_ERROR_DMA; - /* if fatal bus error occured */ + /* if fatal bus error occurred */ if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_FBE)) { /* Get DMA error code */ @@ -1532,45 +1903,49 @@ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) 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)); + 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)); + ETH_DMACSR_RBU | ETH_DMACSR_AIS)); } #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) - /* Call registered DMA Error callback*/ - heth->DMAErrorCallback(heth); + /* Call registered Error callback*/ + heth->ErrorCallback(heth); #else /* Ethernet DMA Error callback */ - HAL_ETH_DMAErrorCallback(heth); + HAL_ETH_ErrorCallback(heth); #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ } } /* ETH MAC Error IT */ - if(__HAL_ETH_MAC_GET_IT(heth, (ETH_MACIER_RXSTSIE | ETH_MACIER_TXSTSIE))) + macirqenable = heth->Instance->MACIER; + if (((macirqenable & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \ + ((macirqenable & 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 MAC Error callback*/ - heth->DMAErrorCallback(heth); + /* Call registered Error callback*/ + heth->ErrorCallback(heth); #else - /* Ethernet MAC Error callback */ - HAL_ETH_MACErrorCallback(heth); + /* Ethernet Error callback */ + HAL_ETH_ErrorCallback(heth); #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ heth->MACErrorCode = (uint32_t)(0x0U); } /* ETH PMT IT */ - if(__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_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->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD)); @@ -1587,7 +1962,7 @@ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) } /* ETH EEE IT */ - if(__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_LPI_IT)) + if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_LPI_IT)) { /* Get MAC LPI interrupt source and clear the status register pending bit */ heth->MACLPIEvent = READ_BIT(heth->Instance->MACPCSR, 0x0000000FU); @@ -1607,7 +1982,7 @@ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) if (HAL_GetCurrentCPUID() == CM7_CPUID) { /* check ETH WAKEUP exti flag */ - if(__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET) + 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); @@ -1617,13 +1992,13 @@ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) #else /* ETH WAKEUP callback */ HAL_ETH_WakeUpCallback(heth); -#endif +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ } } else { /* check ETH WAKEUP exti flag */ - if(__HAL_ETH_WAKEUP_EXTID2_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET) + if (__HAL_ETH_WAKEUP_EXTID2_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET) { /* Clear ETH WAKEUP Exti pending bit */ __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); @@ -1633,24 +2008,24 @@ void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) #else /* ETH WAKEUP callback */ HAL_ETH_WakeUpCallback(heth); -#endif +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ } } -#else +#else /* USE_HAL_ETH_REGISTER_CALLBACKS */ /* check ETH WAKEUP exti flag */ - if(__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET) + 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); + /* Call registered WakeUp callback*/ + heth->WakeUpCallback(heth); #else - /* ETH WAKEUP callback */ - HAL_ETH_WakeUpCallback(heth); -#endif + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ } -#endif +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ } /** @@ -1684,32 +2059,17 @@ __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) } /** - * @brief Ethernet DMA 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_DMAErrorCallback(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_DMAErrorCallback could be implemented in the user file - */ -} - -/** -* @brief Ethernet MAC transfer error callbacks + * @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_MACErrorCallback(ETH_HandleTypeDef *heth) +__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_MACErrorCallback could be implemented in the user file + the HAL_ETH_ErrorCallback could be implemented in the user file */ } @@ -1767,12 +2127,14 @@ __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth) * @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) +HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t *pRegValue) { - uint32_t tmpreg, tickstart; + uint32_t tickstart; + uint32_t tmpreg; /* Check for the Busy flag */ - if(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != 0U) + if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) { return HAL_ERROR; } @@ -1786,7 +2148,7 @@ HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYA - Set the read mode - Set the MII Busy bit */ - MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr <<21)); + 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); @@ -1797,9 +2159,9 @@ HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYA tickstart = HAL_GetTick(); /* Wait for the Busy flag */ - while(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) + while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) { - if(((HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT)) + if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) { return HAL_ERROR; } @@ -1821,12 +2183,14 @@ HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYA * @param RegValue: the value to write * @retval HAL status */ -HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, uint32_t RegValue) +HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t RegValue) { - uint32_t tmpreg, tickstart; + uint32_t tickstart; + uint32_t tmpreg; /* Check for the Busy flag */ - if(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != 0U) + if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) { return HAL_ERROR; } @@ -1840,7 +2204,7 @@ HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHY - Set the write mode - Set the MII Busy bit */ - MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr <<21)); + 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); @@ -1855,9 +2219,9 @@ HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHY tickstart = HAL_GetTick(); /* Wait for the Busy flag */ - while(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) + while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) { - if(((HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT)) + if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) { return HAL_ERROR; } @@ -1902,22 +2266,25 @@ HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTyp /* 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->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->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->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->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->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); @@ -1925,8 +2292,10 @@ HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTyp 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->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; @@ -1940,14 +2309,17 @@ HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTyp 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->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->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; + macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, + ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE; return HAL_OK; } @@ -1969,11 +2341,11 @@ HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTyp 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->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->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->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; @@ -1982,7 +2354,6 @@ HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTyp 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; } @@ -1996,12 +2367,12 @@ HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTyp */ HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) { - if(macconf == NULL) + if (macconf == NULL) { return HAL_ERROR; } - if(heth->RxState == HAL_ETH_STATE_READY) + if (heth->gState == HAL_ETH_STATE_READY) { ETH_SetMACConfig(heth, macconf); @@ -2023,12 +2394,12 @@ HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTy */ HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) { - if(dmaconf == NULL) + if (dmaconf == NULL) { return HAL_ERROR; } - if(heth->RxState == HAL_ETH_STATE_READY) + if (heth->gState == HAL_ETH_STATE_READY) { ETH_SetDMAConfig(heth, dmaconf); @@ -2048,34 +2419,35 @@ HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTy */ void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth) { - uint32_t tmpreg, hclk; + uint32_t hclk; + uint32_t tmpreg; /* Get the ETHERNET MACMDIOAR value */ tmpreg = (heth->Instance)->MACMDIOAR; - /* Clear CSR Clock Range bits */ + /* Clear CSR Clock Range bits */ tmpreg &= ~ETH_MACMDIOAR_CR; - /* Get hclk frequency value */ + /* Get hclk frequency value */ hclk = HAL_RCC_GetHCLKFreq(); - /* Set CR bits depending on hclk value */ - if((hclk >= 20000000U)&&(hclk < 35000000U)) + /* Set CR bits depending on hclk value */ + if ((hclk >= 20000000U) && (hclk < 35000000U)) { /* CSR Clock Range between 20-35 MHz */ tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16; } - else if((hclk >= 35000000U)&&(hclk < 60000000U)) + else if ((hclk >= 35000000U) && (hclk < 60000000U)) { /* CSR Clock Range between 35-60 MHz */ tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26; } - else if((hclk >= 60000000U)&&(hclk < 100000000U)) + else if ((hclk >= 60000000U) && (hclk < 100000000U)) { /* CSR Clock Range between 60-100 MHz */ tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42; } - else if((hclk >= 100000000U)&&(hclk < 150000000U)) + else if ((hclk >= 100000000U) && (hclk < 150000000U)) { /* CSR Clock Range between 100-150 MHz */ tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62; @@ -2102,22 +2474,22 @@ HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFil { uint32_t filterconfig; - if(pFilterConfig == NULL) + 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); + ((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); @@ -2134,7 +2506,7 @@ HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFil */ HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig) { - if(pFilterConfig == NULL) + if (pFilterConfig == NULL) { return HAL_ERROR; } @@ -2142,13 +2514,16 @@ HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFil 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->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->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->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; @@ -2168,17 +2543,18 @@ HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFil */ HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef *heth, uint32_t AddrNbr, uint8_t *pMACAddr) { - uint32_t macaddrhr, macaddrlr; + uint32_t macaddrlr; + uint32_t macaddrhr; - if(pMACAddr == NULL) + if (pMACAddr == NULL) { return HAL_ERROR; } /* Get mac addr high reg offset */ - macaddrhr = ((uint32_t)&(heth->Instance->MACA0HR) + AddrNbr); + macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr); /* Get mac addr low reg offset */ - macaddrlr = ((uint32_t)&(heth->Instance->MACA0LR) + AddrNbr); + 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]); @@ -2186,7 +2562,7 @@ HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef *heth, uint32_ (*(__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 */ + /* Enable address and set source address bit */ (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE); return HAL_OK; @@ -2202,7 +2578,7 @@ HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef *heth, uint32_ */ HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable) { - if(pHashTable == NULL) + if (pHashTable == NULL) { return HAL_ERROR; } @@ -2224,14 +2600,14 @@ HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashT */ void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier) { - if(ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) + if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) { - MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL , VLANIdentifier); + 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); + MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier); SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV); } } @@ -2241,7 +2617,7 @@ void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBit * @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 configration + * that contains the Power Down configuration * @retval None. */ void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, ETH_PowerDownConfigTypeDef *pPowerDownConfig) @@ -2250,9 +2626,9 @@ void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, ETH_PowerDownConfigType powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) | ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) | - ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) | - ((uint32_t)pPowerDownConfig->WakeUpForward << 10) | - ETH_MACPCSR_PWRDWN); + ((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); @@ -2269,9 +2645,10 @@ void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, ETH_PowerDownConfigType 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); + 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) != 0U) + if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET) { /* Exit power down mode */ CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN); @@ -2293,7 +2670,7 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi { uint32_t regindex; - if(pFilter == NULL) + if (pFilter == NULL) { return HAL_ERROR; } @@ -2302,7 +2679,7 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST); /* Wake up packet filter config */ - for(regindex = 0; regindex < Count; regindex++) + for (regindex = 0; regindex < Count; regindex++) { /* Write filter regs */ WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]); @@ -2341,13 +2718,7 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi */ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth) { - HAL_ETH_StateTypeDef ret; - HAL_ETH_StateTypeDef gstate = heth->gState; - HAL_ETH_StateTypeDef rxstate =heth->RxState; - - ret = gstate; - ret |= rxstate; - return ret; + return heth->gState; } /** @@ -2402,42 +2773,47 @@ uint32_t HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef *heth) * @} */ +/** @addtogroup ETH_Private_Functions ETH Private Functions + * @{ + */ + + static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, 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); + 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); + 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); @@ -2452,8 +2828,8 @@ static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *mac /*------------------------ MACTFCR Configuration --------------------*/ macregval = (((uint32_t)macconf->TransmitFlowControl << 1) | macconf->PauseLowThreshold | - ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U)<< 7) | - (macconf->PauseTime << 16)); + ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) | + (macconf->PauseTime << 16)); /* Write to MACTFCR */ MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval); @@ -2472,8 +2848,8 @@ static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *mac /*------------------------ MTLRQOMR Configuration --------------------*/ macregval = (macconf->ReceiveQueueMode | ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) | - ((uint32_t)macconf->ForwardRxErrorPacket << 4) | - ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3)); + ((uint32_t)macconf->ForwardRxErrorPacket << 4) | + ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3)); /* Write to MTLRQOMR */ MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval); @@ -2489,7 +2865,7 @@ static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dma /*------------------------ DMASBMR Configuration --------------------*/ dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) | dmaconf->BurstMode | - ((uint32_t)dmaconf->RebuildINCRxBurst << 15)); + ((uint32_t)dmaconf->RebuildINCRxBurst << 15)); MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval); @@ -2501,8 +2877,8 @@ static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dma /*------------------------ DMACTCR Configuration --------------------*/ dmaregval = (dmaconf->TxDMABurstLength | - ((uint32_t)dmaconf->SecondPacketOperate << 4)| - ((uint32_t)dmaconf->TCPSegmentation << 12)); + ((uint32_t)dmaconf->SecondPacketOperate << 4) | + ((uint32_t)dmaconf->TCPSegmentation << 12)); MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval); @@ -2581,62 +2957,12 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth) dmaDefaultConf.SecondPacketOperate = DISABLE; dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; dmaDefaultConf.TCPSegmentation = DISABLE; - dmaDefaultConf.MaximumSegmentSize = 536; + dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT; /* DMA default configuration */ ETH_SetDMAConfig(heth, &dmaDefaultConf); } -/** - * @brief Configures the Clock range of SMI interface. - * 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_MAC_MDIO_ClkConfig(ETH_HandleTypeDef *heth) -{ - uint32_t tmpreg, hclk; - - /* 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 >= 20000000U)&&(hclk < 35000000U)) - { - /* CSR Clock Range between 20-35 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16; - } - else if((hclk >= 35000000U)&&(hclk < 60000000U)) - { - /* CSR Clock Range between 35-60 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26; - } - else if((hclk >= 60000000U)&&(hclk < 100000000U)) - { - /* CSR Clock Range between 60-100 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42; - } - else if((hclk >= 100000000U)&&(hclk < 150000000U)) - { - /* CSR Clock Range between 100-150 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62; - } - else /* (hclk >= 150000000)&&(hclk <= 200000000) */ - { - /* CSR Clock Range between 150-200 MHz */ - tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102; - } - - /* Configure the CSR Clock Range */ - (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg; -} /** * @brief Initializes the DMA Tx descriptors. @@ -2652,7 +2978,7 @@ static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) uint32_t i; /* Fill each DMATxDesc descriptor with the right values */ - for(i=0; i < (uint32_t)ETH_TX_DESC_CNT; i++) + for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++) { dmatxdesc = heth->Init.TxDesc + i; @@ -2662,12 +2988,13 @@ static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) WRITE_REG(dmatxdesc->DESC3, 0x0); 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 -1)); + 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); @@ -2690,7 +3017,7 @@ static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) ETH_DMADescTypeDef *dmarxdesc; uint32_t i; - for(i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) + for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) { dmarxdesc = heth->Init.RxDesc + i; @@ -2701,24 +3028,26 @@ static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) WRITE_REG(dmarxdesc->BackupAddr0, 0x0); WRITE_REG(dmarxdesc->BackupAddr1, 0x0); - /* Set Rx descritors adresses */ + + /* Set Rx descritors addresses */ WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc); + } - WRITE_REG(heth->RxDescList.CurRxDesc, 0); - WRITE_REG(heth->RxDescList.FirstAppDesc, 0); - WRITE_REG(heth->RxDescList.AppDescNbr, 0); + WRITE_REG(heth->RxDescList.RxDescIdx, 0); + WRITE_REG(heth->RxDescList.RxDescCnt, 0); + WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0); + WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0); WRITE_REG(heth->RxDescList.ItMode, 0); - WRITE_REG(heth->RxDescList.AppContextDesc, 0); /* Set Receive Descriptor Ring Length */ - WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1))); + 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 - 1))*sizeof(ETH_DMADescTypeDef))))); + WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U)))); #endif /* __rtems__ */ } @@ -2736,13 +3065,16 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; uint32_t descidx = dmatxdesclist->CurTxDesc; uint32_t firstdescidx = dmatxdesclist->CurTxDesc; - uint32_t descnbr = 0, idx; + 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; /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ - if(READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) + if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) + || (dmatxdesclist->PacketAddress[descidx] != NULL)) { return HAL_ETH_ERROR_BUSY; } @@ -2751,7 +3083,7 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket /***************** Context descriptor configuration (Optional) **********/ /***************************************************************************/ /* If VLAN tag is enabled for this packet */ - if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U) + 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); @@ -2761,7 +3093,7 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI); /* if inner VLAN is enabled */ - if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != 0U) + 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)); @@ -2778,8 +3110,8 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket } } - /* if tcp segementation is enabled for this packet */ - if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U) + /* 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); @@ -2787,10 +3119,13 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV); } - if((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U)|| (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U)) + 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 */ @@ -2801,9 +3136,11 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket 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) + 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); @@ -2822,7 +3159,7 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket /* Set header or buffer 1 Length */ MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); - if(txbuffer->next != NULL) + if (txbuffer->next != NULL) { txbuffer = txbuffer->next; /* Set buffer 2 address */ @@ -2837,7 +3174,7 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); } - if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U) + 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)); @@ -2850,18 +3187,18 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket { MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); - if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U) + 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) != 0U) + 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) != 0U) + 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); @@ -2871,16 +3208,18 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket 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) != 0U) + 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 splitted into more than one descriptors > 1 */ + /* only if the packet is split into more than one descriptors > 1 */ while (txbuffer->next != NULL) { /* Clear the LD bit of previous descriptor */ @@ -2894,14 +3233,18 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket 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) + 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 ++) + 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 */ @@ -2916,7 +3259,7 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket descnbr += 1U; /* Get the next Tx buffer in the list */ - txbuffer = (struct __ETH_BufferTypeDef *)txbuffer->next; + txbuffer = txbuffer->next; /* Set header or buffer 1 address */ WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); @@ -2926,7 +3269,7 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket if (txbuffer->next != NULL) { /* Get the next Tx buffer in the list */ - txbuffer = (struct __ETH_BufferTypeDef *)txbuffer->next; + txbuffer = txbuffer->next; /* Set buffer 2 address */ WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); /* Set buffer 2 Length */ @@ -2939,7 +3282,7 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); } - if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U) + 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); @@ -2951,35 +3294,50 @@ static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacket /* Set the packet length */ MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); - if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U) + 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)) + if (ItMode != ((uint32_t)RESET)) { - /* Set Interrupt on completition bit */ + /* Set Interrupt on completion bit */ SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); } else { - /* Clear Interrupt on completition bit */ + /* 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; + /* disable the interrupt */ + __disable_irq(); + + dmatxdesclist->BuffersInUse += bd_count + 1U; + + /* Enable interrupts back */ + __enable_irq(); + + /* Return function status */ return HAL_ETH_ERROR_NONE; } @@ -2990,14 +3348,22 @@ 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->DMAErrorCallback = HAL_ETH_DMAErrorCallback; /* Legacy weak DMAErrorCallback */ - heth->MACErrorCallback = HAL_ETH_MACErrorCallback; /* Legacy weak MACErrorCallback */ + 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 */ +/** + * @} + */ /** * @} @@ -3011,4 +3377,3 @@ static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth) * @} */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |