1 /**
2   ******************************************************************************
3   * @file    stm32h7rsxx_hal_eth.c
4   * @author  MCD Application Team
5   * @brief   ETH HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Ethernet (ETH) peripheral:
8   *           + Initialization and deinitialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2022 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                     ##### How to use this driver #####
27   ==============================================================================
28      [..]
29      The ETH HAL driver can be used as follows:
30 
31       (#)Declare a ETH_HandleTypeDef handle structure, for example:
32          ETH_HandleTypeDef  heth;
33 
34       (#)Fill parameters of Init structure in heth handle
35 
36       (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
37 
38       (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
39           (##) Enable the Ethernet interface clock using
40                 (+++)  __HAL_RCC_ETH1MAC_CLK_ENABLE()
41                 (+++)  __HAL_RCC_ETH1TX_CLK_ENABLE()
42                 (+++)  __HAL_RCC_ETH1RX_CLK_ENABLE()
43 
44           (##) Initialize the related GPIO clocks
45           (##) Configure Ethernet pinout
46           (##) Configure Ethernet NVIC interrupt (in Interrupt mode)
47 
48       (#) Ethernet data reception is asynchronous, so call the following API
49           to start the listening mode:
50           (##) HAL_ETH_Start():
51                This API starts the MAC and DMA transmission and reception process,
52                without enabling end of transfer interrupts, in this mode user
53                has to poll for data reception by calling HAL_ETH_ReadData()
54           (##) HAL_ETH_Start_IT():
55                This API starts the MAC and DMA transmission and reception process,
56                end of transfer interrupts are enabled in this mode,
57                HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received
58 
59       (#) When data is received user can call the following API to get received data:
60           (##) HAL_ETH_ReadData(): Read a received packet
61 
62       (#) For transmission path, two APIs are available:
63          (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode
64          (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode,
65               HAL_ETH_TxCpltCallback() will be executed when end of transfer occur
66 
67       (#) Communication with an external PHY device:
68          (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY
69          (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register
70 
71       (#) Configure the Ethernet MAC after ETH peripheral initialization
72           (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef
73           (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef
74 
75       (#) Configure the Ethernet DMA after ETH peripheral initialization
76           (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef
77           (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef
78 
79       (#) Configure the Ethernet PTP after ETH peripheral initialization
80           (##) Define HAL_ETH_USE_PTP to use PTP APIs.
81           (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef
82           (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef
83           (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers
84           (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers
85           (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers
86           (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission
87           (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp
88           (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp
89 
90       -@- The ARP offload feature is not supported in this driver.
91 
92       -@- The PTP offload feature is not supported in this driver.
93 
94   *** Callback registration ***
95   =============================================
96 
97   The compilation define  USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
98   allows the user to configure dynamically the driver callbacks.
99   Use Function HAL_ETH_RegisterCallback() to register an interrupt callback.
100 
101   Function HAL_ETH_RegisterCallback() allows to register following callbacks:
102     (+) TxCpltCallback   : Tx Complete Callback.
103     (+) RxCpltCallback   : Rx Complete Callback.
104     (+) ErrorCallback    : Error Callback.
105     (+) PMTCallback      : Power Management Callback
106     (+) EEECallback      : EEE Callback.
107     (+) WakeUpCallback   : Wake UP Callback
108     (+) MspInitCallback  : MspInit Callback.
109     (+) MspDeInitCallback: MspDeInit Callback.
110 
111   This function takes as parameters the HAL peripheral handle, the Callback ID
112   and a pointer to the user callback function.
113 
114   For specific callbacks RxAllocateCallback use dedicated register callbacks:
115   respectively HAL_ETH_RegisterRxAllocateCallback().
116 
117   For specific callbacks RxLinkCallback use dedicated register callbacks:
118   respectively HAL_ETH_RegisterRxLinkCallback().
119 
120   For specific callbacks TxFreeCallback use dedicated register callbacks:
121   respectively HAL_ETH_RegisterTxFreeCallback().
122 
123   For specific callbacks TxPtpCallback use dedicated register callbacks:
124   respectively HAL_ETH_RegisterTxPtpCallback().
125 
126   Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default
127   weak function.
128   HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
129   and the Callback ID.
130   This function allows to reset following callbacks:
131     (+) TxCpltCallback   : Tx Complete Callback.
132     (+) RxCpltCallback   : Rx Complete Callback.
133     (+) ErrorCallback    : Error Callback.
134     (+) PMTCallback      : Power Management Callback
135     (+) EEECallback      : EEE Callback.
136     (+) WakeUpCallback   : Wake UP Callback
137     (+) MspInitCallback  : MspInit Callback.
138     (+) MspDeInitCallback: MspDeInit Callback.
139 
140   For specific callbacks RxAllocateCallback use dedicated unregister callbacks:
141   respectively HAL_ETH_UnRegisterRxAllocateCallback().
142 
143   For specific callbacks RxLinkCallback use dedicated unregister callbacks:
144   respectively HAL_ETH_UnRegisterRxLinkCallback().
145 
146   For specific callbacks TxFreeCallback use dedicated unregister callbacks:
147   respectively HAL_ETH_UnRegisterTxFreeCallback().
148 
149   For specific callbacks TxPtpCallback use dedicated unregister callbacks:
150   respectively HAL_ETH_UnRegisterTxPtpCallback().
151 
152   By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
153   all callbacks are set to the corresponding weak functions:
154   examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback().
155   Exception done for MspInit and MspDeInit functions that are
156   reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when
157   these callbacks are null (not registered beforehand).
158   if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit
159   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
160 
161   Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
162   Exception done MspInit/MspDeInit that can be registered/unregistered
163   in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
164   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
165   In that case first register the MspInit/MspDeInit user callbacks
166   using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit
167   or HAL_ETH_Init function.
168 
169   When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
170   not defined, the callback registration feature is not available and all callbacks
171   are set to the corresponding weak functions.
172 
173   @endverbatim
174   ******************************************************************************
175   */
176 
177 /* Includes ------------------------------------------------------------------*/
178 #include "stm32h7rsxx_hal.h"
179 
180 /** @addtogroup STM32H7RSxx_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_ConfigEthernetPHY(SBS_ETHERNET_PHY_GMII_OR_MII);
343   }
344   else
345   {
346     HAL_SBS_ConfigEthernetPHY(SBS_ETHERNET_PHY_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;
1043   ETH_DMADescTypeDef *dmarxdesc;
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_CTXT)  != (uint32_t)RESET)
1069     {
1070       /* Get timestamp high */
1071       heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1;
1072       /* Get timestamp low */
1073       heth->RxDescList.TimeStamp.TimeStampLow  = dmarxdesc->DESC0;
1074     }
1075     if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
1076     {
1077       /* Check if first descriptor */
1078       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET)
1079       {
1080         heth->RxDescList.RxDescCnt = 0;
1081         heth->RxDescList.RxDataLength = 0;
1082       }
1083 
1084       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1085       bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength;
1086 
1087       /* Check if last descriptor */
1088       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET)
1089       {
1090         /* Save Last descriptor index */
1091         heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3;
1092 
1093         /* Packet ready */
1094         rxdataready = 1;
1095       }
1096 
1097       /* Link data */
1098 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1099       /*Call registered Link callback*/
1100       heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1101                            (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
1102 #else
1103       /* Link callback */
1104       HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1105                              (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
1106 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1107       heth->RxDescList.RxDescCnt++;
1108       heth->RxDescList.RxDataLength += bufflength;
1109 
1110       /* Clear buffer pointer */
1111       dmarxdesc->BackupAddr0 = 0;
1112     }
1113 
1114     /* Increment current rx descriptor index */
1115     INCR_RX_DESC_INDEX(descidx, 1U);
1116     /* Get current descriptor address */
1117     dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1118     desccnt++;
1119   }
1120 
1121   heth->RxDescList.RxBuildDescCnt += desccnt;
1122   if ((heth->RxDescList.RxBuildDescCnt) != 0U)
1123   {
1124     /* Update Descriptors */
1125     ETH_UpdateDescriptor(heth);
1126   }
1127 
1128   heth->RxDescList.RxDescIdx = descidx;
1129 
1130   if (rxdataready == 1U)
1131   {
1132     /* Return received packet */
1133     *pAppBuff = heth->RxDescList.pRxStart;
1134     /* Reset first element */
1135     heth->RxDescList.pRxStart = NULL;
1136 
1137     return HAL_OK;
1138   }
1139 
1140   /* Packet not ready */
1141   return HAL_ERROR;
1142 }
1143 
1144 /**
1145   * @brief  This function gives back Rx Desc of the last received Packet
1146   *         to the DMA, so ETH DMA will be able to use these descriptors
1147   *         to receive next Packets.
1148   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1149   *         the configuration information for ETHERNET module
1150   * @retval HAL status
1151   */
ETH_UpdateDescriptor(ETH_HandleTypeDef * heth)1152 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
1153 {
1154   uint32_t descidx;
1155   uint32_t tailidx;
1156   uint32_t desccount;
1157   ETH_DMADescTypeDef *dmarxdesc;
1158   uint8_t *buff = NULL;
1159   uint8_t allocStatus = 1U;
1160 
1161   descidx = heth->RxDescList.RxBuildDescIdx;
1162   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1163   desccount = heth->RxDescList.RxBuildDescCnt;
1164 
1165   while ((desccount > 0U) && (allocStatus != 0U))
1166   {
1167     /* Check if a buffer's attached the descriptor */
1168     if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
1169     {
1170       /* Get a new buffer. */
1171 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1172       /*Call registered Allocate callback*/
1173       heth->rxAllocateCallback(&buff);
1174 #else
1175       /* Allocate callback */
1176       HAL_ETH_RxAllocateCallback(&buff);
1177 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1178       if (buff == NULL)
1179       {
1180         allocStatus = 0U;
1181       }
1182       else
1183       {
1184         WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
1185         WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff);
1186       }
1187     }
1188 
1189     if (allocStatus != 0U)
1190     {
1191 
1192       if (heth->RxDescList.ItMode != 0U)
1193       {
1194         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC);
1195       }
1196       else
1197       {
1198         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V);
1199       }
1200 
1201       /* Increment current rx descriptor index */
1202       INCR_RX_DESC_INDEX(descidx, 1U);
1203       /* Get current descriptor address */
1204       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1205       desccount--;
1206     }
1207   }
1208 
1209   if (heth->RxDescList.RxBuildDescCnt != desccount)
1210   {
1211     /* Set the tail pointer index */
1212     tailidx = (descidx + 1U) % ETH_RX_DESC_CNT;
1213 
1214     /* DMB instruction to avoid race condition */
1215     __DMB();
1216 
1217     /* Set the Tail pointer address */
1218     WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (tailidx))));
1219 
1220     heth->RxDescList.RxBuildDescIdx = descidx;
1221     heth->RxDescList.RxBuildDescCnt = desccount;
1222   }
1223 }
1224 
1225 /**
1226   * @brief  Register the Rx alloc callback.
1227   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1228   *         the configuration information for ETHERNET module
1229   * @param  rxAllocateCallback: pointer to function to alloc buffer
1230   * @retval HAL status
1231   */
HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef * heth,pETH_rxAllocateCallbackTypeDef rxAllocateCallback)1232 HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
1233                                                      pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
1234 {
1235   if (rxAllocateCallback == NULL)
1236   {
1237     /* No buffer to save */
1238     return HAL_ERROR;
1239   }
1240 
1241   /* Set function to allocate buffer */
1242   heth->rxAllocateCallback = rxAllocateCallback;
1243 
1244   return HAL_OK;
1245 }
1246 
1247 /**
1248   * @brief  Unregister the Rx alloc callback.
1249   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1250   *         the configuration information for ETHERNET module
1251   * @retval HAL status
1252   */
HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef * heth)1253 HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
1254 {
1255   /* Set function to allocate buffer */
1256   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
1257 
1258   return HAL_OK;
1259 }
1260 
1261 /**
1262   * @brief  Rx Allocate callback.
1263   * @param  buff: pointer to allocated buffer
1264   * @retval None
1265   */
HAL_ETH_RxAllocateCallback(uint8_t ** buff)1266 __weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
1267 {
1268   /* Prevent unused argument(s) compilation warning */
1269   UNUSED(buff);
1270   /* NOTE : This function Should not be modified, when the callback is needed,
1271   the HAL_ETH_RxAllocateCallback could be implemented in the user file
1272   */
1273 }
1274 
1275 /**
1276   * @brief  Rx Link callback.
1277   * @param  pStart: pointer to packet start
1278   * @param  pEnd: pointer to packet end
1279   * @param  buff: pointer to received data
1280   * @param  Length: received data length
1281   * @retval None
1282   */
HAL_ETH_RxLinkCallback(void ** pStart,void ** pEnd,uint8_t * buff,uint16_t Length)1283 __weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
1284 {
1285   /* Prevent unused argument(s) compilation warning */
1286   UNUSED(pStart);
1287   UNUSED(pEnd);
1288   UNUSED(buff);
1289   UNUSED(Length);
1290   /* NOTE : This function Should not be modified, when the callback is needed,
1291   the HAL_ETH_RxLinkCallback could be implemented in the user file
1292   */
1293 }
1294 
1295 /**
1296   * @brief  Set the Rx link data function.
1297   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1298   *         the configuration information for ETHERNET module
1299   * @param  rxLinkCallback: pointer to function to link data
1300   * @retval HAL status
1301   */
HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef * heth,pETH_rxLinkCallbackTypeDef rxLinkCallback)1302 HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
1303 {
1304   if (rxLinkCallback == NULL)
1305   {
1306     /* No buffer to save */
1307     return HAL_ERROR;
1308   }
1309 
1310   /* Set function to link data */
1311   heth->rxLinkCallback = rxLinkCallback;
1312 
1313   return HAL_OK;
1314 }
1315 
1316 /**
1317   * @brief  Unregister the Rx link callback.
1318   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1319   *         the configuration information for ETHERNET module
1320   * @retval HAL status
1321   */
HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef * heth)1322 HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
1323 {
1324   /* Set function to allocate buffer */
1325   heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
1326 
1327   return HAL_OK;
1328 }
1329 
1330 /**
1331   * @brief  Get the error state of the last received packet.
1332   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1333   *         the configuration information for ETHERNET module
1334   * @param  pErrorCode: pointer to uint32_t to hold the error code
1335   * @retval HAL status
1336   */
HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef * heth,uint32_t * pErrorCode)1337 HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
1338 {
1339   /* Get error bits. */
1340   *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK);
1341 
1342   return HAL_OK;
1343 }
1344 
1345 /**
1346   * @brief  Set the Tx free function.
1347   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1348   *         the configuration information for ETHERNET module
1349   * @param  txFreeCallback: pointer to function to release the packet
1350   * @retval HAL status
1351   */
HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef * heth,pETH_txFreeCallbackTypeDef txFreeCallback)1352 HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
1353 {
1354   if (txFreeCallback == NULL)
1355   {
1356     /* No buffer to save */
1357     return HAL_ERROR;
1358   }
1359 
1360   /* Set function to free transmmitted packet */
1361   heth->txFreeCallback = txFreeCallback;
1362 
1363   return HAL_OK;
1364 }
1365 
1366 /**
1367   * @brief  Unregister the Tx free callback.
1368   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1369   *         the configuration information for ETHERNET module
1370   * @retval HAL status
1371   */
HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef * heth)1372 HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
1373 {
1374   /* Set function to allocate buffer */
1375   heth->txFreeCallback = HAL_ETH_TxFreeCallback;
1376 
1377   return HAL_OK;
1378 }
1379 
1380 /**
1381   * @brief  Tx Free callback.
1382   * @param  buff: pointer to buffer to free
1383   * @retval None
1384   */
HAL_ETH_TxFreeCallback(uint32_t * buff)1385 __weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
1386 {
1387   /* Prevent unused argument(s) compilation warning */
1388   UNUSED(buff);
1389   /* NOTE : This function Should not be modified, when the callback is needed,
1390   the HAL_ETH_TxFreeCallback could be implemented in the user file
1391   */
1392 }
1393 
1394 /**
1395   * @brief  Release transmitted Tx packets.
1396   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1397   *         the configuration information for ETHERNET module
1398   * @retval HAL status
1399   */
HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef * heth)1400 HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
1401 {
1402   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1403   uint32_t numOfBuf =  dmatxdesclist->BuffersInUse;
1404   uint32_t idx =       dmatxdesclist->releaseIndex;
1405   uint8_t pktTxStatus = 1U;
1406   uint8_t pktInUse;
1407 #ifdef HAL_ETH_USE_PTP
1408   ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
1409 #endif /* HAL_ETH_USE_PTP */
1410 
1411   /* Loop through buffers in use.  */
1412   while ((numOfBuf != 0U) && (pktTxStatus != 0U))
1413   {
1414     pktInUse = 1U;
1415     numOfBuf--;
1416     /* If no packet, just examine the next packet.  */
1417     if (dmatxdesclist->PacketAddress[idx] == NULL)
1418     {
1419       /* No packet in use, skip to next.  */
1420       INCR_TX_DESC_INDEX(idx, 1U);
1421       pktInUse = 0U;
1422     }
1423 
1424     if (pktInUse != 0U)
1425     {
1426       /* Determine if the packet has been transmitted.  */
1427       if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U)
1428       {
1429 #ifdef HAL_ETH_USE_PTP
1430 
1431         /* Disable Ptp transmission */
1432         CLEAR_BIT(heth->Init.TxDesc[idx].DESC3, (0x40000000U));
1433 
1434         if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_LD)
1435             && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_TTSS))
1436         {
1437           /* Get timestamp low */
1438           timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0;
1439           /* Get timestamp high */
1440           timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1;
1441         }
1442         else
1443         {
1444           timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX;
1445         }
1446 #endif /* HAL_ETH_USE_PTP */
1447 
1448 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1449         /*Call registered callbacks*/
1450 #ifdef HAL_ETH_USE_PTP
1451         /* Handle Ptp  */
1452         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1453         {
1454           heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1455         }
1456 #endif  /* HAL_ETH_USE_PTP */
1457         /* Release the packet.  */
1458         heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1459 #else
1460         /* Call callbacks */
1461 #ifdef HAL_ETH_USE_PTP
1462         /* Handle Ptp  */
1463         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1464         {
1465           HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1466         }
1467 #endif  /* HAL_ETH_USE_PTP */
1468         /* Release the packet.  */
1469         HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1470 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1471 
1472         /* Clear the entry in the in-use array.  */
1473         dmatxdesclist->PacketAddress[idx] = NULL;
1474 
1475         /* Update the transmit relesae index and number of buffers in use.  */
1476         INCR_TX_DESC_INDEX(idx, 1U);
1477         dmatxdesclist->BuffersInUse = numOfBuf;
1478         dmatxdesclist->releaseIndex = idx;
1479       }
1480       else
1481       {
1482         /* Get out of the loop!  */
1483         pktTxStatus = 0U;
1484       }
1485     }
1486   }
1487   return HAL_OK;
1488 }
1489 
1490 #ifdef HAL_ETH_USE_PTP
1491 /**
1492   * @brief  Set the Ethernet PTP configuration.
1493   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1494   *         the configuration information for ETHERNET module
1495   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1496   *         the configuration information for PTP
1497   * @retval HAL status
1498   */
HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1499 HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1500 {
1501   uint32_t tmpTSCR;
1502   ETH_TimeTypeDef time;
1503 
1504   if (ptpconfig == NULL)
1505   {
1506     return HAL_ERROR;
1507   }
1508 
1509   tmpTSCR = ptpconfig->Timestamp |
1510             ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) |
1511             ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) |
1512             ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) |
1513             ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) |
1514             ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) |
1515             ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) |
1516             ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) |
1517             ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) |
1518             ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) |
1519             ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) |
1520             ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) |
1521             ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) |
1522             ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos);
1523 
1524   /* Write to MACTSCR */
1525   MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1526 
1527   /* Enable Timestamp */
1528   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1529   WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc);
1530   WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend);
1531 
1532   /* Enable Timestamp */
1533   if (ptpconfig->TimestampAddendUpdate == ENABLE)
1534   {
1535     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG);
1536     while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0)
1537     {
1538 
1539     }
1540   }
1541 
1542   /* Ptp Init */
1543   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT);
1544 
1545   /* Set PTP Configuration done */
1546   heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED;
1547 
1548   /* Set Seconds */
1549   time.Seconds = heth->Instance->MACSTSR;
1550   /* Set NanoSeconds */
1551   time.NanoSeconds = heth->Instance->MACSTNR;
1552 
1553   HAL_ETH_PTP_SetTime(heth, &time);
1554 
1555   /* Return function status */
1556   return HAL_OK;
1557 }
1558 
1559 /**
1560   * @brief  Get the Ethernet PTP configuration.
1561   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1562   *         the configuration information for ETHERNET module
1563   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1564   *         the configuration information for PTP
1565   * @retval HAL status
1566   */
HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1567 HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1568 {
1569   if (ptpconfig == NULL)
1570   {
1571     return HAL_ERROR;
1572   }
1573   ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1574   ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR,
1575                                           ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE;
1576   ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR,
1577                                        ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE;
1578   ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR,
1579                                                 ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U)
1580                                      ? ENABLE : DISABLE;
1581   ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR,
1582                                       ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE;
1583   ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR,
1584                                             ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE;
1585   ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR,
1586                                         ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE;
1587   ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR,
1588                                         ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE;
1589   ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR,
1590                                          ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE;
1591   ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR,
1592                                           ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE;
1593   ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR,
1594                                              ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U)
1595                                   ? ENABLE : DISABLE;
1596   ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR,
1597                                           ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U)
1598                                ? ENABLE : DISABLE;
1599   ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR,
1600                                                       ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE;
1601   ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR,
1602                                               ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U)
1603                                    ? ENABLE : DISABLE;
1604 
1605   /* Return function status */
1606   return HAL_OK;
1607 }
1608 
1609 /**
1610   * @brief  Set Seconds and Nanoseconds for the Ethernet PTP registers.
1611   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1612   *         the configuration information for ETHERNET module
1613   * @param  time: pointer to a ETH_TimeTypeDef structure that contains
1614   *         time to set
1615   * @retval HAL status
1616   */
HAL_ETH_PTP_SetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1617 HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1618 {
1619   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1620   {
1621     /* Set Seconds */
1622     heth->Instance->MACSTSUR = time->Seconds;
1623 
1624     /* Set NanoSeconds */
1625     heth->Instance->MACSTNUR = time->NanoSeconds;
1626 
1627     /* the system time is updated */
1628     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT);
1629 
1630     /* Return function status */
1631     return HAL_OK;
1632   }
1633   else
1634   {
1635     /* Return function status */
1636     return HAL_ERROR;
1637   }
1638 }
1639 
1640 /**
1641   * @brief  Get Seconds and Nanoseconds for the Ethernet PTP registers.
1642   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1643   *         the configuration information for ETHERNET module
1644   * @param  time: pointer to a ETH_TimeTypeDef structure that contains
1645   *         time to get
1646   * @retval HAL status
1647   */
HAL_ETH_PTP_GetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1648 HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1649 {
1650   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1651   {
1652     /* Get Seconds */
1653     time->Seconds = heth->Instance->MACSTSR;
1654     /* Get NanoSeconds */
1655     time->NanoSeconds = heth->Instance->MACSTNR;
1656 
1657     /* Return function status */
1658     return HAL_OK;
1659   }
1660   else
1661   {
1662     /* Return function status */
1663     return HAL_ERROR;
1664   }
1665 }
1666 
1667 /**
1668   * @brief  Update time for the Ethernet PTP registers.
1669   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1670   *         the configuration information for ETHERNET module
1671   * @param  timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains
1672   *         the time update information
1673   * @retval HAL status
1674   */
HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef * heth,ETH_PtpUpdateTypeDef ptpoffsettype,ETH_TimeTypeDef * timeoffset)1675 HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1676                                             ETH_TimeTypeDef *timeoffset)
1677 {
1678   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1679   {
1680     if (ptpoffsettype ==  HAL_ETH_PTP_NEGATIVE_UPDATE)
1681     {
1682       /* Set Seconds update */
1683       heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U;
1684 
1685       if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR)
1686       {
1687         /* Set nanoSeconds update */
1688         heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds;
1689       }
1690       else
1691       {
1692         /* Set nanoSeconds update */
1693         heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U;
1694       }
1695     }
1696     else
1697     {
1698       /* Set Seconds update */
1699       heth->Instance->MACSTSUR = timeoffset->Seconds;
1700       /* Set nanoSeconds update */
1701       heth->Instance->MACSTNUR = timeoffset->NanoSeconds;
1702     }
1703 
1704     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT);
1705 
1706     /* Return function status */
1707     return HAL_OK;
1708   }
1709   else
1710   {
1711     /* Return function status */
1712     return HAL_ERROR;
1713   }
1714 }
1715 
1716 /**
1717   * @brief  Insert Timestamp in transmission.
1718   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1719   *         the configuration information for ETHERNET module
1720   * @retval HAL status
1721   */
HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef * heth)1722 HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1723 {
1724   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1725   uint32_t descidx = dmatxdesclist->CurTxDesc;
1726   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1727 
1728   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1729   {
1730     /* Enable Time Stamp transmission */
1731     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE);
1732 
1733     /* Return function status */
1734     return HAL_OK;
1735   }
1736   else
1737   {
1738     /* Return function status */
1739     return HAL_ERROR;
1740   }
1741 }
1742 
1743 /**
1744   * @brief  Get transmission timestamp.
1745   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1746   *         the configuration information for ETHERNET module
1747   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1748   *         transmission timestamp
1749   * @retval HAL status
1750   */
HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1751 HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1752 {
1753   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1754   uint32_t idx =       dmatxdesclist->releaseIndex;
1755   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1756 
1757   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1758   {
1759     /* Get timestamp low */
1760     timestamp->TimeStampLow = dmatxdesc->DESC0;
1761     /* Get timestamp high */
1762     timestamp->TimeStampHigh = dmatxdesc->DESC1;
1763 
1764     /* Return function status */
1765     return HAL_OK;
1766   }
1767   else
1768   {
1769     /* Return function status */
1770     return HAL_ERROR;
1771   }
1772 }
1773 
1774 /**
1775   * @brief  Get receive timestamp.
1776   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1777   *         the configuration information for ETHERNET module
1778   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1779   *         receive timestamp
1780   * @retval HAL status
1781   */
HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1782 HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1783 {
1784   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1785   {
1786     /* Get timestamp low */
1787     timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
1788     /* Get timestamp high */
1789     timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
1790 
1791     /* Return function status */
1792     return HAL_OK;
1793   }
1794   else
1795   {
1796     /* Return function status */
1797     return HAL_ERROR;
1798   }
1799 }
1800 
1801 /**
1802   * @brief  Register the Tx Ptp callback.
1803   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1804   *         the configuration information for ETHERNET module
1805   * @param  txPtpCallback: Function to handle Ptp transmission
1806   * @retval HAL status
1807   */
HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef * heth,pETH_txPtpCallbackTypeDef txPtpCallback)1808 HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1809 {
1810   if (txPtpCallback == NULL)
1811   {
1812     /* No buffer to save */
1813     return HAL_ERROR;
1814   }
1815   /* Set Function to handle Tx Ptp */
1816   heth->txPtpCallback = txPtpCallback;
1817 
1818   return HAL_OK;
1819 }
1820 
1821 /**
1822   * @brief  Unregister the Tx Ptp callback.
1823   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1824   *         the configuration information for ETHERNET module
1825   * @retval HAL status
1826   */
HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef * heth)1827 HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1828 {
1829   /* Set function to allocate buffer */
1830   heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1831 
1832   return HAL_OK;
1833 }
1834 
1835 /**
1836   * @brief  Tx Ptp callback.
1837   * @param  buff: pointer to application buffer
1838   * @param  timestamp: pointer to ETH_TimeStampTypeDef structure that contains
1839   *         transmission timestamp
1840   * @retval None
1841   */
HAL_ETH_TxPtpCallback(uint32_t * buff,ETH_TimeStampTypeDef * timestamp)1842 __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1843 {
1844   /* Prevent unused argument(s) compilation warning */
1845   UNUSED(buff);
1846   /* NOTE : This function Should not be modified, when the callback is needed,
1847   the HAL_ETH_TxPtpCallback could be implemented in the user file
1848   */
1849 }
1850 #endif  /* HAL_ETH_USE_PTP */
1851 
1852 /**
1853   * @brief  This function handles ETH interrupt request.
1854   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1855   *         the configuration information for ETHERNET module
1856   * @retval HAL status
1857   */
HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)1858 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1859 {
1860   uint32_t mac_flag = READ_REG(heth->Instance->MACISR);
1861   uint32_t dma_flag = READ_REG(heth->Instance->DMACSR);
1862   uint32_t dma_itsource = READ_REG(heth->Instance->DMACIER);
1863   uint32_t exti_flag = READ_REG(EXTI->PR2);
1864 
1865   /* Packet received */
1866   if (((dma_flag & ETH_DMACSR_RI) != 0U) && ((dma_itsource & ETH_DMACIER_RIE) != 0U))
1867   {
1868     /* Clear the Eth DMA Rx IT pending bits */
1869     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
1870 
1871 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1872     /*Call registered Receive complete callback*/
1873     heth->RxCpltCallback(heth);
1874 #else
1875     /* Receive complete callback */
1876     HAL_ETH_RxCpltCallback(heth);
1877 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1878   }
1879 
1880   /* Packet transmitted */
1881   if (((dma_flag & ETH_DMACSR_TI) != 0U) && ((dma_itsource & ETH_DMACIER_TIE) != 0U))
1882   {
1883     /* Clear the Eth DMA Tx IT pending bits */
1884     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
1885 
1886 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1887     /*Call registered Transmit complete callback*/
1888     heth->TxCpltCallback(heth);
1889 #else
1890     /* Transfer complete callback */
1891     HAL_ETH_TxCpltCallback(heth);
1892 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1893   }
1894 
1895   /* ETH DMA Error */
1896   if (((dma_flag & ETH_DMACSR_AIS) != 0U) && ((dma_itsource & ETH_DMACIER_AIE) != 0U))
1897   {
1898     heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1899     /* if fatal bus error occurred */
1900     if ((dma_flag & ETH_DMACSR_FBE) != 0U)
1901     {
1902       /* Get DMA error code  */
1903       heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS));
1904 
1905       /* Disable all interrupts */
1906       __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE);
1907 
1908       /* Set HAL state to ERROR */
1909       heth->gState = HAL_ETH_STATE_ERROR;
1910     }
1911     else
1912     {
1913       /* Get DMA error status  */
1914       heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1915                                                              ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1916 
1917       /* Clear the interrupt summary flag */
1918       __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1919                                     ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1920     }
1921 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1922     /* Call registered Error callback*/
1923     heth->ErrorCallback(heth);
1924 #else
1925     /* Ethernet DMA Error callback */
1926     HAL_ETH_ErrorCallback(heth);
1927 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1928   }
1929 
1930   /* ETH MAC Error IT */
1931   if (((mac_flag & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \
1932       ((mac_flag & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE))
1933   {
1934     heth->ErrorCode |= HAL_ETH_ERROR_MAC;
1935 
1936     /* Get MAC Rx Tx status and clear Status register pending bit */
1937     heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR);
1938 
1939     heth->gState = HAL_ETH_STATE_ERROR;
1940 
1941 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1942     /* Call registered Error callback*/
1943     heth->ErrorCallback(heth);
1944 #else
1945     /* Ethernet Error callback */
1946     HAL_ETH_ErrorCallback(heth);
1947 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1948     heth->MACErrorCode = (uint32_t)(0x0U);
1949   }
1950 
1951   /* ETH PMT IT */
1952   if ((mac_flag & ETH_MAC_PMT_IT) != 0U)
1953   {
1954     /* Get MAC Wake-up source and clear the status register pending bit */
1955     heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD));
1956 
1957 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1958     /* Call registered PMT callback*/
1959     heth->PMTCallback(heth);
1960 #else
1961     /* Ethernet PMT callback */
1962     HAL_ETH_PMTCallback(heth);
1963 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1964 
1965     heth->MACWakeUpEvent = (uint32_t)(0x0U);
1966   }
1967 
1968   /* ETH EEE IT */
1969   if ((mac_flag & ETH_MAC_LPI_IT) != 0U)
1970   {
1971     /* Get MAC LPI interrupt source and clear the status register pending bit */
1972     heth->MACLPIEvent = READ_BIT(heth->Instance->MACPCSR, 0x0000000FU);
1973 
1974 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1975     /* Call registered EEE callback*/
1976     heth->EEECallback(heth);
1977 #else
1978     /* Ethernet EEE callback */
1979     HAL_ETH_EEECallback(heth);
1980 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1981 
1982     heth->MACLPIEvent = (uint32_t)(0x0U);
1983   }
1984 
1985   /* check ETH WAKEUP exti flag */
1986   if ((exti_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
1987   {
1988     /* Clear ETH WAKEUP Exti pending bit */
1989     __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
1990 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1991     /* Call registered WakeUp callback*/
1992     heth->WakeUpCallback(heth);
1993 #else
1994     /* ETH WAKEUP callback */
1995     HAL_ETH_WakeUpCallback(heth);
1996 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1997   }
1998 }
1999 
2000 /**
2001   * @brief  Tx Transfer completed callbacks.
2002   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2003   *         the configuration information for ETHERNET module
2004   * @retval None
2005   */
HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)2006 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
2007 {
2008   /* Prevent unused argument(s) compilation warning */
2009   UNUSED(heth);
2010   /* NOTE : This function Should not be modified, when the callback is needed,
2011   the HAL_ETH_TxCpltCallback could be implemented in the user file
2012   */
2013 }
2014 
2015 /**
2016   * @brief  Rx Transfer completed callbacks.
2017   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2018   *         the configuration information for ETHERNET module
2019   * @retval None
2020   */
HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)2021 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2022 {
2023   /* Prevent unused argument(s) compilation warning */
2024   UNUSED(heth);
2025   /* NOTE : This function Should not be modified, when the callback is needed,
2026   the HAL_ETH_RxCpltCallback could be implemented in the user file
2027   */
2028 }
2029 
2030 /**
2031   * @brief  Ethernet transfer error callbacks
2032   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2033   *         the configuration information for ETHERNET module
2034   * @retval None
2035   */
HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)2036 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2037 {
2038   /* Prevent unused argument(s) compilation warning */
2039   UNUSED(heth);
2040   /* NOTE : This function Should not be modified, when the callback is needed,
2041   the HAL_ETH_ErrorCallback could be implemented in the user file
2042   */
2043 }
2044 
2045 /**
2046   * @brief  Ethernet Power Management module IT callback
2047   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2048   *         the configuration information for ETHERNET module
2049   * @retval None
2050   */
HAL_ETH_PMTCallback(ETH_HandleTypeDef * heth)2051 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2052 {
2053   /* Prevent unused argument(s) compilation warning */
2054   UNUSED(heth);
2055   /* NOTE : This function Should not be modified, when the callback is needed,
2056   the HAL_ETH_PMTCallback could be implemented in the user file
2057   */
2058 }
2059 
2060 /**
2061   * @brief  Energy Efficient Etherent IT callback
2062   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2063   *         the configuration information for ETHERNET module
2064   * @retval None
2065   */
HAL_ETH_EEECallback(ETH_HandleTypeDef * heth)2066 __weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth)
2067 {
2068   /* Prevent unused argument(s) compilation warning */
2069   UNUSED(heth);
2070   /* NOTE : This function Should not be modified, when the callback is needed,
2071   the HAL_ETH_EEECallback could be implemented in the user file
2072   */
2073 }
2074 
2075 /**
2076   * @brief  ETH WAKEUP interrupt callback
2077   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2078   *         the configuration information for ETHERNET module
2079   * @retval None
2080   */
HAL_ETH_WakeUpCallback(ETH_HandleTypeDef * heth)2081 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2082 {
2083   /* Prevent unused argument(s) compilation warning */
2084   UNUSED(heth);
2085   /* NOTE : This function Should not be modified, when the callback is needed,
2086             the HAL_ETH_WakeUpCallback could be implemented in the user file
2087    */
2088 }
2089 
2090 /**
2091   * @brief  Read a PHY register
2092   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2093   *         the configuration information for ETHERNET module
2094   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2095   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2096   * @param pRegValue: parameter to hold read value
2097   * @retval HAL status
2098   */
HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t * pRegValue)2099 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2100                                           uint32_t *pRegValue)
2101 {
2102   uint32_t tickstart;
2103   uint32_t tmpreg;
2104 
2105   /* Check for the Busy flag */
2106   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2107   {
2108     return HAL_ERROR;
2109   }
2110 
2111   /* Get the  MACMDIOAR value */
2112   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2113 
2114   /* Prepare the MDIO Address Register value
2115      - Set the PHY device address
2116      - Set the PHY register address
2117      - Set the read mode
2118      - Set the MII Busy bit */
2119 
2120   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2121   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2122   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD);
2123   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2124 
2125   /* Write the result value into the MDII Address register */
2126   WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
2127 
2128   tickstart = HAL_GetTick();
2129 
2130   /* Wait for the Busy flag */
2131   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2132   {
2133     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2134     {
2135       return HAL_ERROR;
2136     }
2137   }
2138 
2139   /* Get MACMIIDR value */
2140   WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR);
2141 
2142   return HAL_OK;
2143 }
2144 
2145 /**
2146   * @brief  Writes to a PHY register.
2147   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2148   *         the configuration information for ETHERNET module
2149   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2150   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2151   * @param  RegValue: the value to write
2152   * @retval HAL status
2153   */
HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t RegValue)2154 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2155                                            uint32_t RegValue)
2156 {
2157   uint32_t tickstart;
2158   uint32_t tmpreg;
2159 
2160   /* Check for the Busy flag */
2161   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2162   {
2163     return HAL_ERROR;
2164   }
2165 
2166   /* Get the  MACMDIOAR value */
2167   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2168 
2169   /* Prepare the MDIO Address Register value
2170      - Set the PHY device address
2171      - Set the PHY register address
2172      - Set the write mode
2173      - Set the MII Busy bit */
2174 
2175   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2176   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2177   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR);
2178   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2179 
2180   /* Give the value to the MII data register */
2181   WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue);
2182 
2183   /* Write the result value into the MII Address register */
2184   WRITE_REG(ETH->MACMDIOAR, tmpreg);
2185 
2186   tickstart = HAL_GetTick();
2187 
2188   /* Wait for the Busy flag */
2189   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2190   {
2191     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2192     {
2193       return HAL_ERROR;
2194     }
2195   }
2196 
2197   return HAL_OK;
2198 }
2199 
2200 /**
2201   * @}
2202   */
2203 
2204 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
2205   *  @brief   ETH control functions
2206   *
2207 @verbatim
2208   ==============================================================================
2209                       ##### Peripheral Control functions #####
2210   ==============================================================================
2211   [..]
2212     This subsection provides a set of functions allowing to control the ETH
2213     peripheral.
2214 
2215 @endverbatim
2216   * @{
2217   */
2218 /**
2219   * @brief  Get the configuration of the MAC and MTL subsystems.
2220   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2221   *         the configuration information for ETHERNET module
2222   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
2223   *         the configuration of the MAC.
2224   * @retval HAL Status
2225   */
HAL_ETH_GetMACConfig(const ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2226 HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2227 {
2228   if (macconf == NULL)
2229   {
2230     return HAL_ERROR;
2231   }
2232 
2233   /* Get MAC parameters */
2234   macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN);
2235   macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2236   macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2237   macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE;
2238   macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U)
2239                                         ? ENABLE : DISABLE;
2240   macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE;
2241   macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR,
2242                                                    ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE;
2243   macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2244   macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2245   macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2246   macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE;
2247   macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE;
2248   macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE;
2249   macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE;
2250   macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE;
2251   macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE;
2252   macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR,
2253                                                     ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE;
2254   macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG);
2255   macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE;
2256   macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC);
2257 
2258   macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL);
2259   macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE;
2260   macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE;
2261   macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR,
2262                                                         ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE;
2263   macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U)
2264                                     ? ENABLE : DISABLE;
2265   macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25;
2266 
2267   macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE;
2268   macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO);
2269 
2270   macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE;
2271   macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE;
2272   macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT);
2273   macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16);
2274   macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE;
2275   macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U)
2276                                       ? ENABLE : DISABLE;
2277 
2278   macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF));
2279 
2280   macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF));
2281   macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2282                                                       ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE;
2283   macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE;
2284   macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2285                                                      ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE;
2286 
2287   return HAL_OK;
2288 }
2289 
2290 /**
2291   * @brief  Get the configuration of the DMA.
2292   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2293   *         the configuration information for ETHERNET module
2294   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2295   *         the configuration of the ETH DMA.
2296   * @retval HAL Status
2297   */
HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2298 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2299 {
2300   if (dmaconf == NULL)
2301   {
2302     return HAL_ERROR;
2303   }
2304 
2305   dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE;
2306   dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB);
2307   dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE;
2308 
2309   dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA));
2310 
2311   dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE;
2312   dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS);
2313 
2314   dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR,  ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE;
2315   dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL);
2316 
2317   dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE;
2318   dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE;
2319   dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL);
2320 
2321   return HAL_OK;
2322 }
2323 
2324 /**
2325   * @brief  Set the MAC configuration.
2326   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2327   *         the configuration information for ETHERNET module
2328   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that contains
2329   *         the configuration of the MAC.
2330   * @retval HAL status
2331   */
HAL_ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2332 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2333 {
2334   if (macconf == NULL)
2335   {
2336     return HAL_ERROR;
2337   }
2338 
2339   if (heth->gState == HAL_ETH_STATE_READY)
2340   {
2341     ETH_SetMACConfig(heth, macconf);
2342 
2343     return HAL_OK;
2344   }
2345   else
2346   {
2347     return HAL_ERROR;
2348   }
2349 }
2350 
2351 /**
2352   * @brief  Set the ETH DMA configuration.
2353   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2354   *         the configuration information for ETHERNET module
2355   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2356   *         the configuration of the ETH DMA.
2357   * @retval HAL status
2358   */
HAL_ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2359 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2360 {
2361   if (dmaconf == NULL)
2362   {
2363     return HAL_ERROR;
2364   }
2365 
2366   if (heth->gState == HAL_ETH_STATE_READY)
2367   {
2368     ETH_SetDMAConfig(heth, dmaconf);
2369 
2370     return HAL_OK;
2371   }
2372   else
2373   {
2374     return HAL_ERROR;
2375   }
2376 }
2377 
2378 /**
2379   * @brief  Configures the Clock range of ETH MDIO interface.
2380   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2381   *         the configuration information for ETHERNET module
2382   * @retval None
2383   */
HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef * heth)2384 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2385 {
2386   uint32_t hclk;
2387   uint32_t tmpreg;
2388 
2389   /* Get the ETHERNET MACMDIOAR value */
2390   tmpreg = (heth->Instance)->MACMDIOAR;
2391 
2392   /* Clear CSR Clock Range bits */
2393   tmpreg &= ~ETH_MACMDIOAR_CR;
2394 
2395   /* Get hclk frequency value */
2396   hclk = HAL_RCC_GetHCLKFreq();
2397 
2398   /* Set CR bits depending on hclk value */
2399   if (hclk < 35000000U)
2400   {
2401     /* CSR Clock Range between 0-35 MHz */
2402     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2403   }
2404   else if (hclk < 60000000U)
2405   {
2406     /* CSR Clock Range between 35-60 MHz */
2407     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2408   }
2409   else if (hclk < 100000000U)
2410   {
2411     /* CSR Clock Range between 60-100 MHz */
2412     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2413   }
2414   else if (hclk < 150000000U)
2415   {
2416     /* CSR Clock Range between 100-150 MHz */
2417     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2418   }
2419   else if (hclk < 250000000U)
2420   {
2421     /* CSR Clock Range between 150-250 MHz */
2422     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2423   }
2424   else /* (hclk >= 250000000U) */
2425   {
2426     /* CSR Clock >= 250 MHz */
2427     tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV124);
2428   }
2429 
2430   /* Configure the CSR Clock Range */
2431   (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2432 }
2433 
2434 /**
2435   * @brief  Set the ETH MAC (L2) Filters configuration.
2436   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2437   *         the configuration information for ETHERNET module
2438   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2439   *         the configuration of the ETH MAC filters.
2440   * @retval HAL status
2441   */
HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef * heth,const ETH_MACFilterConfigTypeDef * pFilterConfig)2442 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig)
2443 {
2444   uint32_t filterconfig;
2445 
2446   if (pFilterConfig == NULL)
2447   {
2448     return HAL_ERROR;
2449   }
2450 
2451   filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2452                   ((uint32_t)pFilterConfig->HashUnicast << 1) |
2453                   ((uint32_t)pFilterConfig->HashMulticast << 2)  |
2454                   ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2455                   ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2456                   ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) |
2457                   ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2458                   ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2459                   ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2460                   ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2461                   pFilterConfig->ControlPacketsFilter);
2462 
2463   MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig);
2464 
2465   return HAL_OK;
2466 }
2467 
2468 /**
2469   * @brief  Get the ETH MAC (L2) Filters configuration.
2470   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2471   *         the configuration information for ETHERNET module
2472   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2473   *         the configuration of the ETH MAC filters.
2474   * @retval HAL status
2475   */
HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2476 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2477 {
2478   if (pFilterConfig == NULL)
2479   {
2480     return HAL_ERROR;
2481   }
2482 
2483   pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE;
2484   pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE;
2485   pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE;
2486   pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2487                                                        ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2488   pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE;
2489   pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE;
2490   pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF);
2491   pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2492                                                       ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2493   pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2494   pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U)
2495                                        ? ENABLE : DISABLE;
2496   pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2497 
2498   return HAL_OK;
2499 }
2500 
2501 /**
2502   * @brief  Set the source MAC Address to be matched.
2503   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2504   *         the configuration information for ETHERNET module
2505   * @param  AddrNbr: The MAC address to configure
2506   *          This parameter must be a value of the following:
2507   *            ETH_MAC_ADDRESS1
2508   *            ETH_MAC_ADDRESS2
2509   *            ETH_MAC_ADDRESS3
2510   * @param  pMACAddr: Pointer to MAC address buffer data (6 bytes)
2511   * @retval HAL status
2512   */
HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef * heth,uint32_t AddrNbr,const uint8_t * pMACAddr)2513 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr,
2514                                                 const uint8_t *pMACAddr)
2515 {
2516   uint32_t macaddrlr;
2517   uint32_t macaddrhr;
2518 
2519   if (pMACAddr == NULL)
2520   {
2521     return HAL_ERROR;
2522   }
2523 
2524   /* Get mac addr high reg offset */
2525   macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2526   /* Get mac addr low reg offset */
2527   macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2528 
2529   /* Set MAC addr bits 32 to 47 */
2530   (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2531   /* Set MAC addr bits 0 to 31 */
2532   (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2533                                    ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2534 
2535   /* Enable address and set source address bit */
2536   (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE);
2537 
2538   return HAL_OK;
2539 }
2540 
2541 /**
2542   * @brief  Set the ETH Hash Table Value.
2543   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2544   *         the configuration information for ETHERNET module
2545   * @param  pHashTable: pointer to a table of two 32 bit values, that contains
2546   *         the 64 bits of the hash table.
2547   * @retval HAL status
2548   */
HAL_ETH_SetHashTable(ETH_HandleTypeDef * heth,uint32_t * pHashTable)2549 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2550 {
2551   if (pHashTable == NULL)
2552   {
2553     return HAL_ERROR;
2554   }
2555 
2556   heth->Instance->MACHT0R = pHashTable[0];
2557   heth->Instance->MACHT1R = pHashTable[1];
2558 
2559   return HAL_OK;
2560 }
2561 
2562 /**
2563   * @brief  Set the VLAN Identifier for Rx packets
2564   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2565   *         the configuration information for ETHERNET module
2566   * @param  ComparisonBits: 12 or 16 bit comparison mode
2567             must be a value of @ref ETH_VLAN_Tag_Comparison
2568   * @param  VLANIdentifier: VLAN Identifier value
2569   * @retval None
2570   */
HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t ComparisonBits,uint32_t VLANIdentifier)2571 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2572 {
2573   if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2574   {
2575     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier);
2576     CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2577   }
2578   else
2579   {
2580     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier);
2581     SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2582   }
2583 }
2584 
2585 /**
2586   * @brief  Enters the Power down mode.
2587   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2588   *         the configuration information for ETHERNET module
2589   * @param  pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2590   *         that contains the Power Down configuration
2591   * @retval None.
2592   */
HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef * heth,const ETH_PowerDownConfigTypeDef * pPowerDownConfig)2593 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2594 {
2595   uint32_t powerdownconfig;
2596 
2597   powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) |
2598                      ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) |
2599                      ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) |
2600                      ((uint32_t)pPowerDownConfig->WakeUpForward << 10) |
2601                      ETH_MACPCSR_PWRDWN);
2602 
2603   /* Enable PMT interrupt */
2604   __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE);
2605 
2606   MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig);
2607 }
2608 
2609 /**
2610   * @brief  Exits from the Power down mode.
2611   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2612   *         the configuration information for ETHERNET module
2613   * @retval None.
2614   */
HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef * heth)2615 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2616 {
2617   /* clear wake up sources */
2618   CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST |
2619             ETH_MACPCSR_RWKPFE);
2620 
2621   if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET)
2622   {
2623     /* Exit power down mode */
2624     CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN);
2625   }
2626 
2627   /* Disable PMT interrupt */
2628   __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE);
2629 }
2630 
2631 /**
2632   * @brief  Set the WakeUp filter.
2633   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2634   *         the configuration information for ETHERNET module
2635   * @param  pFilter: pointer to filter registers values
2636   * @param  Count: number of filter registers, must be from 1 to 8.
2637   * @retval None.
2638   */
HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef * heth,uint32_t * pFilter,uint32_t Count)2639 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2640 {
2641   uint32_t regindex;
2642 
2643   if (pFilter == NULL)
2644   {
2645     return HAL_ERROR;
2646   }
2647 
2648   /* Reset Filter Pointer */
2649   SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST);
2650 
2651   /* Wake up packet filter config */
2652   for (regindex = 0; regindex < Count; regindex++)
2653   {
2654     /* Write filter regs */
2655     WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]);
2656   }
2657 
2658   return HAL_OK;
2659 }
2660 
2661 /**
2662   * @}
2663   */
2664 
2665 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2666   *  @brief   ETH State and Errors functions
2667   *
2668 @verbatim
2669   ==============================================================================
2670                  ##### Peripheral State and Errors functions #####
2671   ==============================================================================
2672  [..]
2673    This subsection provides a set of functions allowing to return the State of
2674    ETH communication process, return Peripheral Errors occurred during communication
2675    process
2676 
2677 
2678 @endverbatim
2679   * @{
2680   */
2681 
2682 /**
2683   * @brief  Returns the ETH state.
2684   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2685   *         the configuration information for ETHERNET module
2686   * @retval HAL state
2687   */
HAL_ETH_GetState(const ETH_HandleTypeDef * heth)2688 HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth)
2689 {
2690   return heth->gState;
2691 }
2692 
2693 /**
2694   * @brief  Returns the ETH error code
2695   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2696   *         the configuration information for ETHERNET module
2697   * @retval ETH Error Code
2698   */
HAL_ETH_GetError(const ETH_HandleTypeDef * heth)2699 uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth)
2700 {
2701   return heth->ErrorCode;
2702 }
2703 
2704 /**
2705   * @brief  Returns the ETH DMA error code
2706   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2707   *         the configuration information for ETHERNET module
2708   * @retval ETH DMA Error Code
2709   */
HAL_ETH_GetDMAError(const ETH_HandleTypeDef * heth)2710 uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth)
2711 {
2712   return heth->DMAErrorCode;
2713 }
2714 
2715 /**
2716   * @brief  Returns the ETH MAC error code
2717   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2718   *         the configuration information for ETHERNET module
2719   * @retval ETH MAC Error Code
2720   */
HAL_ETH_GetMACError(const ETH_HandleTypeDef * heth)2721 uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth)
2722 {
2723   return heth->MACErrorCode;
2724 }
2725 
2726 /**
2727   * @brief  Returns the ETH MAC WakeUp event source
2728   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2729   *         the configuration information for ETHERNET module
2730   * @retval ETH MAC WakeUp event source
2731   */
HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef * heth)2732 uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth)
2733 {
2734   return heth->MACWakeUpEvent;
2735 }
2736 
2737 /**
2738   * @}
2739   */
2740 
2741 /**
2742   * @}
2743   */
2744 
2745 /** @addtogroup ETH_Private_Functions   ETH Private Functions
2746   * @{
2747   */
2748 
ETH_SetMACConfig(ETH_HandleTypeDef * heth,const ETH_MACConfigTypeDef * macconf)2749 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf)
2750 {
2751   uint32_t macregval;
2752 
2753   /*------------------------ MACCR Configuration --------------------*/
2754   macregval = (macconf->InterPacketGapVal |
2755                macconf->SourceAddrControl |
2756                ((uint32_t)macconf->ChecksumOffload << 27) |
2757                ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) |
2758                ((uint32_t)macconf->Support2KPacket  << 22) |
2759                ((uint32_t)macconf->CRCStripTypePacket << 21) |
2760                ((uint32_t)macconf->AutomaticPadCRCStrip << 20) |
2761                ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) |
2762                ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) |
2763                ((uint32_t)macconf->JumboPacket << 16) |
2764                macconf->Speed |
2765                macconf->DuplexMode |
2766                ((uint32_t)macconf->LoopbackMode << 12) |
2767                ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) |
2768                ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) |
2769                ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) |
2770                ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) |
2771                macconf->BackOffLimit |
2772                ((uint32_t)macconf->DeferralCheck << 4) |
2773                macconf->PreambleLength);
2774 
2775   /* Write to MACCR */
2776   MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval);
2777 
2778   /*------------------------ MACECR Configuration --------------------*/
2779   macregval = ((macconf->ExtendedInterPacketGapVal << 25) |
2780                ((uint32_t)macconf->ExtendedInterPacketGap << 24) |
2781                ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) |
2782                ((uint32_t)macconf->SlowProtocolDetect << 17) |
2783                ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) |
2784                macconf->GiantPacketSizeLimit);
2785 
2786   /* Write to MACECR */
2787   MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval);
2788 
2789   /*------------------------ MACWTR Configuration --------------------*/
2790   macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) |
2791                macconf->WatchdogTimeout);
2792 
2793   /* Write to MACWTR */
2794   MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval);
2795 
2796   /*------------------------ MACTFCR Configuration --------------------*/
2797   macregval = (((uint32_t)macconf->TransmitFlowControl << 1) |
2798                macconf->PauseLowThreshold |
2799                ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) |
2800                (macconf->PauseTime << 16));
2801 
2802   /* Write to MACTFCR */
2803   MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval);
2804 
2805   /*------------------------ MACRFCR Configuration --------------------*/
2806   macregval = ((uint32_t)macconf->ReceiveFlowControl |
2807                ((uint32_t)macconf->UnicastPausePacketDetect << 1));
2808 
2809   /* Write to MACRFCR */
2810   MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval);
2811 
2812   /*------------------------ MTLTQOMR Configuration --------------------*/
2813   /* Write to MTLTQOMR */
2814   MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode);
2815 
2816   /*------------------------ MTLRQOMR Configuration --------------------*/
2817   macregval = (macconf->ReceiveQueueMode |
2818                ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) |
2819                ((uint32_t)macconf->ForwardRxErrorPacket << 4) |
2820                ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3));
2821 
2822   /* Write to MTLRQOMR */
2823   MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval);
2824 }
2825 
ETH_SetDMAConfig(ETH_HandleTypeDef * heth,const ETH_DMAConfigTypeDef * dmaconf)2826 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf)
2827 {
2828   uint32_t dmaregval;
2829 
2830   /*------------------------ DMAMR Configuration --------------------*/
2831   MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration);
2832 
2833   /*------------------------ DMASBMR Configuration --------------------*/
2834   dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) |
2835                dmaconf->BurstMode |
2836                ((uint32_t)dmaconf->RebuildINCRxBurst << 15));
2837 
2838   MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval);
2839 
2840   /*------------------------ DMACCR Configuration --------------------*/
2841   dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) |
2842                dmaconf->MaximumSegmentSize);
2843   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval);
2844 
2845   /*------------------------ DMACTCR Configuration --------------------*/
2846   dmaregval = (dmaconf->TxDMABurstLength |
2847                ((uint32_t)dmaconf->SecondPacketOperate << 4) |
2848                ((uint32_t)dmaconf->TCPSegmentation << 12));
2849 
2850   MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval);
2851 
2852   /*------------------------ DMACRCR Configuration --------------------*/
2853   dmaregval = (((uint32_t)dmaconf->FlushRxPacket  << 31) |
2854                dmaconf->RxDMABurstLength);
2855 
2856   /* Write to DMACRCR */
2857   MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval);
2858 }
2859 
2860 /**
2861   * @brief  Configures Ethernet MAC and DMA with default parameters.
2862   *         called by HAL_ETH_Init() API.
2863   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2864   *         the configuration information for ETHERNET module
2865   * @retval HAL status
2866   */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth)2867 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2868 {
2869   ETH_MACConfigTypeDef macDefaultConf;
2870   ETH_DMAConfigTypeDef dmaDefaultConf;
2871 
2872   /*--------------- ETHERNET MAC registers default Configuration --------------*/
2873   macDefaultConf.AutomaticPadCRCStrip = ENABLE;
2874   macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2875   macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
2876   macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2877   macDefaultConf.ChecksumOffload = ENABLE;
2878   macDefaultConf.CRCCheckingRxPackets = ENABLE;
2879   macDefaultConf.CRCStripTypePacket = ENABLE;
2880   macDefaultConf.DeferralCheck = DISABLE;
2881   macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE;
2882   macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2883   macDefaultConf.ExtendedInterPacketGap = DISABLE;
2884   macDefaultConf.ExtendedInterPacketGapVal = 0x0U;
2885   macDefaultConf.ForwardRxErrorPacket = DISABLE;
2886   macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE;
2887   macDefaultConf.GiantPacketSizeLimit = 0x618U;
2888   macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
2889   macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
2890   macDefaultConf.Jabber = ENABLE;
2891   macDefaultConf.JumboPacket = DISABLE;
2892   macDefaultConf.LoopbackMode = DISABLE;
2893   macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
2894   macDefaultConf.PauseTime = 0x0U;
2895   macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
2896   macDefaultConf.ProgrammableWatchdog = DISABLE;
2897   macDefaultConf.ReceiveFlowControl = DISABLE;
2898   macDefaultConf.ReceiveOwn = ENABLE;
2899   macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
2900   macDefaultConf.RetryTransmission = ENABLE;
2901   macDefaultConf.SlowProtocolDetect = DISABLE;
2902   macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0;
2903   macDefaultConf.Speed = ETH_SPEED_100M;
2904   macDefaultConf.Support2KPacket = DISABLE;
2905   macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
2906   macDefaultConf.TransmitFlowControl = DISABLE;
2907   macDefaultConf.UnicastPausePacketDetect = DISABLE;
2908   macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
2909   macDefaultConf.Watchdog = ENABLE;
2910   macDefaultConf.WatchdogTimeout =  ETH_MACWTR_WTO_2KB;
2911   macDefaultConf.ZeroQuantaPause = ENABLE;
2912 
2913   /* MAC default configuration */
2914   ETH_SetMACConfig(heth, &macDefaultConf);
2915 
2916   /*--------------- ETHERNET DMA registers default Configuration --------------*/
2917   dmaDefaultConf.AddressAlignedBeats = ENABLE;
2918   dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2919   dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1;
2920   dmaDefaultConf.FlushRxPacket = DISABLE;
2921   dmaDefaultConf.PBLx8Mode = DISABLE;
2922   dmaDefaultConf.RebuildINCRxBurst = DISABLE;
2923   dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2924   dmaDefaultConf.SecondPacketOperate = DISABLE;
2925   dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2926   dmaDefaultConf.TCPSegmentation = DISABLE;
2927   dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT;
2928 
2929   /* DMA default configuration */
2930   ETH_SetDMAConfig(heth, &dmaDefaultConf);
2931 }
2932 
2933 /**
2934   * @brief  Initializes the DMA Tx descriptors.
2935   *         called by HAL_ETH_Init() API.
2936   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2937   *         the configuration information for ETHERNET module
2938   * @retval None
2939   */
ETH_DMATxDescListInit(ETH_HandleTypeDef * heth)2940 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
2941 {
2942   ETH_DMADescTypeDef *dmatxdesc;
2943   uint32_t i;
2944 
2945   /* Fill each DMATxDesc descriptor with the right values */
2946   for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
2947   {
2948     dmatxdesc = heth->Init.TxDesc + i;
2949 
2950     WRITE_REG(dmatxdesc->DESC0, 0x0U);
2951     WRITE_REG(dmatxdesc->DESC1, 0x0U);
2952     WRITE_REG(dmatxdesc->DESC2, 0x0U);
2953     WRITE_REG(dmatxdesc->DESC3, 0x0U);
2954 
2955     WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
2956 
2957   }
2958 
2959   heth->TxDescList.CurTxDesc = 0;
2960 
2961   /* Set Transmit Descriptor Ring Length */
2962   WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U));
2963 
2964   /* Set Transmit Descriptor List Address */
2965   WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc);
2966 
2967   /* Set Transmit Descriptor Tail pointer */
2968   WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc);
2969 }
2970 
2971 /**
2972   * @brief  Initializes the DMA Rx descriptors in chain mode.
2973   *         called by HAL_ETH_Init() API.
2974   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2975   *         the configuration information for ETHERNET module
2976   * @retval None
2977   */
ETH_DMARxDescListInit(ETH_HandleTypeDef * heth)2978 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
2979 {
2980   ETH_DMADescTypeDef *dmarxdesc;
2981   uint32_t i;
2982 
2983   for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
2984   {
2985     dmarxdesc =  heth->Init.RxDesc + i;
2986 
2987     WRITE_REG(dmarxdesc->DESC0, 0x0U);
2988     WRITE_REG(dmarxdesc->DESC1, 0x0U);
2989     WRITE_REG(dmarxdesc->DESC2, 0x0U);
2990     WRITE_REG(dmarxdesc->DESC3, 0x0U);
2991     WRITE_REG(dmarxdesc->BackupAddr0, 0x0U);
2992     WRITE_REG(dmarxdesc->BackupAddr1, 0x0U);
2993 
2994     /* Set Rx descritors addresses */
2995     WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
2996 
2997   }
2998 
2999   WRITE_REG(heth->RxDescList.RxDescIdx, 0U);
3000   WRITE_REG(heth->RxDescList.RxDescCnt, 0U);
3001   WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U);
3002   WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U);
3003   WRITE_REG(heth->RxDescList.ItMode, 0U);
3004 
3005   /* Set Receive Descriptor Ring Length */
3006   WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U)));
3007 
3008   /* Set Receive Descriptor List Address */
3009   WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);
3010 
3011   /* Set Receive Descriptor Tail pointer Address */
3012   WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U))));
3013 }
3014 
3015 /**
3016   * @brief  Prepare Tx DMA descriptor before transmission.
3017   *         called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
3018   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3019   *         the configuration information for ETHERNET module
3020   * @param  pTxConfig: Tx packet configuration
3021   * @param  ItMode: Enable or disable Tx EOT interrept
3022   * @retval Status
3023   */
ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef * heth,const ETH_TxPacketConfigTypeDef * pTxConfig,uint32_t ItMode)3024 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
3025                                            uint32_t ItMode)
3026 {
3027   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
3028   uint32_t descidx = dmatxdesclist->CurTxDesc;
3029   uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3030   uint32_t idx;
3031   uint32_t descnbr = 0;
3032   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3033 
3034   ETH_BufferTypeDef  *txbuffer = pTxConfig->TxBuffer;
3035   uint32_t           bd_count = 0;
3036   uint32_t primask_bit;
3037 
3038   /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3039   if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3040       || (dmatxdesclist->PacketAddress[descidx] != NULL))
3041   {
3042     return HAL_ETH_ERROR_BUSY;
3043   }
3044 
3045   /***************************************************************************/
3046   /*****************    Context descriptor configuration (Optional) **********/
3047   /***************************************************************************/
3048   /* If VLAN tag is enabled for this packet */
3049   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3050   {
3051     /* Set vlan tag value */
3052     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag);
3053     /* Set vlan tag valid bit */
3054     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV);
3055     /* Set the descriptor as the vlan input source */
3056     SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI);
3057 
3058     /* if inner VLAN is enabled */
3059     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET)
3060     {
3061       /* Set inner vlan tag value */
3062       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16));
3063       /* Set inner vlan tag valid bit */
3064       SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV);
3065 
3066       /* Set Vlan Tag control */
3067       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl);
3068 
3069       /* Set the descriptor as the inner vlan input source */
3070       SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI);
3071       /* Enable double VLAN processing */
3072       SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP);
3073     }
3074   }
3075 
3076   /* if tcp segmentation is enabled for this packet */
3077   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3078   {
3079     /* Set MSS value */
3080     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize);
3081     /* Set MSS valid bit */
3082     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV);
3083   }
3084 
3085   if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3086       || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET))
3087   {
3088     /* Set as context descriptor */
3089     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT);
3090     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3091     __DMB();
3092     /* Set own bit */
3093     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3094     /* Increment current tx descriptor index */
3095     INCR_TX_DESC_INDEX(descidx, 1U);
3096     /* Get current descriptor address */
3097     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3098 
3099     descnbr += 1U;
3100 
3101     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3102     if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3103     {
3104       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
3105       /* Ensure rest of descriptor is written to RAM before the OWN bit */
3106       __DMB();
3107       /* Clear own bit */
3108       CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3109 
3110       return HAL_ETH_ERROR_BUSY;
3111     }
3112   }
3113 
3114   /***************************************************************************/
3115   /*****************    Normal descriptors configuration     *****************/
3116   /***************************************************************************/
3117 
3118   descnbr += 1U;
3119 
3120   /* Set header or buffer 1 address */
3121   WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3122   /* Set header or buffer 1 Length */
3123   MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3124 
3125   if (txbuffer->next != NULL)
3126   {
3127     txbuffer = txbuffer->next;
3128     /* Set buffer 2 address */
3129     WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3130     /* Set buffer 2 Length */
3131     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3132   }
3133   else
3134   {
3135     WRITE_REG(dmatxdesc->DESC1, 0x0U);
3136     /* Set buffer 2 Length */
3137     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3138   }
3139 
3140   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3141   {
3142     /* Set TCP Header length */
3143     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19));
3144     /* Set TCP payload length */
3145     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3146     /* Set TCP Segmentation Enabled bit */
3147     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3148   }
3149   else
3150   {
3151     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3152 
3153     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3154     {
3155       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3156     }
3157 
3158     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET)
3159     {
3160       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl);
3161     }
3162   }
3163 
3164   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3165   {
3166     /* Set Vlan Tag control */
3167     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl);
3168   }
3169 
3170   /* Mark it as First Descriptor */
3171   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3172   /* Mark it as NORMAL descriptor */
3173   CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3174   /* Ensure rest of descriptor is written to RAM before the OWN bit */
3175   __DMB();
3176   /* set OWN bit of FIRST descriptor */
3177   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3178 
3179   /* If source address insertion/replacement is enabled for this packet */
3180   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET)
3181   {
3182     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl);
3183   }
3184 
3185   /* only if the packet is split into more than one descriptors > 1 */
3186   while (txbuffer->next != NULL)
3187   {
3188     /* Clear the LD bit of previous descriptor */
3189     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3190     /* Increment current tx descriptor index */
3191     INCR_TX_DESC_INDEX(descidx, 1U);
3192     /* Get current descriptor address */
3193     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3194 
3195     /* Clear the FD bit of new Descriptor */
3196     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3197 
3198     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3199     if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN)
3200         || (dmatxdesclist->PacketAddress[descidx] != NULL))
3201     {
3202       descidx = firstdescidx;
3203       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3204 
3205       /* clear previous desc own bit */
3206       for (idx = 0; idx < descnbr; idx ++)
3207       {
3208         /* Ensure rest of descriptor is written to RAM before the OWN bit */
3209         __DMB();
3210 
3211         CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3212 
3213         /* Increment current tx descriptor index */
3214         INCR_TX_DESC_INDEX(descidx, 1U);
3215         /* Get current descriptor address */
3216         dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3217       }
3218 
3219       return HAL_ETH_ERROR_BUSY;
3220     }
3221 
3222     descnbr += 1U;
3223 
3224     /* Get the next Tx buffer in the list */
3225     txbuffer = txbuffer->next;
3226 
3227     /* Set header or buffer 1 address */
3228     WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3229     /* Set header or buffer 1 Length */
3230     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3231 
3232     if (txbuffer->next != NULL)
3233     {
3234       /* Get the next Tx buffer in the list */
3235       txbuffer = txbuffer->next;
3236       /* Set buffer 2 address */
3237       WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3238       /* Set buffer 2 Length */
3239       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3240     }
3241     else
3242     {
3243       WRITE_REG(dmatxdesc->DESC1, 0x0U);
3244       /* Set buffer 2 Length */
3245       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3246     }
3247 
3248     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3249     {
3250       /* Set TCP payload length */
3251       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3252       /* Set TCP Segmentation Enabled bit */
3253       SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3254     }
3255     else
3256     {
3257       /* Set the packet length */
3258       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3259 
3260       if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3261       {
3262         /* Checksum Insertion Control */
3263         MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3264       }
3265     }
3266 
3267     bd_count += 1U;
3268 
3269     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3270     __DMB();
3271     /* Set Own bit */
3272     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3273     /* Mark it as NORMAL descriptor */
3274     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3275   }
3276 
3277   if (ItMode != ((uint32_t)RESET))
3278   {
3279     /* Set Interrupt on completion bit */
3280     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3281   }
3282   else
3283   {
3284     /* Clear Interrupt on completion bit */
3285     CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3286   }
3287 
3288   /* Mark it as LAST descriptor */
3289   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3290   /* Save the current packet address to expose it to the application */
3291   dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3292 
3293   dmatxdesclist->CurTxDesc = descidx;
3294 
3295   /* Enter critical section */
3296   primask_bit = __get_PRIMASK();
3297   __set_PRIMASK(1);
3298 
3299   dmatxdesclist->BuffersInUse += bd_count + 1U;
3300 
3301   /* Exit critical section: restore previous priority mask */
3302   __set_PRIMASK(primask_bit);
3303 
3304   /* Return function status */
3305   return HAL_ETH_ERROR_NONE;
3306 }
3307 
3308 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)3309 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3310 {
3311   /* Init the ETH Callback settings */
3312   heth->TxCpltCallback   = HAL_ETH_TxCpltCallback;    /* Legacy weak TxCpltCallback   */
3313   heth->RxCpltCallback   = HAL_ETH_RxCpltCallback;    /* Legacy weak RxCpltCallback   */
3314   heth->ErrorCallback    = HAL_ETH_ErrorCallback;     /* Legacy weak ErrorCallback */
3315   heth->PMTCallback      = HAL_ETH_PMTCallback;       /* Legacy weak PMTCallback      */
3316   heth->EEECallback      = HAL_ETH_EEECallback;       /* Legacy weak EEECallback      */
3317   heth->WakeUpCallback   = HAL_ETH_WakeUpCallback;    /* Legacy weak WakeUpCallback   */
3318   heth->rxLinkCallback   = HAL_ETH_RxLinkCallback;    /* Legacy weak RxLinkCallback   */
3319   heth->txFreeCallback   = HAL_ETH_TxFreeCallback;    /* Legacy weak TxFreeCallback   */
3320 #ifdef HAL_ETH_USE_PTP
3321   heth->txPtpCallback    = HAL_ETH_TxPtpCallback;     /* Legacy weak TxPtpCallback   */
3322 #endif /* HAL_ETH_USE_PTP */
3323   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3324 }
3325 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3326 
3327 /**
3328   * @}
3329   */
3330 
3331 /**
3332   * @}
3333   */
3334 
3335 #endif /* ETH */
3336 
3337 #endif /* HAL_ETH_MODULE_ENABLED */
3338 
3339 /**
3340   * @}
3341   */
3342