Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_eth.c
blob033739e883f57886da91283ecaf6f57aa4958815
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_eth.c
4 * @author MCD Application Team
5 * @brief ETH HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Ethernet (ETH) peripheral:
8 * + Initialization and deinitialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State and Errors functions
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 The ETH HAL driver can be used as follows:
20 (#)Declare a ETH_HandleTypeDef handle structure, for example:
21 ETH_HandleTypeDef heth;
23 (#)Fill parameters of Init structure in heth handle
25 (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
27 (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
28 (##) Enable the Ethernet interface clock using
29 (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE()
30 (+++) __HAL_RCC_ETH1TX_CLK_ENABLE()
31 (+++) __HAL_RCC_ETH1RX_CLK_ENABLE()
33 (##) Initialize the related GPIO clocks
34 (##) Configure Ethernet pinout
35 (##) Configure Ethernet NVIC interrupt (in Interrupt mode)
37 (#) Ethernet data reception is asynchronous, so call the following API
38 to start the listening mode:
39 (##) HAL_ETH_Start():
40 This API starts the MAC and DMA transmission and reception process,
41 without enabling end of transfer interrupts, in this mode user
42 has to poll for data availability by calling HAL_ETH_IsRxDataAvailable()
43 (##) HAL_ETH_Start_IT():
44 This API starts the MAC and DMA transmission and reception process,
45 end of transfer interrupts are enabled in this mode,
46 HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received
48 (#) When data is received (HAL_ETH_IsRxDataAvailable() returns 1 or Rx interrupt
49 occurred), user can call the following APIs to get received data:
50 (##) HAL_ETH_GetRxDataBuffer(): Get buffer address of received frame
51 (##) HAL_ETH_GetRxDataLength(): Get received frame length
52 (##) HAL_ETH_GetRxDataInfo(): Get received frame additional info,
53 please refer to ETH_RxPacketInfo typedef structure
55 (#) For transmission path, two APIs are available:
56 (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode
57 (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode,
58 HAL_ETH_TxCpltCallback() will be executed when end of transfer occur
60 (#) Communication with an external PHY device:
61 (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY
62 (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register
64 (#) Configure the Ethernet MAC after ETH peripheral initialization
65 (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef
66 (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef
68 (#) Configure the Ethernet DMA after ETH peripheral initialization
69 (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef
70 (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef
72 -@- The PTP protocol offload APIs are not supported in this driver.
74 *** Callback registration ***
75 =============================================
77 The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
78 allows the user to configure dynamically the driver callbacks.
79 Use Function @ref HAL_ETH_RegisterCallback() to register an interrupt callback.
81 Function @ref HAL_ETH_RegisterCallback() allows to register following callbacks:
82 (+) TxCpltCallback : Tx Complete Callback.
83 (+) RxCpltCallback : Rx Complete Callback.
84 (+) DMAErrorCallback : DMA Error Callback.
85 (+) MACErrorCallback : MAC Error Callback.
86 (+) PMTCallback : Power Management Callback
87 (+) EEECallback : EEE Callback.
88 (+) WakeUpCallback : Wake UP Callback
89 (+) MspInitCallback : MspInit Callback.
90 (+) MspDeInitCallback: MspDeInit Callback.
92 This function takes as parameters the HAL peripheral handle, the Callback ID
93 and a pointer to the user callback function.
95 Use function @ref HAL_ETH_UnRegisterCallback() to reset a callback to the default
96 weak function.
97 @ref HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
98 and the Callback ID.
99 This function allows to reset following callbacks:
100 (+) TxCpltCallback : Tx Complete Callback.
101 (+) RxCpltCallback : Rx Complete Callback.
102 (+) DMAErrorCallback : DMA Error Callback.
103 (+) MACErrorCallback : MAC Error Callback.
104 (+) PMTCallback : Power Management Callback
105 (+) EEECallback : EEE Callback.
106 (+) WakeUpCallback : Wake UP Callback
107 (+) MspInitCallback : MspInit Callback.
108 (+) MspDeInitCallback: MspDeInit Callback.
110 By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
111 all callbacks are set to the corresponding weak functions:
112 examples @ref HAL_ETH_TxCpltCallback(), @ref HAL_ETH_RxCpltCallback().
113 Exception done for MspInit and MspDeInit functions that are
114 reset to the legacy weak function in the HAL_ETH_Init/ @ref HAL_ETH_DeInit only when
115 these callbacks are null (not registered beforehand).
116 if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ @ref HAL_ETH_DeInit
117 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
119 Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
120 Exception done MspInit/MspDeInit that can be registered/unregistered
121 in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
122 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
123 In that case first register the MspInit/MspDeInit user callbacks
124 using @ref HAL_ETH_RegisterCallback() before calling @ref HAL_ETH_DeInit
125 or HAL_ETH_Init function.
127 When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
128 not defined, the callback registration feature is not available and all callbacks
129 are set to the corresponding weak functions.
131 @endverbatim
132 ******************************************************************************
133 * @attention
135 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
136 * All rights reserved.</center></h2>
138 * This software component is licensed by ST under BSD 3-Clause license,
139 * the "License"; You may not use this file except in compliance with the
140 * License. You may obtain a copy of the License at:
141 * opensource.org/licenses/BSD-3-Clause
143 ******************************************************************************
146 /* Includes ------------------------------------------------------------------*/
147 #include "stm32h7xx_hal.h"
149 /** @addtogroup STM32H7xx_HAL_Driver
150 * @{
152 #ifdef HAL_ETH_MODULE_ENABLED
154 #if defined(ETH)
156 /** @defgroup ETH ETH
157 * @brief ETH HAL module driver
158 * @{
161 /* Private typedef -----------------------------------------------------------*/
162 /* Private define ------------------------------------------------------------*/
163 /** @addtogroup ETH_Private_Constants ETH Private Constants
164 * @{
166 #define ETH_MACCR_MASK ((uint32_t)0xFFFB7F7CU)
167 #define ETH_MACECR_MASK ((uint32_t)0x3F077FFFU)
168 #define ETH_MACPFR_MASK ((uint32_t)0x800007FFU)
169 #define ETH_MACWTR_MASK ((uint32_t)0x0000010FU)
170 #define ETH_MACTFCR_MASK ((uint32_t)0xFFFF00F2U)
171 #define ETH_MACRFCR_MASK ((uint32_t)0x00000003U)
172 #define ETH_MTLTQOMR_MASK ((uint32_t)0x00000072U)
173 #define ETH_MTLRQOMR_MASK ((uint32_t)0x0000007BU)
175 #define ETH_DMAMR_MASK ((uint32_t)0x00007802U)
176 #define ETH_DMASBMR_MASK ((uint32_t)0x0000D001U)
177 #define ETH_DMACCR_MASK ((uint32_t)0x00013FFFU)
178 #define ETH_DMACTCR_MASK ((uint32_t)0x003F1010U)
179 #define ETH_DMACRCR_MASK ((uint32_t)0x803F0000U)
180 #define ETH_MACPCSR_MASK (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \
181 ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \
182 ETH_MACPCSR_RWKPFE)
184 /* Timeout values */
185 #define ETH_SWRESET_TIMEOUT ((uint32_t)500U)
186 #define ETH_MDIO_BUS_TIMEOUT ((uint32_t)1000U)
188 #define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \
189 ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\
190 ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE))
192 #define ETH_MAC_US_TICK ((uint32_t)1000000U)
194 * @}
197 /* Private macros ------------------------------------------------------------*/
198 /** @defgroup ETH_Private_Macros ETH Private Macros
199 * @{
201 /* Helper macros for TX descriptor handling */
202 #define INCR_TX_DESC_INDEX(inx, offset) do {\
203 (inx) += (offset);\
204 if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
205 (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
206 } while (0)
208 /* Helper macros for RX descriptor handling */
209 #define INCR_RX_DESC_INDEX(inx, offset) do {\
210 (inx) += (offset);\
211 if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
212 (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
213 } while (0)
215 * @}
217 /* Private function prototypes -----------------------------------------------*/
218 /** @defgroup ETH_Private_Functions ETH Private Functions
219 * @{
221 static void ETH_MAC_MDIO_ClkConfig(ETH_HandleTypeDef *heth);
222 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf);
223 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf);
224 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
225 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
226 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
227 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode);
229 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
230 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
231 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
233 * @}
236 /* Exported functions ---------------------------------------------------------*/
237 /** @defgroup ETH_Exported_Functions ETH Exported Functions
238 * @{
241 /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions
242 * @brief Initialization and Configuration functions
244 @verbatim
245 ===============================================================================
246 ##### Initialization and Configuration functions #####
247 ===============================================================================
248 [..] This subsection provides a set of functions allowing to initialize and
249 deinitialize the ETH peripheral:
251 (+) User must Implement HAL_ETH_MspInit() function in which he configures
252 all related peripherals resources (CLOCK, GPIO and NVIC ).
254 (+) Call the function HAL_ETH_Init() to configure the selected device with
255 the selected configuration:
256 (++) MAC address
257 (++) Media interface (MII or RMII)
258 (++) Rx DMA Descriptors Tab
259 (++) Tx DMA Descriptors Tab
260 (++) Length of Rx Buffers
262 (+) Call the function HAL_ETH_DescAssignMemory() to assign data buffers
263 for each Rx DMA Descriptor
265 (+) Call the function HAL_ETH_DeInit() to restore the default configuration
266 of the selected ETH peripheral.
268 @endverbatim
269 * @{
273 * @brief Initialize the Ethernet peripheral registers.
274 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
275 * the configuration information for ETHERNET module
276 * @retval HAL status
278 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
280 uint32_t tickstart;
282 if(heth == NULL)
284 return HAL_ERROR;
287 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
289 if(heth->gState == HAL_ETH_STATE_RESET)
291 /* Allocate lock resource and initialize it */
292 heth->Lock = HAL_UNLOCKED;
294 ETH_InitCallbacksToDefault(heth);
296 if(heth->MspInitCallback == NULL)
298 heth->MspInitCallback = HAL_ETH_MspInit;
301 /* Init the low level hardware */
302 heth->MspInitCallback(heth);
305 #else
307 /* Check the ETH peripheral state */
308 if(heth->gState == HAL_ETH_STATE_RESET)
310 /* Init the low level hardware : GPIO, CLOCK, NVIC. */
311 HAL_ETH_MspInit(heth);
313 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
315 heth->gState = HAL_ETH_STATE_BUSY;
317 __HAL_RCC_SYSCFG_CLK_ENABLE();
319 if(heth->Init.MediaInterface == HAL_ETH_MII_MODE)
321 HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII);
323 else
325 HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII);
328 /* Ethernet Software reset */
329 /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
330 /* After reset all the registers holds their respective reset values */
331 SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);
333 /* Get tick */
334 tickstart = HAL_GetTick();
336 /* Wait for software reset */
337 while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
339 if(((HAL_GetTick() - tickstart ) > ETH_SWRESET_TIMEOUT))
341 /* Set Error Code */
342 heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
343 /* Set State as Error */
344 heth->gState = HAL_ETH_STATE_ERROR;
345 /* Return Error */
346 return HAL_ERROR;
350 /*------------------ MDIO CSR Clock Range Configuration --------------------*/
351 ETH_MAC_MDIO_ClkConfig(heth);
353 /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/
354 WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U));
356 /*------------------ MAC, MTL and DMA default Configuration ----------------*/
357 ETH_MACDMAConfig(heth);
359 /* SET DSL to 64 bit */
360 MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);
362 /* Set Receive Buffers Length (must be a multiple of 4) */
363 if ((heth->Init.RxBuffLen % 0x4U) != 0x0U)
365 /* Set Error Code */
366 heth->ErrorCode = HAL_ETH_ERROR_PARAM;
367 /* Set State as Error */
368 heth->gState = HAL_ETH_STATE_ERROR;
369 /* Return Error */
370 return HAL_ERROR;
372 else
374 MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1));
377 /*------------------ DMA Tx Descriptors Configuration ----------------------*/
378 ETH_DMATxDescListInit(heth);
380 /*------------------ DMA Rx Descriptors Configuration ----------------------*/
381 ETH_DMARxDescListInit(heth);
383 /*--------------------- ETHERNET MAC Address Configuration ------------------*/
384 /* Set MAC addr bits 32 to 47 */
385 heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]);
386 /* Set MAC addr bits 0 to 31 */
387 heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) |
388 ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]);
390 heth->ErrorCode = HAL_ETH_ERROR_NONE;
391 heth->gState = HAL_ETH_STATE_READY;
392 heth->RxState = HAL_ETH_STATE_READY;
394 return HAL_OK;
398 * @brief DeInitializes the ETH peripheral.
399 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
400 * the configuration information for ETHERNET module
401 * @retval HAL status
403 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
405 /* Set the ETH peripheral state to BUSY */
406 heth->gState = HAL_ETH_STATE_BUSY;
408 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
410 if(heth->MspDeInitCallback == NULL)
412 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
414 /* DeInit the low level hardware */
415 heth->MspDeInitCallback(heth);
416 #else
418 /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
419 HAL_ETH_MspDeInit(heth);
421 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
423 /* Set ETH HAL state to Disabled */
424 heth->gState= HAL_ETH_STATE_RESET;
426 /* Return function status */
427 return HAL_OK;
431 * @brief Initializes the ETH MSP.
432 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
433 * the configuration information for ETHERNET module
434 * @retval None
436 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
438 /* Prevent unused argument(s) compilation warning */
439 UNUSED(heth);
440 /* NOTE : This function Should not be modified, when the callback is needed,
441 the HAL_ETH_MspInit could be implemented in the user file
446 * @brief DeInitializes ETH MSP.
447 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
448 * the configuration information for ETHERNET module
449 * @retval None
451 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
453 /* Prevent unused argument(s) compilation warning */
454 UNUSED(heth);
455 /* NOTE : This function Should not be modified, when the callback is needed,
456 the HAL_ETH_MspDeInit could be implemented in the user file
460 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
462 * @brief Register a User ETH Callback
463 * To be used instead of the weak predefined callback
464 * @param heth eth handle
465 * @param CallbackID ID of the callback to be registered
466 * This parameter can be one of the following values:
467 * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
468 * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
469 * @arg @ref HAL_ETH_DMA_ERROR_CB_ID DMA Error Callback ID
470 * @arg @ref HAL_ETH_MAC_ERROR_CB_ID MAC Error Callback ID
471 * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID
472 * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID
473 * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID
474 * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID
475 * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID
476 * @param pCallback pointer to the Callback function
477 * @retval status
479 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, pETH_CallbackTypeDef pCallback)
481 HAL_StatusTypeDef status = HAL_OK;
483 if(pCallback == NULL)
485 /* Update the error code */
486 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
488 return HAL_ERROR;
490 /* Process locked */
491 __HAL_LOCK(heth);
493 if(heth->gState == HAL_ETH_STATE_READY)
495 switch (CallbackID)
497 case HAL_ETH_TX_COMPLETE_CB_ID :
498 heth->TxCpltCallback = pCallback;
499 break;
501 case HAL_ETH_RX_COMPLETE_CB_ID :
502 heth->RxCpltCallback = pCallback;
503 break;
505 case HAL_ETH_DMA_ERROR_CB_ID :
506 heth->DMAErrorCallback = pCallback;
507 break;
509 case HAL_ETH_MAC_ERROR_CB_ID :
510 heth->MACErrorCallback = pCallback;
511 break;
513 case HAL_ETH_PMT_CB_ID :
514 heth->PMTCallback = pCallback;
515 break;
517 case HAL_ETH_EEE_CB_ID :
518 heth->EEECallback = pCallback;
519 break;
521 case HAL_ETH_WAKEUP_CB_ID :
522 heth->WakeUpCallback = pCallback;
523 break;
525 case HAL_ETH_MSPINIT_CB_ID :
526 heth->MspInitCallback = pCallback;
527 break;
529 case HAL_ETH_MSPDEINIT_CB_ID :
530 heth->MspDeInitCallback = pCallback;
531 break;
533 default :
534 /* Update the error code */
535 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
536 /* Return error status */
537 status = HAL_ERROR;
538 break;
541 else if(heth->gState == HAL_ETH_STATE_RESET)
543 switch (CallbackID)
545 case HAL_ETH_MSPINIT_CB_ID :
546 heth->MspInitCallback = pCallback;
547 break;
549 case HAL_ETH_MSPDEINIT_CB_ID :
550 heth->MspDeInitCallback = pCallback;
551 break;
553 default :
554 /* Update the error code */
555 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
556 /* Return error status */
557 status = HAL_ERROR;
558 break;
561 else
563 /* Update the error code */
564 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
565 /* Return error status */
566 status = HAL_ERROR;
569 /* Release Lock */
570 __HAL_UNLOCK(heth);
572 return status;
576 * @brief Unregister an ETH Callback
577 * ETH callabck is redirected to the weak predefined callback
578 * @param heth eth handle
579 * @param CallbackID ID of the callback to be unregistered
580 * This parameter can be one of the following values:
581 * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
582 * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
583 * @arg @ref HAL_ETH_DMA_ERROR_CB_ID DMA Error Callback ID
584 * @arg @ref HAL_ETH_MAC_ERROR_CB_ID MAC Error Callback ID
585 * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID
586 * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID
587 * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID
588 * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID
589 * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID
590 * @retval status
592 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
594 HAL_StatusTypeDef status = HAL_OK;
596 /* Process locked */
597 __HAL_LOCK(heth);
599 if(heth->gState == HAL_ETH_STATE_READY)
601 switch (CallbackID)
603 case HAL_ETH_TX_COMPLETE_CB_ID :
604 heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
605 break;
607 case HAL_ETH_RX_COMPLETE_CB_ID :
608 heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
609 break;
611 case HAL_ETH_DMA_ERROR_CB_ID :
612 heth->DMAErrorCallback = HAL_ETH_DMAErrorCallback;
613 break;
615 case HAL_ETH_MAC_ERROR_CB_ID :
616 heth->MACErrorCallback = HAL_ETH_MACErrorCallback;
617 break;
619 case HAL_ETH_PMT_CB_ID :
620 heth->PMTCallback = HAL_ETH_PMTCallback;
621 break;
623 case HAL_ETH_EEE_CB_ID :
624 heth->EEECallback = HAL_ETH_EEECallback;
625 break;
627 case HAL_ETH_WAKEUP_CB_ID :
628 heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
629 break;
631 case HAL_ETH_MSPINIT_CB_ID :
632 heth->MspInitCallback = HAL_ETH_MspInit;
633 break;
635 case HAL_ETH_MSPDEINIT_CB_ID :
636 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
637 break;
639 default :
640 /* Update the error code */
641 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
642 /* Return error status */
643 status = HAL_ERROR;
644 break;
647 else if(heth->gState == HAL_ETH_STATE_RESET)
649 switch (CallbackID)
651 case HAL_ETH_MSPINIT_CB_ID :
652 heth->MspInitCallback = HAL_ETH_MspInit;
653 break;
655 case HAL_ETH_MSPDEINIT_CB_ID :
656 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
657 break;
659 default :
660 /* Update the error code */
661 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
662 /* Return error status */
663 status = HAL_ERROR;
664 break;
667 else
669 /* Update the error code */
670 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
671 /* Return error status */
672 status = HAL_ERROR;
675 /* Release Lock */
676 __HAL_UNLOCK(heth);
678 return status;
680 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
683 * @brief Assign memory buffers to a DMA Rx descriptor
684 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
685 * the configuration information for ETHERNET module
686 * @param Index : index of the DMA Rx descriptor
687 * this parameter can be a value from 0x0 to (ETH_RX_DESC_CNT -1)
688 * @param pBuffer1: address of buffer 1
689 * @param pBuffer2: address of buffer 2 if available
690 * @retval HAL status
692 HAL_StatusTypeDef HAL_ETH_DescAssignMemory(ETH_HandleTypeDef *heth, uint32_t Index, uint8_t *pBuffer1, uint8_t *pBuffer2)
694 ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[Index];
696 if((pBuffer1 == NULL) || (Index >= (uint32_t)ETH_RX_DESC_CNT))
698 /* Set Error Code */
699 heth->ErrorCode = HAL_ETH_ERROR_PARAM;
700 /* Return Error */
701 return HAL_ERROR;
704 /* write buffer address to RDES0 */
705 WRITE_REG(dmarxdesc->DESC0, (uint32_t)pBuffer1);
706 /* store buffer address */
707 WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)pBuffer1);
708 /* set buffer address valid bit to RDES3 */
709 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF1V);
711 if(pBuffer2 != NULL)
713 /* write buffer 2 address to RDES1 */
714 WRITE_REG(dmarxdesc->DESC2, (uint32_t)pBuffer2);
715 /* store buffer 2 address */
716 WRITE_REG(dmarxdesc->BackupAddr1, (uint32_t)pBuffer2);
717 /* set buffer 2 address valid bit to RDES3 */
718 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF2V);
720 /* set OWN bit to RDES3 */
721 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN);
723 return HAL_OK;
727 * @}
730 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
731 * @brief ETH Transmit and Receive functions
733 @verbatim
734 ==============================================================================
735 ##### IO operation functions #####
736 ==============================================================================
737 [..]
738 This subsection provides a set of functions allowing to manage the ETH
739 data transfer.
741 @endverbatim
742 * @{
746 * @brief Enables Ethernet MAC and DMA reception and transmission
747 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
748 * the configuration information for ETHERNET module
749 * @retval HAL status
751 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
753 if(heth->gState == HAL_ETH_STATE_READY)
755 heth->gState = HAL_ETH_STATE_BUSY;
757 /* Enable the MAC transmission */
758 SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
760 /* Enable the MAC reception */
761 SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
763 /* Set the Flush Transmit FIFO bit */
764 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
766 /* Enable the DMA transmission */
767 SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
769 /* Enable the DMA reception */
770 SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
772 /* Clear Tx and Rx process stopped flags */
773 heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
775 heth->gState = HAL_ETH_STATE_READY;
776 heth->RxState = HAL_ETH_STATE_BUSY_RX;
778 return HAL_OK;
780 else
782 return HAL_ERROR;
787 * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode
788 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
789 * the configuration information for ETHERNET module
790 * @retval HAL status
792 HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
794 uint32_t descindex;
796 ETH_DMADescTypeDef *dmarxdesc;
798 if(heth->gState == HAL_ETH_STATE_READY)
800 heth->gState = HAL_ETH_STATE_BUSY;
802 /* Set IOC bit to all Rx descriptors */
803 for(descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
805 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
806 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
809 /* save IT mode to ETH Handle */
810 heth->RxDescList.ItMode = 1U;
812 /* Enable the MAC transmission */
813 SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
815 /* Enable the MAC reception */
816 SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
818 /* Set the Flush Transmit FIFO bit */
819 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
821 /* Enable the DMA transmission */
822 SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
824 /* Enable the DMA reception */
825 SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
827 /* Clear Tx and Rx process stopped flags */
828 heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
830 /* Enable ETH DMA interrupts:
831 - Tx complete interrupt
832 - Rx complete interrupt
833 - Fatal bus interrupt
835 __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE |
836 ETH_DMACIER_FBEE | ETH_DMACIER_AIE));
838 heth->gState = HAL_ETH_STATE_READY;
839 heth->RxState = HAL_ETH_STATE_BUSY_RX;
841 return HAL_OK;
843 else
845 return HAL_ERROR;
850 * @brief Stop Ethernet MAC and DMA reception/transmission
851 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
852 * the configuration information for ETHERNET module
853 * @retval HAL status
855 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
857 if(heth->gState != HAL_ETH_STATE_RESET)
859 /* Set the ETH peripheral state to BUSY */
860 heth->gState = HAL_ETH_STATE_BUSY;
862 /* Disable the DMA transmission */
863 CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
865 /* Disable the DMA reception */
866 CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
868 /* Disable the MAC reception */
869 CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE);
871 /* Set the Flush Transmit FIFO bit */
872 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
874 /* Disable the MAC transmission */
875 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
877 heth->gState = HAL_ETH_STATE_READY;
878 heth->RxState = HAL_ETH_STATE_READY;
880 /* Return function status */
881 return HAL_OK;
883 else
885 return HAL_ERROR;
890 * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode
891 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
892 * the configuration information for ETHERNET module
893 * @retval HAL status
895 HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
897 ETH_DMADescTypeDef *dmarxdesc;
898 uint32_t descindex;
900 if(heth->gState != HAL_ETH_STATE_RESET)
902 /* Set the ETH peripheral state to BUSY */
903 heth->gState = HAL_ETH_STATE_BUSY;
905 /* Disable intrrupts:
906 - Tx complete interrupt
907 - Rx complete interrupt
908 - Fatal bus interrupt
910 __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE |
911 ETH_DMACIER_FBEE | ETH_DMACIER_AIE));
913 /* Disable the DMA transmission */
914 CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
916 /* Disable the DMA reception */
917 CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
919 /* Disable the MAC reception */
920 CLEAR_BIT( heth->Instance->MACCR, ETH_MACCR_RE);
922 /* Set the Flush Transmit FIFO bit */
923 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
925 /* Disable the MAC transmission */
926 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
928 /* Clear IOC bit to all Rx descriptors */
929 for(descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
931 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
932 CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
935 heth->RxDescList.ItMode = 0U;
937 heth->gState = HAL_ETH_STATE_READY;
938 heth->RxState = HAL_ETH_STATE_READY;
940 /* Return function status */
941 return HAL_OK;
943 else
945 return HAL_ERROR;
950 * @brief Sends an Ethernet Packet in polling mode.
951 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
952 * the configuration information for ETHERNET module
953 * @param pTxConfig: Hold the configuration of packet to be transmitted
954 * @param Timeout: timeout value
955 * @retval HAL status
957 HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout)
959 uint32_t tickstart;
960 const ETH_DMADescTypeDef *dmatxdesc;
962 if(pTxConfig == NULL)
964 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
965 return HAL_ERROR;
968 if(heth->gState == HAL_ETH_STATE_READY)
970 /* Config DMA Tx descriptor by Tx Packet info */
971 if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
973 /* Set the ETH error code */
974 heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
975 return HAL_ERROR;
978 dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc];
980 /* Incr current tx desc index */
981 INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
983 /* Start transmission */
984 /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
985 WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
987 tickstart = HAL_GetTick();
989 /* Wait for data to be transmitted or timeout occured */
990 while((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET)
992 if((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET)
994 heth->ErrorCode |= HAL_ETH_ERROR_DMA;
995 heth->DMAErrorCode = heth->Instance->DMACSR;
996 /* Set ETH HAL State to Ready */
997 heth->gState = HAL_ETH_STATE_ERROR;
998 /* Return function status */
999 return HAL_ERROR;
1002 /* Check for the Timeout */
1003 if(Timeout != HAL_MAX_DELAY)
1005 if(((HAL_GetTick() - tickstart ) > Timeout) || (Timeout == 0U))
1007 heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
1008 heth->gState = HAL_ETH_STATE_ERROR;
1009 return HAL_ERROR;
1014 /* Return function status */
1015 return HAL_OK;
1017 else
1019 return HAL_ERROR;
1024 * @brief Sends an Ethernet Packet in interrupt mode.
1025 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1026 * the configuration information for ETHERNET module
1027 * @param pTxConfig: Hold the configuration of packet to be transmitted
1028 * @retval HAL status
1030 HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig)
1032 if(pTxConfig == NULL)
1034 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1035 return HAL_ERROR;
1038 if(heth->gState == HAL_ETH_STATE_READY)
1040 /* Config DMA Tx descriptor by Tx Packet info */
1041 if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
1043 heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
1044 return HAL_ERROR;
1047 /* Incr current tx desc index */
1048 INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
1050 /* Start transmission */
1051 /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
1052 WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
1054 return HAL_OK;
1057 else
1059 return HAL_ERROR;
1064 * @brief Checks for received Packets.
1065 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1066 * the configuration information for ETHERNET module
1067 * @retval 1: A Packet is received
1068 * 0: no Packet received
1070 uint8_t HAL_ETH_IsRxDataAvailable(ETH_HandleTypeDef *heth)
1072 ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList;
1073 uint32_t descidx = dmarxdesclist->CurRxDesc;
1074 ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1075 uint32_t descscancnt = 0;
1076 uint32_t appdesccnt = 0, firstappdescidx = 0;
1078 if(dmarxdesclist->AppDescNbr != 0U)
1080 /* data already received by not yet processed*/
1081 return 0;
1084 /* Check if descriptor is not owned by DMA */
1085 while((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (descscancnt < (uint32_t)ETH_RX_DESC_CNT))
1087 descscancnt++;
1089 /* Check if last descriptor */
1090 if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET)
1092 /* Increment the number of descriptors to be passed to the application */
1093 appdesccnt += 1U;
1095 if(appdesccnt == 1U)
1097 WRITE_REG(firstappdescidx, descidx);
1100 /* Increment current rx descriptor index */
1101 INCR_RX_DESC_INDEX(descidx, 1U);
1103 /* Check for Context descriptor */
1104 /* Get current descriptor address */
1105 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1107 if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET)
1109 if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET)
1111 /* Increment the number of descriptors to be passed to the application */
1112 dmarxdesclist->AppContextDesc = 1;
1113 /* Increment current rx descriptor index */
1114 INCR_RX_DESC_INDEX(descidx, 1U);
1117 /* Fill information to Rx descriptors list */
1118 dmarxdesclist->CurRxDesc = descidx;
1119 dmarxdesclist->FirstAppDesc = firstappdescidx;
1120 dmarxdesclist->AppDescNbr = appdesccnt;
1122 /* Return function status */
1123 return 1;
1125 /* Check if first descriptor */
1126 else if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET)
1128 WRITE_REG(firstappdescidx, descidx);
1129 /* Increment the number of descriptors to be passed to the application */
1130 appdesccnt = 1U;
1132 /* Increment current rx descriptor index */
1133 INCR_RX_DESC_INDEX(descidx, 1U);
1134 /* Get current descriptor address */
1135 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1137 /* It should be an intermediate descriptor */
1138 else
1140 /* Increment the number of descriptors to be passed to the application */
1141 appdesccnt += 1U;
1143 /* Increment current rx descriptor index */
1144 INCR_RX_DESC_INDEX(descidx, 1U);
1145 /* Get current descriptor address */
1146 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1150 /* Build Descriptors if an incomplete Packet is received */
1151 if(appdesccnt > 0U)
1153 dmarxdesclist->CurRxDesc = descidx;
1154 dmarxdesclist->FirstAppDesc = firstappdescidx;
1155 descidx = firstappdescidx;
1156 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1158 for(descscancnt = 0; descscancnt < appdesccnt; descscancnt++)
1160 WRITE_REG(dmarxdesc->DESC0, dmarxdesc->BackupAddr0);
1161 WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF1V);
1163 if (READ_REG(dmarxdesc->BackupAddr1) != ((uint32_t)RESET))
1165 WRITE_REG(dmarxdesc->DESC2, dmarxdesc->BackupAddr1);
1166 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF2V);
1169 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN);
1171 if(dmarxdesclist->ItMode != ((uint32_t)RESET))
1173 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
1175 if(descscancnt < (appdesccnt - 1U))
1177 /* Increment rx descriptor index */
1178 INCR_RX_DESC_INDEX(descidx, 1U);
1179 /* Get descriptor address */
1180 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1184 /* Set the Tail pointer address to the last rx descriptor hold by the app */
1185 WRITE_REG(heth->Instance->DMACRDTPR, (uint32_t)dmarxdesc);
1188 /* Fill information to Rx descriptors list: No received Packet */
1189 dmarxdesclist->AppDescNbr = 0U;
1191 return 0;
1195 * @brief This function gets the buffer address of last received Packet.
1196 * @note Please insure to allocate the RxBuffer structure before calling this function
1197 * how to use example:
1198 * HAL_ETH_GetRxDataLength(heth, &Length);
1199 * BuffersNbr = (Length / heth->Init.RxBuffLen) + 1;
1200 * RxBuffer = (ETH_BufferTypeDef *)malloc(BuffersNbr * sizeof(ETH_BufferTypeDef));
1201 * HAL_ETH_GetRxDataBuffer(heth, RxBuffer);
1202 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1203 * the configuration information for ETHERNET module
1204 * @param RxBuffer: Pointer to a ETH_BufferTypeDef structure
1205 * @retval HAL status
1207 HAL_StatusTypeDef HAL_ETH_GetRxDataBuffer(ETH_HandleTypeDef *heth, ETH_BufferTypeDef *RxBuffer)
1209 ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList;
1210 uint32_t descidx = dmarxdesclist->FirstAppDesc;
1211 uint32_t index, accumulatedlen = 0, lastdesclen;
1212 __IO const ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1213 ETH_BufferTypeDef *rxbuff = RxBuffer;
1215 if(rxbuff == NULL)
1217 heth->ErrorCode = HAL_ETH_ERROR_PARAM;
1218 return HAL_ERROR;
1221 if(dmarxdesclist->AppDescNbr == 0U)
1223 if(HAL_ETH_IsRxDataAvailable(heth) == 0U)
1225 /* No data to be transferred to the application */
1226 return HAL_ERROR;
1228 else
1230 descidx = dmarxdesclist->FirstAppDesc;
1231 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1235 /* Get intermediate descriptors buffers: in case of the Packet is splitted into multi descriptors */
1236 for(index = 0; index < (dmarxdesclist->AppDescNbr - 1U); index++)
1238 /* Get Address and length of the first buffer address */
1239 rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr0;
1240 rxbuff->len = heth->Init.RxBuffLen;
1242 /* Check if the second buffer address of this descriptor is valid */
1243 if(dmarxdesc->BackupAddr1 != 0U)
1245 /* Point to next buffer */
1246 rxbuff = rxbuff->next;
1247 /* Get Address and length of the second buffer address */
1248 rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr1;
1249 rxbuff->len = heth->Init.RxBuffLen;
1251 else
1253 /* Nothing to do here */
1256 /* get total length until this descriptor */
1257 accumulatedlen = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL);
1259 /* Increment to next descriptor */
1260 INCR_RX_DESC_INDEX(descidx, 1U);
1261 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1263 /* Point to next buffer */
1264 rxbuff = rxbuff->next;
1267 /* last descriptor data length */
1268 lastdesclen = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - accumulatedlen;
1270 /* Get Address of the first buffer address */
1271 rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr0;
1273 /* data is in only one buffer */
1274 if(lastdesclen <= heth->Init.RxBuffLen)
1276 rxbuff->len = lastdesclen;
1278 /* data is in two buffers */
1279 else if(dmarxdesc->BackupAddr1 != 0U)
1281 /* Get the Length of the first buffer address */
1282 rxbuff->len = heth->Init.RxBuffLen;
1283 /* Point to next buffer */
1284 rxbuff = rxbuff->next;
1285 /* Get the Address the Length of the second buffer address */
1286 rxbuff->buffer = (uint8_t *) dmarxdesc->BackupAddr1;
1287 rxbuff->len = lastdesclen - (heth->Init.RxBuffLen);
1289 else /* Buffer 2 not valid*/
1291 return HAL_ERROR;
1294 return HAL_OK;
1298 * @brief This function gets the length of last received Packet.
1299 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1300 * the configuration information for ETHERNET module
1301 * @param Length: parameter to hold Rx packet length
1302 * @retval HAL Status
1304 HAL_StatusTypeDef HAL_ETH_GetRxDataLength(ETH_HandleTypeDef *heth, uint32_t *Length)
1306 ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList;
1307 uint32_t descidx = dmarxdesclist->FirstAppDesc;
1308 __IO const ETH_DMADescTypeDef *dmarxdesc;
1310 if(dmarxdesclist->AppDescNbr == 0U)
1312 if(HAL_ETH_IsRxDataAvailable(heth) == 0U)
1314 /* No data to be transferred to the application */
1315 return HAL_ERROR;
1319 /* Get index of last descriptor */
1320 INCR_RX_DESC_INDEX(descidx, (dmarxdesclist->AppDescNbr - 1U));
1321 /* Point to last descriptor */
1322 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1324 *Length = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL);
1326 return HAL_OK;
1330 * @brief Get the Rx data info (Packet type, VLAN tag, Filters status, ...)
1331 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1332 * the configuration information for ETHERNET module
1333 * @param RxPacketInfo: parameter to hold info of received buffer
1334 * @retval HAL status
1336 HAL_StatusTypeDef HAL_ETH_GetRxDataInfo(ETH_HandleTypeDef *heth, ETH_RxPacketInfo *RxPacketInfo)
1338 ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList;
1339 uint32_t descidx = dmarxdesclist->FirstAppDesc;
1340 __IO const ETH_DMADescTypeDef *dmarxdesc;
1342 if(dmarxdesclist->AppDescNbr == 0U)
1344 if(HAL_ETH_IsRxDataAvailable(heth) == 0U)
1346 /* No data to be transferred to the application */
1347 return HAL_ERROR;
1351 /* Get index of last descriptor */
1352 INCR_RX_DESC_INDEX(descidx, ((dmarxdesclist->AppDescNbr) - 1U));
1353 /* Point to last descriptor */
1354 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];
1356 if((dmarxdesc->DESC3 & ETH_DMARXNDESCWBF_ES) != (uint32_t)RESET)
1358 RxPacketInfo->ErrorCode = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_ERRORS_MASK);
1360 else
1362 if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_RS0V) != 0U)
1365 if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LT) == ETH_DMARXNDESCWBF_LT_DVLAN)
1367 RxPacketInfo->VlanTag = READ_BIT(dmarxdesc->DESC0, ETH_DMARXNDESCWBF_OVT);
1368 RxPacketInfo->InnerVlanTag = READ_BIT(dmarxdesc->DESC0, ETH_DMARXNDESCWBF_IVT) >> 16;
1370 else
1372 RxPacketInfo->VlanTag = READ_BIT(dmarxdesc->DESC0, ETH_DMARXNDESCWBF_OVT);
1376 if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_RS1V) != 0U)
1378 /* Get Payload type */
1379 RxPacketInfo->PayloadType =READ_BIT( dmarxdesc->DESC1, ETH_DMARXNDESCWBF_PT);
1380 /* Get Header type */
1381 RxPacketInfo->HeaderType = READ_BIT(dmarxdesc->DESC1, (ETH_DMARXNDESCWBF_IPV4 | ETH_DMARXNDESCWBF_IPV6));
1382 /* Get Checksum status */
1383 RxPacketInfo->Checksum = READ_BIT(dmarxdesc->DESC1, (ETH_DMARXNDESCWBF_IPCE | ETH_DMARXNDESCWBF_IPCB | ETH_DMARXNDESCWBF_IPHE));
1386 if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_RS2V) != 0U)
1388 RxPacketInfo->MacFilterStatus = READ_BIT(dmarxdesc->DESC2, (ETH_DMARXNDESCWBF_HF | ETH_DMARXNDESCWBF_DAF | ETH_DMARXNDESCWBF_SAF | ETH_DMARXNDESCWBF_VF));
1389 RxPacketInfo->L3FilterStatus = READ_BIT(dmarxdesc->DESC2, (ETH_DMARXNDESCWBF_L3FM | ETH_DMARXNDESCWBF_L3L4FM));
1390 RxPacketInfo->L4FilterStatus = READ_BIT(dmarxdesc->DESC2, (ETH_DMARXNDESCWBF_L4FM | ETH_DMARXNDESCWBF_L3L4FM));
1394 /* Get the segment count */
1395 WRITE_REG(RxPacketInfo->SegmentCnt, dmarxdesclist->AppDescNbr);
1397 return HAL_OK;
1401 * @brief This function gives back Rx Desc of the last received Packet
1402 * to the DMA, so ETH DMA will be able to use these descriptors
1403 * to receive next Packets.
1404 * It should be called after processing the received Packet.
1405 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1406 * the configuration information for ETHERNET module
1407 * @retval HAL status.
1409 HAL_StatusTypeDef HAL_ETH_BuildRxDescriptors(ETH_HandleTypeDef *heth)
1411 ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList;
1412 uint32_t descindex = dmarxdesclist->FirstAppDesc;
1413 __IO ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descindex];
1414 uint32_t totalappdescnbr = dmarxdesclist->AppDescNbr;
1415 uint32_t descscan;
1417 if(dmarxdesclist->AppDescNbr == 0U)
1419 /* No Rx descriptors to build */
1420 return HAL_ERROR;
1423 if(dmarxdesclist->AppContextDesc != 0U)
1425 /* A context descriptor is available */
1426 totalappdescnbr += 1U;
1429 for(descscan =0; descscan < totalappdescnbr; descscan++)
1431 WRITE_REG(dmarxdesc->DESC0, dmarxdesc->BackupAddr0);
1432 WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF1V);
1434 if (READ_REG(dmarxdesc->BackupAddr1) != 0U)
1436 WRITE_REG(dmarxdesc->DESC2, dmarxdesc->BackupAddr1);
1437 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_BUF2V);
1440 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN);
1442 if(dmarxdesclist->ItMode != 0U)
1444 SET_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
1447 if(descscan < (totalappdescnbr - 1U))
1449 /* Increment rx descriptor index */
1450 INCR_RX_DESC_INDEX(descindex, 1U);
1451 /* Get descriptor address */
1452 dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descindex];
1456 /* Set the Tail pointer address to the last rx descriptor hold by the app */
1457 WRITE_REG(heth->Instance->DMACRDTPR, (uint32_t)dmarxdesc);
1459 /* reset the Application desc number */
1460 WRITE_REG(dmarxdesclist->AppDescNbr, 0);
1462 /* reset the application context descriptor */
1463 WRITE_REG(heth->RxDescList.AppContextDesc, 0);
1465 return HAL_OK;
1470 * @brief This function handles ETH interrupt request.
1471 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1472 * the configuration information for ETHERNET module
1473 * @retval HAL status
1475 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1477 /* Packet received */
1478 if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_RI))
1480 if(__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_RIE))
1483 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1484 /*Call registered Receive complete callback*/
1485 heth->RxCpltCallback(heth);
1486 #else
1487 /* Receive complete callback */
1488 HAL_ETH_RxCpltCallback(heth);
1489 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1491 /* Clear the Eth DMA Rx IT pending bits */
1492 __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
1496 /* Packet transmitted */
1497 if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_TI))
1499 if(__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_TIE))
1501 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1502 /*Call registered Transmit complete callback*/
1503 heth->TxCpltCallback(heth);
1504 #else
1505 /* Transfer complete callback */
1506 HAL_ETH_TxCpltCallback(heth);
1507 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1509 /* Clear the Eth DMA Tx IT pending bits */
1510 __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
1515 /* ETH DMA Error */
1516 if(__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_AIS))
1518 if(__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_AIE))
1520 heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1522 /* if fatal bus error occured */
1523 if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_FBE))
1525 /* Get DMA error code */
1526 heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS));
1528 /* Disable all interrupts */
1529 __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE);
1531 /* Set HAL state to ERROR */
1532 heth->gState = HAL_ETH_STATE_ERROR;
1534 else
1536 /* Get DMA error status */
1537 heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1538 ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1540 /* Clear the interrupt summary flag */
1541 __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1542 ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1544 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1545 /* Call registered DMA Error callback*/
1546 heth->DMAErrorCallback(heth);
1547 #else
1548 /* Ethernet DMA Error callback */
1549 HAL_ETH_DMAErrorCallback(heth);
1550 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1555 /* ETH MAC Error IT */
1556 if(__HAL_ETH_MAC_GET_IT(heth, (ETH_MACIER_RXSTSIE | ETH_MACIER_TXSTSIE)))
1558 /* Get MAC Rx Tx status and clear Status register pending bit */
1559 heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR);
1561 heth->gState = HAL_ETH_STATE_ERROR;
1563 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1564 /* Call registered MAC Error callback*/
1565 heth->DMAErrorCallback(heth);
1566 #else
1567 /* Ethernet MAC Error callback */
1568 HAL_ETH_MACErrorCallback(heth);
1569 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1571 heth->MACErrorCode = (uint32_t)(0x0U);
1574 /* ETH PMT IT */
1575 if(__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_PMT_IT))
1577 /* Get MAC Wake-up source and clear the status register pending bit */
1578 heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD));
1580 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1581 /* Call registered PMT callback*/
1582 heth->PMTCallback(heth);
1583 #else
1584 /* Ethernet PMT callback */
1585 HAL_ETH_PMTCallback(heth);
1586 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1588 heth->MACWakeUpEvent = (uint32_t)(0x0U);
1591 /* ETH EEE IT */
1592 if(__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_LPI_IT))
1594 /* Get MAC LPI interrupt source and clear the status register pending bit */
1595 heth->MACLPIEvent = READ_BIT(heth->Instance->MACPCSR, 0x0000000FU);
1597 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1598 /* Call registered EEE callback*/
1599 heth->EEECallback(heth);
1600 #else
1601 /* Ethernet EEE callback */
1602 HAL_ETH_EEECallback(heth);
1603 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1605 heth->MACLPIEvent = (uint32_t)(0x0U);
1608 #if defined(DUAL_CORE)
1609 if (HAL_GetCurrentCPUID() == CM7_CPUID)
1611 /* check ETH WAKEUP exti flag */
1612 if(__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
1614 /* Clear ETH WAKEUP Exti pending bit */
1615 __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
1616 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1617 /* Call registered WakeUp callback*/
1618 heth->WakeUpCallback(heth);
1619 #else
1620 /* ETH WAKEUP callback */
1621 HAL_ETH_WakeUpCallback(heth);
1622 #endif
1625 else
1627 /* check ETH WAKEUP exti flag */
1628 if(__HAL_ETH_WAKEUP_EXTID2_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
1630 /* Clear ETH WAKEUP Exti pending bit */
1631 __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
1632 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1633 /* Call registered WakeUp callback*/
1634 heth->WakeUpCallback(heth);
1635 #else
1636 /* ETH WAKEUP callback */
1637 HAL_ETH_WakeUpCallback(heth);
1638 #endif
1641 #else
1642 /* check ETH WAKEUP exti flag */
1643 if(__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
1645 /* Clear ETH WAKEUP Exti pending bit */
1646 __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
1647 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1648 /* Call registered WakeUp callback*/
1649 heth->WakeUpCallback(heth);
1650 #else
1651 /* ETH WAKEUP callback */
1652 HAL_ETH_WakeUpCallback(heth);
1653 #endif
1655 #endif
1659 * @brief Tx Transfer completed callbacks.
1660 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1661 * the configuration information for ETHERNET module
1662 * @retval None
1664 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
1666 /* Prevent unused argument(s) compilation warning */
1667 UNUSED(heth);
1668 /* NOTE : This function Should not be modified, when the callback is needed,
1669 the HAL_ETH_TxCpltCallback could be implemented in the user file
1674 * @brief Rx Transfer completed callbacks.
1675 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1676 * the configuration information for ETHERNET module
1677 * @retval None
1679 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
1681 /* Prevent unused argument(s) compilation warning */
1682 UNUSED(heth);
1683 /* NOTE : This function Should not be modified, when the callback is needed,
1684 the HAL_ETH_RxCpltCallback could be implemented in the user file
1689 * @brief Ethernet DMA transfer error callbacks
1690 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1691 * the configuration information for ETHERNET module
1692 * @retval None
1694 __weak void HAL_ETH_DMAErrorCallback(ETH_HandleTypeDef *heth)
1696 /* Prevent unused argument(s) compilation warning */
1697 UNUSED(heth);
1698 /* NOTE : This function Should not be modified, when the callback is needed,
1699 the HAL_ETH_DMAErrorCallback could be implemented in the user file
1704 * @brief Ethernet MAC transfer error callbacks
1705 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1706 * the configuration information for ETHERNET module
1707 * @retval None
1709 __weak void HAL_ETH_MACErrorCallback(ETH_HandleTypeDef *heth)
1711 /* Prevent unused argument(s) compilation warning */
1712 UNUSED(heth);
1713 /* NOTE : This function Should not be modified, when the callback is needed,
1714 the HAL_ETH_MACErrorCallback could be implemented in the user file
1719 * @brief Ethernet Power Management module IT callback
1720 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1721 * the configuration information for ETHERNET module
1722 * @retval None
1724 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
1726 /* Prevent unused argument(s) compilation warning */
1727 UNUSED(heth);
1728 /* NOTE : This function Should not be modified, when the callback is needed,
1729 the HAL_ETH_PMTCallback could be implemented in the user file
1734 * @brief Energy Efficient Etherent IT callback
1735 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1736 * the configuration information for ETHERNET module
1737 * @retval None
1739 __weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth)
1741 /* Prevent unused argument(s) compilation warning */
1742 UNUSED(heth);
1743 /* NOTE : This function Should not be modified, when the callback is needed,
1744 the HAL_ETH_EEECallback could be implemented in the user file
1749 * @brief ETH WAKEUP interrupt callback
1750 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1751 * the configuration information for ETHERNET module
1752 * @retval None
1754 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
1756 /* Prevent unused argument(s) compilation warning */
1757 UNUSED(heth);
1758 /* NOTE : This function Should not be modified, when the callback is needed,
1759 the HAL_ETH_WakeUpCallback could be implemented in the user file
1764 * @brief Read a PHY register
1765 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1766 * the configuration information for ETHERNET module
1767 * @param PHYAddr: PHY port address, must be a value from 0 to 31
1768 * @param PHYReg: PHY register address, must be a value from 0 to 31
1769 * @param pRegValue: parameter to hold read value
1770 * @retval HAL status
1772 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, uint32_t *pRegValue)
1774 uint32_t tmpreg, tickstart;
1776 /* Check for the Busy flag */
1777 if(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != 0U)
1779 return HAL_ERROR;
1782 /* Get the MACMDIOAR value */
1783 WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
1785 /* Prepare the MDIO Address Register value
1786 - Set the PHY device address
1787 - Set the PHY register address
1788 - Set the read mode
1789 - Set the MII Busy bit */
1791 MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr <<21));
1792 MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
1793 MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD);
1794 SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
1796 /* Write the result value into the MDII Address register */
1797 WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
1799 tickstart = HAL_GetTick();
1801 /* Wait for the Busy flag */
1802 while(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
1804 if(((HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT))
1806 return HAL_ERROR;
1810 /* Get MACMIIDR value */
1811 WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR);
1813 return HAL_OK;
1818 * @brief Writes to a PHY register.
1819 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1820 * the configuration information for ETHERNET module
1821 * @param PHYAddr: PHY port address, must be a value from 0 to 31
1822 * @param PHYReg: PHY register address, must be a value from 0 to 31
1823 * @param RegValue: the value to write
1824 * @retval HAL status
1826 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, uint32_t RegValue)
1828 uint32_t tmpreg, tickstart;
1830 /* Check for the Busy flag */
1831 if(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != 0U)
1833 return HAL_ERROR;
1836 /* Get the MACMDIOAR value */
1837 WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
1839 /* Prepare the MDIO Address Register value
1840 - Set the PHY device address
1841 - Set the PHY register address
1842 - Set the write mode
1843 - Set the MII Busy bit */
1845 MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr <<21));
1846 MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
1847 MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR);
1848 SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
1851 /* Give the value to the MII data register */
1852 WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue);
1854 /* Write the result value into the MII Address register */
1855 WRITE_REG(ETH->MACMDIOAR, tmpreg);
1857 tickstart = HAL_GetTick();
1859 /* Wait for the Busy flag */
1860 while(READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
1862 if(((HAL_GetTick() - tickstart ) > ETH_MDIO_BUS_TIMEOUT))
1864 return HAL_ERROR;
1868 return HAL_OK;
1872 * @}
1875 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
1876 * @brief ETH control functions
1878 @verbatim
1879 ==============================================================================
1880 ##### Peripheral Control functions #####
1881 ==============================================================================
1882 [..]
1883 This subsection provides a set of functions allowing to control the ETH
1884 peripheral.
1886 @endverbatim
1887 * @{
1890 * @brief Get the configuration of the MAC and MTL subsystems.
1891 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1892 * the configuration information for ETHERNET module
1893 * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
1894 * the configuration of the MAC.
1895 * @retval HAL Status
1897 HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
1899 if (macconf == NULL)
1901 return HAL_ERROR;
1904 /* Get MAC parameters */
1905 macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN);
1906 macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC)>> 4) > 0U) ? ENABLE : DISABLE;
1907 macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
1908 macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE;
1909 macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U) ? ENABLE : DISABLE;
1910 macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE;
1911 macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE;
1912 macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
1913 macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
1914 macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
1915 macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE;
1916 macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >>17) == 0U) ? ENABLE : DISABLE;
1917 macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >>19) == 0U) ? ENABLE : DISABLE;
1918 macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE;
1919 macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE;
1920 macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE;
1921 macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE;
1922 macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG);
1923 macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE;
1924 macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC);
1926 macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL);
1927 macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE;
1928 macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE;
1929 macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE;
1930 macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U) ? ENABLE : DISABLE;
1931 macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25;
1934 macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE;
1935 macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO);
1937 macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE;
1938 macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE;
1939 macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT);
1940 macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16);
1943 macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE;
1944 macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U) ? ENABLE : DISABLE;
1946 macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF));
1948 macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF));
1949 macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE;
1950 macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE;
1951 macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE;
1953 return HAL_OK;
1957 * @brief Get the configuration of the DMA.
1958 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1959 * the configuration information for ETHERNET module
1960 * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
1961 * the configuration of the ETH DMA.
1962 * @retval HAL Status
1964 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
1966 if (dmaconf == NULL)
1968 return HAL_ERROR;
1971 dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE;
1972 dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB);
1973 dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB)>> 15) > 0U) ? ENABLE : DISABLE;
1975 dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR |ETH_DMAMR_PR | ETH_DMAMR_DA));
1977 dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL)>> 16) > 0U) ? ENABLE : DISABLE;
1978 dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS);
1980 dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE;
1981 dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL);
1983 dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE;
1984 dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE;
1985 dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL);
1987 return HAL_OK;
1991 * @brief Set the MAC configuration.
1992 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1993 * the configuration information for ETHERNET module
1994 * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains
1995 * the configuration of the MAC.
1996 * @retval HAL status
1998 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2000 if(macconf == NULL)
2002 return HAL_ERROR;
2005 if(heth->RxState == HAL_ETH_STATE_READY)
2007 ETH_SetMACConfig(heth, macconf);
2009 return HAL_OK;
2011 else
2013 return HAL_ERROR;
2018 * @brief Set the ETH DMA configuration.
2019 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2020 * the configuration information for ETHERNET module
2021 * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2022 * the configuration of the ETH DMA.
2023 * @retval HAL status
2025 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2027 if(dmaconf == NULL)
2029 return HAL_ERROR;
2032 if(heth->RxState == HAL_ETH_STATE_READY)
2034 ETH_SetDMAConfig(heth, dmaconf);
2036 return HAL_OK;
2038 else
2040 return HAL_ERROR;
2045 * @brief Configures the Clock range of ETH MDIO interface.
2046 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2047 * the configuration information for ETHERNET module
2048 * @retval None
2050 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2052 uint32_t tmpreg, hclk;
2054 /* Get the ETHERNET MACMDIOAR value */
2055 tmpreg = (heth->Instance)->MACMDIOAR;
2057 /* Clear CSR Clock Range bits */
2058 tmpreg &= ~ETH_MACMDIOAR_CR;
2060 /* Get hclk frequency value */
2061 hclk = HAL_RCC_GetHCLKFreq();
2063 /* Set CR bits depending on hclk value */
2064 if((hclk >= 20000000U)&&(hclk < 35000000U))
2066 /* CSR Clock Range between 20-35 MHz */
2067 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2069 else if((hclk >= 35000000U)&&(hclk < 60000000U))
2071 /* CSR Clock Range between 35-60 MHz */
2072 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2074 else if((hclk >= 60000000U)&&(hclk < 100000000U))
2076 /* CSR Clock Range between 60-100 MHz */
2077 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2079 else if((hclk >= 100000000U)&&(hclk < 150000000U))
2081 /* CSR Clock Range between 100-150 MHz */
2082 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2084 else /* (hclk >= 150000000)&&(hclk <= 200000000) */
2086 /* CSR Clock Range between 150-200 MHz */
2087 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2090 /* Configure the CSR Clock Range */
2091 (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2095 * @brief Set the ETH MAC (L2) Filters configuration.
2096 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2097 * the configuration information for ETHERNET module
2098 * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2099 * the configuration of the ETH MAC filters.
2100 * @retval HAL status
2102 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2104 uint32_t filterconfig;
2106 if(pFilterConfig == NULL)
2108 return HAL_ERROR;
2111 filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2112 ((uint32_t)pFilterConfig->HashUnicast << 1) |
2113 ((uint32_t)pFilterConfig->HashMulticast << 2) |
2114 ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2115 ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2116 ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) |
2117 ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2118 ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2119 ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2120 ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2121 pFilterConfig->ControlPacketsFilter);
2123 MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig);
2125 return HAL_OK;
2129 * @brief Get the ETH MAC (L2) Filters configuration.
2130 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2131 * the configuration information for ETHERNET module
2132 * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2133 * the configuration of the ETH MAC filters.
2134 * @retval HAL status
2136 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2138 if(pFilterConfig == NULL)
2140 return HAL_ERROR;
2143 pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE;
2144 pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE;
2145 pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE;
2146 pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2147 pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE;
2148 pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE;
2149 pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF);
2150 pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2151 pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2152 pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U) ? ENABLE : DISABLE;
2153 pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2155 return HAL_OK;
2159 * @brief Set the source MAC Address to be matched.
2160 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2161 * the configuration information for ETHERNET module
2162 * @param AddrNbr: The MAC address to configure
2163 * This parameter must be a value of the following:
2164 * ETH_MAC_ADDRESS1
2165 * ETH_MAC_ADDRESS2
2166 * ETH_MAC_ADDRESS3
2167 * @param pMACAddr: Pointer to MAC address buffer data (6 bytes)
2168 * @retval HAL status
2170 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef *heth, uint32_t AddrNbr, uint8_t *pMACAddr)
2172 uint32_t macaddrhr, macaddrlr;
2174 if(pMACAddr == NULL)
2176 return HAL_ERROR;
2179 /* Get mac addr high reg offset */
2180 macaddrhr = ((uint32_t)&(heth->Instance->MACA0HR) + AddrNbr);
2181 /* Get mac addr low reg offset */
2182 macaddrlr = ((uint32_t)&(heth->Instance->MACA0LR) + AddrNbr);
2184 /* Set MAC addr bits 32 to 47 */
2185 (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2186 /* Set MAC addr bits 0 to 31 */
2187 (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2188 ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2190 /* Enable address and set source address bit */
2191 (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE);
2193 return HAL_OK;
2197 * @brief Set the ETH Hash Table Value.
2198 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2199 * the configuration information for ETHERNET module
2200 * @param pHashTable: pointer to a table of two 32 bit values, that contains
2201 * the 64 bits of the hash table.
2202 * @retval HAL status
2204 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2206 if(pHashTable == NULL)
2208 return HAL_ERROR;
2211 heth->Instance->MACHT0R = pHashTable[0];
2212 heth->Instance->MACHT1R = pHashTable[1];
2214 return HAL_OK;
2218 * @brief Set the VLAN Identifier for Rx packets
2219 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2220 * the configuration information for ETHERNET module
2221 * @param ComparisonBits: 12 or 16 bit comparison mode
2222 must be a value of @ref ETH_VLAN_Tag_Comparison
2223 * @param VLANIdentifier: VLAN Identifier value
2224 * @retval None
2226 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2228 if(ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2230 MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL , VLANIdentifier);
2231 CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2233 else
2235 MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID , VLANIdentifier);
2236 SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2241 * @brief Enters the Power down mode.
2242 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2243 * the configuration information for ETHERNET module
2244 * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2245 * that contains the Power Down configration
2246 * @retval None.
2248 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2250 uint32_t powerdownconfig;
2252 powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) |
2253 ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) |
2254 ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) |
2255 ((uint32_t)pPowerDownConfig->WakeUpForward << 10) |
2256 ETH_MACPCSR_PWRDWN);
2258 /* Enable PMT interrupt */
2259 __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE);
2261 MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig);
2265 * @brief Exits from the Power down mode.
2266 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2267 * the configuration information for ETHERNET module
2268 * @retval None.
2270 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2272 /* clear wake up sources */
2273 CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | ETH_MACPCSR_RWKPFE);
2275 if(READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != 0U)
2277 /* Exit power down mode */
2278 CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN);
2281 /* Disable PMT interrupt */
2282 __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE);
2286 * @brief Set the WakeUp filter.
2287 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2288 * the configuration information for ETHERNET module
2289 * @param pFilter: pointer to filter registers values
2290 * @param Count: number of filter registers, must be from 1 to 8.
2291 * @retval None.
2293 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2295 uint32_t regindex;
2297 if(pFilter == NULL)
2299 return HAL_ERROR;
2302 /* Reset Filter Pointer */
2303 SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST);
2305 /* Wake up packet filter config */
2306 for(regindex = 0; regindex < Count; regindex++)
2308 /* Write filter regs */
2309 WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]);
2312 return HAL_OK;
2316 * @}
2319 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2320 * @brief ETH State and Errors functions
2322 @verbatim
2323 ==============================================================================
2324 ##### Peripheral State and Errors functions #####
2325 ==============================================================================
2326 [..]
2327 This subsection provides a set of functions allowing to return the State of
2328 ETH communication process, return Peripheral Errors occurred during communication
2329 process
2332 @endverbatim
2333 * @{
2337 * @brief Returns the ETH state.
2338 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2339 * the configuration information for ETHERNET module
2340 * @retval HAL state
2342 HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
2344 HAL_ETH_StateTypeDef ret;
2345 HAL_ETH_StateTypeDef gstate = heth->gState;
2346 HAL_ETH_StateTypeDef rxstate =heth->RxState;
2348 ret = gstate;
2349 ret |= rxstate;
2350 return ret;
2354 * @brief Returns the ETH error code
2355 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2356 * the configuration information for ETHERNET module
2357 * @retval ETH Error Code
2359 uint32_t HAL_ETH_GetError(ETH_HandleTypeDef *heth)
2361 return heth->ErrorCode;
2365 * @brief Returns the ETH DMA error code
2366 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2367 * the configuration information for ETHERNET module
2368 * @retval ETH DMA Error Code
2370 uint32_t HAL_ETH_GetDMAError(ETH_HandleTypeDef *heth)
2372 return heth->DMAErrorCode;
2376 * @brief Returns the ETH MAC error code
2377 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2378 * the configuration information for ETHERNET module
2379 * @retval ETH MAC Error Code
2381 uint32_t HAL_ETH_GetMACError(ETH_HandleTypeDef *heth)
2383 return heth->MACErrorCode;
2387 * @brief Returns the ETH MAC WakeUp event source
2388 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2389 * the configuration information for ETHERNET module
2390 * @retval ETH MAC WakeUp event source
2392 uint32_t HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef *heth)
2394 return heth->MACWakeUpEvent;
2398 * @}
2402 * @}
2405 /** @addtogroup ETH_Private_Functions ETH Private Functions
2406 * @{
2409 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2411 uint32_t macregval;
2413 /*------------------------ MACCR Configuration --------------------*/
2414 macregval =(macconf->InterPacketGapVal |
2415 macconf->SourceAddrControl |
2416 ((uint32_t)macconf->ChecksumOffload<< 27) |
2417 ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) |
2418 ((uint32_t)macconf->Support2KPacket << 22) |
2419 ((uint32_t)macconf->CRCStripTypePacket << 21) |
2420 ((uint32_t)macconf->AutomaticPadCRCStrip << 20) |
2421 ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) |
2422 ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) |
2423 ((uint32_t)macconf->JumboPacket << 16) |
2424 macconf->Speed |
2425 macconf->DuplexMode |
2426 ((uint32_t)macconf->LoopbackMode << 12) |
2427 ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11)|
2428 ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10)|
2429 ((uint32_t)macconf->CarrierSenseDuringTransmit << 9)|
2430 ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8)|
2431 macconf->BackOffLimit |
2432 ((uint32_t)macconf->DeferralCheck << 4)|
2433 macconf->PreambleLength);
2435 /* Write to MACCR */
2436 MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval);
2438 /*------------------------ MACECR Configuration --------------------*/
2439 macregval = ((macconf->ExtendedInterPacketGapVal << 25)|
2440 ((uint32_t)macconf->ExtendedInterPacketGap << 24)|
2441 ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18)|
2442 ((uint32_t)macconf->SlowProtocolDetect << 17)|
2443 ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U)<< 16) |
2444 macconf->GiantPacketSizeLimit);
2446 /* Write to MACECR */
2447 MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval);
2449 /*------------------------ MACWTR Configuration --------------------*/
2450 macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) |
2451 macconf->WatchdogTimeout);
2453 /* Write to MACWTR */
2454 MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval);
2456 /*------------------------ MACTFCR Configuration --------------------*/
2457 macregval = (((uint32_t)macconf->TransmitFlowControl << 1) |
2458 macconf->PauseLowThreshold |
2459 ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U)<< 7) |
2460 (macconf->PauseTime << 16));
2462 /* Write to MACTFCR */
2463 MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval);
2465 /*------------------------ MACRFCR Configuration --------------------*/
2466 macregval = ((uint32_t)macconf->ReceiveFlowControl |
2467 ((uint32_t)macconf->UnicastPausePacketDetect << 1));
2469 /* Write to MACRFCR */
2470 MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval);
2472 /*------------------------ MTLTQOMR Configuration --------------------*/
2473 /* Write to MTLTQOMR */
2474 MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode);
2476 /*------------------------ MTLRQOMR Configuration --------------------*/
2477 macregval = (macconf->ReceiveQueueMode |
2478 ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) |
2479 ((uint32_t)macconf->ForwardRxErrorPacket << 4) |
2480 ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3));
2482 /* Write to MTLRQOMR */
2483 MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval);
2486 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2488 uint32_t dmaregval;
2490 /*------------------------ DMAMR Configuration --------------------*/
2491 MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration);
2493 /*------------------------ DMASBMR Configuration --------------------*/
2494 dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) |
2495 dmaconf->BurstMode |
2496 ((uint32_t)dmaconf->RebuildINCRxBurst << 15));
2498 MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval);
2500 /*------------------------ DMACCR Configuration --------------------*/
2501 dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) |
2502 dmaconf->MaximumSegmentSize);
2504 MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval);
2506 /*------------------------ DMACTCR Configuration --------------------*/
2507 dmaregval = (dmaconf->TxDMABurstLength |
2508 ((uint32_t)dmaconf->SecondPacketOperate << 4)|
2509 ((uint32_t)dmaconf->TCPSegmentation << 12));
2511 MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval);
2513 /*------------------------ DMACRCR Configuration --------------------*/
2514 dmaregval = (((uint32_t)dmaconf->FlushRxPacket << 31) |
2515 dmaconf->RxDMABurstLength);
2517 /* Write to DMACRCR */
2518 MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval);
2522 * @brief Configures Ethernet MAC and DMA with default parameters.
2523 * called by HAL_ETH_Init() API.
2524 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2525 * the configuration information for ETHERNET module
2526 * @retval HAL status
2528 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2530 ETH_MACConfigTypeDef macDefaultConf;
2531 ETH_DMAConfigTypeDef dmaDefaultConf;
2533 /*--------------- ETHERNET MAC registers default Configuration --------------*/
2534 macDefaultConf.AutomaticPadCRCStrip = ENABLE;
2535 macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2536 macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
2537 macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2538 macDefaultConf.ChecksumOffload = ENABLE;
2539 macDefaultConf.CRCCheckingRxPackets = ENABLE;
2540 macDefaultConf.CRCStripTypePacket = ENABLE;
2541 macDefaultConf.DeferralCheck = DISABLE;
2542 macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE;
2543 macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2544 macDefaultConf.ExtendedInterPacketGap = DISABLE;
2545 macDefaultConf.ExtendedInterPacketGapVal = 0x0;
2546 macDefaultConf.ForwardRxErrorPacket = DISABLE;
2547 macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE;
2548 macDefaultConf.GiantPacketSizeLimit = 0x618;
2549 macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
2550 macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
2551 macDefaultConf.Jabber = ENABLE;
2552 macDefaultConf.JumboPacket = DISABLE;
2553 macDefaultConf.LoopbackMode = DISABLE;
2554 macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
2555 macDefaultConf.PauseTime = 0x0;
2556 macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
2557 macDefaultConf.ProgrammableWatchdog = DISABLE;
2558 macDefaultConf.ReceiveFlowControl = DISABLE;
2559 macDefaultConf.ReceiveOwn = ENABLE;
2560 macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
2561 macDefaultConf.RetryTransmission = ENABLE;
2562 macDefaultConf.SlowProtocolDetect = DISABLE;
2563 macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0;
2564 macDefaultConf.Speed = ETH_SPEED_100M;
2565 macDefaultConf.Support2KPacket = DISABLE;
2566 macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
2567 macDefaultConf.TransmitFlowControl = DISABLE;
2568 macDefaultConf.UnicastPausePacketDetect = DISABLE;
2569 macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
2570 macDefaultConf.Watchdog = ENABLE;
2571 macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB;
2572 macDefaultConf.ZeroQuantaPause = ENABLE;
2574 /* MAC default configuration */
2575 ETH_SetMACConfig(heth, &macDefaultConf);
2577 /*--------------- ETHERNET DMA registers default Configuration --------------*/
2578 dmaDefaultConf.AddressAlignedBeats = ENABLE;
2579 dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2580 dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1;
2581 dmaDefaultConf.FlushRxPacket = DISABLE;
2582 dmaDefaultConf.PBLx8Mode = DISABLE;
2583 dmaDefaultConf.RebuildINCRxBurst = DISABLE;
2584 dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2585 dmaDefaultConf.SecondPacketOperate = DISABLE;
2586 dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2587 dmaDefaultConf.TCPSegmentation = DISABLE;
2588 dmaDefaultConf.MaximumSegmentSize = 536;
2590 /* DMA default configuration */
2591 ETH_SetDMAConfig(heth, &dmaDefaultConf);
2595 * @brief Configures the Clock range of SMI interface.
2596 * called by HAL_ETH_Init() API.
2597 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2598 * the configuration information for ETHERNET module
2599 * @retval None
2601 static void ETH_MAC_MDIO_ClkConfig(ETH_HandleTypeDef *heth)
2603 uint32_t tmpreg, hclk;
2605 /* Get the ETHERNET MACMDIOAR value */
2606 tmpreg = (heth->Instance)->MACMDIOAR;
2608 /* Clear CSR Clock Range bits */
2609 tmpreg &= ~ETH_MACMDIOAR_CR;
2611 /* Get hclk frequency value */
2612 hclk = HAL_RCC_GetHCLKFreq();
2614 /* Set CR bits depending on hclk value */
2615 if((hclk >= 20000000U)&&(hclk < 35000000U))
2617 /* CSR Clock Range between 20-35 MHz */
2618 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2620 else if((hclk >= 35000000U)&&(hclk < 60000000U))
2622 /* CSR Clock Range between 35-60 MHz */
2623 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2625 else if((hclk >= 60000000U)&&(hclk < 100000000U))
2627 /* CSR Clock Range between 60-100 MHz */
2628 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2630 else if((hclk >= 100000000U)&&(hclk < 150000000U))
2632 /* CSR Clock Range between 100-150 MHz */
2633 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2635 else /* (hclk >= 150000000)&&(hclk <= 200000000) */
2637 /* CSR Clock Range between 150-200 MHz */
2638 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2641 /* Configure the CSR Clock Range */
2642 (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2646 * @brief Initializes the DMA Tx descriptors.
2647 * called by HAL_ETH_Init() API.
2648 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2649 * the configuration information for ETHERNET module
2650 * @retval None
2652 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
2654 ETH_DMADescTypeDef *dmatxdesc;
2655 uint32_t i;
2657 /* Fill each DMATxDesc descriptor with the right values */
2658 for(i=0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
2660 dmatxdesc = heth->Init.TxDesc + i;
2662 WRITE_REG(dmatxdesc->DESC0, 0x0);
2663 WRITE_REG(dmatxdesc->DESC1, 0x0);
2664 WRITE_REG(dmatxdesc->DESC2, 0x0);
2665 WRITE_REG(dmatxdesc->DESC3, 0x0);
2667 WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
2670 heth->TxDescList.CurTxDesc = 0;
2672 /* Set Transmit Descriptor Ring Length */
2673 WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT -1));
2675 /* Set Transmit Descriptor List Address */
2676 WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc);
2678 /* Set Transmit Descriptor Tail pointer */
2679 WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc);
2683 * @brief Initializes the DMA Rx descriptors in chain mode.
2684 * called by HAL_ETH_Init() API.
2685 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2686 * the configuration information for ETHERNET module
2687 * @retval None
2689 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
2691 ETH_DMADescTypeDef *dmarxdesc;
2692 uint32_t i;
2694 for(i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
2696 dmarxdesc = heth->Init.RxDesc + i;
2698 WRITE_REG(dmarxdesc->DESC0, 0x0);
2699 WRITE_REG(dmarxdesc->DESC1, 0x0);
2700 WRITE_REG(dmarxdesc->DESC2, 0x0);
2701 WRITE_REG(dmarxdesc->DESC3, 0x0);
2702 WRITE_REG(dmarxdesc->BackupAddr0, 0x0);
2703 WRITE_REG(dmarxdesc->BackupAddr1, 0x0);
2705 /* Set Rx descritors adresses */
2706 WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
2709 WRITE_REG(heth->RxDescList.CurRxDesc, 0);
2710 WRITE_REG(heth->RxDescList.FirstAppDesc, 0);
2711 WRITE_REG(heth->RxDescList.AppDescNbr, 0);
2712 WRITE_REG(heth->RxDescList.ItMode, 0);
2713 WRITE_REG(heth->RxDescList.AppContextDesc, 0);
2715 /* Set Receive Descriptor Ring Length */
2716 WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1)));
2718 /* Set Receive Descriptor List Address */
2719 WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);
2721 /* Set Receive Descriptor Tail pointer Address */
2722 WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1))));
2726 * @brief Prepare Tx DMA descriptor before transmission.
2727 * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
2728 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2729 * the configuration information for ETHERNET module
2730 * @param pTxConfig: Tx packet configuration
2731 * @param ItMode: Enable or disable Tx EOT interrept
2732 * @retval Status
2734 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode)
2736 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
2737 uint32_t descidx = dmatxdesclist->CurTxDesc;
2738 uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
2739 uint32_t descnbr = 0, idx;
2740 ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
2742 ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer;
2744 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
2745 if(READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
2747 return HAL_ETH_ERROR_BUSY;
2750 /***************************************************************************/
2751 /***************** Context descriptor configuration (Optional) **********/
2752 /***************************************************************************/
2753 /* If VLAN tag is enabled for this packet */
2754 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U)
2756 /* Set vlan tag value */
2757 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag);
2758 /* Set vlan tag valid bit */
2759 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV);
2760 /* Set the descriptor as the vlan input source */
2761 SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI);
2763 /* if inner VLAN is enabled */
2764 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != 0U)
2766 /* Set inner vlan tag value */
2767 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16));
2768 /* Set inner vlan tag valid bit */
2769 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV);
2771 /* Set Vlan Tag control */
2772 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl);
2774 /* Set the descriptor as the inner vlan input source */
2775 SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI);
2776 /* Enable double VLAN processing */
2777 SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP);
2781 /* if tcp segementation is enabled for this packet */
2782 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U)
2784 /* Set MSS value */
2785 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize);
2786 /* Set MSS valid bit */
2787 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV);
2790 if((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U)|| (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U))
2792 /* Set as context descriptor */
2793 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT);
2794 /* Set own bit */
2795 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
2796 /* Increment current tx descriptor index */
2797 INCR_TX_DESC_INDEX(descidx, 1U);
2798 /* Get current descriptor address */
2799 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
2801 descnbr += 1U;
2803 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
2804 if(READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
2806 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
2807 /* Clear own bit */
2808 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
2810 return HAL_ETH_ERROR_BUSY;
2814 /***************************************************************************/
2815 /***************** Normal descriptors configuration *****************/
2816 /***************************************************************************/
2818 descnbr += 1U;
2820 /* Set header or buffer 1 address */
2821 WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
2822 /* Set header or buffer 1 Length */
2823 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
2825 if(txbuffer->next != NULL)
2827 txbuffer = txbuffer->next;
2828 /* Set buffer 2 address */
2829 WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
2830 /* Set buffer 2 Length */
2831 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
2833 else
2835 WRITE_REG(dmatxdesc->DESC1, 0x0);
2836 /* Set buffer 2 Length */
2837 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
2840 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U)
2842 /* Set TCP Header length */
2843 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19));
2844 /* Set TCP payload length */
2845 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
2846 /* Set TCP Segmentation Enabled bit */
2847 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
2849 else
2851 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
2853 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U)
2855 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
2858 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != 0U)
2860 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl);
2864 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U)
2866 /* Set Vlan Tag control */
2867 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl);
2870 /* Mark it as First Descriptor */
2871 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
2872 /* Mark it as NORMAL descriptor */
2873 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
2874 /* set OWN bit of FIRST descriptor */
2875 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
2877 /* If source address insertion/replacement is enabled for this packet */
2878 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != 0U)
2880 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl);
2883 /* only if the packet is splitted into more than one descriptors > 1 */
2884 while (txbuffer->next != NULL)
2886 /* Clear the LD bit of previous descriptor */
2887 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
2888 /* Increment current tx descriptor index */
2889 INCR_TX_DESC_INDEX(descidx, 1U);
2890 /* Get current descriptor address */
2891 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
2893 /* Clear the FD bit of new Descriptor */
2894 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
2896 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
2897 if(READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN)
2899 descidx = firstdescidx;
2900 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
2902 /* clear previous desc own bit */
2903 for(idx = 0; idx < descnbr; idx ++)
2905 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
2907 /* Increment current tx descriptor index */
2908 INCR_TX_DESC_INDEX(descidx, 1U);
2909 /* Get current descriptor address */
2910 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
2913 return HAL_ETH_ERROR_BUSY;
2916 descnbr += 1U;
2918 /* Get the next Tx buffer in the list */
2919 txbuffer = txbuffer->next;
2921 /* Set header or buffer 1 address */
2922 WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
2923 /* Set header or buffer 1 Length */
2924 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
2926 if (txbuffer->next != NULL)
2928 /* Get the next Tx buffer in the list */
2929 txbuffer = txbuffer->next;
2930 /* Set buffer 2 address */
2931 WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
2932 /* Set buffer 2 Length */
2933 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
2935 else
2937 WRITE_REG(dmatxdesc->DESC1, 0x0);
2938 /* Set buffer 2 Length */
2939 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
2942 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != 0U)
2944 /* Set TCP payload length */
2945 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
2946 /* Set TCP Segmentation Enabled bit */
2947 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
2949 else
2951 /* Set the packet length */
2952 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
2954 if(READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U)
2956 /* Checksum Insertion Control */
2957 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
2961 /* Set Own bit */
2962 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
2963 /* Mark it as NORMAL descriptor */
2964 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
2967 if(ItMode != ((uint32_t)RESET))
2969 /* Set Interrupt on completition bit */
2970 SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
2972 else
2974 /* Clear Interrupt on completition bit */
2975 CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
2978 /* Mark it as LAST descriptor */
2979 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
2981 dmatxdesclist->CurTxDesc = descidx;
2983 /* Return function status */
2984 return HAL_ETH_ERROR_NONE;
2987 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2988 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
2990 /* Init the ETH Callback settings */
2991 heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */
2992 heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */
2993 heth->DMAErrorCallback = HAL_ETH_DMAErrorCallback; /* Legacy weak DMAErrorCallback */
2994 heth->MACErrorCallback = HAL_ETH_MACErrorCallback; /* Legacy weak MACErrorCallback */
2995 heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */
2996 heth->EEECallback = HAL_ETH_EEECallback; /* Legacy weak EEECallback */
2997 heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */
2999 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3002 * @}
3006 * @}
3009 #endif /* ETH */
3011 #endif /* HAL_ETH_MODULE_ENABLED */
3014 * @}
3017 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/