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