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