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