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