1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_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) 2016 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 "stm32f4xx_hal.h"
179 
180 /** @addtogroup STM32F4xx_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_MACFFR_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_MACPMTCSR_MASK      (ETH_MACPMTCSR_PD | ETH_MACPMTCSR_WFE | \
212                                  ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU)
213 
214 /* Timeout values */
215 #define ETH_SWRESET_TIMEOUT     500U
216 #define ETH_MDIO_BUS_TIMEOUT    1000U
217 
218 #define ETH_DMARXDESC_ERRORS_MASK ((uint32_t)(ETH_DMARXDESC_DBE | ETH_DMARXDESC_RE | \
219                                               ETH_DMARXDESC_OE  | ETH_DMARXDESC_RWT |\
220                                               ETH_DMARXDESC_LC | ETH_DMARXDESC_CE |\
221                                               ETH_DMARXDESC_DE | ETH_DMARXDESC_IPV4HCE))
222 
223 #define ETH_MAC_US_TICK         1000000U
224 
225 #define ETH_MACTSCR_MASK        0x0087FF2FU
226 
227 #define ETH_PTPTSHR_VALUE       0xFFFFFFFFU
228 #define ETH_PTPTSLR_VALUE       0xBB9ACA00U
229 
230 /* Ethernet MACMIIAR register Mask */
231 #define ETH_MACMIIAR_CR_MASK    0xFFFFFFE3U
232 
233 /* Delay to wait when writing to some Ethernet registers */
234 #define ETH_REG_WRITE_DELAY     0x00000001U
235 
236 /* ETHERNET MACCR register Mask */
237 #define ETH_MACCR_CLEAR_MASK    0xFF20810FU
238 
239 /* ETHERNET MACFCR register Mask */
240 #define ETH_MACFCR_CLEAR_MASK   0x0000FF41U
241 
242 /* ETHERNET DMAOMR register Mask */
243 #define ETH_DMAOMR_CLEAR_MASK   0xF8DE3F23U
244 
245 /* ETHERNET MAC address offsets */
246 #define ETH_MAC_ADDR_HBASE      (uint32_t)(ETH_MAC_BASE + 0x40U)  /* ETHERNET MAC address high offset */
247 #define ETH_MAC_ADDR_LBASE      (uint32_t)(ETH_MAC_BASE + 0x44U)  /* ETHERNET MAC address low offset */
248 
249 /* ETHERNET DMA Rx descriptors Frame length Shift */
250 #define  ETH_DMARXDESC_FRAMELENGTHSHIFT            16U
251 /**
252   * @}
253   */
254 
255 /* Private macros ------------------------------------------------------------*/
256 /** @defgroup ETH_Private_Macros ETH Private Macros
257   * @{
258   */
259 /* Helper macros for TX descriptor handling */
260 #define INCR_TX_DESC_INDEX(inx, offset) do {\
261                                              (inx) += (offset);\
262                                              if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
263                                              (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
264                                            } while (0)
265 
266 /* Helper macros for RX descriptor handling */
267 #define INCR_RX_DESC_INDEX(inx, offset) do {\
268                                              (inx) += (offset);\
269                                              if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
270                                              (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
271                                            } while (0)
272 /**
273   * @}
274   */
275 /* Private function prototypes -----------------------------------------------*/
276 /** @defgroup ETH_Private_Functions   ETH Private Functions
277   * @{
278   */
279 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf);
280 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf);
281 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
282 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
283 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
284 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode);
285 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth);
286 static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
287 static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
288 
289 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
290 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
291 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
292 /**
293   * @}
294   */
295 
296 /* Exported functions ---------------------------------------------------------*/
297 /** @defgroup ETH_Exported_Functions ETH Exported Functions
298   * @{
299   */
300 
301 /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions
302   *  @brief    Initialization and Configuration functions
303   *
304 @verbatim
305 ===============================================================================
306             ##### Initialization and Configuration functions #####
307  ===============================================================================
308     [..]  This subsection provides a set of functions allowing to initialize and
309           deinitialize the ETH peripheral:
310 
311       (+) User must Implement HAL_ETH_MspInit() function in which he configures
312           all related peripherals resources (CLOCK, GPIO and NVIC ).
313 
314       (+) Call the function HAL_ETH_Init() to configure the selected device with
315           the selected configuration:
316         (++) MAC address
317         (++) Media interface (MII or RMII)
318         (++) Rx DMA Descriptors Tab
319         (++) Tx DMA Descriptors Tab
320         (++) Length of Rx Buffers
321 
322       (+) Call the function HAL_ETH_DeInit() to restore the default configuration
323           of the selected ETH peripheral.
324 
325 @endverbatim
326   * @{
327   */
328 
329 /**
330   * @brief  Initialize the Ethernet peripheral registers.
331   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
332   *         the configuration information for ETHERNET module
333   * @retval HAL status
334   */
HAL_ETH_Init(ETH_HandleTypeDef * heth)335 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
336 {
337   uint32_t tickstart;
338 
339   if (heth == NULL)
340   {
341     return HAL_ERROR;
342   }
343   if (heth->gState == HAL_ETH_STATE_RESET)
344   {
345     heth->gState = HAL_ETH_STATE_BUSY;
346 
347 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
348 
349     ETH_InitCallbacksToDefault(heth);
350 
351     if (heth->MspInitCallback == NULL)
352     {
353       heth->MspInitCallback = HAL_ETH_MspInit;
354     }
355 
356     /* Init the low level hardware */
357     heth->MspInitCallback(heth);
358 #else
359     /* Init the low level hardware : GPIO, CLOCK, NVIC. */
360     HAL_ETH_MspInit(heth);
361 
362 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
363   }
364 
365   __HAL_RCC_SYSCFG_CLK_ENABLE();
366 
367   /* Select MII or RMII Mode*/
368   SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL);
369   SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface;
370   /* Dummy read to sync SYSCFG with ETH */
371   (void)SYSCFG->PMC;
372 
373   /* Ethernet Software reset */
374   /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
375   /* After reset all the registers holds their respective reset values */
376   SET_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR);
377 
378   /* Get tick */
379   tickstart = HAL_GetTick();
380 
381   /* Wait for software reset */
382   while (READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_SR) > 0U)
383   {
384     if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
385     {
386       /* Set Error Code */
387       heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
388       /* Set State as Error */
389       heth->gState = HAL_ETH_STATE_ERROR;
390       /* Return Error */
391       return HAL_ERROR;
392     }
393   }
394 
395 
396   /*------------------ MAC, MTL and DMA default Configuration ----------------*/
397   ETH_MACDMAConfig(heth);
398 
399 
400   /*------------------ DMA Tx Descriptors Configuration ----------------------*/
401   ETH_DMATxDescListInit(heth);
402 
403   /*------------------ DMA Rx Descriptors Configuration ----------------------*/
404   ETH_DMARxDescListInit(heth);
405 
406   /*--------------------- ETHERNET MAC Address Configuration ------------------*/
407   ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
408 
409   heth->ErrorCode = HAL_ETH_ERROR_NONE;
410   heth->gState = HAL_ETH_STATE_READY;
411 
412   return HAL_OK;
413 }
414 
415 /**
416   * @brief  DeInitializes the ETH peripheral.
417   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
418   *         the configuration information for ETHERNET module
419   * @retval HAL status
420   */
HAL_ETH_DeInit(ETH_HandleTypeDef * heth)421 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
422 {
423   /* Set the ETH peripheral state to BUSY */
424   heth->gState = HAL_ETH_STATE_BUSY;
425 
426 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
427 
428   if (heth->MspDeInitCallback == NULL)
429   {
430     heth->MspDeInitCallback = HAL_ETH_MspDeInit;
431   }
432   /* DeInit the low level hardware */
433   heth->MspDeInitCallback(heth);
434 #else
435 
436   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
437   HAL_ETH_MspDeInit(heth);
438 
439 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
440 
441   /* Set ETH HAL state to Disabled */
442   heth->gState = HAL_ETH_STATE_RESET;
443 
444   /* Return function status */
445   return HAL_OK;
446 }
447 
448 /**
449   * @brief  Initializes the ETH MSP.
450   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
451   *         the configuration information for ETHERNET module
452   * @retval None
453   */
HAL_ETH_MspInit(ETH_HandleTypeDef * heth)454 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
455 {
456   /* Prevent unused argument(s) compilation warning */
457   UNUSED(heth);
458   /* NOTE : This function Should not be modified, when the callback is needed,
459   the HAL_ETH_MspInit could be implemented in the user file
460   */
461 }
462 
463 /**
464   * @brief  DeInitializes ETH MSP.
465   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
466   *         the configuration information for ETHERNET module
467   * @retval None
468   */
HAL_ETH_MspDeInit(ETH_HandleTypeDef * heth)469 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
470 {
471   /* Prevent unused argument(s) compilation warning */
472   UNUSED(heth);
473   /* NOTE : This function Should not be modified, when the callback is needed,
474   the HAL_ETH_MspDeInit could be implemented in the user file
475   */
476 }
477 
478 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
479 /**
480   * @brief  Register a User ETH Callback
481   *         To be used instead of the weak predefined callback
482   * @param heth eth handle
483   * @param CallbackID ID of the callback to be registered
484   *        This parameter can be one of the following values:
485   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
486   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
487   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
488   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
489   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
490   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
491   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
492   * @param pCallback pointer to the Callback function
493   * @retval status
494   */
HAL_ETH_RegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID,pETH_CallbackTypeDef pCallback)495 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID,
496                                            pETH_CallbackTypeDef pCallback)
497 {
498   HAL_StatusTypeDef status = HAL_OK;
499 
500   if (pCallback == NULL)
501   {
502     /* Update the error code */
503     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
504 
505     return HAL_ERROR;
506   }
507 
508   if (heth->gState == HAL_ETH_STATE_READY)
509   {
510     switch (CallbackID)
511     {
512       case HAL_ETH_TX_COMPLETE_CB_ID :
513         heth->TxCpltCallback = pCallback;
514         break;
515 
516       case HAL_ETH_RX_COMPLETE_CB_ID :
517         heth->RxCpltCallback = pCallback;
518         break;
519 
520       case HAL_ETH_ERROR_CB_ID :
521         heth->ErrorCallback = pCallback;
522         break;
523 
524       case HAL_ETH_PMT_CB_ID :
525         heth->PMTCallback = pCallback;
526         break;
527 
528 
529       case HAL_ETH_WAKEUP_CB_ID :
530         heth->WakeUpCallback = pCallback;
531         break;
532 
533       case HAL_ETH_MSPINIT_CB_ID :
534         heth->MspInitCallback = pCallback;
535         break;
536 
537       case HAL_ETH_MSPDEINIT_CB_ID :
538         heth->MspDeInitCallback = pCallback;
539         break;
540 
541       default :
542         /* Update the error code */
543         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
544         /* Return error status */
545         status =  HAL_ERROR;
546         break;
547     }
548   }
549   else if (heth->gState == HAL_ETH_STATE_RESET)
550   {
551     switch (CallbackID)
552     {
553       case HAL_ETH_MSPINIT_CB_ID :
554         heth->MspInitCallback = pCallback;
555         break;
556 
557       case HAL_ETH_MSPDEINIT_CB_ID :
558         heth->MspDeInitCallback = pCallback;
559         break;
560 
561       default :
562         /* Update the error code */
563         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
564         /* Return error status */
565         status =  HAL_ERROR;
566         break;
567     }
568   }
569   else
570   {
571     /* Update the error code */
572     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
573     /* Return error status */
574     status =  HAL_ERROR;
575   }
576 
577   return status;
578 }
579 
580 /**
581   * @brief  Unregister an ETH Callback
582   *         ETH callabck is redirected to the weak predefined callback
583   * @param heth eth handle
584   * @param CallbackID ID of the callback to be unregistered
585   *        This parameter can be one of the following values:
586   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
587   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
588   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
589   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
590   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
591   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
592   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
593   * @retval status
594   */
HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID)595 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
596 {
597   HAL_StatusTypeDef status = HAL_OK;
598 
599   if (heth->gState == HAL_ETH_STATE_READY)
600   {
601     switch (CallbackID)
602     {
603       case HAL_ETH_TX_COMPLETE_CB_ID :
604         heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
605         break;
606 
607       case HAL_ETH_RX_COMPLETE_CB_ID :
608         heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
609         break;
610 
611       case HAL_ETH_ERROR_CB_ID :
612         heth->ErrorCallback = HAL_ETH_ErrorCallback;
613         break;
614 
615       case HAL_ETH_PMT_CB_ID :
616         heth->PMTCallback = HAL_ETH_PMTCallback;
617         break;
618 
619 
620       case HAL_ETH_WAKEUP_CB_ID :
621         heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
622         break;
623 
624       case HAL_ETH_MSPINIT_CB_ID :
625         heth->MspInitCallback = HAL_ETH_MspInit;
626         break;
627 
628       case HAL_ETH_MSPDEINIT_CB_ID :
629         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
630         break;
631 
632       default :
633         /* Update the error code */
634         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
635         /* Return error status */
636         status =  HAL_ERROR;
637         break;
638     }
639   }
640   else if (heth->gState == HAL_ETH_STATE_RESET)
641   {
642     switch (CallbackID)
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
661   {
662     /* Update the error code */
663     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
664     /* Return error status */
665     status =  HAL_ERROR;
666   }
667 
668   return status;
669 }
670 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
671 
672 /**
673   * @}
674   */
675 
676 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
677   *  @brief ETH Transmit and Receive functions
678   *
679 @verbatim
680   ==============================================================================
681                       ##### IO operation functions #####
682   ==============================================================================
683   [..]
684     This subsection provides a set of functions allowing to manage the ETH
685     data transfer.
686 
687 @endverbatim
688   * @{
689   */
690 
691 /**
692   * @brief  Enables Ethernet MAC and DMA reception and transmission
693   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
694   *         the configuration information for ETHERNET module
695   * @retval HAL status
696   */
HAL_ETH_Start(ETH_HandleTypeDef * heth)697 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
698 {
699   uint32_t tmpreg1;
700 
701   if (heth->gState == HAL_ETH_STATE_READY)
702   {
703     heth->gState = HAL_ETH_STATE_BUSY;
704 
705     /* Set nombre of descriptors to build */
706     heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
707 
708     /* Build all descriptors */
709     ETH_UpdateDescriptor(heth);
710 
711     /* Enable the MAC transmission */
712     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
713 
714     /* Wait until the write operation will be taken into account :
715     at least four TX_CLK/RX_CLK clock cycles */
716     tmpreg1 = (heth->Instance)->MACCR;
717     HAL_Delay(ETH_REG_WRITE_DELAY);
718     (heth->Instance)->MACCR = tmpreg1;
719 
720     /* Enable the MAC reception */
721     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
722 
723     /* Wait until the write operation will be taken into account :
724     at least four TX_CLK/RX_CLK clock cycles */
725     tmpreg1 = (heth->Instance)->MACCR;
726     HAL_Delay(ETH_REG_WRITE_DELAY);
727     (heth->Instance)->MACCR = tmpreg1;
728 
729     /* Flush Transmit FIFO */
730     ETH_FlushTransmitFIFO(heth);
731 
732     /* Enable the DMA transmission */
733     SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
734 
735     /* Enable the DMA reception */
736     SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
737 
738     heth->gState = HAL_ETH_STATE_STARTED;
739 
740     return HAL_OK;
741   }
742   else
743   {
744     return HAL_ERROR;
745   }
746 }
747 
748 /**
749   * @brief  Enables Ethernet MAC and DMA reception/transmission in Interrupt mode
750   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
751   *         the configuration information for ETHERNET module
752   * @retval HAL status
753   */
HAL_ETH_Start_IT(ETH_HandleTypeDef * heth)754 HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
755 {
756   uint32_t tmpreg1;
757 
758   if (heth->gState == HAL_ETH_STATE_READY)
759   {
760     heth->gState = HAL_ETH_STATE_BUSY;
761 
762     /* save IT mode to ETH Handle */
763     heth->RxDescList.ItMode = 1U;
764     /* Disable MMC Interrupts */
765     SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM);
766 
767     /* Disable Rx MMC Interrupts */
768     SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | \
769             ETH_MMCRIMR_RFCEM);
770 
771     /* Disable Tx MMC Interrupts */
772     SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | \
773             ETH_MMCTIMR_TGFSCM);
774 
775     /* Set nombre of descriptors to build */
776     heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
777 
778     /* Build all descriptors */
779     ETH_UpdateDescriptor(heth);
780 
781     /* Enable the MAC transmission */
782     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
783 
784     /* Wait until the write operation will be taken into account :
785     at least four TX_CLK/RX_CLK clock cycles */
786     tmpreg1 = (heth->Instance)->MACCR;
787     HAL_Delay(ETH_REG_WRITE_DELAY);
788     (heth->Instance)->MACCR = tmpreg1;
789 
790     /* Enable the MAC reception */
791     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
792 
793     /* Wait until the write operation will be taken into account :
794     at least four TX_CLK/RX_CLK clock cycles */
795     tmpreg1 = (heth->Instance)->MACCR;
796     HAL_Delay(ETH_REG_WRITE_DELAY);
797     (heth->Instance)->MACCR = tmpreg1;
798 
799     /* Flush Transmit FIFO */
800     ETH_FlushTransmitFIFO(heth);
801 
802     /* Enable the DMA transmission */
803     SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
804 
805     /* Enable the DMA reception */
806     SET_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
807 
808     /* Enable ETH DMA interrupts:
809     - Tx complete interrupt
810     - Rx complete interrupt
811     - Fatal bus interrupt
812     */
813     __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE  |
814                                    ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE));
815 
816     heth->gState = HAL_ETH_STATE_STARTED;
817     return HAL_OK;
818   }
819   else
820   {
821     return HAL_ERROR;
822   }
823 }
824 
825 /**
826   * @brief  Stop Ethernet MAC and DMA reception/transmission
827   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
828   *         the configuration information for ETHERNET module
829   * @retval HAL status
830   */
HAL_ETH_Stop(ETH_HandleTypeDef * heth)831 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
832 {
833   uint32_t tmpreg1;
834 
835   if (heth->gState == HAL_ETH_STATE_STARTED)
836   {
837     /* Set the ETH peripheral state to BUSY */
838     heth->gState = HAL_ETH_STATE_BUSY;
839     /* Disable the DMA transmission */
840     CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
841 
842     /* Disable the DMA reception */
843     CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
844 
845     /* Disable the MAC reception */
846     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
847 
848     /* Wait until the write operation will be taken into account :
849     at least four TX_CLK/RX_CLK clock cycles */
850     tmpreg1 = (heth->Instance)->MACCR;
851     HAL_Delay(ETH_REG_WRITE_DELAY);
852     (heth->Instance)->MACCR = tmpreg1;
853 
854     /* Flush Transmit FIFO */
855     ETH_FlushTransmitFIFO(heth);
856 
857     /* Disable the MAC transmission */
858     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
859 
860     /* Wait until the write operation will be taken into account :
861     at least four TX_CLK/RX_CLK clock cycles */
862     tmpreg1 = (heth->Instance)->MACCR;
863     HAL_Delay(ETH_REG_WRITE_DELAY);
864     (heth->Instance)->MACCR = tmpreg1;
865 
866     heth->gState = HAL_ETH_STATE_READY;
867 
868     /* Return function status */
869     return HAL_OK;
870   }
871   else
872   {
873     return HAL_ERROR;
874   }
875 }
876 
877 /**
878   * @brief  Stop Ethernet MAC and DMA reception/transmission in Interrupt mode
879   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
880   *         the configuration information for ETHERNET module
881   * @retval HAL status
882   */
HAL_ETH_Stop_IT(ETH_HandleTypeDef * heth)883 HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
884 {
885   ETH_DMADescTypeDef *dmarxdesc;
886   uint32_t descindex;
887   uint32_t tmpreg1;
888 
889   if (heth->gState == HAL_ETH_STATE_STARTED)
890   {
891     /* Set the ETH peripheral state to BUSY */
892     heth->gState = HAL_ETH_STATE_BUSY;
893 
894     __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE  |
895                                     ETH_DMAIER_FBEIE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE));
896 
897     /* Disable the DMA transmission */
898     CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_ST);
899 
900     /* Disable the DMA reception */
901     CLEAR_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_SR);
902 
903     /* Disable the MAC reception */
904     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
905 
906     /* Wait until the write operation will be taken into account :
907     at least four TX_CLK/RX_CLK clock cycles */
908     tmpreg1 = (heth->Instance)->MACCR;
909     HAL_Delay(ETH_REG_WRITE_DELAY);
910     (heth->Instance)->MACCR = tmpreg1;
911 
912     /* Flush Transmit FIFO */
913     ETH_FlushTransmitFIFO(heth);
914 
915     /* Disable the MAC transmission */
916     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
917 
918     /* Wait until the write operation will be taken into account :
919     at least four TX_CLK/RX_CLK clock cycles */
920     tmpreg1 = (heth->Instance)->MACCR;
921     HAL_Delay(ETH_REG_WRITE_DELAY);
922     (heth->Instance)->MACCR = tmpreg1;
923 
924     /* Clear IOC bit to all Rx descriptors */
925     for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
926     {
927       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
928       SET_BIT(dmarxdesc->DESC1, ETH_DMARXDESC_DIC);
929     }
930 
931     heth->RxDescList.ItMode = 0U;
932 
933     heth->gState = HAL_ETH_STATE_READY;
934 
935     /* Return function status */
936     return HAL_OK;
937   }
938   else
939   {
940     return HAL_ERROR;
941   }
942 }
943 
944 /**
945   * @brief  Sends an Ethernet Packet in polling mode.
946   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
947   *         the configuration information for ETHERNET module
948   * @param  pTxConfig: Hold the configuration of packet to be transmitted
949   * @param  Timeout: timeout value
950   * @retval HAL status
951   */
HAL_ETH_Transmit(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig,uint32_t Timeout)952 HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout)
953 {
954   uint32_t tickstart;
955   ETH_DMADescTypeDef *dmatxdesc;
956 
957   if (pTxConfig == NULL)
958   {
959     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
960     return HAL_ERROR;
961   }
962 
963   if (heth->gState == HAL_ETH_STATE_STARTED)
964   {
965     /* Config DMA Tx descriptor by Tx Packet info */
966     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
967     {
968       /* Set the ETH error code */
969       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
970       return HAL_ERROR;
971     }
972 
973     /* Ensure completion of descriptor preparation before transmission start */
974     __DSB();
975 
976     dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc];
977 
978     /* Incr current tx desc index */
979     INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
980 
981     /* Start transmission */
982     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
983     WRITE_REG(heth->Instance->DMATPDR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
984 
985     tickstart = HAL_GetTick();
986 
987     /* Wait for data to be transmitted or timeout occurred */
988     while ((dmatxdesc->DESC0 & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
989     {
990       if ((heth->Instance->DMASR & ETH_DMASR_FBES) != (uint32_t)RESET)
991       {
992         heth->ErrorCode |= HAL_ETH_ERROR_DMA;
993         heth->DMAErrorCode = heth->Instance->DMASR;
994         /* Return function status */
995         return HAL_ERROR;
996       }
997 
998       /* Check for the Timeout */
999       if (Timeout != HAL_MAX_DELAY)
1000       {
1001         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1002         {
1003           heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
1004           /* Clear TX descriptor so that we can proceed */
1005           dmatxdesc->DESC0 = (ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
1006           return HAL_ERROR;
1007         }
1008       }
1009     }
1010 
1011     /* Return function status */
1012     return HAL_OK;
1013   }
1014   else
1015   {
1016     return HAL_ERROR;
1017   }
1018 }
1019 
1020 /**
1021   * @brief  Sends an Ethernet Packet in interrupt mode.
1022   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1023   *         the configuration information for ETHERNET module
1024   * @param  pTxConfig: Hold the configuration of packet to be transmitted
1025   * @retval HAL status
1026   */
HAL_ETH_Transmit_IT(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig)1027 HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig)
1028 {
1029   if (pTxConfig == NULL)
1030   {
1031     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1032     return HAL_ERROR;
1033   }
1034 
1035   if (heth->gState == HAL_ETH_STATE_STARTED)
1036   {
1037     /* Save the packet pointer to release.  */
1038     heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData;
1039 
1040     /* Config DMA Tx descriptor by Tx Packet info */
1041     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
1042     {
1043       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
1044       return HAL_ERROR;
1045     }
1046 
1047     /* Ensure completion of descriptor preparation before transmission start */
1048     __DSB();
1049 
1050     /* Incr current tx desc index */
1051     INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
1052 
1053     /* Start transmission */
1054     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
1055     if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
1056     {
1057       /* Clear TBUS ETHERNET DMA flag */
1058       (heth->Instance)->DMASR = ETH_DMASR_TBUS;
1059       /* Resume DMA transmission*/
1060       (heth->Instance)->DMATPDR = 0U;
1061     }
1062 
1063     return HAL_OK;
1064 
1065   }
1066   else
1067   {
1068     return HAL_ERROR;
1069   }
1070 }
1071 
1072 /**
1073   * @brief  Read a received packet.
1074   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1075   *         the configuration information for ETHERNET module
1076   * @param  pAppBuff: Pointer to an application buffer to receive the packet.
1077   * @retval HAL status
1078   */
HAL_ETH_ReadData(ETH_HandleTypeDef * heth,void ** pAppBuff)1079 HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
1080 {
1081   uint32_t descidx;
1082   ETH_DMADescTypeDef *dmarxdesc;
1083   uint32_t desccnt = 0U;
1084   uint32_t desccntmax;
1085   uint32_t bufflength;
1086   uint8_t rxdataready = 0U;
1087 
1088 
1089   if (pAppBuff == NULL)
1090   {
1091     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1092     return HAL_ERROR;
1093   }
1094 
1095   if (heth->gState != HAL_ETH_STATE_STARTED)
1096   {
1097     return HAL_ERROR;
1098   }
1099 
1100   descidx = heth->RxDescList.RxDescIdx;
1101   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1102   desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt;
1103 
1104   /* Check if descriptor is not owned by DMA */
1105   while ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
1106          && (rxdataready == 0U))
1107   {
1108     if (READ_BIT(dmarxdesc->DESC0,  ETH_DMARXDESC_LS)  != (uint32_t)RESET)
1109     {
1110       /* Get timestamp high */
1111       heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC6;
1112       /* Get timestamp low */
1113       heth->RxDescList.TimeStamp.TimeStampLow  = dmarxdesc->DESC7;
1114     }
1115     if ((READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
1116     {
1117       /* Check first descriptor */
1118       if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_FS) != (uint32_t)RESET)
1119       {
1120         heth->RxDescList.RxDescCnt = 0;
1121         heth->RxDescList.RxDataLength = 0;
1122       }
1123 
1124       /* Check if last descriptor */
1125       bufflength = heth->Init.RxBuffLen;
1126       if (READ_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_LS) != (uint32_t)RESET)
1127       {
1128         /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1129         bufflength = ((dmarxdesc->DESC0 & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
1130 
1131         /* Save Last descriptor index */
1132         heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC0;
1133 
1134         /* Packet ready */
1135         rxdataready = 1;
1136       }
1137 
1138       /* Link data */
1139       WRITE_REG(dmarxdesc->BackupAddr0, dmarxdesc->DESC2);
1140 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1141       /*Call registered Link callback*/
1142       heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1143                            (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
1144 #else
1145       /* Link callback */
1146       HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1147                              (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
1148 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1149       heth->RxDescList.RxDescCnt++;
1150       heth->RxDescList.RxDataLength += bufflength;
1151 
1152       /* Clear buffer pointer */
1153       dmarxdesc->BackupAddr0 = 0;
1154     }
1155 
1156     /* Increment current rx descriptor index */
1157     INCR_RX_DESC_INDEX(descidx, 1U);
1158     /* Get current descriptor address */
1159     dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1160     desccnt++;
1161   }
1162 
1163   heth->RxDescList.RxBuildDescCnt += desccnt;
1164   if ((heth->RxDescList.RxBuildDescCnt) != 0U)
1165   {
1166     /* Update Descriptors */
1167     ETH_UpdateDescriptor(heth);
1168   }
1169 
1170   heth->RxDescList.RxDescIdx = descidx;
1171 
1172   if (rxdataready == 1U)
1173   {
1174     /* Return received packet */
1175     *pAppBuff = heth->RxDescList.pRxStart;
1176     /* Reset first element */
1177     heth->RxDescList.pRxStart = NULL;
1178 
1179     return HAL_OK;
1180   }
1181 
1182   /* Packet not ready */
1183   return HAL_ERROR;
1184 }
1185 
1186 /**
1187   * @brief  This function gives back Rx Desc of the last received Packet
1188   *         to the DMA, so ETH DMA will be able to use these descriptors
1189   *         to receive next Packets.
1190   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1191   *         the configuration information for ETHERNET module
1192   * @retval HAL status
1193   */
ETH_UpdateDescriptor(ETH_HandleTypeDef * heth)1194 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
1195 {
1196   uint32_t descidx;
1197   uint32_t desccount;
1198   ETH_DMADescTypeDef *dmarxdesc;
1199   uint8_t *buff = NULL;
1200   uint8_t allocStatus = 1U;
1201 
1202   descidx = heth->RxDescList.RxBuildDescIdx;
1203   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1204   desccount = heth->RxDescList.RxBuildDescCnt;
1205 
1206   while ((desccount > 0U) && (allocStatus != 0U))
1207   {
1208     /* Check if a buffer's attached the descriptor */
1209     if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
1210     {
1211       /* Get a new buffer. */
1212 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1213       /*Call registered Allocate callback*/
1214       heth->rxAllocateCallback(&buff);
1215 #else
1216       /* Allocate callback */
1217       HAL_ETH_RxAllocateCallback(&buff);
1218 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1219       if (buff == NULL)
1220       {
1221         allocStatus = 0U;
1222       }
1223       else
1224       {
1225         WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
1226         WRITE_REG(dmarxdesc->DESC2, (uint32_t)buff);
1227       }
1228     }
1229 
1230     if (allocStatus != 0U)
1231     {
1232       if (heth->RxDescList.ItMode == 0U)
1233       {
1234         WRITE_REG(dmarxdesc->DESC1, ETH_DMARXDESC_DIC | ETH_RX_BUF_SIZE | ETH_DMARXDESC_RCH);
1235       }
1236       else
1237       {
1238         WRITE_REG(dmarxdesc->DESC1, ETH_RX_BUF_SIZE | ETH_DMARXDESC_RCH);
1239       }
1240 
1241       /* Before transferring the ownership to DMA, make sure that the RX descriptors bits writing
1242          is fully performed.
1243          The __DMB() instruction is added to avoid any potential compiler optimization that
1244          may lead to abnormal behavior. */
1245       __DMB();
1246 
1247       SET_BIT(dmarxdesc->DESC0, ETH_DMARXDESC_OWN);
1248 
1249       /* Increment current rx descriptor index */
1250       INCR_RX_DESC_INDEX(descidx, 1U);
1251       /* Get current descriptor address */
1252       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1253       desccount--;
1254     }
1255   }
1256 
1257   if (heth->RxDescList.RxBuildDescCnt != desccount)
1258   {
1259     /* Set the Tail pointer address */
1260     WRITE_REG(heth->Instance->DMARPDR, 0);
1261 
1262     heth->RxDescList.RxBuildDescIdx = descidx;
1263     heth->RxDescList.RxBuildDescCnt = desccount;
1264   }
1265 }
1266 
1267 /**
1268   * @brief  Register the Rx alloc callback.
1269   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1270   *         the configuration information for ETHERNET module
1271   * @param  rxAllocateCallback: pointer to function to alloc buffer
1272   * @retval HAL status
1273   */
HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef * heth,pETH_rxAllocateCallbackTypeDef rxAllocateCallback)1274 HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
1275                                                      pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
1276 {
1277   if (rxAllocateCallback == NULL)
1278   {
1279     /* No buffer to save */
1280     return HAL_ERROR;
1281   }
1282 
1283   /* Set function to allocate buffer */
1284   heth->rxAllocateCallback = rxAllocateCallback;
1285 
1286   return HAL_OK;
1287 }
1288 
1289 /**
1290   * @brief  Unregister the Rx alloc callback.
1291   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1292   *         the configuration information for ETHERNET module
1293   * @retval HAL status
1294   */
HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef * heth)1295 HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
1296 {
1297   /* Set function to allocate buffer */
1298   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
1299 
1300   return HAL_OK;
1301 }
1302 
1303 /**
1304   * @brief  Rx Allocate callback.
1305   * @param  buff: pointer to allocated buffer
1306   * @retval None
1307   */
HAL_ETH_RxAllocateCallback(uint8_t ** buff)1308 __weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
1309 {
1310   /* Prevent unused argument(s) compilation warning */
1311   UNUSED(buff);
1312   /* NOTE : This function Should not be modified, when the callback is needed,
1313   the HAL_ETH_RxAllocateCallback could be implemented in the user file
1314   */
1315 }
1316 
1317 /**
1318   * @brief  Rx Link callback.
1319   * @param  pStart: pointer to packet start
1320   * @param  pStart: pointer to packet end
1321   * @param  buff: pointer to received data
1322   * @param  Length: received data length
1323   * @retval None
1324   */
HAL_ETH_RxLinkCallback(void ** pStart,void ** pEnd,uint8_t * buff,uint16_t Length)1325 __weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
1326 {
1327   /* Prevent unused argument(s) compilation warning */
1328   UNUSED(pStart);
1329   UNUSED(pEnd);
1330   UNUSED(buff);
1331   UNUSED(Length);
1332   /* NOTE : This function Should not be modified, when the callback is needed,
1333   the HAL_ETH_RxLinkCallback could be implemented in the user file
1334   */
1335 }
1336 
1337 /**
1338   * @brief  Set the Rx link data function.
1339   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1340   *         the configuration information for ETHERNET module
1341   * @param  rxLinkCallback: pointer to function to link data
1342   * @retval HAL status
1343   */
HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef * heth,pETH_rxLinkCallbackTypeDef rxLinkCallback)1344 HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
1345 {
1346   if (rxLinkCallback == NULL)
1347   {
1348     /* No buffer to save */
1349     return HAL_ERROR;
1350   }
1351 
1352   /* Set function to link data */
1353   heth->rxLinkCallback = rxLinkCallback;
1354 
1355   return HAL_OK;
1356 }
1357 
1358 /**
1359   * @brief  Unregister the Rx link callback.
1360   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1361   *         the configuration information for ETHERNET module
1362   * @retval HAL status
1363   */
HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef * heth)1364 HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
1365 {
1366   /* Set function to allocate buffer */
1367   heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
1368 
1369   return HAL_OK;
1370 }
1371 
1372 /**
1373   * @brief  Get the error state of the last received packet.
1374   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1375   *         the configuration information for ETHERNET module
1376   * @param  pErrorCode: pointer to uint32_t to hold the error code
1377   * @retval HAL status
1378   */
HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef * heth,uint32_t * pErrorCode)1379 HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
1380 {
1381   /* Get error bits. */
1382   *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXDESC_ERRORS_MASK);
1383 
1384   return HAL_OK;
1385 }
1386 
1387 /**
1388   * @brief  Set the Tx free function.
1389   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1390   *         the configuration information for ETHERNET module
1391   * @param  txFreeCallback: pointer to function to release the packet
1392   * @retval HAL status
1393   */
HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef * heth,pETH_txFreeCallbackTypeDef txFreeCallback)1394 HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
1395 {
1396   if (txFreeCallback == NULL)
1397   {
1398     /* No buffer to save */
1399     return HAL_ERROR;
1400   }
1401 
1402   /* Set function to free transmmitted packet */
1403   heth->txFreeCallback = txFreeCallback;
1404 
1405   return HAL_OK;
1406 }
1407 
1408 /**
1409   * @brief  Unregister the Tx free callback.
1410   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1411   *         the configuration information for ETHERNET module
1412   * @retval HAL status
1413   */
HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef * heth)1414 HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
1415 {
1416   /* Set function to allocate buffer */
1417   heth->txFreeCallback = HAL_ETH_TxFreeCallback;
1418 
1419   return HAL_OK;
1420 }
1421 
1422 /**
1423   * @brief  Tx Free callback.
1424   * @param  buff: pointer to buffer to free
1425   * @retval None
1426   */
HAL_ETH_TxFreeCallback(uint32_t * buff)1427 __weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
1428 {
1429   /* Prevent unused argument(s) compilation warning */
1430   UNUSED(buff);
1431   /* NOTE : This function Should not be modified, when the callback is needed,
1432   the HAL_ETH_TxFreeCallback could be implemented in the user file
1433   */
1434 }
1435 
1436 /**
1437   * @brief  Release transmitted Tx packets.
1438   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1439   *         the configuration information for ETHERNET module
1440   * @retval HAL status
1441   */
HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef * heth)1442 HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
1443 {
1444   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1445   uint32_t numOfBuf =  dmatxdesclist->BuffersInUse;
1446   uint32_t idx =       dmatxdesclist->releaseIndex;
1447   uint8_t pktTxStatus = 1U;
1448   uint8_t pktInUse;
1449 #ifdef HAL_ETH_USE_PTP
1450   ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
1451 #endif /* HAL_ETH_USE_PTP */
1452 
1453   /* Loop through buffers in use.  */
1454   while ((numOfBuf != 0U) && (pktTxStatus != 0U))
1455   {
1456     pktInUse = 1U;
1457     numOfBuf--;
1458     /* If no packet, just examine the next packet.  */
1459     if (dmatxdesclist->PacketAddress[idx] == NULL)
1460     {
1461       /* No packet in use, skip to next.  */
1462       idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U);
1463       pktInUse = 0U;
1464     }
1465 
1466     if (pktInUse != 0U)
1467     {
1468       /* Determine if the packet has been transmitted.  */
1469       if ((heth->Init.TxDesc[idx].DESC0 & ETH_DMATXDESC_OWN) == 0U)
1470       {
1471 #ifdef HAL_ETH_USE_PTP
1472         /* Get timestamp low */
1473         timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC6;
1474         /* Get timestamp high */
1475         timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC7;
1476 #endif /* HAL_ETH_USE_PTP */
1477 
1478 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1479         /*Call registered callbacks*/
1480 #ifdef HAL_ETH_USE_PTP
1481         /* Handle Ptp  */
1482         heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1483 #endif  /* HAL_ETH_USE_PTP */
1484         /* Release the packet.  */
1485         heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1486 #else
1487         /* Call callbacks */
1488 #ifdef HAL_ETH_USE_PTP
1489         /* Handle Ptp  */
1490         HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1491 #endif  /* HAL_ETH_USE_PTP */
1492         /* Release the packet.  */
1493         HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1494 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1495 
1496         /* Clear the entry in the in-use array.  */
1497         dmatxdesclist->PacketAddress[idx] = NULL;
1498 
1499         /* Update the transmit relesae index and number of buffers in use.  */
1500         idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U);
1501         dmatxdesclist->BuffersInUse = numOfBuf;
1502         dmatxdesclist->releaseIndex = idx;
1503       }
1504       else
1505       {
1506         /* Get out of the loop!  */
1507         pktTxStatus = 0U;
1508       }
1509     }
1510   }
1511   return HAL_OK;
1512 }
1513 
1514 #ifdef HAL_ETH_USE_PTP
1515 /**
1516   * @brief  Set the Ethernet PTP configuration.
1517   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1518   *         the configuration information for ETHERNET module
1519   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1520   *         the configuration information for PTP
1521   * @retval HAL status
1522   */
HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1523 HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1524 {
1525   uint32_t tmpTSCR;
1526   ETH_TimeTypeDef time;
1527 
1528   if (ptpconfig == NULL)
1529   {
1530     return HAL_ERROR;
1531   }
1532 
1533   tmpTSCR = ptpconfig->Timestamp |
1534             ((uint32_t)ptpconfig->TimestampUpdate << ETH_PTPTSCR_TSFCU_Pos) |
1535             ((uint32_t)ptpconfig->TimestampAll << ETH_PTPTSCR_TSSARFE_Pos) |
1536             ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_PTPTSCR_TSSSR_Pos) |
1537             ((uint32_t)ptpconfig->TimestampV2 << ETH_PTPTSCR_TSPTPPSV2E_Pos) |
1538             ((uint32_t)ptpconfig->TimestampEthernet << ETH_PTPTSCR_TSSPTPOEFE_Pos) |
1539             ((uint32_t)ptpconfig->TimestampIPv6 << ETH_PTPTSCR_TSSIPV6FE_Pos) |
1540             ((uint32_t)ptpconfig->TimestampIPv4 << ETH_PTPTSCR_TSSIPV4FE_Pos) |
1541             ((uint32_t)ptpconfig->TimestampEvent << ETH_PTPTSCR_TSSEME_Pos) |
1542             ((uint32_t)ptpconfig->TimestampMaster << ETH_PTPTSCR_TSSMRME_Pos) |
1543             ((uint32_t)ptpconfig->TimestampFilter << ETH_PTPTSCR_TSPFFMAE_Pos) |
1544             ((uint32_t)ptpconfig->TimestampClockType << ETH_PTPTSCR_TSCNT_Pos);
1545 
1546   /* Write to MACTSCR */
1547   MODIFY_REG(heth->Instance->PTPTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1548 
1549   /* Enable Timestamp */
1550   SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE);
1551   WRITE_REG(heth->Instance->PTPSSIR, ptpconfig->TimestampSubsecondInc);
1552   WRITE_REG(heth->Instance->PTPTSAR, ptpconfig->TimestampAddend);
1553 
1554   /* Enable Timestamp */
1555   if (ptpconfig->TimestampAddendUpdate == ENABLE)
1556   {
1557     SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSARU);
1558     while ((heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU) != 0) {}
1559   }
1560 
1561   /* Enable Update mode */
1562   if (ptpconfig->TimestampUpdateMode == ENABLE)
1563   {
1564     SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSFCU);
1565   }
1566 
1567   /* Initialize Time */
1568   time.Seconds = 0;
1569   time.NanoSeconds = 0;
1570   HAL_ETH_PTP_SetTime(heth, &time);
1571 
1572   /* Ptp Init */
1573   SET_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSTI);
1574 
1575   /* Set PTP Configuration done */
1576   heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED;
1577 
1578   /* Return function status */
1579   return HAL_OK;
1580 }
1581 
1582 /**
1583   * @brief  Get the Ethernet PTP configuration.
1584   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1585   *         the configuration information for ETHERNET module
1586   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1587   *         the configuration information for PTP
1588   * @retval HAL status
1589   */
HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1590 HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1591 {
1592   if (ptpconfig == NULL)
1593   {
1594     return HAL_ERROR;
1595   }
1596   ptpconfig->Timestamp = READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSE);
1597   ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->PTPTSCR,
1598                                           ETH_PTPTSCR_TSFCU) >> ETH_PTPTSCR_TSFCU_Pos) > 0U) ? ENABLE : DISABLE;
1599   ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->PTPTSCR,
1600                                        ETH_PTPTSCR_TSSARFE) >> ETH_PTPTSCR_TSSARFE_Pos) > 0U) ? ENABLE : DISABLE;
1601   ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->PTPTSCR,
1602                                                 ETH_PTPTSCR_TSSSR) >> ETH_PTPTSCR_TSSSR_Pos) > 0U)
1603                                      ? ENABLE : DISABLE;
1604   ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->PTPTSCR,
1605                                       ETH_PTPTSCR_TSPTPPSV2E) >> ETH_PTPTSCR_TSPTPPSV2E_Pos) > 0U) ? ENABLE : DISABLE;
1606   ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->PTPTSCR,
1607                                             ETH_PTPTSCR_TSSPTPOEFE) >> ETH_PTPTSCR_TSSPTPOEFE_Pos) > 0U)
1608                                  ? ENABLE : DISABLE;
1609   ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->PTPTSCR,
1610                                         ETH_PTPTSCR_TSSIPV6FE) >> ETH_PTPTSCR_TSSIPV6FE_Pos) > 0U) ? ENABLE : DISABLE;
1611   ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->PTPTSCR,
1612                                         ETH_PTPTSCR_TSSIPV4FE) >> ETH_PTPTSCR_TSSIPV4FE_Pos) > 0U) ? ENABLE : DISABLE;
1613   ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->PTPTSCR,
1614                                          ETH_PTPTSCR_TSSEME) >> ETH_PTPTSCR_TSSEME_Pos) > 0U) ? ENABLE : DISABLE;
1615   ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->PTPTSCR,
1616                                           ETH_PTPTSCR_TSSMRME) >> ETH_PTPTSCR_TSSMRME_Pos) > 0U) ? ENABLE : DISABLE;
1617   ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->PTPTSCR,
1618                                           ETH_PTPTSCR_TSPFFMAE) >> ETH_PTPTSCR_TSPFFMAE_Pos) > 0U) ? ENABLE : DISABLE;
1619   ptpconfig->TimestampClockType = ((READ_BIT(heth->Instance->PTPTSCR,
1620                                              ETH_PTPTSCR_TSCNT) >> ETH_PTPTSCR_TSCNT_Pos) > 0U) ? ENABLE : DISABLE;
1621 
1622   /* Return function status */
1623   return HAL_OK;
1624 }
1625 
1626 /**
1627   * @brief  Set Seconds and Nanoseconds for the Ethernet PTP registers.
1628   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1629   *         the configuration information for ETHERNET module
1630   * @param  heth: pointer to a ETH_TimeTypeDef structure that contains
1631   *         time to set
1632   * @retval HAL status
1633   */
HAL_ETH_PTP_SetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1634 HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1635 {
1636   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1637   {
1638     /* Set Seconds */
1639     heth->Instance->PTPTSHUR = time->Seconds;
1640 
1641     /* Set NanoSeconds */
1642     heth->Instance->PTPTSLUR = time->NanoSeconds;
1643 
1644     /* Return function status */
1645     return HAL_OK;
1646   }
1647   else
1648   {
1649     /* Return function status */
1650     return HAL_ERROR;
1651   }
1652 }
1653 
1654 /**
1655   * @brief  Get Seconds and Nanoseconds for the Ethernet PTP registers.
1656   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1657   *         the configuration information for ETHERNET module
1658   * @param  heth: pointer to a ETH_TimeTypeDef structure that contains
1659   *         time to get
1660   * @retval HAL status
1661   */
HAL_ETH_PTP_GetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1662 HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1663 {
1664   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1665   {
1666     /* Get Seconds */
1667     time->Seconds = heth->Instance->PTPTSHR;
1668 
1669     /* Get NanoSeconds */
1670     time->NanoSeconds = heth->Instance->PTPTSLR;
1671 
1672     /* Return function status */
1673     return HAL_OK;
1674   }
1675   else
1676   {
1677     /* Return function status */
1678     return HAL_ERROR;
1679   }
1680 }
1681 
1682 /**
1683   * @brief  Update time for the Ethernet PTP registers.
1684   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1685   *         the configuration information for ETHERNET module
1686   * @param  timeupdate: pointer to a ETH_TIMEUPDATETypeDef structure that contains
1687   *         the time update information
1688   * @retval HAL status
1689   */
HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef * heth,ETH_PtpUpdateTypeDef ptpoffsettype,ETH_TimeTypeDef * timeoffset)1690 HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1691                                             ETH_TimeTypeDef *timeoffset)
1692 {
1693   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1694   {
1695     if (ptpoffsettype ==  HAL_ETH_PTP_NEGATIVE_UPDATE)
1696     {
1697       /* Set Seconds update */
1698       heth->Instance->PTPTSHUR = ETH_PTPTSHR_VALUE - timeoffset->Seconds + 1U;
1699 
1700       if (READ_BIT(heth->Instance->PTPTSCR, ETH_PTPTSCR_TSSSR) == ETH_PTPTSCR_TSSSR)
1701       {
1702         /* Set nanoSeconds update */
1703         heth->Instance->PTPTSLUR = ETH_PTPTSLR_VALUE - timeoffset->NanoSeconds;
1704       }
1705       else
1706       {
1707         heth->Instance->PTPTSLUR = ETH_PTPTSHR_VALUE - timeoffset->NanoSeconds + 1U;
1708       }
1709     }
1710     else
1711     {
1712       /* Set Seconds update */
1713       heth->Instance->PTPTSHUR = timeoffset->Seconds;
1714       /* Set nanoSeconds update */
1715       heth->Instance->PTPTSLUR = timeoffset->NanoSeconds;
1716     }
1717 
1718     /* Return function status */
1719     return HAL_OK;
1720   }
1721   else
1722   {
1723     /* Return function status */
1724     return HAL_ERROR;
1725   }
1726 }
1727 
1728 /**
1729   * @brief  Insert Timestamp in transmission.
1730   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1731   *         the configuration information for ETHERNET module
1732   * @param  txtimestampconf: Enable or Disable timestamp in transmission
1733   * @retval HAL status
1734   */
HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef * heth)1735 HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1736 {
1737   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1738   uint32_t descidx = dmatxdesclist->CurTxDesc;
1739   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1740 
1741   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1742   {
1743     /* Enable Time Stamp transmission */
1744     SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TTSE);
1745 
1746     /* Return function status */
1747     return HAL_OK;
1748   }
1749   else
1750   {
1751     /* Return function status */
1752     return HAL_ERROR;
1753   }
1754 }
1755 
1756 /**
1757   * @brief  Get transmission timestamp.
1758   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1759   *         the configuration information for ETHERNET module
1760   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1761   *         transmission timestamp
1762   * @retval HAL status
1763   */
HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1764 HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1765 {
1766   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1767   uint32_t idx =       dmatxdesclist->releaseIndex;
1768   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1769 
1770   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1771   {
1772     /* Get timestamp low */
1773     timestamp->TimeStampLow = dmatxdesc->DESC0;
1774     /* Get timestamp high */
1775     timestamp->TimeStampHigh = dmatxdesc->DESC1;
1776 
1777     /* Return function status */
1778     return HAL_OK;
1779   }
1780   else
1781   {
1782     /* Return function status */
1783     return HAL_ERROR;
1784   }
1785 }
1786 
1787 /**
1788   * @brief  Get receive timestamp.
1789   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1790   *         the configuration information for ETHERNET module
1791   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1792   *         receive timestamp
1793   * @retval HAL status
1794   */
HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1795 HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1796 {
1797   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED)
1798   {
1799     /* Get timestamp low */
1800     timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
1801     /* Get timestamp high */
1802     timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
1803 
1804     /* Return function status */
1805     return HAL_OK;
1806   }
1807   else
1808   {
1809     /* Return function status */
1810     return HAL_ERROR;
1811   }
1812 }
1813 
1814 /**
1815   * @brief  Register the Tx Ptp callback.
1816   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1817   *         the configuration information for ETHERNET module
1818   * @param  txPtpCallback: Function to handle Ptp transmission
1819   * @retval HAL status
1820   */
HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef * heth,pETH_txPtpCallbackTypeDef txPtpCallback)1821 HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1822 {
1823   if (txPtpCallback == NULL)
1824   {
1825     /* No buffer to save */
1826     return HAL_ERROR;
1827   }
1828   /* Set Function to handle Tx Ptp */
1829   heth->txPtpCallback = txPtpCallback;
1830 
1831   return HAL_OK;
1832 }
1833 
1834 /**
1835   * @brief  Unregister the Tx Ptp callback.
1836   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1837   *         the configuration information for ETHERNET module
1838   * @retval HAL status
1839   */
HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef * heth)1840 HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1841 {
1842   /* Set function to allocate buffer */
1843   heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1844 
1845   return HAL_OK;
1846 }
1847 
1848 /**
1849   * @brief  Tx Ptp callback.
1850   * @param  buff: pointer to application buffer
1851   * @retval None
1852   */
HAL_ETH_TxPtpCallback(uint32_t * buff,ETH_TimeStampTypeDef * timestamp)1853 __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1854 {
1855   /* Prevent unused argument(s) compilation warning */
1856   UNUSED(buff);
1857   /* NOTE : This function Should not be modified, when the callback is needed,
1858   the HAL_ETH_TxPtpCallback could be implemented in the user file
1859   */
1860 }
1861 #endif  /* HAL_ETH_USE_PTP */
1862 
1863 /**
1864   * @brief  This function handles ETH interrupt request.
1865   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1866   *         the configuration information for ETHERNET module
1867   * @retval HAL status
1868   */
HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)1869 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1870 {
1871   /* Packet received */
1872   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_RS))
1873   {
1874     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_RIE))
1875     {
1876       /* Clear the Eth DMA Rx IT pending bits */
1877       __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_RS | ETH_DMASR_NIS);
1878 
1879 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1880       /*Call registered Receive complete callback*/
1881       heth->RxCpltCallback(heth);
1882 #else
1883       /* Receive complete callback */
1884       HAL_ETH_RxCpltCallback(heth);
1885 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1886     }
1887   }
1888 
1889   /* Packet transmitted */
1890   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_TS))
1891   {
1892     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_TIE))
1893     {
1894       /* Clear the Eth DMA Tx IT pending bits */
1895       __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMASR_TS | ETH_DMASR_NIS);
1896 
1897 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1898       /*Call registered Transmit complete callback*/
1899       heth->TxCpltCallback(heth);
1900 #else
1901       /* Transfer complete callback */
1902       HAL_ETH_TxCpltCallback(heth);
1903 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1904     }
1905   }
1906 
1907 
1908   /* ETH DMA Error */
1909   if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_AIS))
1910   {
1911     if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_AISE))
1912     {
1913       heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1914 
1915       /* if fatal bus error occurred */
1916       if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_FBES))
1917       {
1918         /* Get DMA error code  */
1919         heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS));
1920 
1921         /* Disable all interrupts */
1922         __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE);
1923 
1924         /* Set HAL state to ERROR */
1925         heth->gState = HAL_ETH_STATE_ERROR;
1926       }
1927       else
1928       {
1929         /* Get DMA error status  */
1930         heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
1931                                                               ETH_DMASR_RBUS | ETH_DMASR_AIS));
1932 
1933         /* Clear the interrupt summary flag */
1934         __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
1935                                       ETH_DMASR_RBUS | ETH_DMASR_AIS));
1936       }
1937 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1938       /* Call registered Error callback*/
1939       heth->ErrorCallback(heth);
1940 #else
1941       /* Ethernet DMA Error callback */
1942       HAL_ETH_ErrorCallback(heth);
1943 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1944 
1945     }
1946   }
1947 
1948 
1949   /* ETH PMT IT */
1950   if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_PMT_IT))
1951   {
1952     /* Get MAC Wake-up source and clear the status register pending bit */
1953     heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPMTCSR, (ETH_MACPMTCSR_WFR | ETH_MACPMTCSR_MPR));
1954 
1955 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1956     /* Call registered PMT callback*/
1957     heth->PMTCallback(heth);
1958 #else
1959     /* Ethernet PMT callback */
1960     HAL_ETH_PMTCallback(heth);
1961 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1962 
1963     heth->MACWakeUpEvent = (uint32_t)(0x0U);
1964   }
1965 
1966 
1967   /* check ETH WAKEUP exti flag */
1968   if (__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET)
1969   {
1970     /* Clear ETH WAKEUP Exti pending bit */
1971     __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
1972 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1973     /* Call registered WakeUp callback*/
1974     heth->WakeUpCallback(heth);
1975 #else
1976     /* ETH WAKEUP callback */
1977     HAL_ETH_WakeUpCallback(heth);
1978 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1979   }
1980 }
1981 
1982 /**
1983   * @brief  Tx Transfer completed callbacks.
1984   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1985   *         the configuration information for ETHERNET module
1986   * @retval None
1987   */
HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)1988 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
1989 {
1990   /* Prevent unused argument(s) compilation warning */
1991   UNUSED(heth);
1992   /* NOTE : This function Should not be modified, when the callback is needed,
1993   the HAL_ETH_TxCpltCallback could be implemented in the user file
1994   */
1995 }
1996 
1997 /**
1998   * @brief  Rx Transfer completed callbacks.
1999   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2000   *         the configuration information for ETHERNET module
2001   * @retval None
2002   */
HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)2003 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2004 {
2005   /* Prevent unused argument(s) compilation warning */
2006   UNUSED(heth);
2007   /* NOTE : This function Should not be modified, when the callback is needed,
2008   the HAL_ETH_RxCpltCallback could be implemented in the user file
2009   */
2010 }
2011 
2012 /**
2013   * @brief  Ethernet transfer error callbacks
2014   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2015   *         the configuration information for ETHERNET module
2016   * @retval None
2017   */
HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)2018 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2019 {
2020   /* Prevent unused argument(s) compilation warning */
2021   UNUSED(heth);
2022   /* NOTE : This function Should not be modified, when the callback is needed,
2023   the HAL_ETH_ErrorCallback could be implemented in the user file
2024   */
2025 }
2026 
2027 /**
2028   * @brief  Ethernet Power Management module IT callback
2029   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2030   *         the configuration information for ETHERNET module
2031   * @retval None
2032   */
HAL_ETH_PMTCallback(ETH_HandleTypeDef * heth)2033 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2034 {
2035   /* Prevent unused argument(s) compilation warning */
2036   UNUSED(heth);
2037   /* NOTE : This function Should not be modified, when the callback is needed,
2038   the HAL_ETH_PMTCallback could be implemented in the user file
2039   */
2040 }
2041 
2042 
2043 /**
2044   * @brief  ETH WAKEUP interrupt callback
2045   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2046   *         the configuration information for ETHERNET module
2047   * @retval None
2048   */
HAL_ETH_WakeUpCallback(ETH_HandleTypeDef * heth)2049 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2050 {
2051   /* Prevent unused argument(s) compilation warning */
2052   UNUSED(heth);
2053   /* NOTE : This function Should not be modified, when the callback is needed,
2054             the HAL_ETH_WakeUpCallback could be implemented in the user file
2055    */
2056 }
2057 
2058 /**
2059   * @brief  Read a PHY register
2060   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2061   *         the configuration information for ETHERNET module
2062   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2063   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2064   * @param pRegValue: parameter to hold read value
2065   * @retval HAL status
2066   */
HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t * pRegValue)2067 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2068                                           uint32_t *pRegValue)
2069 {
2070   uint32_t tmpreg1;
2071   uint32_t tickstart;
2072 
2073   /* Get the ETHERNET MACMIIAR value */
2074   tmpreg1 = heth->Instance->MACMIIAR;
2075 
2076   /* Keep only the CSR Clock Range CR[2:0] bits value */
2077   tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
2078 
2079   /* Prepare the MII address register value */
2080   tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA);                        /* Set the PHY device address   */
2081   tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);                /* Set the PHY register address */
2082   tmpreg1 &= ~ETH_MACMIIAR_MW;                                            /* Set the read mode            */
2083   tmpreg1 |= ETH_MACMIIAR_MB;                                             /* Set the MII Busy bit         */
2084 
2085   /* Write the result value into the MII Address register */
2086   heth->Instance->MACMIIAR = tmpreg1;
2087 
2088 
2089   tickstart = HAL_GetTick();
2090 
2091   /* Check for the Busy flag */
2092   while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
2093   {
2094     /* Check for the Timeout */
2095     if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
2096     {
2097       return HAL_ERROR;
2098     }
2099 
2100     tmpreg1 = heth->Instance->MACMIIAR;
2101   }
2102 
2103   /* Get MACMIIDR value */
2104   *pRegValue = (uint16_t)(heth->Instance->MACMIIDR);
2105 
2106   return HAL_OK;
2107 }
2108 
2109 
2110 /**
2111   * @brief  Writes to a PHY register.
2112   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2113   *         the configuration information for ETHERNET module
2114   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2115   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2116   * @param  RegValue: the value to write
2117   * @retval HAL status
2118   */
HAL_ETH_WritePHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t RegValue)2119 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2120                                            uint32_t RegValue)
2121 {
2122   uint32_t tmpreg1;
2123   uint32_t tickstart;
2124 
2125   /* Get the ETHERNET MACMIIAR value */
2126   tmpreg1 = heth->Instance->MACMIIAR;
2127 
2128   /* Keep only the CSR Clock Range CR[2:0] bits value */
2129   tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
2130 
2131   /* Prepare the MII register address value */
2132   tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA);                      /* Set the PHY device address */
2133   tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);              /* Set the PHY register address */
2134   tmpreg1 |= ETH_MACMIIAR_MW;                                           /* Set the write mode */
2135   tmpreg1 |= ETH_MACMIIAR_MB;                                           /* Set the MII Busy bit */
2136 
2137   /* Give the value to the MII data register */
2138   heth->Instance->MACMIIDR = (uint16_t)RegValue;
2139 
2140   /* Write the result value into the MII Address register */
2141   heth->Instance->MACMIIAR = tmpreg1;
2142 
2143   /* Get tick */
2144   tickstart = HAL_GetTick();
2145 
2146   /* Check for the Busy flag */
2147   while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
2148   {
2149     /* Check for the Timeout */
2150     if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
2151     {
2152       return HAL_ERROR;
2153     }
2154 
2155     tmpreg1 = heth->Instance->MACMIIAR;
2156   }
2157 
2158   return HAL_OK;
2159 }
2160 
2161 /**
2162   * @}
2163   */
2164 
2165 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
2166   *  @brief   ETH control functions
2167   *
2168 @verbatim
2169   ==============================================================================
2170                       ##### Peripheral Control functions #####
2171   ==============================================================================
2172   [..]
2173     This subsection provides a set of functions allowing to control the ETH
2174     peripheral.
2175 
2176 @endverbatim
2177   * @{
2178   */
2179 /**
2180   * @brief  Get the configuration of the MAC and MTL subsystems.
2181   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2182   *         the configuration information for ETHERNET module
2183   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
2184   *         the configuration of the MAC.
2185   * @retval HAL Status
2186   */
HAL_ETH_GetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2187 HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2188 {
2189   if (macconf == NULL)
2190   {
2191     return HAL_ERROR;
2192   }
2193 
2194   /* Get MAC parameters */
2195   macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2196   macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2197   macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_RD) >> 9) == 0U) ? ENABLE : DISABLE;
2198   macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CSD) >> 16) > 0U)
2199                                         ? ENABLE : DISABLE;
2200   macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ROD) >> 13) == 0U) ? ENABLE : DISABLE;
2201   macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2202   macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2203   macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2204   macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 22) == 0U) ? ENABLE : DISABLE;
2205   macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 23) == 0U) ? ENABLE : DISABLE;
2206   macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_APCS) >> 7) > 0U) ? ENABLE : DISABLE;
2207   macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IFG);
2208   macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPCO) >> 10U) > 0U) ? ENABLE : DISABLE;
2209 
2210 
2211   macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_TFCE) >> 1) > 0U) ? ENABLE : DISABLE;
2212   macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_ZQPD) >> 7) == 0U) ? ENABLE : DISABLE;
2213   macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PLT);
2214   macconf->PauseTime = (READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_PT) >> 16);
2215   macconf->ReceiveFlowControl = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_RFCE) >> 2U) > 0U) ? ENABLE : DISABLE;
2216   macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACFCR, ETH_MACFCR_UPFD) >> 3U) > 0U)
2217                                       ? ENABLE : DISABLE;
2218 
2219   return HAL_OK;
2220 }
2221 
2222 /**
2223   * @brief  Get the configuration of the DMA.
2224   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2225   *         the configuration information for ETHERNET module
2226   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2227   *         the configuration of the ETH DMA.
2228   * @retval HAL Status
2229   */
HAL_ETH_GetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2230 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2231 {
2232   if (dmaconf == NULL)
2233   {
2234     return HAL_ERROR;
2235   }
2236 
2237   dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMABMR,
2238                                     (ETH_DMAARBITRATION_RXPRIORTX | ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1));
2239   dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_AAB) >> 25U) > 0U) ? ENABLE : DISABLE;
2240   dmaconf->BurstMode = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_FB | ETH_DMABMR_MB);
2241   dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_RDP);
2242   dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_PBL);
2243   dmaconf->EnhancedDescriptorFormat = ((READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_EDE) >> 7) > 0U) ? ENABLE : DISABLE;
2244   dmaconf->DescriptorSkipLength = READ_BIT(heth->Instance->DMABMR, ETH_DMABMR_DSL) >> 2;
2245 
2246   dmaconf->DropTCPIPChecksumErrorFrame = ((READ_BIT(heth->Instance->DMAOMR,
2247                                                     ETH_DMAOMR_DTCEFD) >> 26) > 0U) ? DISABLE : ENABLE;
2248   dmaconf->ReceiveStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RSF) >> 25) > 0U) ? ENABLE : DISABLE;
2249   dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FTF) >> 20) > 0U) ? DISABLE : ENABLE;
2250   dmaconf->TransmitStoreForward = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TSF) >> 21) > 0U) ? ENABLE : DISABLE;
2251   dmaconf->TransmitThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_TTC);
2252   dmaconf->ForwardErrorFrames = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_FEF) >> 7) > 0U) ? ENABLE : DISABLE;
2253   dmaconf->ForwardUndersizedGoodFrames = ((READ_BIT(heth->Instance->DMAOMR,
2254                                                     ETH_DMAOMR_FUGF) >> 6) > 0U) ? ENABLE : DISABLE;
2255   dmaconf->ReceiveThresholdControl = READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_RTC);
2256   dmaconf->SecondFrameOperate = ((READ_BIT(heth->Instance->DMAOMR, ETH_DMAOMR_OSF) >> 2) > 0U) ? ENABLE : DISABLE;
2257   return HAL_OK;
2258 }
2259 
2260 /**
2261   * @brief  Set the MAC configuration.
2262   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2263   *         the configuration information for ETHERNET module
2264   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that contains
2265   *         the configuration of the MAC.
2266   * @retval HAL status
2267   */
HAL_ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2268 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2269 {
2270   if (macconf == NULL)
2271   {
2272     return HAL_ERROR;
2273   }
2274 
2275   if (heth->gState == HAL_ETH_STATE_READY)
2276   {
2277     ETH_SetMACConfig(heth, macconf);
2278 
2279     return HAL_OK;
2280   }
2281   else
2282   {
2283     return HAL_ERROR;
2284   }
2285 }
2286 
2287 /**
2288   * @brief  Set the ETH DMA configuration.
2289   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2290   *         the configuration information for ETHERNET module
2291   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2292   *         the configuration of the ETH DMA.
2293   * @retval HAL status
2294   */
HAL_ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2295 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2296 {
2297   if (dmaconf == NULL)
2298   {
2299     return HAL_ERROR;
2300   }
2301 
2302   if (heth->gState == HAL_ETH_STATE_READY)
2303   {
2304     ETH_SetDMAConfig(heth, dmaconf);
2305 
2306     return HAL_OK;
2307   }
2308   else
2309   {
2310     return HAL_ERROR;
2311   }
2312 }
2313 
2314 /**
2315   * @brief  Configures the Clock range of ETH MDIO interface.
2316   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2317   *         the configuration information for ETHERNET module
2318   * @retval None
2319   */
HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef * heth)2320 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2321 {
2322   uint32_t hclk;
2323   uint32_t tmpreg;
2324 
2325   /* Get the ETHERNET MACMIIAR value */
2326   tmpreg = (heth->Instance)->MACMIIAR;
2327   /* Clear CSR Clock Range CR[2:0] bits */
2328   tmpreg &= ETH_MACMIIAR_CR_MASK;
2329 
2330   /* Get hclk frequency value */
2331   hclk = HAL_RCC_GetHCLKFreq();
2332 
2333   /* Set CR bits depending on hclk value */
2334   if ((hclk >= 20000000U) && (hclk < 35000000U))
2335   {
2336     /* CSR Clock Range between 20-35 MHz */
2337     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16;
2338   }
2339   else if ((hclk >= 35000000U) && (hclk < 60000000U))
2340   {
2341     /* CSR Clock Range between 35-60 MHz */
2342     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26;
2343   }
2344   else if ((hclk >= 60000000U) && (hclk < 100000000U))
2345   {
2346     /* CSR Clock Range between 60-100 MHz */
2347     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
2348   }
2349   else if ((hclk >= 100000000U) && (hclk < 150000000U))
2350   {
2351     /* CSR Clock Range between 100-150 MHz */
2352     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
2353   }
2354   else /* ((hclk >= 150000000)&&(hclk <= 183000000))*/
2355   {
2356     /* CSR Clock Range between 150-183 MHz */
2357     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
2358   }
2359 
2360   /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
2361   (heth->Instance)->MACMIIAR = (uint32_t)tmpreg;
2362 }
2363 
2364 /**
2365   * @brief  Set the ETH MAC (L2) Filters configuration.
2366   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2367   *         the configuration information for ETHERNET module
2368   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2369   *         the configuration of the ETH MAC filters.
2370   * @retval HAL status
2371   */
HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2372 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2373 {
2374   uint32_t filterconfig;
2375   uint32_t tmpreg1;
2376 
2377   if (pFilterConfig == NULL)
2378   {
2379     return HAL_ERROR;
2380   }
2381 
2382   filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2383                   ((uint32_t)pFilterConfig->HashUnicast << 1) |
2384                   ((uint32_t)pFilterConfig->HashMulticast << 2)  |
2385                   ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2386                   ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2387                   ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) |
2388                   ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2389                   ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2390                   ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2391                   ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2392                   pFilterConfig->ControlPacketsFilter);
2393 
2394   MODIFY_REG(heth->Instance->MACFFR, ETH_MACFFR_MASK, filterconfig);
2395 
2396   /* Wait until the write operation will be taken into account :
2397   at least four TX_CLK/RX_CLK clock cycles */
2398   tmpreg1 = (heth->Instance)->MACFFR;
2399   HAL_Delay(ETH_REG_WRITE_DELAY);
2400   (heth->Instance)->MACFFR = tmpreg1;
2401 
2402   return HAL_OK;
2403 }
2404 
2405 /**
2406   * @brief  Get the ETH MAC (L2) Filters configuration.
2407   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2408   *         the configuration information for ETHERNET module
2409   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2410   *         the configuration of the ETH MAC filters.
2411   * @retval HAL status
2412   */
HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2413 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2414 {
2415   if (pFilterConfig == NULL)
2416   {
2417     return HAL_ERROR;
2418   }
2419 
2420   pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PM)) > 0U) ? ENABLE : DISABLE;
2421   pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HU) >> 1) > 0U) ? ENABLE : DISABLE;
2422   pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HM) >> 2) > 0U) ? ENABLE : DISABLE;
2423   pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR,
2424                                                        ETH_MACFFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2425   pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PAM) >> 4) > 0U) ? ENABLE : DISABLE;
2426   pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_BFD) >> 5) == 0U) ? ENABLE : DISABLE;
2427   pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_PCF);
2428   pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACFFR,
2429                                                       ETH_MACFFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2430   pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2431   pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_HPF) >> 10) > 0U)
2432                                        ? ENABLE : DISABLE;
2433   pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACFFR, ETH_MACFFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2434 
2435   return HAL_OK;
2436 }
2437 
2438 /**
2439   * @brief  Set the source MAC Address to be matched.
2440   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2441   *         the configuration information for ETHERNET module
2442   * @param  AddrNbr: The MAC address to configure
2443   *          This parameter must be a value of the following:
2444   *            ETH_MAC_ADDRESS1
2445   *            ETH_MAC_ADDRESS2
2446   *            ETH_MAC_ADDRESS3
2447   * @param  pMACAddr: Pointer to MAC address buffer data (6 bytes)
2448   * @retval HAL status
2449   */
HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef * heth,uint32_t AddrNbr,uint8_t * pMACAddr)2450 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef *heth, uint32_t AddrNbr, uint8_t *pMACAddr)
2451 {
2452   uint32_t macaddrlr;
2453   uint32_t macaddrhr;
2454 
2455   if (pMACAddr == NULL)
2456   {
2457     return HAL_ERROR;
2458   }
2459 
2460   /* Get mac addr high reg offset */
2461   macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2462   /* Get mac addr low reg offset */
2463   macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2464 
2465   /* Set MAC addr bits 32 to 47 */
2466   (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2467   /* Set MAC addr bits 0 to 31 */
2468   (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2469                                    ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2470 
2471   /* Enable address and set source address bit */
2472   (*(__IO uint32_t *)macaddrhr) |= (ETH_MACA1HR_AE | ETH_MACA1HR_SA);
2473 
2474   return HAL_OK;
2475 }
2476 
2477 /**
2478   * @brief  Set the ETH Hash Table Value.
2479   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2480   *         the configuration information for ETHERNET module
2481   * @param  pHashTable: pointer to a table of two 32 bit values, that contains
2482   *         the 64 bits of the hash table.
2483   * @retval HAL status
2484   */
HAL_ETH_SetHashTable(ETH_HandleTypeDef * heth,uint32_t * pHashTable)2485 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2486 {
2487   uint32_t tmpreg1;
2488   if (pHashTable == NULL)
2489   {
2490     return HAL_ERROR;
2491   }
2492 
2493   heth->Instance->MACHTHR = pHashTable[0];
2494 
2495   /* Wait until the write operation will be taken into account :
2496   at least four TX_CLK/RX_CLK clock cycles */
2497   tmpreg1 = (heth->Instance)->MACHTHR;
2498   HAL_Delay(ETH_REG_WRITE_DELAY);
2499   (heth->Instance)->MACHTHR = tmpreg1;
2500 
2501   heth->Instance->MACHTLR = pHashTable[1];
2502 
2503   /* Wait until the write operation will be taken into account :
2504   at least four TX_CLK/RX_CLK clock cycles */
2505   tmpreg1 = (heth->Instance)->MACHTLR;
2506   HAL_Delay(ETH_REG_WRITE_DELAY);
2507   (heth->Instance)->MACHTLR = tmpreg1;
2508 
2509   return HAL_OK;
2510 }
2511 
2512 /**
2513   * @brief  Set the VLAN Identifier for Rx packets
2514   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2515   *         the configuration information for ETHERNET module
2516   * @param  ComparisonBits: 12 or 16 bit comparison mode
2517             must be a value of @ref ETH_VLAN_Tag_Comparison
2518   * @param  VLANIdentifier: VLAN Identifier value
2519   * @retval None
2520   */
HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t ComparisonBits,uint32_t VLANIdentifier)2521 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2522 {
2523   uint32_t tmpreg1;
2524   MODIFY_REG(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTI, VLANIdentifier);
2525   if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2526   {
2527     CLEAR_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC);
2528   }
2529   else
2530   {
2531     SET_BIT(heth->Instance->MACVLANTR, ETH_MACVLANTR_VLANTC);
2532   }
2533 
2534   /* Wait until the write operation will be taken into account :
2535   at least four TX_CLK/RX_CLK clock cycles */
2536   tmpreg1 = (heth->Instance)->MACVLANTR;
2537   HAL_Delay(ETH_REG_WRITE_DELAY);
2538   (heth->Instance)->MACVLANTR = tmpreg1;
2539 }
2540 
2541 /**
2542   * @brief  Enters the Power down mode.
2543   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2544   *         the configuration information for ETHERNET module
2545   * @param  pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2546   *         that contains the Power Down configuration
2547   * @retval None.
2548   */
HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef * heth,ETH_PowerDownConfigTypeDef * pPowerDownConfig)2549 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2550 {
2551   uint32_t powerdownconfig;
2552 
2553   powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << ETH_MACPMTCSR_MPE_Pos) |
2554                      ((uint32_t)pPowerDownConfig->WakeUpPacket << ETH_MACPMTCSR_WFE_Pos) |
2555                      ((uint32_t)pPowerDownConfig->GlobalUnicast << ETH_MACPMTCSR_GU_Pos) |
2556                      ETH_MACPMTCSR_PD);
2557 
2558   MODIFY_REG(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_MASK, powerdownconfig);
2559 }
2560 
2561 /**
2562   * @brief  Exits from the Power down mode.
2563   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2564   *         the configuration information for ETHERNET module
2565   * @retval None.
2566   */
HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef * heth)2567 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2568 {
2569   uint32_t tmpreg1;
2570 
2571   /* clear wake up sources */
2572   CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFE | ETH_MACPMTCSR_MPE | ETH_MACPMTCSR_GU);
2573 
2574   /* Wait until the write operation will be taken into account :
2575   at least four TX_CLK/RX_CLK clock cycles */
2576   tmpreg1 = (heth->Instance)->MACPMTCSR;
2577   HAL_Delay(ETH_REG_WRITE_DELAY);
2578   (heth->Instance)->MACPMTCSR = tmpreg1;
2579 
2580   if (READ_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD) != 0U)
2581   {
2582     /* Exit power down mode */
2583     CLEAR_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_PD);
2584 
2585     /* Wait until the write operation will be taken into account :
2586     at least four TX_CLK/RX_CLK clock cycles */
2587     tmpreg1 = (heth->Instance)->MACPMTCSR;
2588     HAL_Delay(ETH_REG_WRITE_DELAY);
2589     (heth->Instance)->MACPMTCSR = tmpreg1;
2590   }
2591 
2592   /* Disable PMT interrupt */
2593   SET_BIT(heth->Instance->MACIMR, ETH_MACIMR_PMTIM);
2594 }
2595 
2596 /**
2597   * @brief  Set the WakeUp filter.
2598   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2599   *         the configuration information for ETHERNET module
2600   * @param  pFilter: pointer to filter registers values
2601   * @param  Count: number of filter registers, must be from 1 to 8.
2602   * @retval None.
2603   */
HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef * heth,uint32_t * pFilter,uint32_t Count)2604 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2605 {
2606   uint32_t regindex;
2607 
2608   if (pFilter == NULL)
2609   {
2610     return HAL_ERROR;
2611   }
2612 
2613   /* Reset Filter Pointer */
2614   SET_BIT(heth->Instance->MACPMTCSR, ETH_MACPMTCSR_WFFRPR);
2615 
2616   /* Wake up packet filter config */
2617   for (regindex = 0; regindex < Count; regindex++)
2618   {
2619     /* Write filter regs */
2620     WRITE_REG(heth->Instance->MACRWUFFR, pFilter[regindex]);
2621   }
2622 
2623   return HAL_OK;
2624 }
2625 
2626 /**
2627   * @}
2628   */
2629 
2630 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2631   *  @brief   ETH State and Errors functions
2632   *
2633 @verbatim
2634   ==============================================================================
2635                  ##### Peripheral State and Errors functions #####
2636   ==============================================================================
2637  [..]
2638    This subsection provides a set of functions allowing to return the State of
2639    ETH communication process, return Peripheral Errors occurred during communication
2640    process
2641 
2642 
2643 @endverbatim
2644   * @{
2645   */
2646 
2647 /**
2648   * @brief  Returns the ETH state.
2649   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2650   *         the configuration information for ETHERNET module
2651   * @retval HAL state
2652   */
HAL_ETH_GetState(ETH_HandleTypeDef * heth)2653 HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
2654 {
2655   return heth->gState;
2656 }
2657 
2658 /**
2659   * @brief  Returns the ETH error code
2660   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2661   *         the configuration information for ETHERNET module
2662   * @retval ETH Error Code
2663   */
HAL_ETH_GetError(ETH_HandleTypeDef * heth)2664 uint32_t HAL_ETH_GetError(ETH_HandleTypeDef *heth)
2665 {
2666   return heth->ErrorCode;
2667 }
2668 
2669 /**
2670   * @brief  Returns the ETH DMA error code
2671   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2672   *         the configuration information for ETHERNET module
2673   * @retval ETH DMA Error Code
2674   */
HAL_ETH_GetDMAError(ETH_HandleTypeDef * heth)2675 uint32_t HAL_ETH_GetDMAError(ETH_HandleTypeDef *heth)
2676 {
2677   return heth->DMAErrorCode;
2678 }
2679 
2680 /**
2681   * @brief  Returns the ETH MAC error code
2682   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2683   *         the configuration information for ETHERNET module
2684   * @retval ETH MAC Error Code
2685   */
HAL_ETH_GetMACError(ETH_HandleTypeDef * heth)2686 uint32_t HAL_ETH_GetMACError(ETH_HandleTypeDef *heth)
2687 {
2688   return heth->MACErrorCode;
2689 }
2690 
2691 /**
2692   * @brief  Returns the ETH MAC WakeUp event source
2693   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2694   *         the configuration information for ETHERNET module
2695   * @retval ETH MAC WakeUp event source
2696   */
HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef * heth)2697 uint32_t HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef *heth)
2698 {
2699   return heth->MACWakeUpEvent;
2700 }
2701 
2702 /**
2703   * @}
2704   */
2705 
2706 /**
2707   * @}
2708   */
2709 
2710 /** @addtogroup ETH_Private_Functions   ETH Private Functions
2711   * @{
2712   */
2713 
2714 /**
2715   * @brief  Clears the ETHERNET transmit FIFO.
2716   * @param  heth pointer to a ETH_HandleTypeDef structure that contains
2717   *         the configuration information for ETHERNET module
2718   * @retval None
2719   */
ETH_FlushTransmitFIFO(ETH_HandleTypeDef * heth)2720 static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
2721 {
2722   __IO uint32_t tmpreg = 0;
2723 
2724   /* Set the Flush Transmit FIFO bit */
2725   (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
2726 
2727   /* Wait until the write operation will be taken into account:
2728      at least four TX_CLK/RX_CLK clock cycles */
2729   tmpreg = (heth->Instance)->DMAOMR;
2730   HAL_Delay(ETH_REG_WRITE_DELAY);
2731   (heth->Instance)->DMAOMR = tmpreg;
2732 }
2733 
ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2734 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2735 {
2736   uint32_t tmpreg1;
2737 
2738   /*------------------------ ETHERNET MACCR Configuration --------------------*/
2739   /* Get the ETHERNET MACCR value */
2740   tmpreg1 = (heth->Instance)->MACCR;
2741   /* Clear WD, PCE, PS, TE and RE bits */
2742   tmpreg1 &= ETH_MACCR_CLEAR_MASK;
2743 
2744   tmpreg1 |= (uint32_t)(((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 23U) |
2745                         ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 22U) |
2746                         (uint32_t)macconf->InterPacketGapVal |
2747                         ((uint32_t)macconf->CarrierSenseDuringTransmit << 16U) |
2748                         macconf->Speed |
2749                         ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 13U) |
2750                         ((uint32_t)macconf->LoopbackMode << 12U) |
2751                         macconf->DuplexMode |
2752                         ((uint32_t)macconf->ChecksumOffload << 10U) |
2753                         ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 9U) |
2754                         ((uint32_t)macconf->AutomaticPadCRCStrip << 7U) |
2755                         macconf->BackOffLimit |
2756                         ((uint32_t)macconf->DeferralCheck << 4U));
2757 
2758   /* Write to ETHERNET MACCR */
2759   (heth->Instance)->MACCR = (uint32_t)tmpreg1;
2760 
2761   /* Wait until the write operation will be taken into account :
2762   at least four TX_CLK/RX_CLK clock cycles */
2763   tmpreg1 = (heth->Instance)->MACCR;
2764   HAL_Delay(ETH_REG_WRITE_DELAY);
2765   (heth->Instance)->MACCR = tmpreg1;
2766 
2767   /*----------------------- ETHERNET MACFCR Configuration --------------------*/
2768 
2769   /* Get the ETHERNET MACFCR value */
2770   tmpreg1 = (heth->Instance)->MACFCR;
2771   /* Clear xx bits */
2772   tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
2773 
2774   tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
2775                         ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7U) |
2776                         macconf->PauseLowThreshold |
2777                         ((uint32_t)((macconf->UnicastPausePacketDetect == ENABLE) ? 1U : 0U) << 3U) |
2778                         ((uint32_t)((macconf->ReceiveFlowControl == ENABLE) ? 1U : 0U) << 2U) |
2779                         ((uint32_t)((macconf->TransmitFlowControl == ENABLE) ? 1U : 0U) << 1U));
2780 
2781   /* Write to ETHERNET MACFCR */
2782   (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
2783 
2784   /* Wait until the write operation will be taken into account :
2785   at least four TX_CLK/RX_CLK clock cycles */
2786   tmpreg1 = (heth->Instance)->MACFCR;
2787   HAL_Delay(ETH_REG_WRITE_DELAY);
2788   (heth->Instance)->MACFCR = tmpreg1;
2789 }
2790 
ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2791 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2792 {
2793   uint32_t tmpreg1;
2794 
2795   /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
2796   /* Get the ETHERNET DMAOMR value */
2797   tmpreg1 = (heth->Instance)->DMAOMR;
2798   /* Clear xx bits */
2799   tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
2800 
2801   tmpreg1 |= (uint32_t)(((uint32_t)((dmaconf->DropTCPIPChecksumErrorFrame == DISABLE) ? 1U : 0U) << 26U) |
2802                         ((uint32_t)dmaconf->ReceiveStoreForward << 25U) |
2803                         ((uint32_t)((dmaconf->FlushRxPacket == DISABLE) ? 1U : 0U) << 20U) |
2804                         ((uint32_t)dmaconf->TransmitStoreForward << 21U) |
2805                         dmaconf->TransmitThresholdControl |
2806                         ((uint32_t)dmaconf->ForwardErrorFrames << 7U) |
2807                         ((uint32_t)dmaconf->ForwardUndersizedGoodFrames << 6U) |
2808                         dmaconf->ReceiveThresholdControl |
2809                         ((uint32_t)dmaconf->SecondFrameOperate << 2U));
2810 
2811   /* Write to ETHERNET DMAOMR */
2812   (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
2813 
2814   /* Wait until the write operation will be taken into account:
2815   at least four TX_CLK/RX_CLK clock cycles */
2816   tmpreg1 = (heth->Instance)->DMAOMR;
2817   HAL_Delay(ETH_REG_WRITE_DELAY);
2818   (heth->Instance)->DMAOMR = tmpreg1;
2819 
2820   /*----------------------- ETHERNET DMABMR Configuration --------------------*/
2821   (heth->Instance)->DMABMR = (uint32_t)(((uint32_t)dmaconf->AddressAlignedBeats << 25U) |
2822                                         dmaconf->BurstMode |
2823                                         dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or
2824                                                                        Rx it is applied for the other */
2825                                         dmaconf->TxDMABurstLength |
2826                                         ((uint32_t)dmaconf->EnhancedDescriptorFormat << 7U) |
2827                                         (dmaconf->DescriptorSkipLength << 2U) |
2828                                         dmaconf->DMAArbitration |
2829                                         ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
2830 
2831   /* Wait until the write operation will be taken into account:
2832      at least four TX_CLK/RX_CLK clock cycles */
2833   tmpreg1 = (heth->Instance)->DMABMR;
2834   HAL_Delay(ETH_REG_WRITE_DELAY);
2835   (heth->Instance)->DMABMR = tmpreg1;
2836 }
2837 
2838 /**
2839   * @brief  Configures Ethernet MAC and DMA with default parameters.
2840   *         called by HAL_ETH_Init() API.
2841   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2842   *         the configuration information for ETHERNET module
2843   * @retval HAL status
2844   */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth)2845 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2846 {
2847   ETH_MACConfigTypeDef macDefaultConf;
2848   ETH_DMAConfigTypeDef dmaDefaultConf;
2849 
2850   /*--------------- ETHERNET MAC registers default Configuration --------------*/
2851   macDefaultConf.Watchdog = ENABLE;
2852   macDefaultConf.Jabber = ENABLE;
2853   macDefaultConf.InterPacketGapVal = ETH_INTERFRAMEGAP_96BIT;
2854   macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2855   macDefaultConf.ReceiveOwn = ENABLE;
2856   macDefaultConf.LoopbackMode = DISABLE;
2857   macDefaultConf.ChecksumOffload = ENABLE;
2858   macDefaultConf.RetryTransmission = DISABLE;
2859   macDefaultConf.AutomaticPadCRCStrip = DISABLE;
2860   macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2861   macDefaultConf.DeferralCheck = DISABLE;
2862   macDefaultConf.PauseTime = 0x0U;
2863   macDefaultConf.ZeroQuantaPause = DISABLE;
2864   macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
2865   macDefaultConf.ReceiveFlowControl = DISABLE;
2866   macDefaultConf.TransmitFlowControl = DISABLE;
2867   macDefaultConf.Speed = ETH_SPEED_100M;
2868   macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2869   macDefaultConf.UnicastPausePacketDetect = DISABLE;
2870 
2871   /* MAC default configuration */
2872   ETH_SetMACConfig(heth, &macDefaultConf);
2873 
2874   /*--------------- ETHERNET DMA registers default Configuration --------------*/
2875   dmaDefaultConf.DropTCPIPChecksumErrorFrame = ENABLE;
2876   dmaDefaultConf.ReceiveStoreForward = ENABLE;
2877   dmaDefaultConf.FlushRxPacket = ENABLE;
2878   dmaDefaultConf.TransmitStoreForward = ENABLE;
2879   dmaDefaultConf.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
2880   dmaDefaultConf.ForwardErrorFrames = DISABLE;
2881   dmaDefaultConf.ForwardUndersizedGoodFrames = DISABLE;
2882   dmaDefaultConf.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
2883   dmaDefaultConf.SecondFrameOperate = ENABLE;
2884   dmaDefaultConf.AddressAlignedBeats = ENABLE;
2885   dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2886   dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2887   dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2888   dmaDefaultConf.EnhancedDescriptorFormat = ENABLE;
2889   dmaDefaultConf.DescriptorSkipLength = 0x0U;
2890   dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
2891 
2892   /* DMA default configuration */
2893   ETH_SetDMAConfig(heth, &dmaDefaultConf);
2894 }
2895 
2896 /**
2897   * @brief  Configures the selected MAC address.
2898   * @param  heth pointer to a ETH_HandleTypeDef structure that contains
2899   *         the configuration information for ETHERNET module
2900   * @param  MacAddr The MAC address to configure
2901   *          This parameter can be one of the following values:
2902   *             @arg ETH_MAC_Address0: MAC Address0
2903   *             @arg ETH_MAC_Address1: MAC Address1
2904   *             @arg ETH_MAC_Address2: MAC Address2
2905   *             @arg ETH_MAC_Address3: MAC Address3
2906   * @param  Addr Pointer to MAC address buffer data (6 bytes)
2907   * @retval HAL status
2908   */
ETH_MACAddressConfig(ETH_HandleTypeDef * heth,uint32_t MacAddr,uint8_t * Addr)2909 static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
2910 {
2911   uint32_t tmpreg1;
2912 
2913   /* Prevent unused argument(s) compilation warning */
2914   UNUSED(heth);
2915 
2916   /* Calculate the selected MAC address high register */
2917   tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
2918   /* Load the selected MAC address high register */
2919   (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
2920   /* Calculate the selected MAC address low register */
2921   tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
2922 
2923   /* Load the selected MAC address low register */
2924   (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
2925 }
2926 
2927 /**
2928   * @brief  Initializes the DMA Tx descriptors.
2929   *         called by HAL_ETH_Init() API.
2930   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2931   *         the configuration information for ETHERNET module
2932   * @retval None
2933   */
ETH_DMATxDescListInit(ETH_HandleTypeDef * heth)2934 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
2935 {
2936   ETH_DMADescTypeDef *dmatxdesc;
2937   uint32_t i;
2938 
2939   /* Fill each DMATxDesc descriptor with the right values */
2940   for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
2941   {
2942     dmatxdesc = heth->Init.TxDesc + i;
2943 
2944     WRITE_REG(dmatxdesc->DESC0, 0x0);
2945     WRITE_REG(dmatxdesc->DESC1, 0x0);
2946     WRITE_REG(dmatxdesc->DESC2, 0x0);
2947     WRITE_REG(dmatxdesc->DESC3, 0x0);
2948 
2949     WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
2950 
2951     /* Set Second Address Chained bit */
2952     SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_TCH);
2953 
2954     if (i < ((uint32_t)ETH_TX_DESC_CNT - 1U))
2955     {
2956       WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc + i + 1U));
2957     }
2958     else
2959     {
2960       WRITE_REG(dmatxdesc->DESC3, (uint32_t)(heth->Init.TxDesc));
2961     }
2962 
2963     /* Set the DMA Tx descriptors checksum insertion */
2964     SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL);
2965   }
2966 
2967   heth->TxDescList.CurTxDesc = 0;
2968 
2969   /* Set Transmit Descriptor List Address */
2970   WRITE_REG(heth->Instance->DMATDLAR, (uint32_t) heth->Init.TxDesc);
2971 }
2972 
2973 /**
2974   * @brief  Initializes the DMA Rx descriptors in chain mode.
2975   *         called by HAL_ETH_Init() API.
2976   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2977   *         the configuration information for ETHERNET module
2978   * @retval None
2979   */
ETH_DMARxDescListInit(ETH_HandleTypeDef * heth)2980 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
2981 {
2982   ETH_DMADescTypeDef *dmarxdesc;
2983   uint32_t i;
2984 
2985   for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
2986   {
2987     dmarxdesc =  heth->Init.RxDesc + i;
2988 
2989     WRITE_REG(dmarxdesc->DESC0, 0x0);
2990     WRITE_REG(dmarxdesc->DESC1, 0x0);
2991     WRITE_REG(dmarxdesc->DESC2, 0x0);
2992     WRITE_REG(dmarxdesc->DESC3, 0x0);
2993     WRITE_REG(dmarxdesc->BackupAddr0, 0x0);
2994     WRITE_REG(dmarxdesc->BackupAddr1, 0x0);
2995 
2996     /* Set Own bit of the Rx descriptor Status */
2997     dmarxdesc->DESC0 = ETH_DMARXDESC_OWN;
2998 
2999     /* Set Buffer1 size and Second Address Chained bit */
3000     dmarxdesc->DESC1 = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
3001 
3002     /* Enable Ethernet DMA Rx Descriptor interrupt */
3003     dmarxdesc->DESC1 &= ~ETH_DMARXDESC_DIC;
3004 
3005     /* Set Rx descritors addresses */
3006     WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
3007 
3008     if (i < ((uint32_t)ETH_RX_DESC_CNT - 1U))
3009     {
3010       WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc + i + 1U));
3011     }
3012     else
3013     {
3014       WRITE_REG(dmarxdesc->DESC3, (uint32_t)(heth->Init.RxDesc));
3015     }
3016   }
3017 
3018   WRITE_REG(heth->RxDescList.RxDescIdx, 0);
3019   WRITE_REG(heth->RxDescList.RxDescCnt, 0);
3020   WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0);
3021   WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0);
3022   WRITE_REG(heth->RxDescList.ItMode, 0);
3023 
3024   /* Set Receive Descriptor List Address */
3025   WRITE_REG(heth->Instance->DMARDLAR, (uint32_t) heth->Init.RxDesc);
3026 }
3027 
3028 /**
3029   * @brief  Prepare Tx DMA descriptor before transmission.
3030   *         called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
3031   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3032   *         the configuration information for ETHERNET module
3033   * @param  pTxConfig: Tx packet configuration
3034   * @param  ItMode: Enable or disable Tx EOT interrept
3035   * @retval Status
3036   */
ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig,uint32_t ItMode)3037 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode)
3038 {
3039   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
3040   uint32_t descidx = dmatxdesclist->CurTxDesc;
3041   uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3042   uint32_t idx;
3043   uint32_t descnbr = 0;
3044   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3045 
3046   ETH_BufferTypeDef  *txbuffer = pTxConfig->TxBuffer;
3047   uint32_t           bd_count = 0;
3048 
3049   /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3050   if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN)
3051       || (dmatxdesclist->PacketAddress[descidx] != NULL))
3052   {
3053     return HAL_ETH_ERROR_BUSY;
3054   }
3055 
3056 
3057   descnbr += 1U;
3058 
3059   /* Set header or buffer 1 address */
3060   WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer);
3061 
3062   /* Set header or buffer 1 Length */
3063   MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len);
3064 
3065   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != 0U)
3066   {
3067     MODIFY_REG(dmatxdesc->DESC0, ETH_DMATXDESC_CIC, pTxConfig->ChecksumCtrl);
3068   }
3069 
3070   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != 0U)
3071   {
3072     MODIFY_REG(dmatxdesc->DESC0, ETH_CRC_PAD_DISABLE, pTxConfig->CRCPadCtrl);
3073   }
3074 
3075 
3076   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != 0U)
3077   {
3078     /* Set Vlan Type */
3079     SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_VF);
3080   }
3081 
3082   /* Mark it as First Descriptor */
3083   SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS);
3084 
3085   /* Ensure rest of descriptor is written to RAM before the OWN bit */
3086   __DMB();
3087   /* set OWN bit of FIRST descriptor */
3088   SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
3089 
3090   /* only if the packet is split into more than one descriptors > 1 */
3091   while (txbuffer->next != NULL)
3092   {
3093     /* Clear the LD bit of previous descriptor */
3094     CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS);
3095     if (ItMode != ((uint32_t)RESET))
3096     {
3097       /* Set Interrupt on completion bit */
3098       SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3099     }
3100     else
3101     {
3102       /* Clear Interrupt on completion bit */
3103       CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3104     }
3105     /* Increment current tx descriptor index */
3106     INCR_TX_DESC_INDEX(descidx, 1U);
3107     /* Get current descriptor address */
3108     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3109 
3110     /* Clear the FD bit of new Descriptor */
3111     CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_FS);
3112 
3113     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3114     if ((READ_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN) == ETH_DMATXDESC_OWN)
3115         || (dmatxdesclist->PacketAddress[descidx] != NULL))
3116     {
3117       descidx = firstdescidx;
3118       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3119 
3120       /* clear previous desc own bit */
3121       for (idx = 0; idx < descnbr; idx ++)
3122       {
3123         /* Ensure rest of descriptor is written to RAM before the OWN bit */
3124         __DMB();
3125 
3126         CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
3127 
3128         /* Increment current tx descriptor index */
3129         INCR_TX_DESC_INDEX(descidx, 1U);
3130         /* Get current descriptor address */
3131         dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3132       }
3133 
3134       return HAL_ETH_ERROR_BUSY;
3135     }
3136 
3137     descnbr += 1U;
3138 
3139     /* Get the next Tx buffer in the list */
3140     txbuffer = txbuffer->next;
3141 
3142     /* Set header or buffer 1 address */
3143     WRITE_REG(dmatxdesc->DESC2, (uint32_t)txbuffer->buffer);
3144 
3145     /* Set header or buffer 1 Length */
3146     MODIFY_REG(dmatxdesc->DESC1, ETH_DMATXDESC_TBS1, txbuffer->len);
3147 
3148     bd_count += 1U;
3149 
3150     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3151     __DMB();
3152     /* Set Own bit */
3153     SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_OWN);
3154   }
3155 
3156   if (ItMode != ((uint32_t)RESET))
3157   {
3158     /* Set Interrupt on completion bit */
3159     SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3160   }
3161   else
3162   {
3163     /* Clear Interrupt on completion bit */
3164     CLEAR_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_IC);
3165   }
3166 
3167   /* Mark it as LAST descriptor */
3168   SET_BIT(dmatxdesc->DESC0, ETH_DMATXDESC_LS);
3169   /* Save the current packet address to expose it to the application */
3170   dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3171 
3172   dmatxdesclist->CurTxDesc = descidx;
3173 
3174   /* disable the interrupt */
3175   __disable_irq();
3176 
3177   dmatxdesclist->BuffersInUse += bd_count + 1U;
3178 
3179   /* Enable interrupts back */
3180   __enable_irq();
3181 
3182 
3183   /* Return function status */
3184   return HAL_ETH_ERROR_NONE;
3185 }
3186 
3187 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)3188 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3189 {
3190   /* Init the ETH Callback settings */
3191   heth->TxCpltCallback   = HAL_ETH_TxCpltCallback;    /* Legacy weak TxCpltCallback   */
3192   heth->RxCpltCallback   = HAL_ETH_RxCpltCallback;    /* Legacy weak RxCpltCallback   */
3193   heth->ErrorCallback    = HAL_ETH_ErrorCallback;     /* Legacy weak ErrorCallback */
3194   heth->PMTCallback      = HAL_ETH_PMTCallback;       /* Legacy weak PMTCallback      */
3195   heth->WakeUpCallback   = HAL_ETH_WakeUpCallback;    /* Legacy weak WakeUpCallback   */
3196   heth->rxLinkCallback   = HAL_ETH_RxLinkCallback;    /* Legacy weak RxLinkCallback   */
3197   heth->txFreeCallback   = HAL_ETH_TxFreeCallback;    /* Legacy weak TxFreeCallback   */
3198 #ifdef HAL_ETH_USE_PTP
3199   heth->txPtpCallback    = HAL_ETH_TxPtpCallback;     /* Legacy weak TxPtpCallback   */
3200 #endif /* HAL_ETH_USE_PTP */
3201   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3202 }
3203 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3204 
3205 /**
3206   * @}
3207   */
3208 
3209 /**
3210   * @}
3211   */
3212 
3213 #endif /* ETH */
3214 
3215 #endif /* HAL_ETH_MODULE_ENABLED */
3216 
3217 /**
3218   * @}
3219   */
3220 
3221