1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_eth.c
4   * @author  MCD Application Team
5   * @brief   ETH HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Ethernet (ETH) peripheral:
8   *           + Initialization and deinitialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2017 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 "stm32h7xx_hal.h"
179 
180 /** @addtogroup STM32H7xx_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_SYSCFG_CLK_ENABLE();
338 
339   if (heth->Init.MediaInterface == HAL_ETH_MII_MODE)
340   {
341     HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII);
342   }
343   else
344   {
345     HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII);
346   }
347 
348   /* Dummy read to sync with ETH */
349   (void)SYSCFG->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 callabck 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         if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_LD )
1436           && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_TTSS))
1437         {
1438           /* Get timestamp low */
1439           timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0;
1440           /* Get timestamp high */
1441           timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1;
1442         }
1443         else
1444         {
1445           timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX;
1446         }
1447 
1448 #endif /* HAL_ETH_USE_PTP */
1449 
1450 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1451         /*Call registered callbacks*/
1452 #ifdef HAL_ETH_USE_PTP
1453         /* Handle Ptp  */
1454         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1455         {
1456           heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1457         }
1458 #endif  /* HAL_ETH_USE_PTP */
1459         /* Release the packet.  */
1460         heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1461 #else
1462         /* Call callbacks */
1463 #ifdef HAL_ETH_USE_PTP
1464         /* Handle Ptp  */
1465         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1466         {
1467           HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1468         }
1469 #endif  /* HAL_ETH_USE_PTP */
1470         /* Release the packet.  */
1471         HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1472 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1473 
1474         /* Clear the entry in the in-use array.  */
1475         dmatxdesclist->PacketAddress[idx] = NULL;
1476 
1477         /* Update the transmit relesae index and number of buffers in use.  */
1478         idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U);
1479         dmatxdesclist->BuffersInUse = numOfBuf;
1480         dmatxdesclist->releaseIndex = idx;
1481       }
1482       else
1483       {
1484         /* Get out of the loop!  */
1485         pktTxStatus = 0U;
1486       }
1487     }
1488   }
1489   return HAL_OK;
1490 }
1491 
1492 #ifdef HAL_ETH_USE_PTP
1493 /**
1494   * @brief  Set the Ethernet PTP configuration.
1495   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1496   *         the configuration information for ETHERNET module
1497   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1498   *         the configuration information for PTP
1499   * @retval HAL status
1500   */
HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1501 HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1502 {
1503   uint32_t tmpTSCR;
1504   ETH_TimeTypeDef time;
1505 
1506   if (ptpconfig == NULL)
1507   {
1508     return HAL_ERROR;
1509   }
1510 
1511   tmpTSCR = ptpconfig->Timestamp |
1512             ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) |
1513             ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) |
1514             ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) |
1515             ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) |
1516             ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) |
1517             ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) |
1518             ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) |
1519             ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) |
1520             ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) |
1521             ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) |
1522             ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) |
1523             ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) |
1524             ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos);
1525 
1526   /* Write to MACTSCR */
1527   MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1528 
1529   /* Enable Timestamp */
1530   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1531   WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc);
1532   WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend);
1533 
1534   /* Enable Timestamp */
1535   if (ptpconfig->TimestampAddendUpdate == ENABLE)
1536   {
1537     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG);
1538     while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0) {}
1539   }
1540 
1541   /* Enable Update mode */
1542   if (ptpconfig->TimestampUpdateMode == ENABLE)
1543   {
1544     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCFUPDT);
1545   }
1546 
1547   /* Initialize Time */
1548   time.Seconds = 0;
1549   time.NanoSeconds = 0;
1550   HAL_ETH_PTP_SetTime(heth, &time);
1551 
1552   /* Ptp Init */
1553   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT);
1554 
1555   /* Set PTP Configuration done */
1556   heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED;
1557 
1558   /* Return function status */
1559   return HAL_OK;
1560 }
1561 
1562 /**
1563   * @brief  Get the Ethernet PTP configuration.
1564   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1565   *         the configuration information for ETHERNET module
1566   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1567   *         the configuration information for PTP
1568   * @retval HAL status
1569   */
HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1570 HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1571 {
1572   if (ptpconfig == NULL)
1573   {
1574     return HAL_ERROR;
1575   }
1576   ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1577   ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR,
1578                                           ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE;
1579   ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR,
1580                                        ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE;
1581   ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR,
1582                                                 ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U)
1583                                      ? ENABLE : DISABLE;
1584   ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR,
1585                                       ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE;
1586   ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR,
1587                                             ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE;
1588   ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR,
1589                                         ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE;
1590   ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR,
1591                                         ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE;
1592   ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR,
1593                                          ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE;
1594   ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR,
1595                                           ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE;
1596   ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR,
1597                                              ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U)
1598                                   ? ENABLE : DISABLE;
1599   ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR,
1600                                           ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U)
1601                                ? ENABLE : DISABLE;
1602   ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR,
1603                                                       ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE;
1604   ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR,
1605                                               ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U)
1606                                    ? ENABLE : DISABLE;
1607 
1608   /* Return function status */
1609   return HAL_OK;
1610 }
1611 
1612 /**
1613   * @brief  Set Seconds and Nanoseconds for the Ethernet PTP registers.
1614   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1615   *         the configuration information for ETHERNET module
1616   * @param  heth: pointer to a ETH_TimeTypeDef structure that contains
1617   *         time to set
1618   * @retval HAL status
1619   */
HAL_ETH_PTP_SetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1620 HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1621 {
1622   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1623   {
1624     /* Set Seconds */
1625     heth->Instance->MACSTSUR = time->Seconds;
1626 
1627     /* Set NanoSeconds */
1628     heth->Instance->MACSTNUR = time->NanoSeconds;
1629 
1630     /* Return function status */
1631     return HAL_OK;
1632   }
1633   else
1634   {
1635     /* Return function status */
1636     return HAL_ERROR;
1637   }
1638 }
1639 
1640 /**
1641   * @brief  Get Seconds and Nanoseconds for the Ethernet PTP registers.
1642   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1643   *         the configuration information for ETHERNET module
1644   * @param  heth: pointer to a ETH_TimeTypeDef structure that contains
1645   *         time to get
1646   * @retval HAL status
1647   */
HAL_ETH_PTP_GetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1648 HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1649 {
1650   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1651   {
1652     /* Get Seconds */
1653     time->Seconds = heth->Instance->MACSTSUR;
1654 
1655     /* Get NanoSeconds */
1656     time->NanoSeconds = heth->Instance->MACSTNUR;
1657 
1658     /* Return function status */
1659     return HAL_OK;
1660   }
1661   else
1662   {
1663     /* Return function status */
1664     return HAL_ERROR;
1665   }
1666 }
1667 
1668 /**
1669   * @brief  Update time for the Ethernet PTP registers.
1670   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1671   *         the configuration information for ETHERNET module
1672   * @param  timeupdate: pointer to a ETH_TIMEUPDATETypeDef structure that contains
1673   *         the time update information
1674   * @retval HAL status
1675   */
HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef * heth,ETH_PtpUpdateTypeDef ptpoffsettype,ETH_TimeTypeDef * timeoffset)1676 HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1677                                             ETH_TimeTypeDef *timeoffset)
1678 {
1679   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1680   {
1681     if (ptpoffsettype ==  HAL_ETH_PTP_NEGATIVE_UPDATE)
1682     {
1683       /* Set Seconds update */
1684       heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U;
1685 
1686       if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR)
1687       {
1688         /* Set nanoSeconds update */
1689         heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds;
1690       }
1691       else
1692       {
1693         /* Set nanoSeconds update */
1694         heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U;
1695       }
1696     }
1697     else
1698     {
1699       /* Set Seconds update */
1700       heth->Instance->MACSTSUR = timeoffset->Seconds;
1701       /* Set nanoSeconds update */
1702       heth->Instance->MACSTNUR = timeoffset->NanoSeconds;
1703     }
1704 
1705     /* Return function status */
1706     return HAL_OK;
1707   }
1708   else
1709   {
1710     /* Return function status */
1711     return HAL_ERROR;
1712   }
1713 }
1714 
1715 /**
1716   * @brief  Insert Timestamp in transmission.
1717   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1718   *         the configuration information for ETHERNET module
1719   * @param  txtimestampconf: Enable or Disable timestamp in transmission
1720   * @retval HAL status
1721   */
HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef * heth)1722 HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1723 {
1724   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1725   uint32_t descidx = dmatxdesclist->CurTxDesc;
1726   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1727 
1728   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1729   {
1730     /* Enable Time Stamp transmission */
1731     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE);
1732 
1733     /* Return function status */
1734     return HAL_OK;
1735   }
1736   else
1737   {
1738     /* Return function status */
1739     return HAL_ERROR;
1740   }
1741 }
1742 
1743 /**
1744   * @brief  Get transmission timestamp.
1745   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1746   *         the configuration information for ETHERNET module
1747   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1748   *         transmission timestamp
1749   * @retval HAL status
1750   */
HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1751 HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1752 {
1753   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1754   uint32_t idx =       dmatxdesclist->releaseIndex;
1755   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1756 
1757   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1758   {
1759     /* Get timestamp low */
1760     timestamp->TimeStampLow = dmatxdesc->DESC0;
1761     /* Get timestamp high */
1762     timestamp->TimeStampHigh = dmatxdesc->DESC1;
1763 
1764     /* Return function status */
1765     return HAL_OK;
1766   }
1767   else
1768   {
1769     /* Return function status */
1770     return HAL_ERROR;
1771   }
1772 }
1773 
1774 /**
1775   * @brief  Get receive timestamp.
1776   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1777   *         the configuration information for ETHERNET module
1778   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1779   *         receive timestamp
1780   * @retval HAL status
1781   */
HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1782 HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1783 {
1784   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1785   {
1786     /* Get timestamp low */
1787     timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
1788     /* Get timestamp high */
1789     timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
1790 
1791     /* Return function status */
1792     return HAL_OK;
1793   }
1794   else
1795   {
1796     /* Return function status */
1797     return HAL_ERROR;
1798   }
1799 }
1800 
1801 /**
1802   * @brief  Register the Tx Ptp callback.
1803   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1804   *         the configuration information for ETHERNET module
1805   * @param  txPtpCallback: Function to handle Ptp transmission
1806   * @retval HAL status
1807   */
HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef * heth,pETH_txPtpCallbackTypeDef txPtpCallback)1808 HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1809 {
1810   if (txPtpCallback == NULL)
1811   {
1812     /* No buffer to save */
1813     return HAL_ERROR;
1814   }
1815   /* Set Function to handle Tx Ptp */
1816   heth->txPtpCallback = txPtpCallback;
1817 
1818   return HAL_OK;
1819 }
1820 
1821 /**
1822   * @brief  Unregister the Tx Ptp callback.
1823   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1824   *         the configuration information for ETHERNET module
1825   * @retval HAL status
1826   */
HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef * heth)1827 HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1828 {
1829   /* Set function to allocate buffer */
1830   heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1831 
1832   return HAL_OK;
1833 }
1834 
1835 /**
1836   * @brief  Tx Ptp callback.
1837   * @param  buff: pointer to application buffer
1838   * @retval None
1839   */
HAL_ETH_TxPtpCallback(uint32_t * buff,ETH_TimeStampTypeDef * timestamp)1840 __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1841 {
1842   /* Prevent unused argument(s) compilation warning */
1843   UNUSED(buff);
1844   /* NOTE : This function Should not be modified, when the callback is needed,
1845   the HAL_ETH_TxPtpCallback could be implemented in the user file
1846   */
1847 }
1848 #endif  /* HAL_ETH_USE_PTP */
1849 
1850 /**
1851   * @brief  This function handles ETH interrupt request.
1852   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1853   *         the configuration information for ETHERNET module
1854   * @retval HAL status
1855   */
HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)1856 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1857 {
1858   uint32_t macirqenable;
1859   /* Packet received */
1860   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_RI))
1861   {
1862     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_RIE))
1863     {
1864       /* Clear the Eth DMA Rx IT pending bits */
1865       __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
1866 
1867 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1868       /*Call registered Receive complete callback*/
1869       heth->RxCpltCallback(heth);
1870 #else
1871       /* Receive complete callback */
1872       HAL_ETH_RxCpltCallback(heth);
1873 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1874     }
1875   }
1876 
1877   /* Packet transmitted */
1878   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_TI))
1879   {
1880     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_TIE))
1881     {
1882       /* Clear the Eth DMA Tx IT pending bits */
1883       __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
1884 
1885 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1886       /*Call registered Transmit complete callback*/
1887       heth->TxCpltCallback(heth);
1888 #else
1889       /* Transfer complete callback */
1890       HAL_ETH_TxCpltCallback(heth);
1891 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1892     }
1893   }
1894 
1895 
1896   /* ETH DMA Error */
1897   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_AIS))
1898   {
1899     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_AIE))
1900     {
1901       heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1902 
1903       /* if fatal bus error occurred */
1904       if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_FBE))
1905       {
1906         /* Get DMA error code  */
1907         heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS));
1908 
1909         /* Disable all interrupts */
1910         __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE);
1911 
1912         /* Set HAL state to ERROR */
1913         heth->gState = HAL_ETH_STATE_ERROR;
1914       }
1915       else
1916       {
1917         /* Get DMA error status  */
1918         heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1919                                                                ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1920 
1921         /* Clear the interrupt summary flag */
1922         __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1923                                       ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1924       }
1925 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1926       /* Call registered Error callback*/
1927       heth->ErrorCallback(heth);
1928 #else
1929       /* Ethernet DMA Error callback */
1930       HAL_ETH_ErrorCallback(heth);
1931 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1932 
1933     }
1934   }
1935 
1936   /* ETH MAC Error IT */
1937   macirqenable = heth->Instance->MACIER;
1938   if (((macirqenable & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \
1939       ((macirqenable & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE))
1940   {
1941     heth->ErrorCode |= HAL_ETH_ERROR_MAC;
1942 
1943     /* Get MAC Rx Tx status and clear Status register pending bit */
1944     heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR);
1945 
1946     heth->gState = HAL_ETH_STATE_ERROR;
1947 
1948 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1949     /* Call registered Error callback*/
1950     heth->ErrorCallback(heth);
1951 #else
1952     /* Ethernet Error callback */
1953     HAL_ETH_ErrorCallback(heth);
1954 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1955 
1956     heth->MACErrorCode = (uint32_t)(0x0U);
1957   }
1958 
1959   /* ETH PMT IT */
1960   if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_PMT_IT))
1961   {
1962     /* Get MAC Wake-up source and clear the status register pending bit */
1963     heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD));
1964 
1965 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1966     /* Call registered PMT callback*/
1967     heth->PMTCallback(heth);
1968 #else
1969     /* Ethernet PMT callback */
1970     HAL_ETH_PMTCallback(heth);
1971 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1972 
1973     heth->MACWakeUpEvent = (uint32_t)(0x0U);
1974   }
1975 
1976   /* ETH EEE IT */
1977   if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_LPI_IT))
1978   {
1979     /* Get MAC LPI interrupt source and clear the status register pending bit */
1980     heth->MACLPIEvent = READ_BIT(heth->Instance->MACPCSR, 0x0000000FU);
1981 
1982 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1983     /* Call registered EEE callback*/
1984     heth->EEECallback(heth);
1985 #else
1986     /* Ethernet EEE callback */
1987     HAL_ETH_EEECallback(heth);
1988 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1989 
1990     heth->MACLPIEvent = (uint32_t)(0x0U);
1991   }
1992 
1993 #if defined(DUAL_CORE)
1994   if (HAL_GetCurrentCPUID() == CM7_CPUID)
1995   {
1996     /* check ETH WAKEUP exti flag */
1997     if (__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
1998     {
1999       /* Clear ETH WAKEUP Exti pending bit */
2000       __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2001 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2002       /* Call registered WakeUp callback*/
2003       heth->WakeUpCallback(heth);
2004 #else
2005       /* ETH WAKEUP callback */
2006       HAL_ETH_WakeUpCallback(heth);
2007 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2008     }
2009   }
2010   else
2011   {
2012     /* check ETH WAKEUP exti flag */
2013     if (__HAL_ETH_WAKEUP_EXTID2_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
2014     {
2015       /* Clear ETH WAKEUP Exti pending bit */
2016       __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2017 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2018       /* Call registered WakeUp callback*/
2019       heth->WakeUpCallback(heth);
2020 #else
2021       /* ETH WAKEUP callback */
2022       HAL_ETH_WakeUpCallback(heth);
2023 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2024     }
2025   }
2026 #else /* USE_HAL_ETH_REGISTER_CALLBACKS */
2027   /* check ETH WAKEUP exti flag */
2028   if (__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
2029   {
2030     /* Clear ETH WAKEUP Exti pending bit */
2031     __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2032 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2033     /* Call registered WakeUp callback*/
2034     heth->WakeUpCallback(heth);
2035 #else
2036     /* ETH WAKEUP callback */
2037     HAL_ETH_WakeUpCallback(heth);
2038 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2039   }
2040 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2041 }
2042 
2043 /**
2044   * @brief  Tx Transfer completed callbacks.
2045   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2046   *         the configuration information for ETHERNET module
2047   * @retval None
2048   */
HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)2049 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
2050 {
2051   /* Prevent unused argument(s) compilation warning */
2052   UNUSED(heth);
2053   /* NOTE : This function Should not be modified, when the callback is needed,
2054   the HAL_ETH_TxCpltCallback could be implemented in the user file
2055   */
2056 }
2057 
2058 /**
2059   * @brief  Rx Transfer completed callbacks.
2060   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2061   *         the configuration information for ETHERNET module
2062   * @retval None
2063   */
HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)2064 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2065 {
2066   /* Prevent unused argument(s) compilation warning */
2067   UNUSED(heth);
2068   /* NOTE : This function Should not be modified, when the callback is needed,
2069   the HAL_ETH_RxCpltCallback could be implemented in the user file
2070   */
2071 }
2072 
2073 /**
2074   * @brief  Ethernet transfer error callbacks
2075   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2076   *         the configuration information for ETHERNET module
2077   * @retval None
2078   */
HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)2079 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2080 {
2081   /* Prevent unused argument(s) compilation warning */
2082   UNUSED(heth);
2083   /* NOTE : This function Should not be modified, when the callback is needed,
2084   the HAL_ETH_ErrorCallback could be implemented in the user file
2085   */
2086 }
2087 
2088 /**
2089   * @brief  Ethernet Power Management module IT callback
2090   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2091   *         the configuration information for ETHERNET module
2092   * @retval None
2093   */
HAL_ETH_PMTCallback(ETH_HandleTypeDef * heth)2094 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2095 {
2096   /* Prevent unused argument(s) compilation warning */
2097   UNUSED(heth);
2098   /* NOTE : This function Should not be modified, when the callback is needed,
2099   the HAL_ETH_PMTCallback could be implemented in the user file
2100   */
2101 }
2102 
2103 /**
2104   * @brief  Energy Efficient Etherent IT callback
2105   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2106   *         the configuration information for ETHERNET module
2107   * @retval None
2108   */
HAL_ETH_EEECallback(ETH_HandleTypeDef * heth)2109 __weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth)
2110 {
2111   /* Prevent unused argument(s) compilation warning */
2112   UNUSED(heth);
2113   /* NOTE : This function Should not be modified, when the callback is needed,
2114   the HAL_ETH_EEECallback could be implemented in the user file
2115   */
2116 }
2117 
2118 /**
2119   * @brief  ETH WAKEUP interrupt callback
2120   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2121   *         the configuration information for ETHERNET module
2122   * @retval None
2123   */
HAL_ETH_WakeUpCallback(ETH_HandleTypeDef * heth)2124 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2125 {
2126   /* Prevent unused argument(s) compilation warning */
2127   UNUSED(heth);
2128   /* NOTE : This function Should not be modified, when the callback is needed,
2129             the HAL_ETH_WakeUpCallback could be implemented in the user file
2130    */
2131 }
2132 
2133 /**
2134   * @brief  Read a PHY register
2135   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2136   *         the configuration information for ETHERNET module
2137   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2138   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2139   * @param pRegValue: parameter to hold read value
2140   * @retval HAL status
2141   */
HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t * pRegValue)2142 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2143                                           uint32_t *pRegValue)
2144 {
2145   uint32_t tickstart;
2146   uint32_t tmpreg;
2147 
2148   /* Check for the Busy flag */
2149   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2150   {
2151     return HAL_ERROR;
2152   }
2153 
2154   /* Get the  MACMDIOAR value */
2155   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2156 
2157   /* Prepare the MDIO Address Register value
2158      - Set the PHY device address
2159      - Set the PHY register address
2160      - Set the read mode
2161      - Set the MII Busy bit */
2162 
2163   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2164   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2165   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD);
2166   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2167 
2168   /* Write the result value into the MDII Address register */
2169   WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
2170 
2171   tickstart = HAL_GetTick();
2172 
2173   /* Wait for the Busy flag */
2174   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2175   {
2176     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2177     {
2178       return HAL_ERROR;
2179     }
2180   }
2181 
2182   /* Get MACMIIDR value */
2183   WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR);
2184 
2185   return HAL_OK;
2186 }
2187 
2188 
2189 /**
2190   * @brief  Writes to a PHY register.
2191   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2192   *         the configuration information for ETHERNET module
2193   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2194   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2195   * @param  RegValue: the value to write
2196   * @retval HAL status
2197   */
HAL_ETH_WritePHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t RegValue)2198 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2199                                            uint32_t RegValue)
2200 {
2201   uint32_t tickstart;
2202   uint32_t tmpreg;
2203 
2204   /* Check for the Busy flag */
2205   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2206   {
2207     return HAL_ERROR;
2208   }
2209 
2210   /* Get the  MACMDIOAR value */
2211   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2212 
2213   /* Prepare the MDIO Address Register value
2214      - Set the PHY device address
2215      - Set the PHY register address
2216      - Set the write mode
2217      - Set the MII Busy bit */
2218 
2219   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2220   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2221   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR);
2222   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2223 
2224 
2225   /* Give the value to the MII data register */
2226   WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue);
2227 
2228   /* Write the result value into the MII Address register */
2229   WRITE_REG(ETH->MACMDIOAR, tmpreg);
2230 
2231   tickstart = HAL_GetTick();
2232 
2233   /* Wait for the Busy flag */
2234   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2235   {
2236     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2237     {
2238       return HAL_ERROR;
2239     }
2240   }
2241 
2242   return HAL_OK;
2243 }
2244 
2245 /**
2246   * @}
2247   */
2248 
2249 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
2250   *  @brief   ETH control functions
2251   *
2252 @verbatim
2253   ==============================================================================
2254                       ##### Peripheral Control functions #####
2255   ==============================================================================
2256   [..]
2257     This subsection provides a set of functions allowing to control the ETH
2258     peripheral.
2259 
2260 @endverbatim
2261   * @{
2262   */
2263 /**
2264   * @brief  Get the configuration of the MAC and MTL subsystems.
2265   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2266   *         the configuration information for ETHERNET module
2267   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
2268   *         the configuration of the MAC.
2269   * @retval HAL Status
2270   */
HAL_ETH_GetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2271 HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2272 {
2273   if (macconf == NULL)
2274   {
2275     return HAL_ERROR;
2276   }
2277 
2278   /* Get MAC parameters */
2279   macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN);
2280   macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2281   macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2282   macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE;
2283   macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U)
2284                                         ? ENABLE : DISABLE;
2285   macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE;
2286   macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR,
2287                                                    ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE;
2288   macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2289   macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2290   macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2291   macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE;
2292   macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE;
2293   macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE;
2294   macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE;
2295   macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE;
2296   macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE;
2297   macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR,
2298                                                     ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE;
2299   macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG);
2300   macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE;
2301   macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC);
2302 
2303   macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL);
2304   macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE;
2305   macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE;
2306   macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR,
2307                                                         ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE;
2308   macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U)
2309                                     ? ENABLE : DISABLE;
2310   macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25;
2311 
2312 
2313   macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE;
2314   macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO);
2315 
2316   macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE;
2317   macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE;
2318   macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT);
2319   macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16);
2320 
2321 
2322   macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE;
2323   macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U)
2324                                       ? ENABLE : DISABLE;
2325 
2326   macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF));
2327 
2328   macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF));
2329   macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2330                                                       ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE;
2331   macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE;
2332   macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2333                                                      ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE;
2334 
2335   return HAL_OK;
2336 }
2337 
2338 /**
2339   * @brief  Get the configuration of the DMA.
2340   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2341   *         the configuration information for ETHERNET module
2342   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2343   *         the configuration of the ETH DMA.
2344   * @retval HAL Status
2345   */
HAL_ETH_GetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2346 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2347 {
2348   if (dmaconf == NULL)
2349   {
2350     return HAL_ERROR;
2351   }
2352 
2353   dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE;
2354   dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB);
2355   dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE;
2356 
2357   dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA));
2358 
2359   dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE;
2360   dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS);
2361 
2362   dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR,  ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE;
2363   dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL);
2364 
2365   dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE;
2366   dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE;
2367   dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL);
2368   return HAL_OK;
2369 }
2370 
2371 /**
2372   * @brief  Set the MAC configuration.
2373   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2374   *         the configuration information for ETHERNET module
2375   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that contains
2376   *         the configuration of the MAC.
2377   * @retval HAL status
2378   */
HAL_ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2379 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2380 {
2381   if (macconf == NULL)
2382   {
2383     return HAL_ERROR;
2384   }
2385 
2386   if (heth->gState == HAL_ETH_STATE_READY)
2387   {
2388     ETH_SetMACConfig(heth, macconf);
2389 
2390     return HAL_OK;
2391   }
2392   else
2393   {
2394     return HAL_ERROR;
2395   }
2396 }
2397 
2398 /**
2399   * @brief  Set the ETH DMA configuration.
2400   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2401   *         the configuration information for ETHERNET module
2402   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2403   *         the configuration of the ETH DMA.
2404   * @retval HAL status
2405   */
HAL_ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2406 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2407 {
2408   if (dmaconf == NULL)
2409   {
2410     return HAL_ERROR;
2411   }
2412 
2413   if (heth->gState == HAL_ETH_STATE_READY)
2414   {
2415     ETH_SetDMAConfig(heth, dmaconf);
2416 
2417     return HAL_OK;
2418   }
2419   else
2420   {
2421     return HAL_ERROR;
2422   }
2423 }
2424 
2425 /**
2426   * @brief  Configures the Clock range of ETH MDIO interface.
2427   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2428   *         the configuration information for ETHERNET module
2429   * @retval None
2430   */
HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef * heth)2431 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2432 {
2433   uint32_t hclk;
2434   uint32_t tmpreg;
2435 
2436   /* Get the ETHERNET MACMDIOAR value */
2437   tmpreg = (heth->Instance)->MACMDIOAR;
2438 
2439   /* Clear CSR Clock Range bits */
2440   tmpreg &= ~ETH_MACMDIOAR_CR;
2441 
2442   /* Get hclk frequency value */
2443   hclk = HAL_RCC_GetHCLKFreq();
2444 
2445   /* Set CR bits depending on hclk value */
2446   if ((hclk >= 20000000U) && (hclk < 35000000U))
2447   {
2448     /* CSR Clock Range between 20-35 MHz */
2449     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2450   }
2451   else if ((hclk >= 35000000U) && (hclk < 60000000U))
2452   {
2453     /* CSR Clock Range between 35-60 MHz */
2454     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2455   }
2456   else if ((hclk >= 60000000U) && (hclk < 100000000U))
2457   {
2458     /* CSR Clock Range between 60-100 MHz */
2459     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2460   }
2461   else if ((hclk >= 100000000U) && (hclk < 150000000U))
2462   {
2463     /* CSR Clock Range between 100-150 MHz */
2464     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2465   }
2466   else /* (hclk >= 150000000)&&(hclk <= 200000000) */
2467   {
2468     /* CSR Clock Range between 150-200 MHz */
2469     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2470   }
2471 
2472   /* Configure the CSR Clock Range */
2473   (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2474 }
2475 
2476 /**
2477   * @brief  Set the ETH MAC (L2) Filters configuration.
2478   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2479   *         the configuration information for ETHERNET module
2480   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2481   *         the configuration of the ETH MAC filters.
2482   * @retval HAL status
2483   */
HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2484 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2485 {
2486   uint32_t filterconfig;
2487 
2488   if (pFilterConfig == NULL)
2489   {
2490     return HAL_ERROR;
2491   }
2492 
2493   filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2494                   ((uint32_t)pFilterConfig->HashUnicast << 1) |
2495                   ((uint32_t)pFilterConfig->HashMulticast << 2)  |
2496                   ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2497                   ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2498                   ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) |
2499                   ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2500                   ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2501                   ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2502                   ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2503                   pFilterConfig->ControlPacketsFilter);
2504 
2505   MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig);
2506 
2507   return HAL_OK;
2508 }
2509 
2510 /**
2511   * @brief  Get the ETH MAC (L2) Filters configuration.
2512   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2513   *         the configuration information for ETHERNET module
2514   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2515   *         the configuration of the ETH MAC filters.
2516   * @retval HAL status
2517   */
HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2518 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2519 {
2520   if (pFilterConfig == NULL)
2521   {
2522     return HAL_ERROR;
2523   }
2524 
2525   pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE;
2526   pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE;
2527   pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE;
2528   pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2529                                                        ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2530   pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE;
2531   pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE;
2532   pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF);
2533   pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2534                                                       ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2535   pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2536   pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U)
2537                                        ? ENABLE : DISABLE;
2538   pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2539 
2540   return HAL_OK;
2541 }
2542 
2543 /**
2544   * @brief  Set the source MAC Address to be matched.
2545   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2546   *         the configuration information for ETHERNET module
2547   * @param  AddrNbr: The MAC address to configure
2548   *          This parameter must be a value of the following:
2549   *            ETH_MAC_ADDRESS1
2550   *            ETH_MAC_ADDRESS2
2551   *            ETH_MAC_ADDRESS3
2552   * @param  pMACAddr: Pointer to MAC address buffer data (6 bytes)
2553   * @retval HAL status
2554   */
HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef * heth,uint32_t AddrNbr,uint8_t * pMACAddr)2555 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef *heth, uint32_t AddrNbr, uint8_t *pMACAddr)
2556 {
2557   uint32_t macaddrlr;
2558   uint32_t macaddrhr;
2559 
2560   if (pMACAddr == NULL)
2561   {
2562     return HAL_ERROR;
2563   }
2564 
2565   /* Get mac addr high reg offset */
2566   macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2567   /* Get mac addr low reg offset */
2568   macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2569 
2570   /* Set MAC addr bits 32 to 47 */
2571   (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2572   /* Set MAC addr bits 0 to 31 */
2573   (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2574                                    ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2575 
2576   /* Enable address and set source address bit */
2577   (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE);
2578 
2579   return HAL_OK;
2580 }
2581 
2582 /**
2583   * @brief  Set the ETH Hash Table Value.
2584   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2585   *         the configuration information for ETHERNET module
2586   * @param  pHashTable: pointer to a table of two 32 bit values, that contains
2587   *         the 64 bits of the hash table.
2588   * @retval HAL status
2589   */
HAL_ETH_SetHashTable(ETH_HandleTypeDef * heth,uint32_t * pHashTable)2590 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2591 {
2592   if (pHashTable == NULL)
2593   {
2594     return HAL_ERROR;
2595   }
2596 
2597   heth->Instance->MACHT0R = pHashTable[0];
2598   heth->Instance->MACHT1R = pHashTable[1];
2599 
2600   return HAL_OK;
2601 }
2602 
2603 /**
2604   * @brief  Set the VLAN Identifier for Rx packets
2605   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2606   *         the configuration information for ETHERNET module
2607   * @param  ComparisonBits: 12 or 16 bit comparison mode
2608             must be a value of @ref ETH_VLAN_Tag_Comparison
2609   * @param  VLANIdentifier: VLAN Identifier value
2610   * @retval None
2611   */
HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t ComparisonBits,uint32_t VLANIdentifier)2612 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2613 {
2614   if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2615   {
2616     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier);
2617     CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2618   }
2619   else
2620   {
2621     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier);
2622     SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2623   }
2624 }
2625 
2626 /**
2627   * @brief  Enters the Power down mode.
2628   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2629   *         the configuration information for ETHERNET module
2630   * @param  pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2631   *         that contains the Power Down configuration
2632   * @retval None.
2633   */
HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef * heth,ETH_PowerDownConfigTypeDef * pPowerDownConfig)2634 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2635 {
2636   uint32_t powerdownconfig;
2637 
2638   powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) |
2639                      ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) |
2640                      ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) |
2641                      ((uint32_t)pPowerDownConfig->WakeUpForward << 10) |
2642                      ETH_MACPCSR_PWRDWN);
2643 
2644   /* Enable PMT interrupt */
2645   __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE);
2646 
2647   MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig);
2648 }
2649 
2650 /**
2651   * @brief  Exits from the Power down mode.
2652   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2653   *         the configuration information for ETHERNET module
2654   * @retval None.
2655   */
HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef * heth)2656 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2657 {
2658   /* clear wake up sources */
2659   CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST |
2660             ETH_MACPCSR_RWKPFE);
2661 
2662   if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET)
2663   {
2664     /* Exit power down mode */
2665     CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN);
2666   }
2667 
2668   /* Disable PMT interrupt */
2669   __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE);
2670 }
2671 
2672 /**
2673   * @brief  Set the WakeUp filter.
2674   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2675   *         the configuration information for ETHERNET module
2676   * @param  pFilter: pointer to filter registers values
2677   * @param  Count: number of filter registers, must be from 1 to 8.
2678   * @retval None.
2679   */
HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef * heth,uint32_t * pFilter,uint32_t Count)2680 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2681 {
2682   uint32_t regindex;
2683 
2684   if (pFilter == NULL)
2685   {
2686     return HAL_ERROR;
2687   }
2688 
2689   /* Reset Filter Pointer */
2690   SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST);
2691 
2692   /* Wake up packet filter config */
2693   for (regindex = 0; regindex < Count; regindex++)
2694   {
2695     /* Write filter regs */
2696     WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]);
2697   }
2698 
2699   return HAL_OK;
2700 }
2701 
2702 /**
2703   * @}
2704   */
2705 
2706 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2707   *  @brief   ETH State and Errors functions
2708   *
2709 @verbatim
2710   ==============================================================================
2711                  ##### Peripheral State and Errors functions #####
2712   ==============================================================================
2713  [..]
2714    This subsection provides a set of functions allowing to return the State of
2715    ETH communication process, return Peripheral Errors occurred during communication
2716    process
2717 
2718 
2719 @endverbatim
2720   * @{
2721   */
2722 
2723 /**
2724   * @brief  Returns the ETH state.
2725   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2726   *         the configuration information for ETHERNET module
2727   * @retval HAL state
2728   */
HAL_ETH_GetState(ETH_HandleTypeDef * heth)2729 HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
2730 {
2731   return heth->gState;
2732 }
2733 
2734 /**
2735   * @brief  Returns the ETH error code
2736   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2737   *         the configuration information for ETHERNET module
2738   * @retval ETH Error Code
2739   */
HAL_ETH_GetError(ETH_HandleTypeDef * heth)2740 uint32_t HAL_ETH_GetError(ETH_HandleTypeDef *heth)
2741 {
2742   return heth->ErrorCode;
2743 }
2744 
2745 /**
2746   * @brief  Returns the ETH DMA error code
2747   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2748   *         the configuration information for ETHERNET module
2749   * @retval ETH DMA Error Code
2750   */
HAL_ETH_GetDMAError(ETH_HandleTypeDef * heth)2751 uint32_t HAL_ETH_GetDMAError(ETH_HandleTypeDef *heth)
2752 {
2753   return heth->DMAErrorCode;
2754 }
2755 
2756 /**
2757   * @brief  Returns the ETH MAC error code
2758   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2759   *         the configuration information for ETHERNET module
2760   * @retval ETH MAC Error Code
2761   */
HAL_ETH_GetMACError(ETH_HandleTypeDef * heth)2762 uint32_t HAL_ETH_GetMACError(ETH_HandleTypeDef *heth)
2763 {
2764   return heth->MACErrorCode;
2765 }
2766 
2767 /**
2768   * @brief  Returns the ETH MAC WakeUp event source
2769   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2770   *         the configuration information for ETHERNET module
2771   * @retval ETH MAC WakeUp event source
2772   */
HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef * heth)2773 uint32_t HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef *heth)
2774 {
2775   return heth->MACWakeUpEvent;
2776 }
2777 
2778 /**
2779   * @}
2780   */
2781 
2782 /**
2783   * @}
2784   */
2785 
2786 /** @addtogroup ETH_Private_Functions   ETH Private Functions
2787   * @{
2788   */
2789 
2790 
ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2791 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2792 {
2793   uint32_t macregval;
2794 
2795   /*------------------------ MACCR Configuration --------------------*/
2796   macregval = (macconf->InterPacketGapVal |
2797                macconf->SourceAddrControl |
2798                ((uint32_t)macconf->ChecksumOffload << 27) |
2799                ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) |
2800                ((uint32_t)macconf->Support2KPacket  << 22) |
2801                ((uint32_t)macconf->CRCStripTypePacket << 21) |
2802                ((uint32_t)macconf->AutomaticPadCRCStrip << 20) |
2803                ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) |
2804                ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) |
2805                ((uint32_t)macconf->JumboPacket << 16) |
2806                macconf->Speed |
2807                macconf->DuplexMode |
2808                ((uint32_t)macconf->LoopbackMode << 12) |
2809                ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) |
2810                ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) |
2811                ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) |
2812                ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) |
2813                macconf->BackOffLimit |
2814                ((uint32_t)macconf->DeferralCheck << 4) |
2815                macconf->PreambleLength);
2816 
2817   /* Write to MACCR */
2818   MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval);
2819 
2820   /*------------------------ MACECR Configuration --------------------*/
2821   macregval = ((macconf->ExtendedInterPacketGapVal << 25) |
2822                ((uint32_t)macconf->ExtendedInterPacketGap << 24) |
2823                ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) |
2824                ((uint32_t)macconf->SlowProtocolDetect << 17) |
2825                ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) |
2826                macconf->GiantPacketSizeLimit);
2827 
2828   /* Write to MACECR */
2829   MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval);
2830 
2831   /*------------------------ MACWTR Configuration --------------------*/
2832   macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) |
2833                macconf->WatchdogTimeout);
2834 
2835   /* Write to MACWTR */
2836   MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval);
2837 
2838   /*------------------------ MACTFCR Configuration --------------------*/
2839   macregval = (((uint32_t)macconf->TransmitFlowControl << 1) |
2840                macconf->PauseLowThreshold |
2841                ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) |
2842                (macconf->PauseTime << 16));
2843 
2844   /* Write to MACTFCR */
2845   MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval);
2846 
2847   /*------------------------ MACRFCR Configuration --------------------*/
2848   macregval = ((uint32_t)macconf->ReceiveFlowControl |
2849                ((uint32_t)macconf->UnicastPausePacketDetect << 1));
2850 
2851   /* Write to MACRFCR */
2852   MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval);
2853 
2854   /*------------------------ MTLTQOMR Configuration --------------------*/
2855   /* Write to MTLTQOMR */
2856   MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode);
2857 
2858   /*------------------------ MTLRQOMR Configuration --------------------*/
2859   macregval = (macconf->ReceiveQueueMode |
2860                ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) |
2861                ((uint32_t)macconf->ForwardRxErrorPacket << 4) |
2862                ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3));
2863 
2864   /* Write to MTLRQOMR */
2865   MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval);
2866 }
2867 
ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2868 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2869 {
2870   uint32_t dmaregval;
2871 
2872   /*------------------------ DMAMR Configuration --------------------*/
2873   MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration);
2874 
2875   /*------------------------ DMASBMR Configuration --------------------*/
2876   dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) |
2877                dmaconf->BurstMode |
2878                ((uint32_t)dmaconf->RebuildINCRxBurst << 15));
2879 
2880   MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval);
2881 
2882   /*------------------------ DMACCR Configuration --------------------*/
2883   dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) |
2884                dmaconf->MaximumSegmentSize);
2885 
2886   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval);
2887 
2888   /*------------------------ DMACTCR Configuration --------------------*/
2889   dmaregval = (dmaconf->TxDMABurstLength |
2890                ((uint32_t)dmaconf->SecondPacketOperate << 4) |
2891                ((uint32_t)dmaconf->TCPSegmentation << 12));
2892 
2893   MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval);
2894 
2895   /*------------------------ DMACRCR Configuration --------------------*/
2896   dmaregval = (((uint32_t)dmaconf->FlushRxPacket  << 31) |
2897                dmaconf->RxDMABurstLength);
2898 
2899   /* Write to DMACRCR */
2900   MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval);
2901 }
2902 
2903 /**
2904   * @brief  Configures Ethernet MAC and DMA with default parameters.
2905   *         called by HAL_ETH_Init() API.
2906   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2907   *         the configuration information for ETHERNET module
2908   * @retval HAL status
2909   */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth)2910 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2911 {
2912   ETH_MACConfigTypeDef macDefaultConf;
2913   ETH_DMAConfigTypeDef dmaDefaultConf;
2914 
2915   /*--------------- ETHERNET MAC registers default Configuration --------------*/
2916   macDefaultConf.AutomaticPadCRCStrip = ENABLE;
2917   macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2918   macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
2919   macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2920   macDefaultConf.ChecksumOffload = ENABLE;
2921   macDefaultConf.CRCCheckingRxPackets = ENABLE;
2922   macDefaultConf.CRCStripTypePacket = ENABLE;
2923   macDefaultConf.DeferralCheck = DISABLE;
2924   macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE;
2925   macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2926   macDefaultConf.ExtendedInterPacketGap = DISABLE;
2927   macDefaultConf.ExtendedInterPacketGapVal = 0x0;
2928   macDefaultConf.ForwardRxErrorPacket = DISABLE;
2929   macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE;
2930   macDefaultConf.GiantPacketSizeLimit = 0x618;
2931   macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
2932   macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
2933   macDefaultConf.Jabber = ENABLE;
2934   macDefaultConf.JumboPacket = DISABLE;
2935   macDefaultConf.LoopbackMode = DISABLE;
2936   macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
2937   macDefaultConf.PauseTime = 0x0;
2938   macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
2939   macDefaultConf.ProgrammableWatchdog = DISABLE;
2940   macDefaultConf.ReceiveFlowControl = DISABLE;
2941   macDefaultConf.ReceiveOwn = ENABLE;
2942   macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
2943   macDefaultConf.RetryTransmission = ENABLE;
2944   macDefaultConf.SlowProtocolDetect = DISABLE;
2945   macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0;
2946   macDefaultConf.Speed = ETH_SPEED_100M;
2947   macDefaultConf.Support2KPacket = DISABLE;
2948   macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
2949   macDefaultConf.TransmitFlowControl = DISABLE;
2950   macDefaultConf.UnicastPausePacketDetect = DISABLE;
2951   macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
2952   macDefaultConf.Watchdog = ENABLE;
2953   macDefaultConf.WatchdogTimeout =  ETH_MACWTR_WTO_2KB;
2954   macDefaultConf.ZeroQuantaPause = ENABLE;
2955 
2956   /* MAC default configuration */
2957   ETH_SetMACConfig(heth, &macDefaultConf);
2958 
2959   /*--------------- ETHERNET DMA registers default Configuration --------------*/
2960   dmaDefaultConf.AddressAlignedBeats = ENABLE;
2961   dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2962   dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1;
2963   dmaDefaultConf.FlushRxPacket = DISABLE;
2964   dmaDefaultConf.PBLx8Mode = DISABLE;
2965   dmaDefaultConf.RebuildINCRxBurst = DISABLE;
2966   dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2967   dmaDefaultConf.SecondPacketOperate = DISABLE;
2968   dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2969   dmaDefaultConf.TCPSegmentation = DISABLE;
2970   dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT;
2971 
2972   /* DMA default configuration */
2973   ETH_SetDMAConfig(heth, &dmaDefaultConf);
2974 }
2975 
2976 
2977 /**
2978   * @brief  Initializes the DMA Tx descriptors.
2979   *         called by HAL_ETH_Init() API.
2980   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2981   *         the configuration information for ETHERNET module
2982   * @retval None
2983   */
ETH_DMATxDescListInit(ETH_HandleTypeDef * heth)2984 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
2985 {
2986   ETH_DMADescTypeDef *dmatxdesc;
2987   uint32_t i;
2988 
2989   /* Fill each DMATxDesc descriptor with the right values */
2990   for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
2991   {
2992     dmatxdesc = heth->Init.TxDesc + i;
2993 
2994     WRITE_REG(dmatxdesc->DESC0, 0x0);
2995     WRITE_REG(dmatxdesc->DESC1, 0x0);
2996     WRITE_REG(dmatxdesc->DESC2, 0x0);
2997     WRITE_REG(dmatxdesc->DESC3, 0x0);
2998 
2999     WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
3000 
3001   }
3002 
3003   heth->TxDescList.CurTxDesc = 0;
3004 
3005   /* Set Transmit Descriptor Ring Length */
3006   WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U));
3007 
3008   /* Set Transmit Descriptor List Address */
3009   WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc);
3010 
3011   /* Set Transmit Descriptor Tail pointer */
3012   WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc);
3013 }
3014 
3015 /**
3016   * @brief  Initializes the DMA Rx descriptors in chain mode.
3017   *         called by HAL_ETH_Init() API.
3018   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3019   *         the configuration information for ETHERNET module
3020   * @retval None
3021   */
ETH_DMARxDescListInit(ETH_HandleTypeDef * heth)3022 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
3023 {
3024   ETH_DMADescTypeDef *dmarxdesc;
3025   uint32_t i;
3026 
3027   for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
3028   {
3029     dmarxdesc =  heth->Init.RxDesc + i;
3030 
3031     WRITE_REG(dmarxdesc->DESC0, 0x0);
3032     WRITE_REG(dmarxdesc->DESC1, 0x0);
3033     WRITE_REG(dmarxdesc->DESC2, 0x0);
3034     WRITE_REG(dmarxdesc->DESC3, 0x0);
3035     WRITE_REG(dmarxdesc->BackupAddr0, 0x0);
3036     WRITE_REG(dmarxdesc->BackupAddr1, 0x0);
3037 
3038 
3039     /* Set Rx descritors addresses */
3040     WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
3041 
3042   }
3043 
3044   WRITE_REG(heth->RxDescList.RxDescIdx, 0);
3045   WRITE_REG(heth->RxDescList.RxDescCnt, 0);
3046   WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0);
3047   WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0);
3048   WRITE_REG(heth->RxDescList.ItMode, 0);
3049 
3050   /* Set Receive Descriptor Ring Length */
3051   WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U)));
3052 
3053   /* Set Receive Descriptor List Address */
3054   WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);
3055 
3056   /* Set Receive Descriptor Tail pointer Address */
3057   WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U))));
3058 }
3059 
3060 /**
3061   * @brief  Prepare Tx DMA descriptor before transmission.
3062   *         called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
3063   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3064   *         the configuration information for ETHERNET module
3065   * @param  pTxConfig: Tx packet configuration
3066   * @param  ItMode: Enable or disable Tx EOT interrept
3067   * @retval Status
3068   */
ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig,uint32_t ItMode)3069 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode)
3070 {
3071   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
3072   uint32_t descidx = dmatxdesclist->CurTxDesc;
3073   uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3074   uint32_t idx;
3075   uint32_t descnbr = 0;
3076   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3077 
3078   ETH_BufferTypeDef  *txbuffer = pTxConfig->TxBuffer;
3079   uint32_t           bd_count = 0;
3080 
3081   /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3082   if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3083       || (dmatxdesclist->PacketAddress[descidx] != NULL))
3084   {
3085     return HAL_ETH_ERROR_BUSY;
3086   }
3087 
3088   /***************************************************************************/
3089   /*****************    Context descriptor configuration (Optional) **********/
3090   /***************************************************************************/
3091   /* If VLAN tag is enabled for this packet */
3092   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3093   {
3094     /* Set vlan tag value */
3095     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag);
3096     /* Set vlan tag valid bit */
3097     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV);
3098     /* Set the descriptor as the vlan input source */
3099     SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI);
3100 
3101     /* if inner VLAN is enabled */
3102     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET)
3103     {
3104       /* Set inner vlan tag value */
3105       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16));
3106       /* Set inner vlan tag valid bit */
3107       SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV);
3108 
3109       /* Set Vlan Tag control */
3110       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl);
3111 
3112       /* Set the descriptor as the inner vlan input source */
3113       SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI);
3114       /* Enable double VLAN processing */
3115       SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP);
3116     }
3117   }
3118 
3119   /* if tcp segmentation is enabled for this packet */
3120   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3121   {
3122     /* Set MSS value */
3123     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize);
3124     /* Set MSS valid bit */
3125     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV);
3126   }
3127 
3128   if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3129       || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET))
3130   {
3131     /* Set as context descriptor */
3132     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT);
3133     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3134     __DMB();
3135     /* Set own bit */
3136     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3137     /* Increment current tx descriptor index */
3138     INCR_TX_DESC_INDEX(descidx, 1U);
3139     /* Get current descriptor address */
3140     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3141 
3142     descnbr += 1U;
3143 
3144     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3145     if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3146     {
3147       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
3148       /* Ensure rest of descriptor is written to RAM before the OWN bit */
3149       __DMB();
3150       /* Clear own bit */
3151       CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3152 
3153       return HAL_ETH_ERROR_BUSY;
3154     }
3155   }
3156 
3157   /***************************************************************************/
3158   /*****************    Normal descriptors configuration     *****************/
3159   /***************************************************************************/
3160 
3161   descnbr += 1U;
3162 
3163   /* Set header or buffer 1 address */
3164   WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3165   /* Set header or buffer 1 Length */
3166   MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3167 
3168   if (txbuffer->next != NULL)
3169   {
3170     txbuffer = txbuffer->next;
3171     /* Set buffer 2 address */
3172     WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3173     /* Set buffer 2 Length */
3174     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3175   }
3176   else
3177   {
3178     WRITE_REG(dmatxdesc->DESC1, 0x0);
3179     /* Set buffer 2 Length */
3180     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3181   }
3182 
3183   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3184   {
3185     /* Set TCP Header length */
3186     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19));
3187     /* Set TCP payload length */
3188     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3189     /* Set TCP Segmentation Enabled bit */
3190     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3191   }
3192   else
3193   {
3194     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3195 
3196     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3197     {
3198       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3199     }
3200 
3201     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET)
3202     {
3203       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl);
3204     }
3205   }
3206 
3207   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3208   {
3209     /* Set Vlan Tag control */
3210     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl);
3211   }
3212 
3213   /* Mark it as First Descriptor */
3214   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3215   /* Mark it as NORMAL descriptor */
3216   CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3217   /* Ensure rest of descriptor is written to RAM before the OWN bit */
3218   __DMB();
3219   /* set OWN bit of FIRST descriptor */
3220   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3221 
3222   /* If source address insertion/replacement is enabled for this packet */
3223   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET)
3224   {
3225     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl);
3226   }
3227 
3228   /* only if the packet is split into more than one descriptors > 1 */
3229   while (txbuffer->next != NULL)
3230   {
3231     /* Clear the LD bit of previous descriptor */
3232     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3233     /* Increment current tx descriptor index */
3234     INCR_TX_DESC_INDEX(descidx, 1U);
3235     /* Get current descriptor address */
3236     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3237 
3238     /* Clear the FD bit of new Descriptor */
3239     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3240 
3241     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3242     if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN)
3243         || (dmatxdesclist->PacketAddress[descidx] != NULL))
3244     {
3245       descidx = firstdescidx;
3246       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3247 
3248       /* clear previous desc own bit */
3249       for (idx = 0; idx < descnbr; idx ++)
3250       {
3251         /* Ensure rest of descriptor is written to RAM before the OWN bit */
3252         __DMB();
3253 
3254         CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3255 
3256         /* Increment current tx descriptor index */
3257         INCR_TX_DESC_INDEX(descidx, 1U);
3258         /* Get current descriptor address */
3259         dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3260       }
3261 
3262       return HAL_ETH_ERROR_BUSY;
3263     }
3264 
3265     descnbr += 1U;
3266 
3267     /* Get the next Tx buffer in the list */
3268     txbuffer = txbuffer->next;
3269 
3270     /* Set header or buffer 1 address */
3271     WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3272     /* Set header or buffer 1 Length */
3273     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3274 
3275     if (txbuffer->next != NULL)
3276     {
3277       /* Get the next Tx buffer in the list */
3278       txbuffer = txbuffer->next;
3279       /* Set buffer 2 address */
3280       WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3281       /* Set buffer 2 Length */
3282       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3283     }
3284     else
3285     {
3286       WRITE_REG(dmatxdesc->DESC1, 0x0);
3287       /* Set buffer 2 Length */
3288       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3289     }
3290 
3291     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3292     {
3293       /* Set TCP payload length */
3294       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3295       /* Set TCP Segmentation Enabled bit */
3296       SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3297     }
3298     else
3299     {
3300       /* Set the packet length */
3301       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3302 
3303       if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3304       {
3305         /* Checksum Insertion Control */
3306         MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3307       }
3308     }
3309 
3310     bd_count += 1U;
3311 
3312     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3313     __DMB();
3314     /* Set Own bit */
3315     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3316     /* Mark it as NORMAL descriptor */
3317     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3318   }
3319 
3320   if (ItMode != ((uint32_t)RESET))
3321   {
3322     /* Set Interrupt on completion bit */
3323     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3324   }
3325   else
3326   {
3327     /* Clear Interrupt on completion bit */
3328     CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3329   }
3330 
3331   /* Mark it as LAST descriptor */
3332   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3333   /* Save the current packet address to expose it to the application */
3334   dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3335 
3336   dmatxdesclist->CurTxDesc = descidx;
3337 
3338   /* disable the interrupt */
3339   __disable_irq();
3340 
3341   dmatxdesclist->BuffersInUse += bd_count + 1U;
3342 
3343   /* Enable interrupts back */
3344   __enable_irq();
3345 
3346 
3347   /* Return function status */
3348   return HAL_ETH_ERROR_NONE;
3349 }
3350 
3351 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)3352 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3353 {
3354   /* Init the ETH Callback settings */
3355   heth->TxCpltCallback   = HAL_ETH_TxCpltCallback;    /* Legacy weak TxCpltCallback   */
3356   heth->RxCpltCallback   = HAL_ETH_RxCpltCallback;    /* Legacy weak RxCpltCallback   */
3357   heth->ErrorCallback    = HAL_ETH_ErrorCallback;     /* Legacy weak ErrorCallback */
3358   heth->PMTCallback      = HAL_ETH_PMTCallback;       /* Legacy weak PMTCallback      */
3359   heth->EEECallback      = HAL_ETH_EEECallback;       /* Legacy weak EEECallback      */
3360   heth->WakeUpCallback   = HAL_ETH_WakeUpCallback;    /* Legacy weak WakeUpCallback   */
3361   heth->rxLinkCallback   = HAL_ETH_RxLinkCallback;    /* Legacy weak RxLinkCallback   */
3362   heth->txFreeCallback   = HAL_ETH_TxFreeCallback;    /* Legacy weak TxFreeCallback   */
3363 #ifdef HAL_ETH_USE_PTP
3364   heth->txPtpCallback    = HAL_ETH_TxPtpCallback;     /* Legacy weak TxPtpCallback   */
3365 #endif /* HAL_ETH_USE_PTP */
3366   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3367 }
3368 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3369 
3370 /**
3371   * @}
3372   */
3373 
3374 /**
3375   * @}
3376   */
3377 
3378 #endif /* ETH */
3379 
3380 #endif /* HAL_ETH_MODULE_ENABLED */
3381 
3382 /**
3383   * @}
3384   */
3385 
3386