1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_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
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2022 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                     ##### How to use this driver #####
27   ==============================================================================
28      [..]
29      The ETH HAL driver can be used as follows:
30 
31       (#)Declare a ETH_HandleTypeDef handle structure, for example:
32          ETH_HandleTypeDef  heth;
33 
34       (#)Fill parameters of Init structure in heth handle
35 
36       (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
37 
38       (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
39           (##) Enable the Ethernet interface clock using
40                 (+++)  __HAL_RCC_ETH1MAC_CLK_ENABLE()
41                 (+++)  __HAL_RCC_ETH1TX_CLK_ENABLE()
42                 (+++)  __HAL_RCC_ETH1RX_CLK_ENABLE()
43 
44           (##) Initialize the related GPIO clocks
45           (##) Configure Ethernet pinout
46           (##) Configure Ethernet NVIC interrupt (in Interrupt mode)
47 
48       (#) Ethernet data reception is asynchronous, so call the following API
49           to start the listening mode:
50           (##) HAL_ETH_Start():
51                This API starts the MAC and DMA transmission and reception process,
52                without enabling end of transfer interrupts, in this mode user
53                has to poll for data reception by calling HAL_ETH_ReadData()
54           (##) HAL_ETH_Start_IT():
55                This API starts the MAC and DMA transmission and reception process,
56                end of transfer interrupts are enabled in this mode,
57                HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received
58 
59       (#) When data is received user can call the following API to get received data:
60           (##) HAL_ETH_ReadData(): Read a received packet
61 
62       (#) For transmission path, two APIs are available:
63          (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode
64          (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode,
65               HAL_ETH_TxCpltCallback() will be executed when end of transfer occur
66 
67       (#) Communication with an external PHY device:
68          (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY
69          (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register
70 
71       (#) Configure the Ethernet MAC after ETH peripheral initialization
72           (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef
73           (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef
74 
75       (#) Configure the Ethernet DMA after ETH peripheral initialization
76           (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef
77           (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef
78 
79       (#) Configure the Ethernet PTP after ETH peripheral initialization
80           (##) Define HAL_ETH_USE_PTP to use PTP APIs.
81           (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef
82           (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef
83           (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers
84           (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers
85           (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers
86           (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission
87           (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp
88           (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp
89 
90       -@- The ARP offload feature is not supported in this driver.
91 
92       -@- The PTP offload feature is not supported in this driver.
93 
94   *** Callback registration ***
95   =============================================
96 
97   The compilation define  USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
98   allows the user to configure dynamically the driver callbacks.
99   Use Function HAL_ETH_RegisterCallback() to register an interrupt callback.
100 
101   Function HAL_ETH_RegisterCallback() allows to register following callbacks:
102     (+) TxCpltCallback   : Tx Complete Callback.
103     (+) RxCpltCallback   : Rx Complete Callback.
104     (+) ErrorCallback    : Error Callback.
105     (+) PMTCallback      : Power Management Callback
106     (+) EEECallback      : EEE Callback.
107     (+) WakeUpCallback   : Wake UP Callback
108     (+) MspInitCallback  : MspInit Callback.
109     (+) MspDeInitCallback: MspDeInit Callback.
110 
111   This function takes as parameters the HAL peripheral handle, the Callback ID
112   and a pointer to the user callback function.
113 
114   For specific callbacks RxAllocateCallback use dedicated register callbacks:
115   respectively HAL_ETH_RegisterRxAllocateCallback().
116 
117   For specific callbacks RxLinkCallback use dedicated register callbacks:
118   respectively HAL_ETH_RegisterRxLinkCallback().
119 
120   For specific callbacks TxFreeCallback use dedicated register callbacks:
121   respectively HAL_ETH_RegisterTxFreeCallback().
122 
123   For specific callbacks TxPtpCallback use dedicated register callbacks:
124   respectively HAL_ETH_RegisterTxPtpCallback().
125 
126   Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default
127   weak function.
128   HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
129   and the Callback ID.
130   This function allows to reset following callbacks:
131     (+) TxCpltCallback   : Tx Complete Callback.
132     (+) RxCpltCallback   : Rx Complete Callback.
133     (+) ErrorCallback    : Error Callback.
134     (+) PMTCallback      : Power Management Callback
135     (+) EEECallback      : EEE Callback.
136     (+) WakeUpCallback   : Wake UP Callback
137     (+) MspInitCallback  : MspInit Callback.
138     (+) MspDeInitCallback: MspDeInit Callback.
139 
140   For specific callbacks RxAllocateCallback use dedicated unregister callbacks:
141   respectively HAL_ETH_UnRegisterRxAllocateCallback().
142 
143   For specific callbacks RxLinkCallback use dedicated unregister callbacks:
144   respectively HAL_ETH_UnRegisterRxLinkCallback().
145 
146   For specific callbacks TxFreeCallback use dedicated unregister callbacks:
147   respectively HAL_ETH_UnRegisterTxFreeCallback().
148 
149   For specific callbacks TxPtpCallback use dedicated unregister callbacks:
150   respectively HAL_ETH_UnRegisterTxPtpCallback().
151 
152   By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
153   all callbacks are set to the corresponding weak functions:
154   examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback().
155   Exception done for MspInit and MspDeInit functions that are
156   reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when
157   these callbacks are null (not registered beforehand).
158   if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit
159   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
160 
161   Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
162   Exception done MspInit/MspDeInit that can be registered/unregistered
163   in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
164   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
165   In that case first register the MspInit/MspDeInit user callbacks
166   using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit
167   or HAL_ETH_Init function.
168 
169   When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
170   not defined, the callback registration feature is not available and all callbacks
171   are set to the corresponding weak functions.
172 
173   @endverbatim
174   ******************************************************************************
175   */
176 
177 /* Includes ------------------------------------------------------------------*/
178 #include "stm32h5xx_hal.h"
179 
180 /** @addtogroup STM32H5xx_HAL_Driver
181   * @{
182   */
183 #ifdef HAL_ETH_MODULE_ENABLED
184 
185 #if defined(ETH)
186 
187 /** @defgroup ETH ETH
188   * @brief ETH HAL module driver
189   * @{
190   */
191 
192 /* Private typedef -----------------------------------------------------------*/
193 /* Private define ------------------------------------------------------------*/
194 /** @addtogroup ETH_Private_Constants ETH Private Constants
195   * @{
196   */
197 #define ETH_MACCR_MASK                0xFFFB7F7CU
198 #define ETH_MACECR_MASK               0x3F077FFFU
199 #define ETH_MACPFR_MASK               0x800007FFU
200 #define ETH_MACWTR_MASK               0x0000010FU
201 #define ETH_MACTFCR_MASK              0xFFFF00F2U
202 #define ETH_MACRFCR_MASK              0x00000003U
203 #define ETH_MTLTQOMR_MASK             0x00000072U
204 #define ETH_MTLRQOMR_MASK             0x0000007BU
205 
206 #define ETH_DMAMR_MASK                0x00007802U
207 #define ETH_DMASBMR_MASK              0x0000D001U
208 #define ETH_DMACCR_MASK               0x00013FFFU
209 #define ETH_DMACTCR_MASK              0x003F1010U
210 #define ETH_DMACRCR_MASK              0x803F0000U
211 #define ETH_MACPCSR_MASK              (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \
212                                        ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \
213                                        ETH_MACPCSR_RWKPFE)
214 
215 /* Timeout values */
216 #define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \
217                                                   ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\
218                                                   ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE))
219 
220 #define ETH_MACTSCR_MASK              0x0087FF2FU
221 
222 #define ETH_MACSTSUR_VALUE            0xFFFFFFFFU
223 #define ETH_MACSTNUR_VALUE            0xBB9ACA00U
224 #define ETH_SEGMENT_SIZE_DEFAULT      0x218U
225 /**
226   * @}
227   */
228 
229 /* Private macros ------------------------------------------------------------*/
230 /** @defgroup ETH_Private_Macros ETH Private Macros
231   * @{
232   */
233 /* Helper macros for TX descriptor handling */
234 #define INCR_TX_DESC_INDEX(inx, offset) do {\
235                                              (inx) += (offset);\
236                                              if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
237                                              (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
238                                            } while (0)
239 
240 /* Helper macros for RX descriptor handling */
241 #define INCR_RX_DESC_INDEX(inx, offset) do {\
242                                              (inx) += (offset);\
243                                              if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
244                                              (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
245                                            } while (0)
246 /**
247   * @}
248   */
249 /* Private function prototypes -----------------------------------------------*/
250 /** @defgroup ETH_Private_Functions   ETH Private Functions
251   * @{
252   */
253 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf);
254 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf);
255 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
256 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
257 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
258 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode);
259 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth);
260 
261 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
262 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
263 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
264 /**
265   * @}
266   */
267 
268 /* Exported functions ---------------------------------------------------------*/
269 /** @defgroup ETH_Exported_Functions ETH Exported Functions
270   * @{
271   */
272 
273 /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions
274   *  @brief    Initialization and Configuration functions
275   *
276 @verbatim
277 ===============================================================================
278             ##### Initialization and Configuration functions #####
279  ===============================================================================
280     [..]  This subsection provides a set of functions allowing to initialize and
281           deinitialize the ETH peripheral:
282 
283       (+) User must Implement HAL_ETH_MspInit() function in which he configures
284           all related peripherals resources (CLOCK, GPIO and NVIC ).
285 
286       (+) Call the function HAL_ETH_Init() to configure the selected device with
287           the selected configuration:
288         (++) MAC address
289         (++) Media interface (MII or RMII)
290         (++) Rx DMA Descriptors Tab
291         (++) Tx DMA Descriptors Tab
292         (++) Length of Rx Buffers
293 
294       (+) Call the function HAL_ETH_DeInit() to restore the default configuration
295           of the selected ETH peripheral.
296 
297 @endverbatim
298   * @{
299   */
300 
301 /**
302   * @brief  Initialize the Ethernet peripheral registers.
303   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
304   *         the configuration information for ETHERNET module
305   * @retval HAL status
306   */
HAL_ETH_Init(ETH_HandleTypeDef * heth)307 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
308 {
309   uint32_t tickstart;
310 
311   if (heth == NULL)
312   {
313     return HAL_ERROR;
314   }
315   if (heth->gState == HAL_ETH_STATE_RESET)
316   {
317     heth->gState = HAL_ETH_STATE_BUSY;
318 
319 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
320 
321     ETH_InitCallbacksToDefault(heth);
322 
323     if (heth->MspInitCallback == NULL)
324     {
325       heth->MspInitCallback = HAL_ETH_MspInit;
326     }
327 
328     /* Init the low level hardware */
329     heth->MspInitCallback(heth);
330 #else
331     /* Init the low level hardware : GPIO, CLOCK, NVIC. */
332     HAL_ETH_MspInit(heth);
333 
334 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
335   }
336 
337   __HAL_RCC_SBS_CLK_ENABLE();
338 
339   if (heth->Init.MediaInterface == HAL_ETH_MII_MODE)
340   {
341     HAL_SBS_ETHInterfaceSelect(SBS_ETH_MII);
342   }
343   else
344   {
345     HAL_SBS_ETHInterfaceSelect(SBS_ETH_RMII);
346   }
347 
348   /* Dummy read to sync with ETH */
349   (void)SBS->PMCR;
350 
351   /* Ethernet Software reset */
352   /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
353   /* After reset all the registers holds their respective reset values */
354   SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);
355 
356   /* Get tick */
357   tickstart = HAL_GetTick();
358 
359   /* Wait for software reset */
360   while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
361   {
362     if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
363     {
364       /* Set Error Code */
365       heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
366       /* Set State as Error */
367       heth->gState = HAL_ETH_STATE_ERROR;
368       /* Return Error */
369       return HAL_ERROR;
370     }
371   }
372 
373   /*------------------ MDIO CSR Clock Range Configuration --------------------*/
374   HAL_ETH_SetMDIOClockRange(heth);
375 
376   /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/
377   WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U));
378 
379   /*------------------ MAC, MTL and DMA default Configuration ----------------*/
380   ETH_MACDMAConfig(heth);
381 
382   /* SET DSL to 64 bit */
383   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);
384 
385   /* Set Receive Buffers Length (must be a multiple of 4) */
386   if ((heth->Init.RxBuffLen % 0x4U) != 0x0U)
387   {
388     /* Set Error Code */
389     heth->ErrorCode = HAL_ETH_ERROR_PARAM;
390     /* Set State as Error */
391     heth->gState = HAL_ETH_STATE_ERROR;
392     /* Return Error */
393     return HAL_ERROR;
394   }
395   else
396   {
397     MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1));
398   }
399 
400   /*------------------ DMA Tx Descriptors Configuration ----------------------*/
401   ETH_DMATxDescListInit(heth);
402 
403   /*------------------ DMA Rx Descriptors Configuration ----------------------*/
404   ETH_DMARxDescListInit(heth);
405 
406   /*--------------------- ETHERNET MAC Address Configuration ------------------*/
407   /* Set MAC addr bits 32 to 47 */
408   heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]);
409   /* Set MAC addr bits 0 to 31 */
410   heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) |
411                              ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]);
412 
413   heth->ErrorCode = HAL_ETH_ERROR_NONE;
414   heth->gState = HAL_ETH_STATE_READY;
415 
416   return HAL_OK;
417 }
418 
419 /**
420   * @brief  DeInitializes the ETH peripheral.
421   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
422   *         the configuration information for ETHERNET module
423   * @retval HAL status
424   */
HAL_ETH_DeInit(ETH_HandleTypeDef * heth)425 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
426 {
427   /* Set the ETH peripheral state to BUSY */
428   heth->gState = HAL_ETH_STATE_BUSY;
429 
430 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
431 
432   if (heth->MspDeInitCallback == NULL)
433   {
434     heth->MspDeInitCallback = HAL_ETH_MspDeInit;
435   }
436   /* DeInit the low level hardware */
437   heth->MspDeInitCallback(heth);
438 #else
439 
440   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
441   HAL_ETH_MspDeInit(heth);
442 
443 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
444 
445   /* Set ETH HAL state to Disabled */
446   heth->gState = HAL_ETH_STATE_RESET;
447 
448   /* Return function status */
449   return HAL_OK;
450 }
451 
452 /**
453   * @brief  Initializes the ETH MSP.
454   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
455   *         the configuration information for ETHERNET module
456   * @retval None
457   */
HAL_ETH_MspInit(ETH_HandleTypeDef * heth)458 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
459 {
460   /* Prevent unused argument(s) compilation warning */
461   UNUSED(heth);
462   /* NOTE : This function Should not be modified, when the callback is needed,
463   the HAL_ETH_MspInit could be implemented in the user file
464   */
465 }
466 
467 /**
468   * @brief  DeInitializes ETH MSP.
469   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
470   *         the configuration information for ETHERNET module
471   * @retval None
472   */
HAL_ETH_MspDeInit(ETH_HandleTypeDef * heth)473 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
474 {
475   /* Prevent unused argument(s) compilation warning */
476   UNUSED(heth);
477   /* NOTE : This function Should not be modified, when the callback is needed,
478   the HAL_ETH_MspDeInit could be implemented in the user file
479   */
480 }
481 
482 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
483 /**
484   * @brief  Register a User ETH Callback
485   *         To be used instead of the weak predefined callback
486   * @param heth eth handle
487   * @param CallbackID ID of the callback to be registered
488   *        This parameter can be one of the following values:
489   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
490   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
491   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
492   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
493   *          @arg @ref HAL_ETH_EEE_CB_ID         EEE Callback ID
494   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
495   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
496   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
497   * @param pCallback pointer to the Callback function
498   * @retval status
499   */
HAL_ETH_RegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID,pETH_CallbackTypeDef pCallback)500 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID,
501                                            pETH_CallbackTypeDef pCallback)
502 {
503   HAL_StatusTypeDef status = HAL_OK;
504 
505   if (pCallback == NULL)
506   {
507     /* Update the error code */
508     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
509 
510     return HAL_ERROR;
511   }
512 
513   if (heth->gState == HAL_ETH_STATE_READY)
514   {
515     switch (CallbackID)
516     {
517       case HAL_ETH_TX_COMPLETE_CB_ID :
518         heth->TxCpltCallback = pCallback;
519         break;
520 
521       case HAL_ETH_RX_COMPLETE_CB_ID :
522         heth->RxCpltCallback = pCallback;
523         break;
524 
525       case HAL_ETH_ERROR_CB_ID :
526         heth->ErrorCallback = pCallback;
527         break;
528 
529       case HAL_ETH_PMT_CB_ID :
530         heth->PMTCallback = pCallback;
531         break;
532 
533       case HAL_ETH_EEE_CB_ID :
534         heth->EEECallback = pCallback;
535         break;
536 
537       case HAL_ETH_WAKEUP_CB_ID :
538         heth->WakeUpCallback = pCallback;
539         break;
540 
541       case HAL_ETH_MSPINIT_CB_ID :
542         heth->MspInitCallback = pCallback;
543         break;
544 
545       case HAL_ETH_MSPDEINIT_CB_ID :
546         heth->MspDeInitCallback = pCallback;
547         break;
548 
549       default :
550         /* Update the error code */
551         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
552         /* Return error status */
553         status =  HAL_ERROR;
554         break;
555     }
556   }
557   else if (heth->gState == HAL_ETH_STATE_RESET)
558   {
559     switch (CallbackID)
560     {
561       case HAL_ETH_MSPINIT_CB_ID :
562         heth->MspInitCallback = pCallback;
563         break;
564 
565       case HAL_ETH_MSPDEINIT_CB_ID :
566         heth->MspDeInitCallback = pCallback;
567         break;
568 
569       default :
570         /* Update the error code */
571         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
572         /* Return error status */
573         status =  HAL_ERROR;
574         break;
575     }
576   }
577   else
578   {
579     /* Update the error code */
580     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
581     /* Return error status */
582     status =  HAL_ERROR;
583   }
584 
585   return status;
586 }
587 
588 /**
589   * @brief  Unregister an ETH Callback
590   *         ETH callback is redirected to the weak predefined callback
591   * @param heth eth handle
592   * @param CallbackID ID of the callback to be unregistered
593   *        This parameter can be one of the following values:
594   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
595   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
596   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
597   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
598   *          @arg @ref HAL_ETH_EEE_CB_ID         EEE Callback ID
599   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
600   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
601   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
602   * @retval status
603   */
HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID)604 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
605 {
606   HAL_StatusTypeDef status = HAL_OK;
607 
608   if (heth->gState == HAL_ETH_STATE_READY)
609   {
610     switch (CallbackID)
611     {
612       case HAL_ETH_TX_COMPLETE_CB_ID :
613         heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
614         break;
615 
616       case HAL_ETH_RX_COMPLETE_CB_ID :
617         heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
618         break;
619 
620       case HAL_ETH_ERROR_CB_ID :
621         heth->ErrorCallback = HAL_ETH_ErrorCallback;
622         break;
623 
624       case HAL_ETH_PMT_CB_ID :
625         heth->PMTCallback = HAL_ETH_PMTCallback;
626         break;
627 
628       case HAL_ETH_EEE_CB_ID :
629         heth->EEECallback = HAL_ETH_EEECallback;
630         break;
631 
632       case HAL_ETH_WAKEUP_CB_ID :
633         heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
634         break;
635 
636       case HAL_ETH_MSPINIT_CB_ID :
637         heth->MspInitCallback = HAL_ETH_MspInit;
638         break;
639 
640       case HAL_ETH_MSPDEINIT_CB_ID :
641         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
642         break;
643 
644       default :
645         /* Update the error code */
646         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
647         /* Return error status */
648         status =  HAL_ERROR;
649         break;
650     }
651   }
652   else if (heth->gState == HAL_ETH_STATE_RESET)
653   {
654     switch (CallbackID)
655     {
656       case HAL_ETH_MSPINIT_CB_ID :
657         heth->MspInitCallback = HAL_ETH_MspInit;
658         break;
659 
660       case HAL_ETH_MSPDEINIT_CB_ID :
661         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
662         break;
663 
664       default :
665         /* Update the error code */
666         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
667         /* Return error status */
668         status =  HAL_ERROR;
669         break;
670     }
671   }
672   else
673   {
674     /* Update the error code */
675     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
676     /* Return error status */
677     status =  HAL_ERROR;
678   }
679 
680   return status;
681 }
682 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
683 
684 /**
685   * @}
686   */
687 
688 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
689   *  @brief ETH Transmit and Receive functions
690   *
691 @verbatim
692   ==============================================================================
693                       ##### IO operation functions #####
694   ==============================================================================
695   [..]
696     This subsection provides a set of functions allowing to manage the ETH
697     data transfer.
698 
699 @endverbatim
700   * @{
701   */
702 
703 /**
704   * @brief  Enables Ethernet MAC and DMA reception and transmission
705   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
706   *         the configuration information for ETHERNET module
707   * @retval HAL status
708   */
HAL_ETH_Start(ETH_HandleTypeDef * heth)709 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
710 {
711   if (heth->gState == HAL_ETH_STATE_READY)
712   {
713     heth->gState = HAL_ETH_STATE_BUSY;
714 
715     /* Set nombre of descriptors to build */
716     heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
717 
718     /* Build all descriptors */
719     ETH_UpdateDescriptor(heth);
720 
721     /* Enable the MAC transmission */
722     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
723 
724     /* Enable the MAC reception */
725     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
726 
727     /* Set the Flush Transmit FIFO bit */
728     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
729 
730     /* Enable the DMA transmission */
731     SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
732 
733     /* Enable the DMA reception */
734     SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
735 
736     /* Clear Tx and Rx process stopped flags */
737     heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
738 
739     heth->gState = HAL_ETH_STATE_STARTED;
740 
741     return HAL_OK;
742   }
743   else
744   {
745     return HAL_ERROR;
746   }
747 }
748 
749 /**
750   * @brief  Enables Ethernet MAC and DMA reception/transmission in Interrupt mode
751   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
752   *         the configuration information for ETHERNET module
753   * @retval HAL status
754   */
HAL_ETH_Start_IT(ETH_HandleTypeDef * heth)755 HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
756 {
757   if (heth->gState == HAL_ETH_STATE_READY)
758   {
759     heth->gState = HAL_ETH_STATE_BUSY;
760 
761     /* save IT mode to ETH Handle */
762     heth->RxDescList.ItMode = 1U;
763     /* Disable Rx MMC Interrupts */
764     SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \
765             ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM);
766 
767     /* Disable Tx MMC Interrupts */
768     SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \
769             ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM);
770 
771     /* Set nombre of descriptors to build */
772     heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
773 
774     /* Build all descriptors */
775     ETH_UpdateDescriptor(heth);
776 
777     /* Enable the MAC transmission */
778     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
779 
780     /* Enable the MAC reception */
781     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
782 
783     /* Set the Flush Transmit FIFO bit */
784     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
785 
786     /* Enable the DMA transmission */
787     SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
788 
789     /* Enable the DMA reception */
790     SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
791 
792     /* Clear Tx and Rx process stopped flags */
793     heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
794 
795     /* Enable ETH DMA interrupts:
796     - Tx complete interrupt
797     - Rx complete interrupt
798     - Fatal bus interrupt
799     */
800     __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE  |
801                                    ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE));
802 
803     heth->gState = HAL_ETH_STATE_STARTED;
804     return HAL_OK;
805   }
806   else
807   {
808     return HAL_ERROR;
809   }
810 }
811 
812 /**
813   * @brief  Stop Ethernet MAC and DMA reception/transmission
814   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
815   *         the configuration information for ETHERNET module
816   * @retval HAL status
817   */
HAL_ETH_Stop(ETH_HandleTypeDef * heth)818 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
819 {
820   if (heth->gState == HAL_ETH_STATE_STARTED)
821   {
822     /* Set the ETH peripheral state to BUSY */
823     heth->gState = HAL_ETH_STATE_BUSY;
824     /* Disable the DMA transmission */
825     CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
826 
827     /* Disable the DMA reception */
828     CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
829 
830     /* Disable the MAC reception */
831     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
832 
833     /* Set the Flush Transmit FIFO bit */
834     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
835 
836     /* Disable the MAC transmission */
837     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
838 
839     heth->gState = HAL_ETH_STATE_READY;
840 
841     /* Return function status */
842     return HAL_OK;
843   }
844   else
845   {
846     return HAL_ERROR;
847   }
848 }
849 
850 /**
851   * @brief  Stop Ethernet MAC and DMA reception/transmission in Interrupt mode
852   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
853   *         the configuration information for ETHERNET module
854   * @retval HAL status
855   */
HAL_ETH_Stop_IT(ETH_HandleTypeDef * heth)856 HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
857 {
858   ETH_DMADescTypeDef *dmarxdesc;
859   uint32_t descindex;
860 
861   if (heth->gState == HAL_ETH_STATE_STARTED)
862   {
863     /* Set the ETH peripheral state to BUSY */
864     heth->gState = HAL_ETH_STATE_BUSY;
865 
866     /* Disable interrupts:
867     - Tx complete interrupt
868     - Rx complete interrupt
869     - Fatal bus interrupt
870     */
871     __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE  |
872                                     ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE));
873 
874     /* Disable the DMA transmission */
875     CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
876 
877     /* Disable the DMA reception */
878     CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
879 
880     /* Disable the MAC reception */
881     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
882     /* Set the Flush Transmit FIFO bit */
883     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
884 
885     /* Disable the MAC transmission */
886     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
887 
888     /* Clear IOC bit to all Rx descriptors */
889     for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
890     {
891       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
892       CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
893     }
894 
895     heth->RxDescList.ItMode = 0U;
896 
897     heth->gState = HAL_ETH_STATE_READY;
898 
899     /* Return function status */
900     return HAL_OK;
901   }
902   else
903   {
904     return HAL_ERROR;
905   }
906 }
907 
908 /**
909   * @brief  Sends an Ethernet Packet in polling mode.
910   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
911   *         the configuration information for ETHERNET module
912   * @param  pTxConfig: Hold the configuration of packet to be transmitted
913   * @param  Timeout: timeout value
914   * @retval HAL status
915   */
HAL_ETH_Transmit(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig,uint32_t Timeout)916 HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout)
917 {
918   uint32_t tickstart;
919   ETH_DMADescTypeDef *dmatxdesc;
920 
921   if (pTxConfig == NULL)
922   {
923     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
924     return HAL_ERROR;
925   }
926 
927   if (heth->gState == HAL_ETH_STATE_STARTED)
928   {
929     /* Config DMA Tx descriptor by Tx Packet info */
930     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
931     {
932       /* Set the ETH error code */
933       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
934       return HAL_ERROR;
935     }
936 
937     /* Ensure completion of descriptor preparation before transmission start */
938     __DSB();
939 
940     dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc];
941 
942     /* Incr current tx desc index */
943     INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
944 
945     /* Start transmission */
946     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
947     WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
948 
949     tickstart = HAL_GetTick();
950 
951     /* Wait for data to be transmitted or timeout occurred */
952     while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET)
953     {
954       if ((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET)
955       {
956         heth->ErrorCode |= HAL_ETH_ERROR_DMA;
957         heth->DMAErrorCode = heth->Instance->DMACSR;
958         /* Return function status */
959         return HAL_ERROR;
960       }
961 
962       /* Check for the Timeout */
963       if (Timeout != HAL_MAX_DELAY)
964       {
965         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
966         {
967           heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
968           /* Clear TX descriptor so that we can proceed */
969           dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD);
970           return HAL_ERROR;
971         }
972       }
973     }
974 
975     /* Return function status */
976     return HAL_OK;
977   }
978   else
979   {
980     return HAL_ERROR;
981   }
982 }
983 
984 /**
985   * @brief  Sends an Ethernet Packet in interrupt mode.
986   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
987   *         the configuration information for ETHERNET module
988   * @param  pTxConfig: Hold the configuration of packet to be transmitted
989   * @retval HAL status
990   */
HAL_ETH_Transmit_IT(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig)991 HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig)
992 {
993   if (pTxConfig == NULL)
994   {
995     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
996     return HAL_ERROR;
997   }
998 
999   if (heth->gState == HAL_ETH_STATE_STARTED)
1000   {
1001     /* Save the packet pointer to release.  */
1002     heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData;
1003 
1004     /* Config DMA Tx descriptor by Tx Packet info */
1005     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
1006     {
1007       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
1008       return HAL_ERROR;
1009     }
1010 
1011     /* Ensure completion of descriptor preparation before transmission start */
1012     __DSB();
1013 
1014     /* Incr current tx desc index */
1015     INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
1016 
1017     /* Start transmission */
1018     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
1019     WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
1020 
1021     return HAL_OK;
1022 
1023   }
1024   else
1025   {
1026     return HAL_ERROR;
1027   }
1028 }
1029 
1030 /**
1031   * @brief  Read a received packet.
1032   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1033   *         the configuration information for ETHERNET module
1034   * @param  pAppBuff: Pointer to an application buffer to receive the packet.
1035   * @retval HAL status
1036   */
HAL_ETH_ReadData(ETH_HandleTypeDef * heth,void ** pAppBuff)1037 HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
1038 {
1039   uint32_t descidx, descidx_temp;
1040   ETH_DMADescTypeDef *dmarxdesc, *dmarxdesc_temp;
1041   uint32_t desccnt = 0U;
1042   uint32_t desccntmax;
1043   uint32_t bufflength;
1044   uint8_t rxdataready = 0U;
1045 
1046 
1047   if (pAppBuff == NULL)
1048   {
1049     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1050     return HAL_ERROR;
1051   }
1052 
1053   if (heth->gState != HAL_ETH_STATE_STARTED)
1054   {
1055     return HAL_ERROR;
1056   }
1057 
1058   descidx = heth->RxDescList.RxDescIdx;
1059   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1060   desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt;
1061 
1062   /* Check if descriptor is not owned by DMA */
1063   while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
1064          && (rxdataready == 0U))
1065   {
1066     if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
1067     {
1068       /* Check if first descriptor */
1069       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET)
1070       {
1071         heth->RxDescList.RxDescCnt = 0;
1072         heth->RxDescList.RxDataLength = 0;
1073       }
1074 
1075       /* Check if last descriptor */
1076       bufflength = heth->Init.RxBuffLen;
1077       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET)
1078       {
1079         bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength;
1080 
1081         /* Save Last descriptor index */
1082         heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3;
1083 
1084         /* Packet ready */
1085         rxdataready = 1;
1086 
1087         if (READ_BIT(dmarxdesc->DESC1, ETH_DMARXNDESCWBF_TSA) != (uint32_t)RESET)
1088         {
1089           descidx_temp = descidx;
1090           INCR_RX_DESC_INDEX(descidx_temp, 1U);
1091 
1092           dmarxdesc_temp = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx_temp];
1093 
1094           if (READ_BIT(dmarxdesc_temp->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET)
1095           {
1096             /* Get timestamp high */
1097             heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc_temp->DESC1;
1098             /* Get timestamp low */
1099             heth->RxDescList.TimeStamp.TimeStampLow  = dmarxdesc_temp->DESC0;
1100           }
1101         }
1102       }
1103 
1104       /* Link data */
1105 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1106       /*Call registered Link callback*/
1107       heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1108                            (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
1109 #else
1110       /* Link callback */
1111       HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1112                              (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
1113 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1114       heth->RxDescList.RxDescCnt++;
1115       heth->RxDescList.RxDataLength += bufflength;
1116 
1117       /* Clear buffer pointer */
1118       dmarxdesc->BackupAddr0 = 0;
1119     }
1120 
1121     /* Increment current rx descriptor index */
1122     INCR_RX_DESC_INDEX(descidx, 1U);
1123     /* Get current descriptor address */
1124     dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1125     desccnt++;
1126   }
1127 
1128   heth->RxDescList.RxBuildDescCnt += desccnt;
1129   if ((heth->RxDescList.RxBuildDescCnt) != 0U)
1130   {
1131     /* Update Descriptors */
1132     ETH_UpdateDescriptor(heth);
1133   }
1134 
1135   heth->RxDescList.RxDescIdx = descidx;
1136 
1137   if (rxdataready == 1U)
1138   {
1139     /* Return received packet */
1140     *pAppBuff = heth->RxDescList.pRxStart;
1141     /* Reset first element */
1142     heth->RxDescList.pRxStart = NULL;
1143 
1144     return HAL_OK;
1145   }
1146 
1147   /* Packet not ready */
1148   return HAL_ERROR;
1149 }
1150 
1151 /**
1152   * @brief  This function gives back Rx Desc of the last received Packet
1153   *         to the DMA, so ETH DMA will be able to use these descriptors
1154   *         to receive next Packets.
1155   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1156   *         the configuration information for ETHERNET module
1157   * @retval HAL status
1158   */
ETH_UpdateDescriptor(ETH_HandleTypeDef * heth)1159 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
1160 {
1161   uint32_t descidx;
1162   uint32_t desccount;
1163   ETH_DMADescTypeDef *dmarxdesc;
1164   uint8_t *buff = NULL;
1165   uint8_t allocStatus = 1U;
1166 
1167   descidx = heth->RxDescList.RxBuildDescIdx;
1168   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1169   desccount = heth->RxDescList.RxBuildDescCnt;
1170 
1171   while ((desccount > 0U) && (allocStatus != 0U))
1172   {
1173     /* Check if a buffer's attached the descriptor */
1174     if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
1175     {
1176       /* Get a new buffer. */
1177 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1178       /*Call registered Allocate callback*/
1179       heth->rxAllocateCallback(&buff);
1180 #else
1181       /* Allocate callback */
1182       HAL_ETH_RxAllocateCallback(&buff);
1183 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1184       if (buff == NULL)
1185       {
1186         allocStatus = 0U;
1187       }
1188       else
1189       {
1190         WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
1191         WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff);
1192       }
1193     }
1194 
1195     if (allocStatus != 0U)
1196     {
1197       /* Ensure rest of descriptor is written to RAM before the OWN bit */
1198       __DMB();
1199 
1200       if (heth->RxDescList.ItMode != 0U)
1201       {
1202         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC);
1203       }
1204       else
1205       {
1206         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V);
1207       }
1208 
1209       /* Increment current rx descriptor index */
1210       INCR_RX_DESC_INDEX(descidx, 1U);
1211       /* Get current descriptor address */
1212       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1213       desccount--;
1214     }
1215   }
1216 
1217   if (heth->RxDescList.RxBuildDescCnt != desccount)
1218   {
1219     /* Set the Tail pointer address */
1220     WRITE_REG(heth->Instance->DMACRDTPR, 0);
1221 
1222     heth->RxDescList.RxBuildDescIdx = descidx;
1223     heth->RxDescList.RxBuildDescCnt = desccount;
1224   }
1225 }
1226 
1227 /**
1228   * @brief  Register the Rx alloc callback.
1229   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1230   *         the configuration information for ETHERNET module
1231   * @param  rxAllocateCallback: pointer to function to alloc buffer
1232   * @retval HAL status
1233   */
HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef * heth,pETH_rxAllocateCallbackTypeDef rxAllocateCallback)1234 HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
1235                                                      pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
1236 {
1237   if (rxAllocateCallback == NULL)
1238   {
1239     /* No buffer to save */
1240     return HAL_ERROR;
1241   }
1242 
1243   /* Set function to allocate buffer */
1244   heth->rxAllocateCallback = rxAllocateCallback;
1245 
1246   return HAL_OK;
1247 }
1248 
1249 /**
1250   * @brief  Unregister the Rx alloc callback.
1251   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1252   *         the configuration information for ETHERNET module
1253   * @retval HAL status
1254   */
HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef * heth)1255 HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
1256 {
1257   /* Set function to allocate buffer */
1258   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
1259 
1260   return HAL_OK;
1261 }
1262 
1263 /**
1264   * @brief  Rx Allocate callback.
1265   * @param  buff: pointer to allocated buffer
1266   * @retval None
1267   */
HAL_ETH_RxAllocateCallback(uint8_t ** buff)1268 __weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
1269 {
1270   /* Prevent unused argument(s) compilation warning */
1271   UNUSED(buff);
1272   /* NOTE : This function Should not be modified, when the callback is needed,
1273   the HAL_ETH_RxAllocateCallback could be implemented in the user file
1274   */
1275 }
1276 
1277 /**
1278   * @brief  Rx Link callback.
1279   * @param  pStart: pointer to packet start
1280   * @param  pStart: pointer to packet end
1281   * @param  buff: pointer to received data
1282   * @param  Length: received data length
1283   * @retval None
1284   */
HAL_ETH_RxLinkCallback(void ** pStart,void ** pEnd,uint8_t * buff,uint16_t Length)1285 __weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
1286 {
1287   /* Prevent unused argument(s) compilation warning */
1288   UNUSED(pStart);
1289   UNUSED(pEnd);
1290   UNUSED(buff);
1291   UNUSED(Length);
1292   /* NOTE : This function Should not be modified, when the callback is needed,
1293   the HAL_ETH_RxLinkCallback could be implemented in the user file
1294   */
1295 }
1296 
1297 /**
1298   * @brief  Set the Rx link data function.
1299   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1300   *         the configuration information for ETHERNET module
1301   * @param  rxLinkCallback: pointer to function to link data
1302   * @retval HAL status
1303   */
HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef * heth,pETH_rxLinkCallbackTypeDef rxLinkCallback)1304 HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
1305 {
1306   if (rxLinkCallback == NULL)
1307   {
1308     /* No buffer to save */
1309     return HAL_ERROR;
1310   }
1311 
1312   /* Set function to link data */
1313   heth->rxLinkCallback = rxLinkCallback;
1314 
1315   return HAL_OK;
1316 }
1317 
1318 /**
1319   * @brief  Unregister the Rx link callback.
1320   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1321   *         the configuration information for ETHERNET module
1322   * @retval HAL status
1323   */
HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef * heth)1324 HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
1325 {
1326   /* Set function to allocate buffer */
1327   heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
1328 
1329   return HAL_OK;
1330 }
1331 
1332 /**
1333   * @brief  Get the error state of the last received packet.
1334   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1335   *         the configuration information for ETHERNET module
1336   * @param  pErrorCode: pointer to uint32_t to hold the error code
1337   * @retval HAL status
1338   */
HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef * heth,uint32_t * pErrorCode)1339 HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
1340 {
1341   /* Get error bits. */
1342   *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK);
1343 
1344   return HAL_OK;
1345 }
1346 
1347 /**
1348   * @brief  Set the Tx free function.
1349   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1350   *         the configuration information for ETHERNET module
1351   * @param  txFreeCallback: pointer to function to release the packet
1352   * @retval HAL status
1353   */
HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef * heth,pETH_txFreeCallbackTypeDef txFreeCallback)1354 HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
1355 {
1356   if (txFreeCallback == NULL)
1357   {
1358     /* No buffer to save */
1359     return HAL_ERROR;
1360   }
1361 
1362   /* Set function to free transmmitted packet */
1363   heth->txFreeCallback = txFreeCallback;
1364 
1365   return HAL_OK;
1366 }
1367 
1368 /**
1369   * @brief  Unregister the Tx free callback.
1370   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1371   *         the configuration information for ETHERNET module
1372   * @retval HAL status
1373   */
HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef * heth)1374 HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
1375 {
1376   /* Set function to allocate buffer */
1377   heth->txFreeCallback = HAL_ETH_TxFreeCallback;
1378 
1379   return HAL_OK;
1380 }
1381 
1382 /**
1383   * @brief  Tx Free callback.
1384   * @param  buff: pointer to buffer to free
1385   * @retval None
1386   */
HAL_ETH_TxFreeCallback(uint32_t * buff)1387 __weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
1388 {
1389   /* Prevent unused argument(s) compilation warning */
1390   UNUSED(buff);
1391   /* NOTE : This function Should not be modified, when the callback is needed,
1392   the HAL_ETH_TxFreeCallback could be implemented in the user file
1393   */
1394 }
1395 
1396 /**
1397   * @brief  Release transmitted Tx packets.
1398   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1399   *         the configuration information for ETHERNET module
1400   * @retval HAL status
1401   */
HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef * heth)1402 HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
1403 {
1404   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1405   uint32_t numOfBuf =  dmatxdesclist->BuffersInUse;
1406   uint32_t idx =       dmatxdesclist->releaseIndex;
1407   uint8_t pktTxStatus = 1U;
1408   uint8_t pktInUse;
1409 #ifdef HAL_ETH_USE_PTP
1410   ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
1411 #endif /* HAL_ETH_USE_PTP */
1412 
1413   /* Loop through buffers in use.  */
1414   while ((numOfBuf != 0U) && (pktTxStatus != 0U))
1415   {
1416     pktInUse = 1U;
1417     numOfBuf--;
1418     /* If no packet, just examine the next packet.  */
1419     if (dmatxdesclist->PacketAddress[idx] == NULL)
1420     {
1421       /* No packet in use, skip to next.  */
1422       idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U);
1423       pktInUse = 0U;
1424     }
1425 
1426     if (pktInUse != 0U)
1427     {
1428       /* Determine if the packet has been transmitted.  */
1429       if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U)
1430       {
1431 #ifdef HAL_ETH_USE_PTP
1432         /* Disable Ptp transmission */
1433         CLEAR_BIT(heth->Init.TxDesc[idx].DESC3, (0x40000000U));
1434 
1435         /* Get timestamp low */
1436         timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0;
1437         /* Get timestamp high */
1438         timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1;
1439 #endif /* HAL_ETH_USE_PTP */
1440 
1441 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1442         /*Call registered callbacks*/
1443 #ifdef HAL_ETH_USE_PTP
1444         /* Handle Ptp  */
1445         heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1446 #endif  /* HAL_ETH_USE_PTP */
1447         /* Release the packet.  */
1448         heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1449 #else
1450         /* Call callbacks */
1451 #ifdef HAL_ETH_USE_PTP
1452         /* Handle Ptp  */
1453         HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1454 #endif  /* HAL_ETH_USE_PTP */
1455         /* Release the packet.  */
1456         HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1457 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1458 
1459         /* Clear the entry in the in-use array.  */
1460         dmatxdesclist->PacketAddress[idx] = NULL;
1461 
1462         /* Update the transmit relesae index and number of buffers in use.  */
1463         idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U);
1464         dmatxdesclist->BuffersInUse = numOfBuf;
1465         dmatxdesclist->releaseIndex = idx;
1466       }
1467       else
1468       {
1469         /* Get out of the loop!  */
1470         pktTxStatus = 0U;
1471       }
1472     }
1473   }
1474   return HAL_OK;
1475 }
1476 
1477 #ifdef HAL_ETH_USE_PTP
1478 /**
1479   * @brief  Set the Ethernet PTP configuration.
1480   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1481   *         the configuration information for ETHERNET module
1482   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1483   *         the configuration information for PTP
1484   * @retval HAL status
1485   */
HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1486 HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1487 {
1488   uint32_t tmpTSCR;
1489   ETH_TimeTypeDef time;
1490 
1491   if (ptpconfig == NULL)
1492   {
1493     return HAL_ERROR;
1494   }
1495 
1496   tmpTSCR = ptpconfig->Timestamp |
1497             ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) |
1498             ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) |
1499             ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) |
1500             ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) |
1501             ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) |
1502             ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) |
1503             ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) |
1504             ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) |
1505             ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) |
1506             ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) |
1507             ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) |
1508             ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) |
1509             ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos);
1510 
1511   /* Write to MACTSCR */
1512   MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1513 
1514   /* Enable Timestamp */
1515   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1516   WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc);
1517   WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend);
1518 
1519   /* Enable Timestamp */
1520   if (ptpconfig->TimestampAddendUpdate == ENABLE)
1521   {
1522     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG);
1523     while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0) {}
1524   }
1525 
1526   /* Enable Update mode */
1527   if (ptpconfig->TimestampUpdateMode == ENABLE)
1528   {
1529     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCFUPDT);
1530   }
1531 
1532   /* Initialize Time */
1533   time.Seconds = 0;
1534   time.NanoSeconds = 0;
1535   HAL_ETH_PTP_SetTime(heth, &time);
1536 
1537   /* Ptp Init */
1538   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT);
1539 
1540   /* Set PTP Configuration done */
1541   heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED;
1542 
1543   /* Return function status */
1544   return HAL_OK;
1545 }
1546 
1547 /**
1548   * @brief  Get the Ethernet PTP configuration.
1549   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1550   *         the configuration information for ETHERNET module
1551   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1552   *         the configuration information for PTP
1553   * @retval HAL status
1554   */
HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1555 HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1556 {
1557   if (ptpconfig == NULL)
1558   {
1559     return HAL_ERROR;
1560   }
1561   ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1562   ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR,
1563                                           ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE;
1564   ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR,
1565                                        ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE;
1566   ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR,
1567                                                 ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U)
1568                                      ? ENABLE : DISABLE;
1569   ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR,
1570                                       ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE;
1571   ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR,
1572                                             ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE;
1573   ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR,
1574                                         ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE;
1575   ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR,
1576                                         ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE;
1577   ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR,
1578                                          ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE;
1579   ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR,
1580                                           ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE;
1581   ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR,
1582                                              ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U)
1583                                   ? ENABLE : DISABLE;
1584   ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR,
1585                                           ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U)
1586                                ? ENABLE : DISABLE;
1587   ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR,
1588                                                       ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE;
1589   ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR,
1590                                               ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U)
1591                                    ? ENABLE : DISABLE;
1592 
1593   /* Return function status */
1594   return HAL_OK;
1595 }
1596 
1597 /**
1598   * @brief  Set Seconds and Nanoseconds for the Ethernet PTP registers.
1599   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1600   *         the configuration information for ETHERNET module
1601   * @param  heth: pointer to a ETH_TimeTypeDef structure that contains
1602   *         time to set
1603   * @retval HAL status
1604   */
HAL_ETH_PTP_SetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1605 HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1606 {
1607   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1608   {
1609     /* Set Seconds */
1610     heth->Instance->MACSTSUR = time->Seconds;
1611 
1612     /* Set NanoSeconds */
1613     heth->Instance->MACSTNUR = time->NanoSeconds;
1614 
1615     /* Return function status */
1616     return HAL_OK;
1617   }
1618   else
1619   {
1620     /* Return function status */
1621     return HAL_ERROR;
1622   }
1623 }
1624 
1625 /**
1626   * @brief  Get Seconds and Nanoseconds for the Ethernet PTP registers.
1627   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1628   *         the configuration information for ETHERNET module
1629   * @param  heth: pointer to a ETH_TimeTypeDef structure that contains
1630   *         time to get
1631   * @retval HAL status
1632   */
HAL_ETH_PTP_GetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1633 HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1634 {
1635   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1636   {
1637     /* Get Seconds */
1638     time->Seconds = heth->Instance->MACSTSUR;
1639 
1640     /* Get NanoSeconds */
1641     time->NanoSeconds = heth->Instance->MACSTNUR;
1642 
1643     /* Return function status */
1644     return HAL_OK;
1645   }
1646   else
1647   {
1648     /* Return function status */
1649     return HAL_ERROR;
1650   }
1651 }
1652 
1653 /**
1654   * @brief  Update time for the Ethernet PTP registers.
1655   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1656   *         the configuration information for ETHERNET module
1657   * @param  timeupdate: pointer to a ETH_TIMEUPDATETypeDef structure that contains
1658   *         the time update information
1659   * @retval HAL status
1660   */
HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef * heth,ETH_PtpUpdateTypeDef ptpoffsettype,ETH_TimeTypeDef * timeoffset)1661 HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1662                                             ETH_TimeTypeDef *timeoffset)
1663 {
1664   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1665   {
1666     if (ptpoffsettype ==  HAL_ETH_PTP_NEGATIVE_UPDATE)
1667     {
1668       /* Set Seconds update */
1669       heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U;
1670 
1671       if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR)
1672       {
1673         /* Set nanoSeconds update */
1674         heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds;
1675       }
1676       else
1677       {
1678         /* Set nanoSeconds update */
1679         heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U;
1680       }
1681     }
1682     else
1683     {
1684       /* Set Seconds update */
1685       heth->Instance->MACSTSUR = timeoffset->Seconds;
1686       /* Set nanoSeconds update */
1687       heth->Instance->MACSTNUR = timeoffset->NanoSeconds;
1688     }
1689 
1690     /* Return function status */
1691     return HAL_OK;
1692   }
1693   else
1694   {
1695     /* Return function status */
1696     return HAL_ERROR;
1697   }
1698 }
1699 
1700 /**
1701   * @brief  Insert Timestamp in transmission.
1702   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1703   *         the configuration information for ETHERNET module
1704   * @param  txtimestampconf: Enable or Disable timestamp in transmission
1705   * @retval HAL status
1706   */
HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef * heth)1707 HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1708 {
1709   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1710   uint32_t descidx = dmatxdesclist->CurTxDesc;
1711   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1712 
1713   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1714   {
1715     /* Enable Time Stamp transmission */
1716     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE);
1717 
1718     /* Return function status */
1719     return HAL_OK;
1720   }
1721   else
1722   {
1723     /* Return function status */
1724     return HAL_ERROR;
1725   }
1726 }
1727 
1728 /**
1729   * @brief  Get transmission timestamp.
1730   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1731   *         the configuration information for ETHERNET module
1732   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1733   *         transmission timestamp
1734   * @retval HAL status
1735   */
HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1736 HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1737 {
1738   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1739   uint32_t idx =       dmatxdesclist->releaseIndex;
1740   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1741 
1742   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1743   {
1744     /* Get timestamp low */
1745     timestamp->TimeStampLow = dmatxdesc->DESC0;
1746     /* Get timestamp high */
1747     timestamp->TimeStampHigh = dmatxdesc->DESC1;
1748 
1749     /* Return function status */
1750     return HAL_OK;
1751   }
1752   else
1753   {
1754     /* Return function status */
1755     return HAL_ERROR;
1756   }
1757 }
1758 
1759 /**
1760   * @brief  Get receive timestamp.
1761   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1762   *         the configuration information for ETHERNET module
1763   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1764   *         receive timestamp
1765   * @retval HAL status
1766   */
HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1767 HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1768 {
1769   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1770   {
1771     /* Get timestamp low */
1772     timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
1773     /* Get timestamp high */
1774     timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
1775 
1776     /* Return function status */
1777     return HAL_OK;
1778   }
1779   else
1780   {
1781     /* Return function status */
1782     return HAL_ERROR;
1783   }
1784 }
1785 
1786 /**
1787   * @brief  Register the Tx Ptp callback.
1788   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1789   *         the configuration information for ETHERNET module
1790   * @param  txPtpCallback: Function to handle Ptp transmission
1791   * @retval HAL status
1792   */
HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef * heth,pETH_txPtpCallbackTypeDef txPtpCallback)1793 HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1794 {
1795   if (txPtpCallback == NULL)
1796   {
1797     /* No buffer to save */
1798     return HAL_ERROR;
1799   }
1800   /* Set Function to handle Tx Ptp */
1801   heth->txPtpCallback = txPtpCallback;
1802 
1803   return HAL_OK;
1804 }
1805 
1806 /**
1807   * @brief  Unregister the Tx Ptp callback.
1808   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1809   *         the configuration information for ETHERNET module
1810   * @retval HAL status
1811   */
HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef * heth)1812 HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1813 {
1814   /* Set function to allocate buffer */
1815   heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1816 
1817   return HAL_OK;
1818 }
1819 
1820 /**
1821   * @brief  Tx Ptp callback.
1822   * @param  buff: pointer to application buffer
1823   * @retval None
1824   */
HAL_ETH_TxPtpCallback(uint32_t * buff,ETH_TimeStampTypeDef * timestamp)1825 __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1826 {
1827   /* Prevent unused argument(s) compilation warning */
1828   UNUSED(buff);
1829   /* NOTE : This function Should not be modified, when the callback is needed,
1830   the HAL_ETH_TxPtpCallback could be implemented in the user file
1831   */
1832 }
1833 #endif  /* HAL_ETH_USE_PTP */
1834 
1835 /**
1836   * @brief  This function handles ETH interrupt request.
1837   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1838   *         the configuration information for ETHERNET module
1839   * @retval HAL status
1840   */
HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)1841 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1842 {
1843   uint32_t macirqenable;
1844   /* Packet received */
1845   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_RI))
1846   {
1847     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_RIE))
1848     {
1849       /* Clear the Eth DMA Rx IT pending bits */
1850       __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
1851 
1852 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1853       /*Call registered Receive complete callback*/
1854       heth->RxCpltCallback(heth);
1855 #else
1856       /* Receive complete callback */
1857       HAL_ETH_RxCpltCallback(heth);
1858 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1859     }
1860   }
1861 
1862   /* Packet transmitted */
1863   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_TI))
1864   {
1865     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_TIE))
1866     {
1867       /* Clear the Eth DMA Tx IT pending bits */
1868       __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
1869 
1870 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1871       /*Call registered Transmit complete callback*/
1872       heth->TxCpltCallback(heth);
1873 #else
1874       /* Transfer complete callback */
1875       HAL_ETH_TxCpltCallback(heth);
1876 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1877     }
1878   }
1879 
1880 
1881   /* ETH DMA Error */
1882   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_AIS))
1883   {
1884     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_AIE))
1885     {
1886       heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1887 
1888       /* if fatal bus error occurred */
1889       if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_FBE))
1890       {
1891         /* Get DMA error code  */
1892         heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS));
1893 
1894         /* Disable all interrupts */
1895         __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE);
1896 
1897         /* Set HAL state to ERROR */
1898         heth->gState = HAL_ETH_STATE_ERROR;
1899       }
1900       else
1901       {
1902         /* Get DMA error status  */
1903         heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1904                                                                ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1905 
1906         /* Clear the interrupt summary flag */
1907         __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1908                                       ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1909       }
1910 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1911       /* Call registered Error callback*/
1912       heth->ErrorCallback(heth);
1913 #else
1914       /* Ethernet DMA Error callback */
1915       HAL_ETH_ErrorCallback(heth);
1916 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1917 
1918     }
1919   }
1920 
1921   /* ETH MAC Error IT */
1922   macirqenable = heth->Instance->MACIER;
1923   if (((macirqenable & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \
1924       ((macirqenable & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE))
1925   {
1926     heth->ErrorCode |= HAL_ETH_ERROR_MAC;
1927 
1928     /* Get MAC Rx Tx status and clear Status register pending bit */
1929     heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR);
1930 
1931     heth->gState = HAL_ETH_STATE_ERROR;
1932 
1933 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1934     /* Call registered Error callback*/
1935     heth->ErrorCallback(heth);
1936 #else
1937     /* Ethernet Error callback */
1938     HAL_ETH_ErrorCallback(heth);
1939 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1940 
1941     heth->MACErrorCode = (uint32_t)(0x0U);
1942   }
1943 
1944   /* ETH PMT IT */
1945   if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_PMT_IT))
1946   {
1947     /* Get MAC Wake-up source and clear the status register pending bit */
1948     heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD));
1949 
1950 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1951     /* Call registered PMT callback*/
1952     heth->PMTCallback(heth);
1953 #else
1954     /* Ethernet PMT callback */
1955     HAL_ETH_PMTCallback(heth);
1956 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1957 
1958     heth->MACWakeUpEvent = (uint32_t)(0x0U);
1959   }
1960 
1961   /* ETH EEE IT */
1962   if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_LPI_IT))
1963   {
1964     /* Get MAC LPI interrupt source and clear the status register pending bit */
1965     heth->MACLPIEvent = READ_BIT(heth->Instance->MACPCSR, 0x0000000FU);
1966 
1967 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1968     /* Call registered EEE callback*/
1969     heth->EEECallback(heth);
1970 #else
1971     /* Ethernet EEE callback */
1972     HAL_ETH_EEECallback(heth);
1973 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1974 
1975     heth->MACLPIEvent = (uint32_t)(0x0U);
1976   }
1977 
1978   /* check ETH WAKEUP exti flag */
1979   if (__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
1980   {
1981     /* Clear ETH WAKEUP Exti pending bit */
1982     __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
1983 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1984     /* Call registered WakeUp callback*/
1985     heth->WakeUpCallback(heth);
1986 #else
1987     /* ETH WAKEUP callback */
1988     HAL_ETH_WakeUpCallback(heth);
1989 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1990   }
1991 }
1992 
1993 /**
1994   * @brief  Tx Transfer completed callbacks.
1995   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1996   *         the configuration information for ETHERNET module
1997   * @retval None
1998   */
HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)1999 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
2000 {
2001   /* Prevent unused argument(s) compilation warning */
2002   UNUSED(heth);
2003   /* NOTE : This function Should not be modified, when the callback is needed,
2004   the HAL_ETH_TxCpltCallback could be implemented in the user file
2005   */
2006 }
2007 
2008 /**
2009   * @brief  Rx Transfer completed callbacks.
2010   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2011   *         the configuration information for ETHERNET module
2012   * @retval None
2013   */
HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)2014 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2015 {
2016   /* Prevent unused argument(s) compilation warning */
2017   UNUSED(heth);
2018   /* NOTE : This function Should not be modified, when the callback is needed,
2019   the HAL_ETH_RxCpltCallback could be implemented in the user file
2020   */
2021 }
2022 
2023 /**
2024   * @brief  Ethernet transfer error callbacks
2025   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2026   *         the configuration information for ETHERNET module
2027   * @retval None
2028   */
HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)2029 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2030 {
2031   /* Prevent unused argument(s) compilation warning */
2032   UNUSED(heth);
2033   /* NOTE : This function Should not be modified, when the callback is needed,
2034   the HAL_ETH_ErrorCallback could be implemented in the user file
2035   */
2036 }
2037 
2038 /**
2039   * @brief  Ethernet Power Management module IT callback
2040   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2041   *         the configuration information for ETHERNET module
2042   * @retval None
2043   */
HAL_ETH_PMTCallback(ETH_HandleTypeDef * heth)2044 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2045 {
2046   /* Prevent unused argument(s) compilation warning */
2047   UNUSED(heth);
2048   /* NOTE : This function Should not be modified, when the callback is needed,
2049   the HAL_ETH_PMTCallback could be implemented in the user file
2050   */
2051 }
2052 
2053 /**
2054   * @brief  Energy Efficient Etherent IT callback
2055   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2056   *         the configuration information for ETHERNET module
2057   * @retval None
2058   */
HAL_ETH_EEECallback(ETH_HandleTypeDef * heth)2059 __weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth)
2060 {
2061   /* Prevent unused argument(s) compilation warning */
2062   UNUSED(heth);
2063   /* NOTE : This function Should not be modified, when the callback is needed,
2064   the HAL_ETH_EEECallback could be implemented in the user file
2065   */
2066 }
2067 
2068 /**
2069   * @brief  ETH WAKEUP interrupt callback
2070   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2071   *         the configuration information for ETHERNET module
2072   * @retval None
2073   */
HAL_ETH_WakeUpCallback(ETH_HandleTypeDef * heth)2074 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2075 {
2076   /* Prevent unused argument(s) compilation warning */
2077   UNUSED(heth);
2078   /* NOTE : This function Should not be modified, when the callback is needed,
2079             the HAL_ETH_WakeUpCallback could be implemented in the user file
2080    */
2081 }
2082 
2083 /**
2084   * @brief  Read a PHY register
2085   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2086   *         the configuration information for ETHERNET module
2087   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2088   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2089   * @param pRegValue: parameter to hold read value
2090   * @retval HAL status
2091   */
HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t * pRegValue)2092 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2093                                           uint32_t *pRegValue)
2094 {
2095   uint32_t tickstart;
2096   uint32_t tmpreg;
2097 
2098   /* Check for the Busy flag */
2099   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2100   {
2101     return HAL_ERROR;
2102   }
2103 
2104   /* Get the  MACMDIOAR value */
2105   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2106 
2107   /* Prepare the MDIO Address Register value
2108      - Set the PHY device address
2109      - Set the PHY register address
2110      - Set the read mode
2111      - Set the MII Busy bit */
2112 
2113   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2114   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2115   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD);
2116   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2117 
2118   /* Write the result value into the MDII Address register */
2119   WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
2120 
2121   tickstart = HAL_GetTick();
2122 
2123   /* Wait for the Busy flag */
2124   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2125   {
2126     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2127     {
2128       return HAL_ERROR;
2129     }
2130   }
2131 
2132   /* Get MACMIIDR value */
2133   WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR);
2134 
2135   return HAL_OK;
2136 }
2137 
2138 
2139 /**
2140   * @brief  Writes to a PHY register.
2141   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2142   *         the configuration information for ETHERNET module
2143   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2144   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2145   * @param  RegValue: the value to write
2146   * @retval HAL status
2147   */
HAL_ETH_WritePHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t RegValue)2148 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2149                                            uint32_t RegValue)
2150 {
2151   uint32_t tickstart;
2152   uint32_t tmpreg;
2153 
2154   /* Check for the Busy flag */
2155   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2156   {
2157     return HAL_ERROR;
2158   }
2159 
2160   /* Get the  MACMDIOAR value */
2161   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2162 
2163   /* Prepare the MDIO Address Register value
2164      - Set the PHY device address
2165      - Set the PHY register address
2166      - Set the write mode
2167      - Set the MII Busy bit */
2168 
2169   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2170   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2171   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR);
2172   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2173 
2174 
2175   /* Give the value to the MII data register */
2176   WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue);
2177 
2178   /* Write the result value into the MII Address register */
2179   WRITE_REG(ETH->MACMDIOAR, tmpreg);
2180 
2181   tickstart = HAL_GetTick();
2182 
2183   /* Wait for the Busy flag */
2184   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2185   {
2186     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2187     {
2188       return HAL_ERROR;
2189     }
2190   }
2191 
2192   return HAL_OK;
2193 }
2194 
2195 /**
2196   * @}
2197   */
2198 
2199 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
2200   *  @brief   ETH control functions
2201   *
2202 @verbatim
2203   ==============================================================================
2204                       ##### Peripheral Control functions #####
2205   ==============================================================================
2206   [..]
2207     This subsection provides a set of functions allowing to control the ETH
2208     peripheral.
2209 
2210 @endverbatim
2211   * @{
2212   */
2213 /**
2214   * @brief  Get the configuration of the MAC and MTL subsystems.
2215   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2216   *         the configuration information for ETHERNET module
2217   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
2218   *         the configuration of the MAC.
2219   * @retval HAL Status
2220   */
HAL_ETH_GetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2221 HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2222 {
2223   if (macconf == NULL)
2224   {
2225     return HAL_ERROR;
2226   }
2227 
2228   /* Get MAC parameters */
2229   macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN);
2230   macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2231   macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2232   macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE;
2233   macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U)
2234                                         ? ENABLE : DISABLE;
2235   macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE;
2236   macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR,
2237                                                    ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE;
2238   macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2239   macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2240   macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2241   macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE;
2242   macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE;
2243   macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE;
2244   macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE;
2245   macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE;
2246   macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE;
2247   macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR,
2248                                                     ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE;
2249   macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG);
2250   macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE;
2251   macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC);
2252 
2253   macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL);
2254   macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE;
2255   macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE;
2256   macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR,
2257                                                         ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE;
2258   macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U)
2259                                     ? ENABLE : DISABLE;
2260   macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25;
2261 
2262 
2263   macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE;
2264   macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO);
2265 
2266   macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE;
2267   macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE;
2268   macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT);
2269   macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16);
2270 
2271 
2272   macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE;
2273   macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U)
2274                                       ? ENABLE : DISABLE;
2275 
2276   macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF));
2277 
2278   macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF));
2279   macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2280                                                       ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE;
2281   macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE;
2282   macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2283                                                      ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE;
2284 
2285   return HAL_OK;
2286 }
2287 
2288 /**
2289   * @brief  Get the configuration of the DMA.
2290   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2291   *         the configuration information for ETHERNET module
2292   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2293   *         the configuration of the ETH DMA.
2294   * @retval HAL Status
2295   */
HAL_ETH_GetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2296 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2297 {
2298   if (dmaconf == NULL)
2299   {
2300     return HAL_ERROR;
2301   }
2302 
2303   dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE;
2304   dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB);
2305   dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE;
2306 
2307   dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA));
2308 
2309   dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE;
2310   dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS);
2311 
2312   dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR,  ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE;
2313   dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL);
2314 
2315   dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE;
2316   dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE;
2317   dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL);
2318   return HAL_OK;
2319 }
2320 
2321 /**
2322   * @brief  Set the MAC configuration.
2323   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2324   *         the configuration information for ETHERNET module
2325   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that contains
2326   *         the configuration of the MAC.
2327   * @retval HAL status
2328   */
HAL_ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2329 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2330 {
2331   if (macconf == NULL)
2332   {
2333     return HAL_ERROR;
2334   }
2335 
2336   if (heth->gState == HAL_ETH_STATE_READY)
2337   {
2338     ETH_SetMACConfig(heth, macconf);
2339 
2340     return HAL_OK;
2341   }
2342   else
2343   {
2344     return HAL_ERROR;
2345   }
2346 }
2347 
2348 /**
2349   * @brief  Set the ETH DMA configuration.
2350   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2351   *         the configuration information for ETHERNET module
2352   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2353   *         the configuration of the ETH DMA.
2354   * @retval HAL status
2355   */
HAL_ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2356 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2357 {
2358   if (dmaconf == NULL)
2359   {
2360     return HAL_ERROR;
2361   }
2362 
2363   if (heth->gState == HAL_ETH_STATE_READY)
2364   {
2365     ETH_SetDMAConfig(heth, dmaconf);
2366 
2367     return HAL_OK;
2368   }
2369   else
2370   {
2371     return HAL_ERROR;
2372   }
2373 }
2374 
2375 /**
2376   * @brief  Configures the Clock range of ETH MDIO interface.
2377   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2378   *         the configuration information for ETHERNET module
2379   * @retval None
2380   */
HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef * heth)2381 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2382 {
2383   uint32_t hclk;
2384   uint32_t tmpreg;
2385 
2386   /* Get the ETHERNET MACMDIOAR value */
2387   tmpreg = (heth->Instance)->MACMDIOAR;
2388 
2389   /* Clear CSR Clock Range bits */
2390   tmpreg &= ~ETH_MACMDIOAR_CR;
2391 
2392   /* Get hclk frequency value */
2393   hclk = HAL_RCC_GetHCLKFreq();
2394 
2395   /* Set CR bits depending on hclk value */
2396   if ((hclk >= 20000000U) && (hclk < 35000000U))
2397   {
2398     /* CSR Clock Range between 20-35 MHz */
2399     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2400   }
2401   else if ((hclk >= 35000000U) && (hclk < 60000000U))
2402   {
2403     /* CSR Clock Range between 35-60 MHz */
2404     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2405   }
2406   else if ((hclk >= 60000000U) && (hclk < 100000000U))
2407   {
2408     /* CSR Clock Range between 60-100 MHz */
2409     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2410   }
2411   else if ((hclk >= 100000000U) && (hclk < 150000000U))
2412   {
2413     /* CSR Clock Range between 100-150 MHz */
2414     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2415   }
2416   else /* (hclk >= 150000000)&&(hclk <= 200000000) */
2417   {
2418     /* CSR Clock Range between 150-200 MHz */
2419     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2420   }
2421 
2422   /* Configure the CSR Clock Range */
2423   (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2424 }
2425 
2426 /**
2427   * @brief  Set the ETH MAC (L2) Filters configuration.
2428   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2429   *         the configuration information for ETHERNET module
2430   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2431   *         the configuration of the ETH MAC filters.
2432   * @retval HAL status
2433   */
HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2434 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2435 {
2436   uint32_t filterconfig;
2437 
2438   if (pFilterConfig == NULL)
2439   {
2440     return HAL_ERROR;
2441   }
2442 
2443   filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2444                   ((uint32_t)pFilterConfig->HashUnicast << 1) |
2445                   ((uint32_t)pFilterConfig->HashMulticast << 2)  |
2446                   ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2447                   ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2448                   ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) |
2449                   ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2450                   ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2451                   ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2452                   ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2453                   pFilterConfig->ControlPacketsFilter);
2454 
2455   MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig);
2456 
2457   return HAL_OK;
2458 }
2459 
2460 /**
2461   * @brief  Get the ETH MAC (L2) Filters configuration.
2462   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2463   *         the configuration information for ETHERNET module
2464   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2465   *         the configuration of the ETH MAC filters.
2466   * @retval HAL status
2467   */
HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2468 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2469 {
2470   if (pFilterConfig == NULL)
2471   {
2472     return HAL_ERROR;
2473   }
2474 
2475   pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE;
2476   pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE;
2477   pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE;
2478   pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2479                                                        ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2480   pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE;
2481   pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE;
2482   pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF);
2483   pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2484                                                       ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2485   pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2486   pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U)
2487                                        ? ENABLE : DISABLE;
2488   pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2489 
2490   return HAL_OK;
2491 }
2492 
2493 /**
2494   * @brief  Set the source MAC Address to be matched.
2495   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2496   *         the configuration information for ETHERNET module
2497   * @param  AddrNbr: The MAC address to configure
2498   *          This parameter must be a value of the following:
2499   *            ETH_MAC_ADDRESS1
2500   *            ETH_MAC_ADDRESS2
2501   *            ETH_MAC_ADDRESS3
2502   * @param  pMACAddr: Pointer to MAC address buffer data (6 bytes)
2503   * @retval HAL status
2504   */
HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef * heth,uint32_t AddrNbr,uint8_t * pMACAddr)2505 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef *heth, uint32_t AddrNbr, uint8_t *pMACAddr)
2506 {
2507   uint32_t macaddrlr;
2508   uint32_t macaddrhr;
2509 
2510   if (pMACAddr == NULL)
2511   {
2512     return HAL_ERROR;
2513   }
2514 
2515   /* Get mac addr high reg offset */
2516   macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2517   /* Get mac addr low reg offset */
2518   macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2519 
2520   /* Set MAC addr bits 32 to 47 */
2521   (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2522   /* Set MAC addr bits 0 to 31 */
2523   (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2524                                    ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2525 
2526   /* Enable address and set source address bit */
2527   (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE);
2528 
2529   return HAL_OK;
2530 }
2531 
2532 /**
2533   * @brief  Set the ETH Hash Table Value.
2534   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2535   *         the configuration information for ETHERNET module
2536   * @param  pHashTable: pointer to a table of two 32 bit values, that contains
2537   *         the 64 bits of the hash table.
2538   * @retval HAL status
2539   */
HAL_ETH_SetHashTable(ETH_HandleTypeDef * heth,uint32_t * pHashTable)2540 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2541 {
2542   if (pHashTable == NULL)
2543   {
2544     return HAL_ERROR;
2545   }
2546 
2547   heth->Instance->MACHT0R = pHashTable[0];
2548   heth->Instance->MACHT1R = pHashTable[1];
2549 
2550   return HAL_OK;
2551 }
2552 
2553 /**
2554   * @brief  Set the VLAN Identifier for Rx packets
2555   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2556   *         the configuration information for ETHERNET module
2557   * @param  ComparisonBits: 12 or 16 bit comparison mode
2558             must be a value of @ref ETH_VLAN_Tag_Comparison
2559   * @param  VLANIdentifier: VLAN Identifier value
2560   * @retval None
2561   */
HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t ComparisonBits,uint32_t VLANIdentifier)2562 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2563 {
2564   if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2565   {
2566     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier);
2567     CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2568   }
2569   else
2570   {
2571     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier);
2572     SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2573   }
2574 }
2575 
2576 /**
2577   * @brief  Enters the Power down mode.
2578   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2579   *         the configuration information for ETHERNET module
2580   * @param  pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2581   *         that contains the Power Down configuration
2582   * @retval None.
2583   */
HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef * heth,ETH_PowerDownConfigTypeDef * pPowerDownConfig)2584 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2585 {
2586   uint32_t powerdownconfig;
2587 
2588   powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) |
2589                      ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) |
2590                      ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) |
2591                      ((uint32_t)pPowerDownConfig->WakeUpForward << 10) |
2592                      ETH_MACPCSR_PWRDWN);
2593 
2594   /* Enable PMT interrupt */
2595   __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE);
2596 
2597   MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig);
2598 }
2599 
2600 /**
2601   * @brief  Exits from the Power down mode.
2602   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2603   *         the configuration information for ETHERNET module
2604   * @retval None.
2605   */
HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef * heth)2606 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2607 {
2608   /* clear wake up sources */
2609   CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST |
2610             ETH_MACPCSR_RWKPFE);
2611 
2612   if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET)
2613   {
2614     /* Exit power down mode */
2615     CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN);
2616   }
2617 
2618   /* Disable PMT interrupt */
2619   __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE);
2620 }
2621 
2622 /**
2623   * @brief  Set the WakeUp filter.
2624   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2625   *         the configuration information for ETHERNET module
2626   * @param  pFilter: pointer to filter registers values
2627   * @param  Count: number of filter registers, must be from 1 to 8.
2628   * @retval None.
2629   */
HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef * heth,uint32_t * pFilter,uint32_t Count)2630 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2631 {
2632   uint32_t regindex;
2633 
2634   if (pFilter == NULL)
2635   {
2636     return HAL_ERROR;
2637   }
2638 
2639   /* Reset Filter Pointer */
2640   SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST);
2641 
2642   /* Wake up packet filter config */
2643   for (regindex = 0; regindex < Count; regindex++)
2644   {
2645     /* Write filter regs */
2646     WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]);
2647   }
2648 
2649   return HAL_OK;
2650 }
2651 
2652 /**
2653   * @}
2654   */
2655 
2656 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2657   *  @brief   ETH State and Errors functions
2658   *
2659 @verbatim
2660   ==============================================================================
2661                  ##### Peripheral State and Errors functions #####
2662   ==============================================================================
2663  [..]
2664    This subsection provides a set of functions allowing to return the State of
2665    ETH communication process, return Peripheral Errors occurred during communication
2666    process
2667 
2668 
2669 @endverbatim
2670   * @{
2671   */
2672 
2673 /**
2674   * @brief  Returns the ETH state.
2675   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2676   *         the configuration information for ETHERNET module
2677   * @retval HAL state
2678   */
HAL_ETH_GetState(ETH_HandleTypeDef * heth)2679 HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
2680 {
2681   return heth->gState;
2682 }
2683 
2684 /**
2685   * @brief  Returns the ETH error code
2686   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2687   *         the configuration information for ETHERNET module
2688   * @retval ETH Error Code
2689   */
HAL_ETH_GetError(ETH_HandleTypeDef * heth)2690 uint32_t HAL_ETH_GetError(ETH_HandleTypeDef *heth)
2691 {
2692   return heth->ErrorCode;
2693 }
2694 
2695 /**
2696   * @brief  Returns the ETH DMA error code
2697   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2698   *         the configuration information for ETHERNET module
2699   * @retval ETH DMA Error Code
2700   */
HAL_ETH_GetDMAError(ETH_HandleTypeDef * heth)2701 uint32_t HAL_ETH_GetDMAError(ETH_HandleTypeDef *heth)
2702 {
2703   return heth->DMAErrorCode;
2704 }
2705 
2706 /**
2707   * @brief  Returns the ETH MAC error code
2708   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2709   *         the configuration information for ETHERNET module
2710   * @retval ETH MAC Error Code
2711   */
HAL_ETH_GetMACError(ETH_HandleTypeDef * heth)2712 uint32_t HAL_ETH_GetMACError(ETH_HandleTypeDef *heth)
2713 {
2714   return heth->MACErrorCode;
2715 }
2716 
2717 /**
2718   * @brief  Returns the ETH MAC WakeUp event source
2719   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2720   *         the configuration information for ETHERNET module
2721   * @retval ETH MAC WakeUp event source
2722   */
HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef * heth)2723 uint32_t HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef *heth)
2724 {
2725   return heth->MACWakeUpEvent;
2726 }
2727 
2728 /**
2729   * @}
2730   */
2731 
2732 /**
2733   * @}
2734   */
2735 
2736 /** @addtogroup ETH_Private_Functions   ETH Private Functions
2737   * @{
2738   */
2739 
2740 
ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2741 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2742 {
2743   uint32_t macregval;
2744 
2745   /*------------------------ MACCR Configuration --------------------*/
2746   macregval = (macconf->InterPacketGapVal |
2747                macconf->SourceAddrControl |
2748                ((uint32_t)macconf->ChecksumOffload << 27) |
2749                ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) |
2750                ((uint32_t)macconf->Support2KPacket  << 22) |
2751                ((uint32_t)macconf->CRCStripTypePacket << 21) |
2752                ((uint32_t)macconf->AutomaticPadCRCStrip << 20) |
2753                ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) |
2754                ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) |
2755                ((uint32_t)macconf->JumboPacket << 16) |
2756                macconf->Speed |
2757                macconf->DuplexMode |
2758                ((uint32_t)macconf->LoopbackMode << 12) |
2759                ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) |
2760                ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) |
2761                ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) |
2762                ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) |
2763                macconf->BackOffLimit |
2764                ((uint32_t)macconf->DeferralCheck << 4) |
2765                macconf->PreambleLength);
2766 
2767   /* Write to MACCR */
2768   MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval);
2769 
2770   /*------------------------ MACECR Configuration --------------------*/
2771   macregval = ((macconf->ExtendedInterPacketGapVal << 25) |
2772                ((uint32_t)macconf->ExtendedInterPacketGap << 24) |
2773                ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) |
2774                ((uint32_t)macconf->SlowProtocolDetect << 17) |
2775                ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) |
2776                macconf->GiantPacketSizeLimit);
2777 
2778   /* Write to MACECR */
2779   MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval);
2780 
2781   /*------------------------ MACWTR Configuration --------------------*/
2782   macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) |
2783                macconf->WatchdogTimeout);
2784 
2785   /* Write to MACWTR */
2786   MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval);
2787 
2788   /*------------------------ MACTFCR Configuration --------------------*/
2789   macregval = (((uint32_t)macconf->TransmitFlowControl << 1) |
2790                macconf->PauseLowThreshold |
2791                ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) |
2792                (macconf->PauseTime << 16));
2793 
2794   /* Write to MACTFCR */
2795   MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval);
2796 
2797   /*------------------------ MACRFCR Configuration --------------------*/
2798   macregval = ((uint32_t)macconf->ReceiveFlowControl |
2799                ((uint32_t)macconf->UnicastPausePacketDetect << 1));
2800 
2801   /* Write to MACRFCR */
2802   MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval);
2803 
2804   /*------------------------ MTLTQOMR Configuration --------------------*/
2805   /* Write to MTLTQOMR */
2806   MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode);
2807 
2808   /*------------------------ MTLRQOMR Configuration --------------------*/
2809   macregval = (macconf->ReceiveQueueMode |
2810                ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) |
2811                ((uint32_t)macconf->ForwardRxErrorPacket << 4) |
2812                ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3));
2813 
2814   /* Write to MTLRQOMR */
2815   MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval);
2816 }
2817 
ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2818 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2819 {
2820   uint32_t dmaregval;
2821 
2822   /*------------------------ DMAMR Configuration --------------------*/
2823   MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration);
2824 
2825   /*------------------------ DMASBMR Configuration --------------------*/
2826   dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) |
2827                dmaconf->BurstMode |
2828                ((uint32_t)dmaconf->RebuildINCRxBurst << 15));
2829 
2830   MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval);
2831 
2832   /*------------------------ DMACCR Configuration --------------------*/
2833   dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) |
2834                dmaconf->MaximumSegmentSize);
2835 
2836   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval);
2837 
2838   /*------------------------ DMACTCR Configuration --------------------*/
2839   dmaregval = (dmaconf->TxDMABurstLength |
2840                ((uint32_t)dmaconf->SecondPacketOperate << 4) |
2841                ((uint32_t)dmaconf->TCPSegmentation << 12));
2842 
2843   MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval);
2844 
2845   /*------------------------ DMACRCR Configuration --------------------*/
2846   dmaregval = (((uint32_t)dmaconf->FlushRxPacket  << 31) |
2847                dmaconf->RxDMABurstLength);
2848 
2849   /* Write to DMACRCR */
2850   MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval);
2851 }
2852 
2853 /**
2854   * @brief  Configures Ethernet MAC and DMA with default parameters.
2855   *         called by HAL_ETH_Init() API.
2856   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2857   *         the configuration information for ETHERNET module
2858   * @retval HAL status
2859   */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth)2860 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2861 {
2862   ETH_MACConfigTypeDef macDefaultConf;
2863   ETH_DMAConfigTypeDef dmaDefaultConf;
2864 
2865   /*--------------- ETHERNET MAC registers default Configuration --------------*/
2866   macDefaultConf.AutomaticPadCRCStrip = ENABLE;
2867   macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2868   macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
2869   macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2870   macDefaultConf.ChecksumOffload = ENABLE;
2871   macDefaultConf.CRCCheckingRxPackets = ENABLE;
2872   macDefaultConf.CRCStripTypePacket = ENABLE;
2873   macDefaultConf.DeferralCheck = DISABLE;
2874   macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE;
2875   macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2876   macDefaultConf.ExtendedInterPacketGap = DISABLE;
2877   macDefaultConf.ExtendedInterPacketGapVal = 0x0;
2878   macDefaultConf.ForwardRxErrorPacket = DISABLE;
2879   macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE;
2880   macDefaultConf.GiantPacketSizeLimit = 0x618;
2881   macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
2882   macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
2883   macDefaultConf.Jabber = ENABLE;
2884   macDefaultConf.JumboPacket = DISABLE;
2885   macDefaultConf.LoopbackMode = DISABLE;
2886   macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
2887   macDefaultConf.PauseTime = 0x0;
2888   macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
2889   macDefaultConf.ProgrammableWatchdog = DISABLE;
2890   macDefaultConf.ReceiveFlowControl = DISABLE;
2891   macDefaultConf.ReceiveOwn = ENABLE;
2892   macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
2893   macDefaultConf.RetryTransmission = ENABLE;
2894   macDefaultConf.SlowProtocolDetect = DISABLE;
2895   macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0;
2896   macDefaultConf.Speed = ETH_SPEED_100M;
2897   macDefaultConf.Support2KPacket = DISABLE;
2898   macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
2899   macDefaultConf.TransmitFlowControl = DISABLE;
2900   macDefaultConf.UnicastPausePacketDetect = DISABLE;
2901   macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
2902   macDefaultConf.Watchdog = ENABLE;
2903   macDefaultConf.WatchdogTimeout =  ETH_MACWTR_WTO_2KB;
2904   macDefaultConf.ZeroQuantaPause = ENABLE;
2905 
2906   /* MAC default configuration */
2907   ETH_SetMACConfig(heth, &macDefaultConf);
2908 
2909   /*--------------- ETHERNET DMA registers default Configuration --------------*/
2910   dmaDefaultConf.AddressAlignedBeats = ENABLE;
2911   dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2912   dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1;
2913   dmaDefaultConf.FlushRxPacket = DISABLE;
2914   dmaDefaultConf.PBLx8Mode = DISABLE;
2915   dmaDefaultConf.RebuildINCRxBurst = DISABLE;
2916   dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2917   dmaDefaultConf.SecondPacketOperate = DISABLE;
2918   dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2919   dmaDefaultConf.TCPSegmentation = DISABLE;
2920   dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT;
2921 
2922   /* DMA default configuration */
2923   ETH_SetDMAConfig(heth, &dmaDefaultConf);
2924 }
2925 
2926 
2927 /**
2928   * @brief  Initializes the DMA Tx descriptors.
2929   *         called by HAL_ETH_Init() API.
2930   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2931   *         the configuration information for ETHERNET module
2932   * @retval None
2933   */
ETH_DMATxDescListInit(ETH_HandleTypeDef * heth)2934 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
2935 {
2936   ETH_DMADescTypeDef *dmatxdesc;
2937   uint32_t i;
2938 
2939   /* Fill each DMATxDesc descriptor with the right values */
2940   for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
2941   {
2942     dmatxdesc = heth->Init.TxDesc + i;
2943 
2944     WRITE_REG(dmatxdesc->DESC0, 0x0);
2945     WRITE_REG(dmatxdesc->DESC1, 0x0);
2946     WRITE_REG(dmatxdesc->DESC2, 0x0);
2947     WRITE_REG(dmatxdesc->DESC3, 0x0);
2948 
2949     WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
2950 
2951   }
2952 
2953   heth->TxDescList.CurTxDesc = 0;
2954 
2955   /* Set Transmit Descriptor Ring Length */
2956   WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U));
2957 
2958   /* Set Transmit Descriptor List Address */
2959   WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc);
2960 
2961   /* Set Transmit Descriptor Tail pointer */
2962   WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc);
2963 }
2964 
2965 /**
2966   * @brief  Initializes the DMA Rx descriptors in chain mode.
2967   *         called by HAL_ETH_Init() API.
2968   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2969   *         the configuration information for ETHERNET module
2970   * @retval None
2971   */
ETH_DMARxDescListInit(ETH_HandleTypeDef * heth)2972 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
2973 {
2974   ETH_DMADescTypeDef *dmarxdesc;
2975   uint32_t i;
2976 
2977   for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
2978   {
2979     dmarxdesc =  heth->Init.RxDesc + i;
2980 
2981     WRITE_REG(dmarxdesc->DESC0, 0x0);
2982     WRITE_REG(dmarxdesc->DESC1, 0x0);
2983     WRITE_REG(dmarxdesc->DESC2, 0x0);
2984     WRITE_REG(dmarxdesc->DESC3, 0x0);
2985     WRITE_REG(dmarxdesc->BackupAddr0, 0x0);
2986     WRITE_REG(dmarxdesc->BackupAddr1, 0x0);
2987 
2988 
2989     /* Set Rx descritors addresses */
2990     WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
2991 
2992   }
2993 
2994   WRITE_REG(heth->RxDescList.RxDescIdx, 0);
2995   WRITE_REG(heth->RxDescList.RxDescCnt, 0);
2996   WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0);
2997   WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0);
2998   WRITE_REG(heth->RxDescList.ItMode, 0);
2999 
3000   /* Set Receive Descriptor Ring Length */
3001   WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U)));
3002 
3003   /* Set Receive Descriptor List Address */
3004   WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);
3005 
3006   /* Set Receive Descriptor Tail pointer Address */
3007   WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U))));
3008 }
3009 
3010 /**
3011   * @brief  Prepare Tx DMA descriptor before transmission.
3012   *         called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
3013   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3014   *         the configuration information for ETHERNET module
3015   * @param  pTxConfig: Tx packet configuration
3016   * @param  ItMode: Enable or disable Tx EOT interrept
3017   * @retval Status
3018   */
ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig,uint32_t ItMode)3019 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode)
3020 {
3021   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
3022   uint32_t descidx = dmatxdesclist->CurTxDesc;
3023   uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3024   uint32_t idx;
3025   uint32_t descnbr = 0;
3026   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3027 
3028   ETH_BufferTypeDef  *txbuffer = pTxConfig->TxBuffer;
3029   uint32_t           bd_count = 0;
3030 
3031   /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3032   if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3033       || (dmatxdesclist->PacketAddress[descidx] != NULL))
3034   {
3035     return HAL_ETH_ERROR_BUSY;
3036   }
3037 
3038   /***************************************************************************/
3039   /*****************    Context descriptor configuration (Optional) **********/
3040   /***************************************************************************/
3041   /* If VLAN tag is enabled for this packet */
3042   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3043   {
3044     /* Set vlan tag value */
3045     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag);
3046     /* Set vlan tag valid bit */
3047     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV);
3048     /* Set the descriptor as the vlan input source */
3049     SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI);
3050 
3051     /* if inner VLAN is enabled */
3052     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET)
3053     {
3054       /* Set inner vlan tag value */
3055       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16));
3056       /* Set inner vlan tag valid bit */
3057       SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV);
3058 
3059       /* Set Vlan Tag control */
3060       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl);
3061 
3062       /* Set the descriptor as the inner vlan input source */
3063       SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI);
3064       /* Enable double VLAN processing */
3065       SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP);
3066     }
3067   }
3068 
3069   /* if tcp segmentation is enabled for this packet */
3070   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3071   {
3072     /* Set MSS value */
3073     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize);
3074     /* Set MSS valid bit */
3075     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV);
3076   }
3077 
3078   if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3079       || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET))
3080   {
3081     /* Set as context descriptor */
3082     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT);
3083     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3084     __DMB();
3085     /* Set own bit */
3086     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3087     /* Increment current tx descriptor index */
3088     INCR_TX_DESC_INDEX(descidx, 1U);
3089     /* Get current descriptor address */
3090     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3091 
3092     descnbr += 1U;
3093 
3094     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3095     if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3096     {
3097       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
3098       /* Ensure rest of descriptor is written to RAM before the OWN bit */
3099       __DMB();
3100       /* Clear own bit */
3101       CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3102 
3103       return HAL_ETH_ERROR_BUSY;
3104     }
3105   }
3106 
3107   /***************************************************************************/
3108   /*****************    Normal descriptors configuration     *****************/
3109   /***************************************************************************/
3110 
3111   descnbr += 1U;
3112 
3113   /* Set header or buffer 1 address */
3114   WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3115   /* Set header or buffer 1 Length */
3116   MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3117 
3118   if (txbuffer->next != NULL)
3119   {
3120     txbuffer = txbuffer->next;
3121     /* Set buffer 2 address */
3122     WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3123     /* Set buffer 2 Length */
3124     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3125   }
3126   else
3127   {
3128     WRITE_REG(dmatxdesc->DESC1, 0x0);
3129     /* Set buffer 2 Length */
3130     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3131   }
3132 
3133   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3134   {
3135     /* Set TCP Header length */
3136     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19));
3137     /* Set TCP payload length */
3138     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3139     /* Set TCP Segmentation Enabled bit */
3140     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3141   }
3142   else
3143   {
3144     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3145 
3146     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3147     {
3148       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3149     }
3150 
3151     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET)
3152     {
3153       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl);
3154     }
3155   }
3156 
3157   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3158   {
3159     /* Set Vlan Tag control */
3160     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl);
3161   }
3162 
3163   /* Mark it as First Descriptor */
3164   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3165   /* Mark it as NORMAL descriptor */
3166   CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3167   /* Ensure rest of descriptor is written to RAM before the OWN bit */
3168   __DMB();
3169   /* set OWN bit of FIRST descriptor */
3170   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3171 
3172   /* If source address insertion/replacement is enabled for this packet */
3173   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET)
3174   {
3175     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl);
3176   }
3177 
3178   /* only if the packet is split into more than one descriptors > 1 */
3179   while (txbuffer->next != NULL)
3180   {
3181     /* Clear the LD bit of previous descriptor */
3182     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3183     /* Increment current tx descriptor index */
3184     INCR_TX_DESC_INDEX(descidx, 1U);
3185     /* Get current descriptor address */
3186     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3187 
3188     /* Clear the FD bit of new Descriptor */
3189     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3190 
3191     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3192     if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN)
3193         || (dmatxdesclist->PacketAddress[descidx] != NULL))
3194     {
3195       descidx = firstdescidx;
3196       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3197 
3198       /* clear previous desc own bit */
3199       for (idx = 0; idx < descnbr; idx ++)
3200       {
3201         /* Ensure rest of descriptor is written to RAM before the OWN bit */
3202         __DMB();
3203 
3204         CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3205 
3206         /* Increment current tx descriptor index */
3207         INCR_TX_DESC_INDEX(descidx, 1U);
3208         /* Get current descriptor address */
3209         dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3210       }
3211 
3212       return HAL_ETH_ERROR_BUSY;
3213     }
3214 
3215     descnbr += 1U;
3216 
3217     /* Get the next Tx buffer in the list */
3218     txbuffer = txbuffer->next;
3219 
3220     /* Set header or buffer 1 address */
3221     WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3222     /* Set header or buffer 1 Length */
3223     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3224 
3225     if (txbuffer->next != NULL)
3226     {
3227       /* Get the next Tx buffer in the list */
3228       txbuffer = txbuffer->next;
3229       /* Set buffer 2 address */
3230       WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3231       /* Set buffer 2 Length */
3232       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3233     }
3234     else
3235     {
3236       WRITE_REG(dmatxdesc->DESC1, 0x0);
3237       /* Set buffer 2 Length */
3238       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3239     }
3240 
3241     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3242     {
3243       /* Set TCP payload length */
3244       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3245       /* Set TCP Segmentation Enabled bit */
3246       SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3247     }
3248     else
3249     {
3250       /* Set the packet length */
3251       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3252 
3253       if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3254       {
3255         /* Checksum Insertion Control */
3256         MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3257       }
3258     }
3259 
3260     bd_count += 1U;
3261 
3262     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3263     __DMB();
3264     /* Set Own bit */
3265     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3266     /* Mark it as NORMAL descriptor */
3267     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3268   }
3269 
3270   if (ItMode != ((uint32_t)RESET))
3271   {
3272     /* Set Interrupt on completion bit */
3273     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3274   }
3275   else
3276   {
3277     /* Clear Interrupt on completion bit */
3278     CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3279   }
3280 
3281   /* Mark it as LAST descriptor */
3282   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3283   /* Save the current packet address to expose it to the application */
3284   dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3285 
3286   dmatxdesclist->CurTxDesc = descidx;
3287 
3288   /* disable the interrupt */
3289   __disable_irq();
3290 
3291   dmatxdesclist->BuffersInUse += bd_count + 1U;
3292 
3293   /* Enable interrupts back */
3294   __enable_irq();
3295 
3296 
3297   /* Return function status */
3298   return HAL_ETH_ERROR_NONE;
3299 }
3300 
3301 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)3302 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3303 {
3304   /* Init the ETH Callback settings */
3305   heth->TxCpltCallback   = HAL_ETH_TxCpltCallback;    /* Legacy weak TxCpltCallback   */
3306   heth->RxCpltCallback   = HAL_ETH_RxCpltCallback;    /* Legacy weak RxCpltCallback   */
3307   heth->ErrorCallback    = HAL_ETH_ErrorCallback;     /* Legacy weak ErrorCallback */
3308   heth->PMTCallback      = HAL_ETH_PMTCallback;       /* Legacy weak PMTCallback      */
3309   heth->EEECallback      = HAL_ETH_EEECallback;       /* Legacy weak EEECallback      */
3310   heth->WakeUpCallback   = HAL_ETH_WakeUpCallback;    /* Legacy weak WakeUpCallback   */
3311   heth->rxLinkCallback   = HAL_ETH_RxLinkCallback;    /* Legacy weak RxLinkCallback   */
3312   heth->txFreeCallback   = HAL_ETH_TxFreeCallback;    /* Legacy weak TxFreeCallback   */
3313 #ifdef HAL_ETH_USE_PTP
3314   heth->txPtpCallback    = HAL_ETH_TxPtpCallback;     /* Legacy weak TxPtpCallback   */
3315 #endif /* HAL_ETH_USE_PTP */
3316   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3317 }
3318 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3319 
3320 /**
3321   * @}
3322   */
3323 
3324 /**
3325   * @}
3326   */
3327 
3328 #endif /* ETH */
3329 
3330 #endif /* HAL_ETH_MODULE_ENABLED */
3331 
3332 /**
3333   * @}
3334   */
3335